No sound when a plugin is on

Topics: Audio, Host Development, Host Processing, Newbie, Plugin Parameters, VST.NET Interop
Nov 5, 2015 at 8:25 AM
Hi. I'm working on my project. Now I'm trying to write simple VST Host.
I'm using NAudio for getting signal and VST.NET for processing.
        private AsioOut asioOut;
        private BufferedWaveProvider bufferedWaveProvider;

        private VstAudioBuffer[] vstBufIn;
        private VstAudioBuffer[] vstBufOut;
        private VstPluginContext pluginContext;

        private VstAudioBufferManager inputAudioBufferManager;
        private VstAudioBufferManager outputAudioBufferManager;

        private void Form1_Load(object sender, EventArgs e)
        {
            IVstPluginCommandStub pluginCommandStub;

            string GuitarRigDllPath = "D:\\VST\\GuitarRig5.dll";
            string AnalogDelayDllPath = "D:\\VST\\AnalogDelay.dll";

            HostCommandStub hcs = new HostCommandStub();
            pluginContext = VstPluginContext.Create(GuitarRigDllPath, hcs);
            pluginCommandStub = pluginContext.PluginCommandStub;

            Rectangle wndRect = new Rectangle();
            this.Text = pluginCommandStub.GetEffectName();
            if (pluginCommandStub.EditorGetRect(out wndRect))
            {
                this.Size = this.SizeFromClientSize(new Size(wndRect.Width, wndRect.Height));
                pluginCommandStub.EditorOpen(this.Handle);
            }

            pluginContext.PluginCommandStub.SetSampleRate(44100f);
            //Blocksize equal buffersize
            pluginContext.PluginCommandStub.SetBlockSize(256);
            
            inputAudioBufferManager = new VstAudioBufferManager(pluginContext.PluginInfo.AudioInputCount, 256);
            outputAudioBufferManager = new VstAudioBufferManager(pluginContext.PluginInfo.AudioOutputCount, 256);

            vstBufIn = inputAudioBufferManager.ToArray();
            vstBufOut = outputAudioBufferManager.ToArray();

            bufferedWaveProvider = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100,2));
            
            asioOut = new AsioOut(1);

            asioOut.InitRecordAndPlayback(bufferedWaveProvider, 2, 44100);
            asioOut.AudioAvailable += AsioOut_AudioAvailable;
            asioOut.Play();

            pluginContext.PluginCommandStub.MainsChanged(true);
            pluginContext.PluginCommandStub.StartProcess();

            this.Closing += OnClosing;
        }

        private void AsioOut_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
        {

            byte[] tmpByteInputBuffer = new byte[e.SamplesPerBuffer*4];

            //Copying the incoming bytes to array of bytes
            Marshal.Copy(e.InputBuffers[1], tmpByteInputBuffer,0,e.SamplesPerBuffer*4);
            
            //Filling the VstAudioBuffer
            for (int i = 0; i < e.SamplesPerBuffer; i++)
            {
                for (int j = 0; j < tmpByteInputBuffer.Length; j += 4)
                {
                    //Converting an array of bytes to a float value
                    vstBufIn[0][i] = BitConverter.ToSingle(tmpByteInputBuffer, j);
                    i++;
                }
            }
            
            pluginContext.PluginCommandStub.ProcessReplacing(vstBufIn, vstBufOut);
            pluginContext.PluginCommandStub.EditorIdle();

            byte[] tmp = new byte[4];
            byte[] OutByteBuffer = new byte[e.SamplesPerBuffer*4];
            int q = 0;

            //Converting array of float to array of bytes
            for (int i = 0; i< e.SamplesPerBuffer; i++)
            {
                //Converting a float value to the array of bytes
                tmp = BitConverter.GetBytes(vstBufOut[0][i]);

                //Adding the converted float value to the end of array of bytes
                for (int j = 0; j < 4; j++)
                {
                    OutByteBuffer[q] = tmp[j];
                    q++;
                }
            }

            //Copying the array of bytes to the output buffer
            Marshal.Copy(OutByteBuffer, 0, e.OutputBuffers[0], e.SamplesPerBuffer*4);
            Marshal.Copy(OutByteBuffer, 0, e.OutputBuffers[1], e.SamplesPerBuffer * 4);

            e.WrittenToOutputBuffers = true;

        }
