NAudio: Using ASIO to Record Sound and Output with a Guitar

I am currently working on SR. a project, which is a windows application that will allow users to plug in a guitar and create distortions in real time and play it using input and output and automatically insert it into ASCII tabs. I'm currently trying to work in real-time listening mode, I have a recording and implementation of distortions that work fine, with only some problems using ASIO. I looked at this post How to record and play back using NAudio using AsioOut , but this did not help me in my problem, here is my code:

private BufferedWaveProvider buffer;
private AsioOut input;
private AsioOut output;

private void listenBtn_Click(object sender, EventArgs e)
{
    input = new AsioOut(RecordInCbox.SelectedIndex);
    WaveFormat format = new WaveFormat();
    buffer = new BufferedWaveProvider(format);
    buffer.DiscardOnBufferOverflow = true;
    input.InitRecordAndPlayback(buffer, 1, 44100);
    input.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs>(AudioAvailable);

    //output = new AsioOut(RecordInCbox.SelectedIndex);
    //output.Init(buffer);

    input.Play();
    //output.Play();
}

public void AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
    byte[] buf = new byte[e.SamplesPerBuffer];
    e.WrittenToOutputBuffers = true;
    for (int i = 0; i < e.InputBuffers.Length; i++)
    {
        Array.Copy(e.InputBuffers, e.OutputBuffers, 1);
        Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer);
        buffer.AddSamples(buf, 0, buf.Length);
    }
}

, . , "" , , , , . !

+4
3

, ASIO , , , , 50 , NAudio, , . ( 20-30 ) .

    private BufferedWaveProvider buffer;
    private WaveOut waveOut;
    private WaveIn sourceStream = null;

    private bool listen = false;

    private void listenBtn_Click(object sender, EventArgs e)
    {
        listen = !listen;
        if (listen)
            listenBtn.Text = "Stop listening";
        else
        {
            listenBtn.Text = "Listen";
            sourceStream.StopRecording();
            return;
        }

        sourceStream = new WaveIn();
        sourceStream.WaveFormat = new WaveFormat(44100, 1);

        waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());

        sourceStream.DataAvailable += new EventHandler<WaveInEventArgs>(sourceStream_DataAvailable);
        sourceStream.RecordingStopped += new EventHandler<StoppedEventArgs>(sourceStream_RecordingStopped);

        buffer = new BufferedWaveProvider(sourceStream.WaveFormat);
        buffer.DiscardOnBufferOverflow = true;
        waveOut.DesiredLatency = 51;
        waveOut.Volume = 1f;
        waveOut.Init(buffer);
        sourceStream.StartRecording();
    }

    private void sourceStream_DataAvailable(object sender, WaveInEventArgs e)
    {
        buffer.AddSamples(e.Buffer, 0, e.BytesRecorded);

        waveOut.Play();
    }

    private void sourceStream_RecordingStopped(object sender, StoppedEventArgs e)
    {
        sourceStream.Dispose();
        waveOut.Dispose();
    }

, ASIO, , . ASIO waveIn "", , , waveOut, , .

0

. . :

[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
private static unsafe extern void MoveMemory(IntPtr dest, IntPtr src, int size);

private void OnAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
    {
        for (int i = 0; i < e.InputBuffers.Length; i++)
        {
            MoveMemory(e.OutputBuffers[i], e.InputBuffers[i], e.SamplesPerBuffer * e.InputBuffers.Length);
        }
        e.WrittenToOutputBuffers = true;
    }

, , , . , - , , .

+1

, , Asio NAudio ( USB-;).

, , :

    private float[] recordingBuffer = null;
    private byte[] recordingByteBuffer = null;

    private BufferedWaveProvider bufferedWaveProvider;
    private BufferedSampleProvider bsp;
    private SampleToWaveProvider swp;



    // somewhere in e.g. constructor
            // set up our signal chain
            bufferedWaveProvider = new BufferedWaveProvider(waveFormat);
            //bufferedWaveProvider.DiscardOnBufferOverflow = true;

            bsp = new BufferedSampleProvider(waveFormat);
            swp = new SampleToWaveProvider(bsp);
    // ...


    private void OnAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
    {
        this.recordingBuffer = BufferHelpers.Ensure(this.recordingBuffer, e.SamplesPerBuffer * e.InputBuffers.Length);
        this.recordingByteBuffer = BufferHelpers.Ensure(this.recordingByteBuffer, e.SamplesPerBuffer  * 4 * e.InputBuffers.Length);

        int count = e.GetAsInterleavedSamples(this.recordingBuffer);

        this.bsp.CurrentBuffer = this.recordingBuffer;

        int count2 = this.swp.Read(this.recordingByteBuffer, 0, count * 4);

        bufferedWaveProvider.AddSamples(this.recordingByteBuffer, 0, this.recordingByteBuffer.Length);
    }

BufferedSampleProvider.cs:

public class BufferedSampleProvider : ISampleProvider
{
    private WaveFormat waveFormat;
    private float[] currentBuffer;

    public BufferedSampleProvider(WaveFormat waveFormat)
    {
        this.waveFormat = waveFormat;
        this.currentBuffer = null;
    }

    public float[] CurrentBuffer 
    {
        get { return this.currentBuffer; }
        set { this.currentBuffer = value; }
    }

    public int Read(float[] buffer, int offset, int count)
    {
        if (this.currentBuffer != null)
        {
            if (count <= currentBuffer.Length)
            {
                for (int i = 0; i < count; i++)
                {
                    buffer[i] = this.currentBuffer[i];
                }
                return count;
            }
        }
        return 0;
    }

    public WaveFormat WaveFormat
    {
        get { return this.waveFormat; }
    }
}

(), asio, .. ( GetAsInterleavedSamples (...)). , BufferedWaveProvider, , () , , . , , "".

asioOut.InitRecordAndPlayback(output, this.InputChannels, this.SampleRate);

. , 512 . , Asio. , .

: WaveIn/WaveOutEvent , ( ), , - ;) WPF WaveOutEvent, , "" GC.

, , Asio GC.

, .

0

Source: https://habr.com/ru/post/1532725/


All Articles