Exemplo n.º 1
0
        public Mixer(Config config)
        {
            Config = config;
            (SampleRate, SamplesPerBuffer) = Utils.FrequencyTable[config.SampleRate];
            SampleRateReciprocal           = 1f / SampleRate;
            _samplesReciprocal             = 1f / SamplesPerBuffer;
            PCM8MasterVolume = config.Volume / 15f;

            _pcm8Channels = new PCM8Channel[24];
            for (int i = 0; i < _pcm8Channels.Length; i++)
            {
                _pcm8Channels[i] = new PCM8Channel(this);
            }
            _psgChannels = new PSGChannel[] { _sq1 = new SquareChannel(this), _sq2 = new SquareChannel(this), _pcm4 = new PCM4Channel(this), _noise = new NoiseChannel(this) };

            int amt = SamplesPerBuffer * 2;

            _audio = new WaveBuffer(amt * sizeof(float))
            {
                FloatBufferCount = amt
            };
            _trackBuffers = new float[0x10][];
            for (int i = 0; i < _trackBuffers.Length; i++)
            {
                _trackBuffers[i] = new float[amt];
            }
            _buffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(SampleRate, 2))
            {
                DiscardOnBufferOverflow = true,
                BufferLength            = SamplesPerBuffer * 64
            };
            Init(_buffer);
        }
Exemplo n.º 2
0
        public PCM8Channel AllocPCM8Channel(Track owner, ADSR env, Note note, byte vol, sbyte pan, int instPan, int pitch, bool bFixed, bool bCompressed, int sampleOffset)
        {
            PCM8Channel nChn = null;
            IOrderedEnumerable <PCM8Channel> byOwner = _pcm8Channels.OrderByDescending(c => c.Owner == null ? 0xFF : c.Owner.Index);

            foreach (PCM8Channel i in byOwner) // Find free
            {
                if (i.State == EnvelopeState.Dead || i.Owner == null)
                {
                    nChn = i;
                    break;
                }
            }
            if (nChn == null) // Find releasing
            {
                foreach (PCM8Channel i in byOwner)
                {
                    if (i.State == EnvelopeState.Releasing)
                    {
                        nChn = i;
                        break;
                    }
                }
            }
            if (nChn == null) // Find prioritized
            {
                foreach (PCM8Channel i in byOwner)
                {
                    if (owner.Priority > i.Owner.Priority)
                    {
                        nChn = i;
                        break;
                    }
                }
            }
            if (nChn == null)                         // None available
            {
                PCM8Channel lowest = byOwner.First(); // Kill lowest track's instrument if the track is lower than this one
                if (lowest.Owner.Index >= owner.Index)
                {
                    nChn = lowest;
                }
            }
            if (nChn != null) // Could still be null from the above if
            {
                nChn.Init(owner, note, env, sampleOffset, vol, pan, instPan, pitch, bFixed, bCompressed);
            }
            return(nChn);
        }
Exemplo n.º 3
0
        public void Process(bool output, bool recording)
        {
            for (int i = 0; i < _trackBuffers.Length; i++)
            {
                float[] buf = _trackBuffers[i];
                Array.Clear(buf, 0, buf.Length);
            }
            _audio.Clear();

            for (int i = 0; i < _pcm8Channels.Length; i++)
            {
                PCM8Channel c = _pcm8Channels[i];
                if (c.Owner != null)
                {
                    c.Process(_trackBuffers[c.Owner.Index]);
                }
            }

            for (int i = 0; i < _psgChannels.Length; i++)
            {
                PSGChannel c = _psgChannels[i];
                if (c.Owner != null)
                {
                    c.Process(_trackBuffers[c.Owner.Index]);
                }
            }

            float masterStep;
            float masterLevel;

            if (_isFading && _fadeMicroFramesLeft == 0)
            {
                masterStep  = 0;
                masterLevel = 0;
            }
            else
            {
                float fromMaster = 1f;
                float toMaster   = 1f;
                if (_fadeMicroFramesLeft > 0)
                {
                    const float scale = 10f / 6f;
                    fromMaster *= (_fadePos < 0f) ? 0f : (float)Math.Pow(_fadePos, scale);
                    _fadePos   += _fadeStepPerMicroframe;
                    toMaster   *= (_fadePos < 0f) ? 0f : (float)Math.Pow(_fadePos, scale);
                    _fadeMicroFramesLeft--;
                }
                masterStep  = (toMaster - fromMaster) * _samplesReciprocal;
                masterLevel = fromMaster;
            }
            for (int i = 0; i < _trackBuffers.Length; i++)
            {
                if (!Mutes[i])
                {
                    float   level = masterLevel;
                    float[] buf   = _trackBuffers[i];
                    for (int j = 0; j < SamplesPerBuffer; j++)
                    {
                        _audio.FloatBuffer[j * 2]       += buf[j * 2] * level;
                        _audio.FloatBuffer[(j * 2) + 1] += buf[(j * 2) + 1] * level;
                        level += masterStep;
                    }
                }
            }
            if (output)
            {
                _buffer.AddSamples(_audio.ByteBuffer, 0, _audio.ByteBufferCount);
            }
            if (recording)
            {
                _waveWriter.Write(_audio.ByteBuffer, 0, _audio.ByteBufferCount);
            }
        }
Exemplo n.º 4
0
        public void Process(bool output, bool recording)
        {
            for (int i = 0; i < trackBuffers.Length; i++)
            {
                float[] buf = trackBuffers[i];
                Array.Clear(buf, 0, buf.Length);
            }
            audio.Clear();

            for (int i = 0; i < pcm8Channels.Length; i++)
            {
                PCM8Channel c = pcm8Channels[i];
                if (c.Owner != null)
                {
                    c.Process(trackBuffers[c.Owner.Index]);
                }
            }

            for (int i = 0; i < psgChannels.Length; i++)
            {
                PSGChannel c = psgChannels[i];
                if (c.Owner != null)
                {
                    c.Process(trackBuffers[c.Owner.Index]);
                }
            }

            float fromMaster = 1f, toMaster = 1f;

            if (fadeMicroFramesLeft > 0)
            {
                const float scale = 10f / 6f;
                fromMaster *= (fadePos < 0f) ? 0f : (float)Math.Pow(fadePos, scale);
                fadePos    += fadeStepPerMicroframe;
                toMaster   *= (fadePos < 0f) ? 0f : (float)Math.Pow(fadePos, scale);
                fadeMicroFramesLeft--;
            }
            float masterStep = (toMaster - fromMaster) * samplesReciprocal;

            for (int i = 0; i < trackBuffers.Length; i++)
            {
                if (!Mutes[i])
                {
                    float   masterLevel = fromMaster;
                    float[] buf         = trackBuffers[i];
                    for (int j = 0; j < SamplesPerBuffer; j++)
                    {
                        audio.FloatBuffer[j * 2]       += buf[j * 2] * masterLevel;
                        audio.FloatBuffer[(j * 2) + 1] += buf[(j * 2) + 1] * masterLevel;
                        masterLevel += masterStep;
                    }
                }
            }
            if (output)
            {
                buffer.AddSamples(audio.ByteBuffer, 0, audio.ByteBufferCount);
            }
            if (recording)
            {
                waveWriter.Write(audio.ByteBuffer, 0, audio.ByteBufferCount);
            }
        }