2013-07-31 8 views
8

Mam pewne problemy z naudio i zapisywanie nagrań dźwiękowych. Kod I obecnie działa tak, że zapisuje plik WAV, ale kiedy go otworzę, Windows Media Player zwraca błąd: "Windows Media Player napotkał problem podczas odtwarzania pliku"dźwięk nagrania z mikrofonu, a następnie zapis

Mam dwa przyciski , przycisk "Record", który zmienia się w przycisk stop po naciśnięciu. I mam przycisk "Zapisz", który po kliknięciu zapisuje nagranie na 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; 
} 
+0

można wyświetlić kod za swoim „zatrzymania” działania proszę? Po prostu zobacz, jak zamykasz 'waveWriter' i takie. – Corey

+0

@Corey, dodałem akcję "stop" do kodu. Twoje zdrowie. – Spencer

+0

OK, testowałem z podobnym kodem i wszystko wydaje się pracować dla mnie. Czy zatrzymujesz nagranie przed próbą odtworzenia go w WMP? – Corey

Odpowiedz

19

Kod recordButton_Click nie nagrywa, to dane z rur o WaveIn do WaveOut, która wcieli się w danych pochodzących ze źródła (mikrofon) bezpośrednio do wyjścia (głośniki). Nie przechowuje tych danych do późniejszego wykorzystania, po prostu przepuszcza je od jednego do drugiego. Jeśli chcesz później zapisać te dane na dysku, musisz je samemu buforować.

Z drugiej strony saveResponse_Click jest począwszy od bezpośrednie nagrywanie danych z mikrofonu do pliku wave na dysku. Po kliknięciu przycisku Save Response poczekaj chwilę, a następnie kliknij przycisk Stop, powinieneś otrzymać nagrany plik wave.

Jeśli chcesz nagrywać bezpośrednio na dysk, jest to w porządku. Jeśli chcesz nagrywać do pamięci, a następnie opcjonalnie zapisywać na dysku, musisz zapisać dane w momencie ich pojawienia się. Być może użyj strumienia pamięci do przechowywania danych podczas nagrywania, a następnie zapisz je na WaveFileWriter, gdy przychodzi czas na zapisanie plik.


Oto kod użyłem do testowania bezpośredni zapis do pliku na dysku fali:

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; 
} 
+0

To działa pięknie. Dziękuję Ci bardzo!! – Spencer

+0

kiedy piszę twój kod, rzuca wyjątek i mówi "BadDeviceId wywołując waveInOpen". jakieś sugestie ? co to za błąd? – abidinberkay

+1

@abidinberkay domyślny DeviceNumber to 0, jeśli ten identyfikator jest zły, prawdopodobnie oznacza to, że nigdy nie podłączono mikrofonu. –

Powiązane problemy