Esempio n. 1
0
        public void LoadChannelPreset(VstPluginChannel channel, ChannelPreset channelPreset)
        {
            // First load instrument
            if (channelPreset.InstrumentVstPreset.State != PluginState.Empty)
            {
                channel.InstrumentPlugin.AttachVstPluginContext(GetVstPluginContext(channelPreset.InstrumentVstPreset.Name), channelPreset.InstrumentVstPreset.Name);
            }

            // Then load all effects
            for (int i = 0; i < VstPluginChannel.NumberOfEffectPlugins; i++)
            {
                if (channelPreset.EffectVstPresets[i].State != PluginState.Empty)
                {
                    channel.EffectPlugins[i].AttachVstPluginContext(GetVstPluginContext(channelPreset.EffectVstPresets[i].Name), channelPreset.EffectVstPresets[i].Name);
                }
            }

            channel.ImportChannelPreset(channelPreset);
        }
Esempio n. 2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="settingsMgr"></param>
        /// <param name="channels"></param>
        public AudioPluginEngine(SettingsManager settingsMgr, VuMeter[] meters, Panel hostScrollPanel)
        {
            // Add editor panel to host to allow scrolling
            mHostScrollPanel = hostScrollPanel;
            Panel hostEditorPanel = new Panel();

            hostScrollPanel.Controls.Add(hostEditorPanel);

            PluginChannels = new VstPluginChannel[NrOfPluginChannels];
            mMidiPanic     = new bool[NrOfPluginChannels];

            // Create all channel, effect and master effect plugins
            for (int i = 0; i < NrOfPluginChannels; i++)
            {
                PluginChannels[i] = new VstPluginChannel(settingsMgr.Settings.AsioBufferSize);
                mMidiPanic[i]     = false;
            }
            MasterEffectPluginChannel = new VstPluginChannel(settingsMgr.Settings.AsioBufferSize);

            foreach (VstPlugin plugin in PluginChannels.SelectMany(x => x.AllPlugins))
            {
                plugin.EditorPanel = hostEditorPanel;
                // Let controls know if other control loaded an editor
                plugin.OnEditorOpening += chCtrl_OnEditorOpen;
                plugin.OnEditorOpened  += chCtrl_OnEditorOpened;
                plugin.OnEditorClosed  += chCtrl_OnEditorClose;
            }

            mSettingsMgr = settingsMgr;
            mVUMeters    = meters;

            if (mSettingsMgr.Settings.VSTPluginFolders != null)
            {
                foreach (string path in mSettingsMgr.Settings.VSTPluginFolders)
                {
                    addPath(path);
                }
            }

            MasterPan = mSettingsMgr.Settings.MasterPan;

            // Send all notes off on midi channel 1
            byte[] midiData = new byte[4];
            // http://www.midi.org/techspecs/midimessages.php
            midiData[0] = 176;  // Send all notes off on midi channel 1
            midiData[1] = 123;  // All Notes Off
            midiData[2] = 0;
            midiData[3] = 0;

            VstMidiEvent midiPanicEvent = new VstMidiEvent(
                /*DeltaFrames*/ 0,
                /*NoteLength*/ 0,
                /*NoteOffset*/ 0,
                midiData,
                /*Detune*/ 0,
                /*NoteOffVelocity*/ 127);

            mMidiPanicEvents    = new VstEvent[1];
            mMidiPanicEvents[0] = midiPanicEvent;

            mMidiDevice = new MidiDevice();
        }
