コード例 #1
0
        private static int SquareFill(ToneChannel ch, short[] buffer, int index, int count)
        {
            if (ch.GenType != ch.GenTypePrev)
            {
                ch.FreqCountPrev = -1;
                ch.Noise.Sign    = 1;
                ch.GenTypePrev   = ch.GenType;
            }

            if (ch.FreqCount != ch.FreqCountPrev)
            {
                ch.Noise.Scale   = (44100 / 2) * ch.FreqCount;
                ch.Noise.Count   = ch.Noise.Scale;
                ch.FreqCountPrev = ch.FreqCount;
            }

            for (int i = index; i < (index + count); i++)
            {
                buffer[i] = (ch.Noise.Sign != 0) ? VolumeTable[ch.Attenuation] : (short)(0 - VolumeTable[ch.Attenuation]);

                // get next sample
                ch.Noise.Count -= Mult;
                while (ch.Noise.Count <= 0)
                {
                    ch.Noise.Sign  ^= 1;
                    ch.Noise.Count += ch.Noise.Scale;
                }
            }

            return(count);
        }
コード例 #2
0
        private static int NoiseFill(ToneChannel ch, short[] buffer, int index, int count)
        {
            if (ch.GenType != ch.GenTypePrev)
            {
                ch.FreqCountPrev = -1;
                ch.GenTypePrev   = ch.GenType;
            }

            if (ch.FreqCount != ch.FreqCountPrev)
            {
                ch.Noise.Scale    = (44100 / 2) * ch.FreqCount;
                ch.Noise.Count    = ch.Noise.Scale;
                ch.FreqCountPrev  = ch.FreqCount;
                ch.Noise.Feedback = ch.GenType == GenerateWhite ? FeedbackWhiteNoise : FeedbackPeriodicNoise;

                // reset noise shifter
                ch.Noise.NoiseState = NoiseGeneratorStartPreset;
                ch.Noise.Sign       = (int)(ch.Noise.NoiseState & 1);
            }

            for (int i = index; i < (index + count); i++)
            {
                buffer[i] = (ch.Noise.Sign != 0) ? VolumeTable[ch.Attenuation] : (short)(0 - VolumeTable[ch.Attenuation]);

                // get next sample
                ch.Noise.Count -= Mult;
                while (ch.Noise.Count <= 0)
                {
                    if ((ch.Noise.NoiseState & 1) != 0)
                    {
                        ch.Noise.NoiseState ^= (uint)ch.Noise.Feedback;
                    }

                    ch.Noise.NoiseState >>= 1;
                    ch.Noise.Sign         = (int)(ch.Noise.NoiseState & 1);
                    ch.Noise.Count       += ch.Noise.Scale;
                }
            }

            return(count);
        }
コード例 #3
0
        int ISoundDriver.Open(int channel)
        {
            ToneChannel tc = new ToneChannel();

            tc.Attenuation   = 0xf; // silence
            tc.AgiChannel    = channel;
            tc.FreqCount     = 250;
            tc.FreqCountPrev = -1;
            tc.GenType       = GenerateTone;
            tc.GenTypePrev   = -1;
            tc.NoteCount     = 0;
            tc.Avail         = 1;

            this.channels.Add(tc);

            tc.Handle = this.pcmDriver.Open(this.TonePcmCallback, tc);
            if (tc.Handle == 0)
            {
                this.channels.Remove(tc);
                return(0);
            }

            return(tc.Handle);
        }
コード例 #4
0
        private int TonePcmCallback(ToneChannel ch, short[] buffer, int count)
        {
            int result = -1;
            int index  = 0;

            while (count > 0)
            {
                if (ch.NoteCount <= 0)
                {
                    // Get new tone data
                    Tone tone = new Tone();
                    tone.FrequencyCount = 0;
                    tone.Attenuation    = 0x0f;
                    tone.Type           = GenerateTone;

                    if (ch.Avail != 0 && this.interpreter.SoundManager.FillChannel(ch.AgiChannel, tone) == 0)
                    {
                        ch.Attenuation = tone.Attenuation;
                        ch.FreqCount   = tone.FrequencyCount;
                        ch.GenType     = tone.Type;

                        // setup counters 'n stuff
                        // 44100 samples per sec.. tone changes 60 times per sec
                        ch.NoteCount = 44100 / 60;

                        result = 0;
                    }
                    else
                    {
                        ch.GenType   = GenerateSilence;
                        ch.NoteCount = count;
                        ch.Avail     = 0;
                    }
                }

                // Write nothing
                if (ch.FreqCount == 0 || ch.Attenuation == 0x0f)
                {
                    ch.GenType = GenerateSilence;
                }

                // Find which is smaller, the buffer or the note count
                int fillSize = ch.NoteCount < count ? ch.NoteCount : count;

                switch (ch.GenType)
                {
                case GenerateTone:
                    fillSize = PcmSoundDriver.SquareFill(ch, buffer, index, fillSize);
                    break;

                case GeneratePeriod:
                case GenerateWhite:
                    fillSize = PcmSoundDriver.NoiseFill(ch, buffer, index, fillSize);
                    break;

                case GenerateSilence:
                default:
                    fillSize = PcmSoundDriver.SilenceFill(buffer, index, fillSize);
                    break;
                }

                ch.NoteCount -= fillSize;
                count        -= fillSize;
                index        += fillSize;
            }

            return(result);
        }