Записать звук с микрофона, затем сохранить

У меня проблемы с наудио и сохранением звуковых записей. Код, который у меня есть, работает до такой степени, что сохраняет файл wav, но когда я его открываю, проигрыватель Windows Media возвращает ошибку: "Во время воспроизведения файла проигрыватель Windows Media обнаружил проблему"

У меня есть две кнопки, кнопка "Запись", которая после нажатия превращается в кнопку остановки. И у меня есть кнопка "Сохранить", которая при нажатии сохраняет запись в sample.wav,

NAudio.Wave.WaveIn sourceStream = null;
NAudio.Wave.DirectSoundOut waveOut = null;
NAudio.Wave.WaveFileWriter waveWriter = null;

private void recordButton_Click(object sender, EventArgs e)
{
    int deviceNumber = sourceList.SelectedItems[0].Index;

    sourceStream = new NAudio.Wave.WaveIn();
    sourceStream.DeviceNumber = deviceNumber;
    sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);

    NAudio.Wave.WaveInProvider waveIn = new NAudio.Wave.WaveInProvider(sourceStream);

    waveOut = new NAudio.Wave.DirectSoundOut();
    waveOut.Init(waveIn);

    sourceStream.StartRecording();
    waveOut.Play();

    recordButton.Visible = false;
    stopRecord.Visible = true;
}

private void saveResponse_Click(object sender, EventArgs e)
{
    int deviceNumber = sourceList.SelectedItems[0].Index;

    string saveLocation = "c:\\wav\\sample.wav";

    sourceStream = new NAudio.Wave.WaveIn();
    sourceStream.DeviceNumber = deviceNumber;
    sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);

    sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable);
    waveWriter = new NAudio.Wave.WaveFileWriter(saveLocation, sourceStream.WaveFormat);

    sourceStream.StartRecording();

    MessageBox.Show("Recording successfully saved.");
}

private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
{
    if (waveWriter == null) return;

    waveWriter.WriteData(e.Buffer, 0, e.BytesRecorded);
    waveWriter.Flush();
}
private void stopRecord_Click(object sender, EventArgs e)
{
    if (waveOut != null)
    {
        waveOut.Stop();
        waveOut.Dispose();
        waveOut = null;
    }
    if (sourceStream != null)
    {
        sourceStream.StopRecording();
        sourceStream.Dispose();
        sourceStream = null;
    }
    if (waveWriter != null)
    {
        waveWriter.Dispose();
        waveWriter = null;
    }

    recordButton.Visible = true;
    stopRecord.Visible = false;
    saveResponse.Enabled = true;
}

1 ответ

Решение

Ваш recordButton_Click код не записывается, он передает данные из WaveIn к WaveOut, который будет воспроизводить данные, поступающие с вашего источника (микрофон) непосредственно на выход (колонки). Он не сохраняет эти данные для последующего использования, он просто передает их от одного к другому. Если вы хотите впоследствии сохранить эти данные на диск, вам нужно самостоятельно их буферизовать.

saveResponse_Click с другой стороны, начинается прямая запись данных с микрофона в волновой файл на диске. Если вы нажмете Save Response подождите немного, затем нажмите Stop Кнопка, вы должны получить записанный волновой файл.

Если вы хотите записать прямо на диск, это нормально. Если вы хотите записать в память, а затем опционально записать на диск, вам нужно сохранить данные по мере их поступления. Возможно, используйте поток памяти для хранения данных во время записи, а затем запишите их в WaveFileWriter когда придет время сохранить файл.


Вот код, который я использовал для тестирования прямой записи в волновой файл на диске:

public WaveIn waveSource = null;
public WaveFileWriter waveFile = null;

private void StartBtn_Click(object sender, EventArgs e)
{
    StartBtn.Enabled = false;
    StopBtn.Enabled = true;

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

    waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
    waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);

    waveFile = new WaveFileWriter(@"C:\Temp\Test0001.wav", waveSource.WaveFormat);

    waveSource.StartRecording();
}

private void StopBtn_Click(object sender, EventArgs e)
{
    StopBtn.Enabled = false;

    waveSource.StopRecording();
}

void waveSource_DataAvailable(object sender, WaveInEventArgs e)
{
    if (waveFile != null)
    {
        waveFile.Write(e.Buffer, 0, e.BytesRecorded);
        waveFile.Flush();
    }
}

void waveSource_RecordingStopped(object sender, StoppedEventArgs e)
{
    if (waveSource != null)
    {
        waveSource.Dispose();
        waveSource = null;
    }

    if (waveFile != null)
    {
        waveFile.Dispose();
        waveFile = null;
    }

    StartBtn.Enabled = true;
}
Другие вопросы по тегам