1

I just recently started making a VST Host and for that i'm using the VST.NET library for C#. Now i'm trying to create the routing between the Line in, through the Plugins and to the Line Out. My plan is to record the audio in the host and sent the recorded buffer (live when recorded not saving a temporary file) to the first plugin. The output of the first Plugin (which will be an Effects Plugin will the go live to the next plugin. After it got routed through all necessary plugins it should be routed to an audio output device.

For the recording part i already took a look at NAudio and created the recording part like this. Now i can get the Audio Buffer in my isDataAvailable method in the form of a byte array. Problem being that VST.NET uses the ProcessReplacing method (i think) to process audio to a plugin and this method requires a buffer in form of an instance of a VstAudioBuffer Array and the constructor of VstAudioBuffer requires a float* buffer.

Now how should i convert those variables to send them to the plugin? Also in the end how can i then convert them back to send to WaveOut?

Another question: Can i, after i call plugin1.processreplacing to send the recorded data to plugin1 call plugin2.processreplacing with the parameters inputBuffer being the outputbuffer of the processreplacing-call to plugin1 to send the processed audio to plugin2?

I tried to modify the example from the link and made this:

void waveIn_DataAvailable(object sender, WaveInEventArgs e)
    {
        if (waveProvider != null)
            waveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
        int bytesRead = waveProvider.Read(naudioBuf,0,e.BytesRecorded);
        naudioBuf = e.Buffer;

        unsafe
        {
            fixed (byte* byteBuf = &naudioBuf[0])
            {
                float* floatBuf = (float*)byteBuf;
                for (int i = 0; i < e.BytesRecorded; i++)
                {
                    vstBufIn[0][i] = *(floatBuf + i);
                }
            }
        }

        cont.PluginCommandStub.MainsChanged(true);
        cont.PluginCommandStub.StartProcess();
        cont.PluginCommandStub.ProcessReplacing(vstBufIn, vstBufOut);
        cont.PluginCommandStub.StopProcess();
        cont.PluginCommandStub.MainsChanged(false);

        unsafe
        {
            float* tmpBufL = ((IDirectBufferAccess32)vstBufOut[0]).Buffer;
            byte[] buffer = BitConverter.GetBytes(*(tmpBufL));
            waveOutProv.AddSamples(buffer, 0, buffer.Length);
        }
    }

The setup for WaveIn and Out looks like this:

        WaveIn waveIn = new WaveIn(this.Handle);
        waveIn = new WaveIn(this.Handle);
        waveIn.BufferMilliseconds = 25;
        waveIn.DataAvailable += waveIn_DataAvailable;

        waveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
        waveOutProv = new BufferedWaveProvider(waveIn.WaveFormat);

        waveOut = new WaveOut();
        waveOut.DesiredLatency = 100;
        waveOut.Init(waveOutProv);

        waveIn.StartRecording();
        waveOut.Play();

        this.sampleRate = 44100;
        this.channels = 2;
        this.blockSize = 4410;

        cont.PluginCommandStub.SetBlockSize(blockSize);
        cont.PluginCommandStub.SetSampleRate((float)sampleRate);

        vstBufManIn = new VstAudioBufferManager(channels, blockSize * channels);
        vstBufManOut = new VstAudioBufferManager(channels, blockSize * channels);

        vstBufIn = vstBufManIn.ToArray();
        vstBufOut = vstBufManOut.ToArray();

        naudioBuf = new byte[blockSize * channels * 4];

I'm getting an output and it also gets louder when the input in the mic is louder but it's just a weird "clicking noise". I'm guessing that i did something wrong with converting the vstBufOut to the bite array but i don't quite know what is wrong.

Community
  • 1
  • 1
MariusR
  • 1,534
  • 2
  • 11
  • 20
  • Did you check the VST.NET discussion board on the codeplex site? https://vstnet.codeplex.com/discussions/228692 – obiwanjacobi Apr 19 '14 at 17:13
  • 2nd: Yes. Serial (chained) audio processing only needs one set of buffers (4 for stereo: 2-in and 2-out). Some hosts even give you one set (2 for both in and out) - but I think that can give side effects with plugins that do not sequentially read-and-write the buffers... – obiwanjacobi Apr 19 '14 at 17:15
  • So i tried to modify the code you linked so that it can be used with wavein but i'm getting a weird output. Code is added to the question. – MariusR Apr 20 '14 at 10:57
  • I'm also having 2 other small questions which aren't really worth creating new questions for: 1: Is the only(best) way to trigger something in a plugin by using Midi Events (by creating an instance of VstMidiEvent and sending it to the plugin)? 2: My plugin is added to a Panel in a Windows Form but i doesn't update properly. Some actions don't have a visual effect until another action is performed. Is there a way to solve that? – MariusR Apr 20 '14 at 16:15
  • I think the samples to NAudio need to be interleaved while the samples in VST(.NET) are separate channels. Also you need to call (AudioProcessor.)Process repeatedly but not the MainChanged and Start/StopProcessing methods. Start/StopProcessing indicate if the audio-engine is running and MainChanged is 'power' on/off for the plugin. – obiwanjacobi Apr 21 '14 at 08:41
  • 1) Besides the normal plugin interface methods, (Midi)Events and Parameters are the main avenues to change plugin state. What 'something' are you trying to trigger? – obiwanjacobi Apr 21 '14 at 08:44
  • 2) Do you call the Idle method on the editor? – obiwanjacobi Apr 21 '14 at 08:44
  • I'm sorry but i'm not that well into audio programming yet so i don't really know how to do that. I know i can get a float* for the Left and one for the right channel and then can add them to a float array like it is in the example in the discussion you linked but wouldn't i need a byte array for my BufferedWaveProvider? I also tried recreating the AudioOutput class like in the link with the modified Read method and changed the wavStream.Read(... to a BufferedWaveProvider.Read filled by WaveIn. The problem is either i'm getting a ArrayIndexOutofBounds exception or my Audio Driver crashes... – MariusR Apr 21 '14 at 11:03
  • 1) Okay thanks. I'm trying to trigger a MIDI Event i setup in the Mobius Looper Plugin so that i can start Recording for example. 2) I'm afraid i don't know (I am still a newbie when it comes to VST.NET and Audio Programming). How would a call to this method look like? – MariusR Apr 21 '14 at 11:05
  • For 2) I figured it out myself. I'm now calling EditorIdle() on the plugin in the isDataAvailable method and the plugin seems to be updated properly The main problem i have still is the byte array to float* to byte array conversion which i can't quite figure out yet. and i also couldn't find any helpful information on the web.... – MariusR Apr 23 '14 at 20:20
  • VST works with samples that are floats in a [-1, 1] range. You have to convert this to whatever it is you are trying to drive. So you may have to convert (map) the value to some integer range as well as interleaving the L- and R-channel samples if the target requires that. – obiwanjacobi Apr 24 '14 at 06:24
  • I couldn't yet solve this problem, though i got kind of close...I decided to post my question in the codeplex forums as i thing this discussion is getting to a point at which it's a bit too big for stackoverflow. https://vstnet.codeplex.com/discussions/544000 – MariusR May 01 '14 at 21:31

0 Answers0