英文:
NAudio, Mixing two raw audio streams into a .wav file
问题
string path = string.Empty;
private void SaveAudioRecording()
{
timer.Dispose();
if (string.IsNullOrEmpty(path))
{
path = Directory.GetCurrentDirectory() + "\\AudioRecordings_" + clientSession.clientInfo[0];
Directory.CreateDirectory(path);
}
WaveMixerStream32 mix = new WaveMixerStream32();
foreach (var stream in new MemoryStream[] { audioOutputMemoryStream, audioInputMemoryStream })
{
stream.Position = 0;
if (stream != null && stream.Length > 0 && stream.Position < stream.Length)
{
RawSourceWaveStream reader = new RawSourceWaveStream(stream, new WaveFormat(41100, 1));
WaveChannel32 channel = new WaveChannel32(reader);
mix.AddInputStream(channel);
}
}
using (FileStream stream = File.Create(System.IO.Path.Combine(path, "Audio_recording_" + Directory.EnumerateFiles(path).Count().ToString() + ".wav"))
{
byte[] buffer = new byte[mix.Length];
mix.Read(buffer, 0, buffer.Length);
stream.Write(buffer, 0, buffer.Length);
WriteWavHeader(stream, Convert.ToInt32(stream.Length));
stream.Flush();
}
recordButton.IsEnabled = true;
}
private void WriteWavHeader(Stream stream, int audioDataSize)
{
using (var writer = new BinaryWriter(stream, Encoding.UTF8, true))
{
writer.Write(Encoding.ASCII.GetBytes("RIFF"));
writer.Write(audioDataSize + 36); // Total file size - 8 bytes
writer.Write(Encoding.ASCII.GetBytes("WAVE"));
writer.Write(Encoding.ASCII.GetBytes("fmt "));
writer.Write(16); // Length of format data
writer.Write((ushort)1); // PCM format
writer.Write((ushort)1); // Not Stereo
writer.Write(41100); // Sample rate
writer.Write(82200); // Byte rate (Sample rate * Channels * BitsPerSample / 8)
writer.Write((ushort)4); // Block align (Channels * BitsPerSample / 8)
writer.Write((ushort)16); // Bits per sample
writer.Write(Encoding.ASCII.GetBytes("data"));
writer.Write(audioDataSize); // Size of audio data
}
}
英文:
string path = string.Empty;
private void SaveAudioRecording()
{
timer.Dispose();
if (string.IsNullOrEmpty(path))
{
path = Directory.GetCurrentDirectory() + "\\AudioRecordings_"+clientSession.clientInfo[0];
Directory.CreateDirectory(path);
}
WaveMixerStream32 mix= new WaveMixerStream32();
foreach (var stream in new MemoryStream[] { audioOutputMemoryStream, audioInputMemoryStream })
{
stream.Position = 0;
if (stream != null && stream.Length > 0 && stream.Position < stream.Length)
{
RawSourceWaveStream reader = new RawSourceWaveStream(stream,new WaveFormat(41100,1));
WaveChannel32 chanel = new WaveChannel32(reader);
mix.AddInputStream(chanel);
}
}
using (FileStream stream = File.Create(System.IO.Path.Combine(path, "Audio_recording_" + Directory.EnumerateFiles(path).Count().ToString() + ".wav")))
{
byte[] buffer = new byte[mix.Length];
mix.Read(buffer, 0, buffer.Length);
stream.Write(buffer, 0, buffer.Length);
WriteWavHeader(stream,Convert.ToInt32(stream.Length));
stream.Flush();
}
recordButton.IsEnabled = true;
}
private void WriteWavHeader(Stream stream, int audioDataSize)
{
using (var writer = new BinaryWriter(stream, Encoding.UTF8, true))
{
writer.Write(Encoding.ASCII.GetBytes("RIFF"));
writer.Write(audioDataSize + 36); // Total file size - 8 bytes
writer.Write(Encoding.ASCII.GetBytes("WAVE"));
writer.Write(Encoding.ASCII.GetBytes("fmt "));
writer.Write(16); // Length of format data
writer.Write((ushort)1); // PCM format
writer.Write((ushort)1); // Not Stereo
writer.Write(41100); // Sample rate
writer.Write(82200); // Byte rate (Sample rate * Channels * BitsPerSample / 8)
writer.Write((ushort)4); // Block align (Channels * BitsPerSample / 8)
writer.Write((ushort)16); // Bits per sample
writer.Write(Encoding.ASCII.GetBytes("data"));
writer.Write(audioDataSize); // Size of audio data
}
}
The file its ctreating is corupted, cant start it, but it do weigh a bit, the bytes do be written.
I was trying to mix two raw audio streams, into a complete .wav file, therefore writing a waveheader on it, the wave header do work, because I've tested it earlier. But now I've changed the code, which is corrupting the file.
What could possibly be the issue?
答案1
得分: 0
问题是在音频数据写入后才写入波形头部引起的。
英文:
The problem was caused by writing the waveheader after the audio data was written.
答案2
得分: 0
首先,您将标题写在数据后面,应该相反。
WriteWavHeader(stream, Convert.ToInt32(stream.Length));
stream.Write(buffer, 0, buffer.Length);
但如果只这样做,您需要调整 "audioDataSize" 以匹配数据大小。如果您将参数 "stream.Length" 保留给 WriteWavHeader 函数,它将是标题的大小,而不是数据的大小,因为此时流只包含标题数据。因此,使用 buffer.Length 代替。那是数据的大小。
WriteWavHeader(stream, Convert.ToInt32(buffer.Length));
stream.Write(buffer, 0, buffer.Length);
这应该可以解决问题。(在这种情况下,Convert.ToInt32() 调用不是必需的,因为 Length 已经是 int,如果我记得正确的话。)
英文:
First of all, you're writing the header after the data, it should be the opposite.
WriteWavHeader(stream,Convert.ToInt32(stream.Length));
stream.Write(buffer, 0, buffer.Length);
But if you do only this, you need then to adapt the "audioDataSize" to match the data size. If you keep the argument "stream.Length" to the function WriteWavHeader, it will be the size of the header, not the data, as the stream a that moment only contains the header data. So, use the buffer.Length instead. That's the data size.
WriteWavHeader(stream,Convert.ToInt32(buffer.Length));
stream.Write(buffer, 0, buffer.Length);
Should do the trick. (Convert.ToInt32() call is not mandatory in that case, Length is already a int if i remember correctly
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论