Esempio n. 3
0
        /// <summary>
        /// Handle ASIO update event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void asio_BufferUpdateHandler(object sender, EventArgs e)
        {
            mCpuLoadStopWatch.Restart();

            //long elapsedticksoutsidehandler = mCpuLoadStopWatch.ElapsedTicks;
            //ticksArray[ticksArrayIndex++] = elapsedticksoutsidehandler - prevTicks;
            //if (ticksArrayIndex == 344)
            //{
            //    ticksArrayIndex = 0;
            //}
            //prevTicks = elapsedticksoutsidehandler;
#endif
            if (mFirstAsioBufferUpdateHandlerCall)
            {
                uint taskIndex;
                Thread.CurrentThread.Priority = ThreadPriority.Highest;
                IntPtr handle = AvSetMmThreadCharacteristics("Pro Audio", out taskIndex);
                mFirstAsioBufferUpdateHandlerCall = false;
            }

            // Clear output buffer
            for (int index = 0; index < mAsioBuffSize; index++)
            {
                mAsioOutputLeft[index]  = 0.0f;
                mAsioOutputRight[index] = 0.0f;
            }

            // Dequeue all midi in messages
            int midiInCount = mMidiDevice.MidiInMessagesCount();

            // Expand array if required
            if (midiInCount > mMidiInMessages.Length)
            {
                mMidiInMessages = new MidiMessage[midiInCount];
            }

            // Now dequeue midi messages
            midiInCount = mMidiDevice.DequeueMidiInMessages(mMidiInMessages, 0, midiInCount);

            for (int i = 0; i < NrOfPluginChannels; i++)
            {
                bool midiPanic = mMidiPanic[i];
                mMidiPanic[i] = false;

                VstPluginChannel channel = PluginChannels[i];

                // Copy Asio input to channel input
                // todo: [JBK] point the VstChannel input buffer directly tot the input buffer from the asio driver to prevent all the copying.
                // For now just try this if it works
                if (channel.InputBuffers.Count > 0)
                {
                    for (int n = 0; n < mAsioBuffSize; ++n)
                    {
                        channel.InputBuffers.Raw[0][n] = mAsioInputLeft[n];
                        channel.InputBuffers.Raw[1][n] = mAsioInputRight[n];
                    }
                }

                if (channel.InstrumentPlugin.State == PluginState.Empty)
                {
                    continue;
                }
                else if (channel.InstrumentPlugin.State == PluginState.Unloading)
                {
                    channel.InstrumentPlugin.FinishUnloading();
                    continue;
                }

                // Activated OR deactivated (still receiving note-off messages):

                VstEvent[] filteredMidiEvents = filterMidiInMessages(midiInCount, channel.InstrumentPlugin);

                if (midiPanic)
                {
                    channel.InstrumentPlugin.VstPluginContext.PluginCommandStub.ProcessEvents(mMidiPanicEvents);
                }
                else
                {
                    channel.InstrumentPlugin.VstPluginContext.PluginCommandStub.ProcessEvents(filteredMidiEvents);
                }

                // Get audio from the instrument plugin
                channel.InstrumentPlugin.VstPluginContext.PluginCommandStub.ProcessReplacing(channel.InstrumentPlugin.InputBuffers.Buffers, channel.InstrumentPlugin.OutputBuffers.Buffers);

                bool swappedBuffers = false;

                // Effect plugins
                for (int n = 0; n < VstPluginChannel.NumberOfEffectPlugins; n++)
                {
                    VstPlugin effectPlugin = channel.EffectPlugins[n];

                    if (effectPlugin.State == PluginState.Empty)
                    {
                        continue;
                    }
                    else if (effectPlugin.State == PluginState.Unloading)
                    {
                        effectPlugin.FinishUnloading();
                        continue;
                    }
                    else if (effectPlugin.State == PluginState.Activated)
                    {
                        if (midiPanic)
                        {
                            channel.InstrumentPlugin.VstPluginContext.PluginCommandStub.ProcessEvents(mMidiPanicEvents);
                        }
                        else
                        {
                            channel.InstrumentPlugin.VstPluginContext.PluginCommandStub.ProcessEvents(filteredMidiEvents);
                        }

                        if (!swappedBuffers)
                        {
                            // Take outputbuffer of the previous 'process replacing' as input, and write output to the other (input) buffer.
                            effectPlugin.VstPluginContext.PluginCommandStub.ProcessReplacing(effectPlugin.OutputBuffers.Buffers, effectPlugin.InputBuffers.Buffers);
                            swappedBuffers = true;
                        }
                        else
                        {
                            // Take inputbuffer of the previous 'process replacing' as input, and write output to the other (output) buffer.
                            effectPlugin.VstPluginContext.PluginCommandStub.ProcessReplacing(effectPlugin.InputBuffers.Buffers, effectPlugin.OutputBuffers.Buffers);
                            swappedBuffers = false;
                        }
                    }
                }

                // Now copy to mix
                for (int index = 0; index < mAsioBuffSize; index++)
                {
                    if (swappedBuffers)
                    {
                        // todo: Pan
                        mAsioOutputLeft[index]  += channel.InputBuffers.Raw[0][index] * channel.InstrumentPlugin.Volume;
                        mAsioOutputRight[index] += channel.InputBuffers.Raw[1][index] * channel.InstrumentPlugin.Volume;
                    }
                    else
                    {
                        // todo: Pan
                        mAsioOutputLeft[index]  += channel.OutputBuffers.Raw[0][index] * channel.InstrumentPlugin.Volume;
                        mAsioOutputRight[index] += channel.OutputBuffers.Raw[1][index] * channel.InstrumentPlugin.Volume;
                    }
                }
            }

            //mMidiEventsAll.Free (midiEventsAllCount );
            //mMidiEventsAllExceptNoteOn.Free(midiEventsAllExceptNoteOnCount);

            // Master pan + measure max volume levels +
            mMaxVolLeft  = 0.0f;
            mMaxVolRight = 0.0f;
            for (int index = 0; index < mAsioBuffSize; index++)
            {
                // Master pan
                mAsioOutputLeft[index]  *= mPanLeft;
                mAsioOutputRight[index] *= mPanRight;

                // Get max volume levels
                if (mAsioOutputLeft[index] > mMaxVolLeft)
                {
                    mMaxVolLeft = mAsioOutputLeft[index];
                }
                if (mAsioOutputRight[index] > mMaxVolRight)
                {
                    mMaxVolRight = mAsioOutputRight[index];
                }
            }
            mVUMeters[0].Value = mMaxVolLeft;
            mVUMeters[1].Value = mMaxVolRight;


            lock (mMP3RecorderLockObj)
            {
                if (mMp3Recorder != null)
                {
                    mMp3Recorder.WriteSamples(mAsioOutputLeft, mAsioOutputRight, mAsioBuffSize);
                }
            }

#if NAUDIO_ASIO
            // Copy mix
            for (int index = 0; index < mMixLeft.Length; index++)
            {
                // First copy left sample
                Buffer.BlockCopy(sampleToInt32Bytes(mMixLeft[index]), 0, mAsioLeftInt32LSBBuff, index * 4, 4);
                // Then copy right sample
                Buffer.BlockCopy(sampleToInt32Bytes(mMixRight[index]), 0, mAsioRightInt32LSBBuff, index * 4, 4);
            }

            // Copy left buff
            Marshal.Copy(mAsioLeftInt32LSBBuff, 0, e.OutputBuffers[0], e.SamplesPerBuffer * 4);

            // Copy right buff
            Marshal.Copy(mAsioRightInt32LSBBuff, 0, e.OutputBuffers[1], e.SamplesPerBuffer * 4);

            mVstTimeInfo.SamplePosition++;
            e.WrittenToOutputBuffers = true;
#else
            // Start buffer calculations for next asio call.
            VstTimeInfo.SamplePosition++;
#endif
            int  cpuLoad = 0;
            long elapsedTicksDuringHandler = mCpuLoadStopWatch.ElapsedTicks;
            cpuLoad = (int)(elapsedTicksDuringHandler * 100 / stopWatchTicksForOneAsioBuffer);
            if (cpuLoad > mMaxCpuLoad)
            {
                mMaxCpuLoad = cpuLoad;
            }
        }