Ejemplo n.º 1
0
        public M4AWrappedSample(int offset)
        {
            this.offset = offset;

            if (offset == 0 || !ROM.IsValidRomOffset(offset))
            {
                goto fail;
            }

            sample = ROM.Instance.Reader.ReadObject <M4AMLSSSample>(offset);

            if (!ROM.IsValidRomOffset(sample.Length + (offset + 0x10)))
            {
                goto fail;
            }

            gSample = new WrappedSample(sample.DoesLoop == 0x40000000, sample.LoopPoint, sample.Length, sample.Frequency >> 10, false);
            gSample.SetOffset(offset + 0x10);
            return;

fail:
            sample  = new M4AMLSSSample();
            gSample = null;
            Console.WriteLine("Error loading instrument at 0x{0:X}.", offset);
        }
Ejemplo n.º 2
0
        public void Init(byte ownerIdx, Note note, ADSR adsr, WrappedSample sample, byte vol, sbyte pan, int pitch, bool bFixed)
        {
            State       = ADSRState.Initializing;
            pos         = 0; processStep = 0; interPos = 0;
            OwnerIdx    = ownerIdx;
            Note        = note;
            this.adsr   = adsr;
            this.sample = sample;
            this.bFixed = bFixed;
            bGoldenSun  = (ROM.Instance.Game.Engine.HasGoldenSunSynths && sample.bLoop && sample.LoopPoint == 0 && sample.Length == 0);
            if (bGoldenSun)
            {
                gsPSG = ROM.Instance.Reader.ReadObject <GoldenSunPSG>(sample.GetOffset());
            }

            SetVolume(vol, pan);
            SetPitch(pitch);
        }
Ejemplo n.º 3
0
 public MLSSWrappedSample(int offset)
 {
     sample  = ROM.Instance.Reader.ReadObject <M4AMLSSSample>(offset);
     gSample = new WrappedSample(sample.DoesLoop == 0x40000000, sample.LoopPoint, sample.Length, sample.Frequency >> 10, true);
     SetOffset(offset);
 }
Ejemplo n.º 4
0
        public DirectSoundChannel NewDSNote(byte owner, ADSR env, Note note, byte vol, sbyte pan, int pitch, bool bFixed, WrappedSample sample, Track[] tracks)
        {
            DirectSoundChannel nChn = null;
            var byOwner             = dsChannels.OrderByDescending(c => c.OwnerIdx);

            foreach (var i in byOwner) // Find free
            {
                if (i.State == ADSRState.Dead || i.OwnerIdx == 0xFF)
                {
                    nChn = i;
                    break;
                }
            }
            if (nChn == null) // Find releasing
            {
                foreach (var i in byOwner)
                {
                    if (i.State == ADSRState.Releasing)
                    {
                        nChn = i;
                        break;
                    }
                }
            }
            if (nChn == null) // Find prioritized
            {
                foreach (var i in byOwner)
                {
                    if (owner >= 16 || tracks[owner].Priority > tracks[i.OwnerIdx].Priority)
                    {
                        nChn = i;
                        break;
                    }
                }
            }
            if (nChn == null)                 // None available
            {
                var lowest = byOwner.First(); // Kill lowest track's instrument if the track is lower than this one
                if (lowest.OwnerIdx >= owner)
                {
                    nChn = lowest;
                }
            }
            if (nChn != null) // Could still be null from the above if
            {
                nChn.Init(owner, note, env, sample, vol, pan, pitch, bFixed);
            }
            return(nChn);
        }
Ejemplo n.º 5
0
        public Channel PlayNote(Track track, sbyte note, byte velocity, int duration)
        {
            int shift = note + track.KeyShift;

            note           = (sbyte)(shift.Clamp(0, 0x7F));
            track.PrevNote = note;

            if (!track.Ready)
            {
                return(null);
            }

            var          owner    = track.Index;
            WrappedVoice voice    = null;
            bool         fromDrum = false;

            try
            {
                voice = Song.VoiceTable.GetVoiceFromNote(track.Voice, note, out fromDrum);
            }
            catch
            {
                System.Console.WriteLine("Track {0} tried to play a bad note... Voice {1} Note {2}", owner, track.Voice, note);
                return(null);
            }

            var aNote = new Note {
                Duration = duration, Velocity = velocity, OriginalKey = note, Key = fromDrum ? voice.Voice.GetRootNote() : note
            };

            if (voice.Voice is M4AVoiceEntry m4a)
            {
                M4AVoiceType type = (M4AVoiceType)(m4a.Type & 0x7);
                switch (type)
                {
                case M4AVoiceType.Direct:
                    bool bFixed = (m4a.Type & (int)M4AVoiceFlags.Fixed) == (int)M4AVoiceFlags.Fixed;
                    return(SoundMixer.Instance.NewDSNote(owner, m4a.ADSR, aNote,
                                                         track.GetVolume(), track.GetPan(), track.GetPitch(),
                                                         bFixed, ((M4AWrappedDirect)voice).Sample.GetSample(), tracks));

                case M4AVoiceType.Square1:
                case M4AVoiceType.Square2:
                    return(SoundMixer.Instance.NewGBNote(owner, m4a.ADSR, aNote,
                                                         track.GetVolume(), track.GetPan(), track.GetPitch(),
                                                         type, m4a.SquarePattern));

                case M4AVoiceType.Wave:
                    return(SoundMixer.Instance.NewGBNote(owner, m4a.ADSR, aNote,
                                                         track.GetVolume(), track.GetPan(), track.GetPitch(),
                                                         type, m4a.Address - ROM.Pak));

                case M4AVoiceType.Noise:
                    return(SoundMixer.Instance.NewGBNote(owner, m4a.ADSR, aNote,
                                                         track.GetVolume(), track.GetPan(), track.GetPitch(),
                                                         type, m4a.NoisePattern));
                }
            }
            else if (voice.Voice is MLSSVoice mlssvoice)
            {
                MLSSVoiceEntry entry; bool bFixed = false; WrappedSample sample = null;
                try
                {
                    entry  = mlssvoice.GetEntryFromNote(note);
                    bFixed = entry.IsFixedFrequency == 0x80;
                    sample = ((MLSSVoiceTable)Song.VoiceTable).Samples[entry.Sample].GetSample();
                }
                catch
                {
                    System.Console.WriteLine("Track {0} tried to play a bad note... Voice {1} Note {2}", owner, track.Voice, note);
                    return(null);
                }
                if (sample != null)
                {
                    return(SoundMixer.Instance.NewDSNote(owner, new ADSR {
                        A = 0xFF, S = 0xFF
                    }, aNote,
                                                         track.GetVolume(), track.GetPan(), track.GetPitch(),
                                                         bFixed, sample, tracks));
                }
            }

            return(null);
        }