public static EffectSet CreateLoopEffectSet(StreamHandle streamHandle, Form form)
 {
     EffectSet set = new EffectSet();
     foreach (EffectDescription desc in s_effectMap.Values) {
         set.Add(desc.ConstructionFunc(streamHandle, form));
     }
     return set;
 }
        public BassStream(int idUniqueWithinPool, Form baseForm)
        {
            m_idUniqueWithinPool = idUniqueWithinPool;

            m_streamHandle = (StreamHandle)Bass.BASS_StreamCreatePush(
                Clock.TimepointRateHz,
                HolofunkBassAsio.InputChannelCount,
                BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE,
                new IntPtr(m_idUniqueWithinPool));

            m_effects = AllEffects.CreateLoopEffectSet(m_streamHandle, baseForm);
        }
        internal HolofunkBassAsioInput(HolofunkBassAsio bassAsio, int asioChannel, BufferAllocator<float> audioAllocator)
        {
            m_bassAsio = bassAsio;
            m_asioChannel = asioChannel;

            // buffer one second's worth of audio; that will always be more than we need to look at
            m_recentPastStream = new DenseSampleFloatStream(
                default(Time<Sample>),
                audioAllocator,
                1, // input channels are mono
                maxBufferedDuration: Clock.TimepointRateHz);

            m_inputToInputPushStreamAsioProc = new ASIOPROC(InputToInputPushStreamAsioProc);

            // create input push stream; this receives data pushed from ASIO's input, and feeds the mixer
            m_inputPushStream = (StreamHandle)Bass.BASS_StreamCreatePush(
                Clock.TimepointRateHz,
                HolofunkBassAsio.InputChannelCount,
                BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT,
                new IntPtr(m_asioChannel));

            // connect to ASIO input channel
            CheckError(BassAsio.BASS_ASIO_ChannelEnable(
                HolofunkBassAsio.IsInputChannel,
                m_asioChannel,
                m_inputToInputPushStreamAsioProc,
                new IntPtr(m_asioChannel)));

            // join right channel if we have more than one input channel
            // (this is not generalized for >stereo)
            if (HolofunkBassAsio.InputChannelCount == 2) {
                CheckError(BassAsio.BASS_ASIO_ChannelJoin(HolofunkBassAsio.IsInputChannel, 1, m_asioChannel));
            }

            // set format and rate of input channel
            CheckError(BassAsio.BASS_ASIO_ChannelSetFormat(HolofunkBassAsio.IsInputChannel, m_asioChannel, BASSASIOFormat.BASS_ASIO_FORMAT_FLOAT));
            CheckError(BassAsio.BASS_ASIO_ChannelSetRate(HolofunkBassAsio.IsInputChannel, m_asioChannel, Clock.TimepointRateHz));

            // add input push stream to mixer
            CheckError(BassMix.BASS_Mixer_StreamAddChannel(
                (int)m_bassAsio.MixerHStream,
                (int)m_inputPushStream,
                BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_NORAMPIN));

            // set up the input effects (aka microphone effects)
            m_inputPushEffects = AllEffects.CreateLoopEffectSet(m_inputPushStream, m_bassAsio.BaseForm);

            // connect peak level meter to input push stream
            m_plmRec = new DSP_PeakLevelMeter((int)m_inputPushStream, 0);
            m_plmRec.Notification += new EventHandler(Plm_Rec_Notification);

            // Register DSPPROC handler for input channel.  Make sure to hold the DSPPROC itself.
            // See documentation for BassAsioHandler.InputChannel
            m_inputDspProc = new DSPPROC(InputDspProc);

            // set up our recording DSP -- priority 10 hopefully means "run first first first!"
            CheckError(Bass.BASS_ChannelSetDSP((int)m_inputPushStream, m_inputDspProc, new IntPtr(0), 10) != 0);
        }