private void Initialize()
        {
            //initialize mixer to take inputs
            mixingSampleProvider           = new MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels));
            mixingSampleProvider.ReadFully = true;

            //  TODO: this is a major issue!
            //waveOut.DesiredLatency = 150;

            //initialize variables
            primarySustain   = amplitude;
            secondarySustain = amplitude;

            //setup signal generators
            primarySignalGenerator      = new SignalGenerator(sampleRate, channels);
            primarySignalGenerator.Type = currentPrimaryWaveType;

            secondarySignalGenerator      = new SignalGenerator(sampleRate, channels);
            secondarySignalGenerator.Type = currentSecondaryWaveType;

            adsr1Array = new AdsrSampleProvider[_polyPhony];
            adsr2Array = new AdsrSampleProvider[_polyPhony];

            sigGen1Array = new SignalGenerator[_polyPhony];
            sigGen2Array = new SignalGenerator[_polyPhony];

            lpf1Array = new LowPassFilterSampleProvider[_polyPhony];
            lpf2Array = new LowPassFilterSampleProvider[_polyPhony];

            for (int i = 0; i < _polyPhony; i++)
            {
                // primary
                sigGen1Array[i]      = new SignalGenerator(sampleRate, channels);
                sigGen1Array[i].Type = currentPrimaryWaveType;
                sigGen1Array[i].Gain = primaryGain;
                lpf1Array[i]         = new LowPassFilterSampleProvider(sigGen1Array[i].ToWaveProvider().ToSampleProvider());
                adsr1Array[i]        = new AdsrSampleProvider(lpf1Array[i].ToWaveProvider().ToSampleProvider(), primaryAttack, primaryDecay, primarySustain, primaryRelease);

                // secondary
                sigGen2Array[i]      = new SignalGenerator(sampleRate, channels);
                sigGen2Array[i].Type = currentSecondaryWaveType;
                sigGen2Array[i].Gain = secondaryGain;
                lpf2Array[i]         = new LowPassFilterSampleProvider(sigGen2Array[i].ToWaveProvider().ToSampleProvider());
                adsr2Array[i]        = new AdsrSampleProvider(lpf2Array[i].ToWaveProvider().ToSampleProvider(), secondaryAttack, secondaryDecay, secondarySustain, secondaryRelease);
            }

            //LFSignalGenerator = new SignalGenerator(sampleRate, channels);
            //LFSignalGenerator.Gain = 0.1;
            //LFSignalGenerator.Type = LFOWaveType ;
        }
        public void StartWave(Double frequency)
        {
            // if this method is being called twice in a row before the call to StopWave...
            if (isStopped == false)
            {
                StopWave();
                Console.WriteLine("Consecutive StartWave call detected");
            }

            //if primary oscillator is active, chain effects
            if (primaryOscillator)
            {
                //wrap signal generator in adsr envelope and add to mixer
                //order of processing is Signal -> LPF -> ADSR -> Mixer
                sigGen1Array[_oscIndex].Frequency = DetuneOctave(frequency, OscillatorIndex.Primary);
                lpf1Array[_oscIndex]  = new LowPassFilterSampleProvider(sigGen1Array[_oscIndex].ToWaveProvider().ToSampleProvider());
                adsr1Array[_oscIndex] = new AdsrSampleProvider(sigGen1Array[_oscIndex].ToWaveProvider().ToSampleProvider(), primaryAttack, primaryDecay, primarySustain, primaryRelease);
                mixingSampleProvider.AddMixerInput(adsr1Array[_oscIndex]);
            } //same chaining process for secondary oscillator
            if (secondaryOscillator)
            {
                sigGen2Array[_oscIndex].Frequency = DetuneOctave(frequency, OscillatorIndex.Secondary);
                lpf2Array[_oscIndex]  = new LowPassFilterSampleProvider(sigGen2Array[_oscIndex].ToWaveProvider().ToSampleProvider());
                adsr2Array[_oscIndex] = new AdsrSampleProvider(sigGen2Array[_oscIndex].ToWaveProvider().ToSampleProvider(), secondaryAttack, secondaryDecay, secondarySustain, secondaryRelease);
                mixingSampleProvider.AddMixerInput(adsr2Array[_oscIndex]);
            }

            isStopped = false;

            //add LFO signalto mixer
            //if (LFO)
            //{
            //    LFSignalGenerator.Frequency = 5;
            //    OffsetSampleProvider offsetSampleProvider = new OffsetSampleProvider(LFSignalGenerator.ToWaveProvider().ToSampleProvider());
            //    mixingSampleProvider.AddMixerInput(offsetSampleProvider);
            //}
            // increment the play index upon each play
            // _oscIndex = _oscIndex == _polyPhony - 1 ? 0 : _oscIndex + 1;
        }
        public MixingSampleProvider PreparePlay(double frequency)
        {
            //if primary oscillator is active, chain effects
            if (primaryOscillator)
            {
                //wrap signal generator in adsr envelope and add to mixer
                //order of processing is Signal -> LPF -> ADSR -> Mixer
                sigGen1Array[_oscIndex].Frequency = DetuneOctave(frequency, OscillatorIndex.Primary);
                lpf1Array[_oscIndex]  = new LowPassFilterSampleProvider(sigGen1Array[_oscIndex].ToWaveProvider().ToSampleProvider());
                adsr1Array[_oscIndex] = new AdsrSampleProvider(sigGen1Array[_oscIndex].ToWaveProvider().ToSampleProvider(), primaryAttack, primaryDecay, primarySustain, primaryRelease);
                mixingSampleProvider.AddMixerInput(adsr1Array[_oscIndex]);
            } //same chaining process for secondary oscillator
            if (secondaryOscillator)
            {
                sigGen2Array[_oscIndex].Frequency = DetuneOctave(frequency, OscillatorIndex.Secondary);
                lpf2Array[_oscIndex]  = new LowPassFilterSampleProvider(sigGen2Array[_oscIndex].ToWaveProvider().ToSampleProvider());
                adsr2Array[_oscIndex] = new AdsrSampleProvider(sigGen2Array[_oscIndex].ToWaveProvider().ToSampleProvider(), secondaryAttack, secondaryDecay, secondarySustain, secondaryRelease);
                mixingSampleProvider.AddMixerInput(adsr2Array[_oscIndex]);
            }

            // Console.WriteLine("Oscillator Passing " + mixingSampleProvider.MixerInputs.Count() + "inputs");

            return(mixingSampleProvider);
        }