NAudio Правильное использование BufferedWaveProvider - PullRequest
0 голосов
/ 06 августа 2020

У меня есть приложение, в котором мне нужно воспроизводить аудио в буферизованном режиме. Это означает, что rawdata становится доступной в некоторых блоках, которые мне нужно будет передать в очередь аудиопотока. Мне нужно еще разобраться, но для меня ясно, что мне понадобится какое-то буферизованное воспроизведение звука, поэтому я попытался написать небольшой пример, чтобы привыкнуть к BufferedWaveProvider из NAudio. Идея заключалась в том, чтобы просто полностью прочитать 16-битный монофонический волновой файл в массив, а затем воспроизвести его блоками с помощью BufferedWaveProvider. Однако, когда я добавляю 1 с звука, например, 10 раз подряд, я ожидаю услышать непрерывный звук 10 с, если буфер достаточно длинный, но вместо этого он заикается. Думаю, проблема как-то связана с потоками, но я не знаю, с чего начать. Есть предложения?

Вот мой код:


private double[] audiodata;
private NAudio.Wave.BufferedWaveProvider waveProvider;
private NAudio.Wave.WaveOut player;
private int nbits = 16;
private int samplerate = 44100;
private int channels = 1;
private int appendAudioCounter = 0;

public MainWindow()
{
    InitializeComponent();
    
    // Initialize BufferedWaveProvider and WaveOut
    waveProvider = new NAudio.Wave.BufferedWaveProvider(new NAudio.Wave.WaveFormat(samplerate,nbits,channels));
    waveProvider.BufferLength = samplerate * nbits/8 * 10;
    player = new NAudio.Wave.WaveOut();
    player.Init(waveProvider);
    player.Play();
    
    // Read 16 bit mono Wave File
    using var wfr = new NAudio.Wave.WaveFileReader("C:\\Users\\MyUserName\\Documents\\sinesweep_2m_mono_16bit.wav");
    byte[] bytesBuffer = new byte[wfr.Length];
    int read = wfr.Read(bytesBuffer, 0, bytesBuffer.Length);
    audiodata = new double[read / (nbits / 8)];
    for (int ii = 0; ii < read / (nbits/8); ii++)
    {
        audiodata[ii] = (double)BitConverter.ToInt16(bytesBuffer, ii * nbits / 8) / (Math.Pow(2, nbits - 1));
    }

    // Append 5s of Audio data
    for (int ii = 0; ii < 10; ii++) Append1sAudio();
}

private void Append1sAudio()
{
    // append 1s of audio to BufferedWaveProvider
    byte[] buffer = new byte[samplerate * nbits / 8];
    
    for (int ii = appendAudioCounter * samplerate; ii < appendAudioCounter * samplerate + samplerate; ii++)
    {
        var bytes = BitConverter.GetBytes((int)(audiodata[ii] * Math.Pow(2, nbits - 1)));
        for (int jj = 0; jj < nbits / 8; jj++) buffer[(ii - appendAudioCounter * samplerate) * nbits / 8 + jj] = bytes[jj];
    }

    waveProvider.AddSamples(buffer, 0, samplerate);
    appendAudioCounter++;
}

...