So, it is important that the programm will working with Guitar Rig. When ProcessReplacing happens there's come very quiet and distorted sound (sound of my guitar, not the noise) to the output.

Also i tried to connect another plugins such as delay and equalizer.
With delay only I heard was very loud distorted noise.
With equalizer it was normal sound, but when I tried to change the level of some frequency the sound disappears.
Hope someone can help me.

P.S. I know, my english is not good. Please, sorry.
Coordinator
Nov 5, 2015 at 3:26 PM
My guess would be that there is an error in the conversion of the audio buffer formats used by VST (float value between -1.0 and +1.0) and the Asio buffer format (not sure which format that is).

Perhaps this will help?
https://vstnet.codeplex.com/releases/view/122820
Nov 5, 2015 at 3:49 PM
obiwanjacobi wrote:
My guess would be that there is an error in the conversion of the audio buffer formats used by VST (float value between -1.0 and +1.0) and the Asio buffer format (not sure which format that is).

Perhaps this will help?
https://vstnet.codeplex.com/releases/view/122820
Thanks for your answer! I'll check that soon.
Nov 5, 2015 at 5:17 PM
https://vstnet.codeplex.com/releases/view/122820
This is most probably evident but you do realize your code is mono, right?
There might be inconsistencies I see you initialize AsioOut with 1 (whatever that means) then pass 2 in the init function.
Nov 5, 2015 at 5:28 PM
Edited Nov 5, 2015 at 5:34 PM
My guess would be that there is an error in the conversion of the audio buffer formats used by VST (float value between -1.0 and +1.0) and the Asio buffer format (not sure which format that is).
  • I can see that happening. You are converting a [-1 to 1] single value to it's 4 byte representation. It's fine if NAudio uses a [-1 to 1] sample range format but it is most likely using something like [0 to 65535]. In that case you need convert the range of the value not just the type. What you want is not a signed float represented as 4 bytes, you want to convert the [-1 to 1] signed float value to an unsigned 16 bit integer in the range [0 to 65535]. Both use 4 bytes for their representation but the type is different signed single vs unsigned integer. Range will differ depending on your wave format (16 bit, 32 bit etc..), documentation will specify wheter it is signed unsigned etc...
Nov 5, 2015 at 6:15 PM
YuryK wrote:
https://vstnet.codeplex.com/releases/view/122820
This is most probably evident but you do realize your code is mono, right?
There might be inconsistencies I see you initialize AsioOut with 1 (whatever that means) then pass 2 in the init function.
"new AsioOut(1)" means that I have two ASIO drivers and I want to use the second one.
The second parameter of Init function is the number of channels I want to record. If I pass 1, there's nothing come from the input buffer. I don't know why. So I have to pass 2 and use the second buffer.

Thanks for help, YuryK. I'll check that soon and write about results here.
Nov 5, 2015 at 11:33 PM
Edited Nov 5, 2015 at 11:41 PM
OK got it. The reason why 1 channel is not working is because your audio driver doesn't support it. They support one or more modes but they will vary based on arbitrary design choice. You have to interrogate them to know if they support the mode. You can ask 2 inputs and 2 outputs channels at 44.1 kHz 16 bit and it will succeed almost every time because it's a very common configuration. Pro audio cards tend to have wild configurations and come with tables to list what is supported. Of course to do mono, you can always use a common configuration and leave unwanted channels undisturbed.

On second thought could also be a bug in some of your lower level API. I remember I had to patch PortAudio.Net at 2-3 places.
Nov 8, 2015 at 1:27 PM
Yeah! Got that! I had the same problem like in that thread.
YuryK wrote:
https://vstnet.codeplex.com/releases/view/122820
This is most probably evident but you do realize your code is mono, right?
There might be inconsistencies I see you initialize AsioOut with 1 (whatever that means) then pass 2 in the init function.
Thank YuryK and Marc for helping me!