gpt4 book ai didi

c# - 为内存中的流创建有效的 wav 文件头

转载 作者:太空狗 更新时间:2023-10-30 00:10:32 25 4
gpt4 key购买 nike

我有原始无 header 的 wav 音频数据作为 MemoryStream

Stream rawAudioStream = Producer.GetRawAudioFileStream(...);

我知道那些流数据格式:

// WaveFormat(int rate, int bits, int channels);
WaveFormat waveformat = new WaveFormat(8000, 16, 1);

我想要的是以编程方式为这些内存流添加正确的 header 信息,而不是将它们写入物理文件。

我该怎么做?

PS:我检查了 NAudio 库,但只找到了一种通过将流写入真实物理文件来创建 header 的方法,这不适合我的情况

var waveformat = new WaveFormat(8000,16,1);

var reader = new RawSourceWaveStream(rawAudioMemStream, waveformat);

using (var convertedStream = WaveFormatConversionStream.CreatePcmStream(reader))
{
WaveFileWriter.CreateWaveFile(fileName, convertedStream);
}

rawAudioMemStream.Close();

最佳答案

下面的代码会将 Wav header 写入 MemoryStream 的开头。这意味着您需要首先将 header 写入您的流,然后您才能编写示例。否则流开头的示例将被元数据覆盖,

// totalSampleCount needs to be the combined count of samples of all channels. So if the left and right channels contain 1000 samples each, then totalSampleCount should be 2000.
// isFloatingPoint should only be true if the audio data is in 32-bit floating-point format.

private void WriteWavHeader(MemoryStream stream, bool isFloatingPoint, ushort channelCount, ushort bitDepth, int sampleRate, int totalSampleCount)
{
stream.Position = 0;

// RIFF header.
// Chunk ID.
stream.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4);

// Chunk size.
stream.Write(BitConverter.GetBytes(((bitDepth / 8) * totalSampleCount) + 36), 0, 4);

// Format.
stream.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4);



// Sub-chunk 1.
// Sub-chunk 1 ID.
stream.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4);

// Sub-chunk 1 size.
stream.Write(BitConverter.GetBytes(16), 0, 4);

// Audio format (floating point (3) or PCM (1)). Any other format indicates compression.
stream.Write(BitConverter.GetBytes((ushort)(isFloatingPoint ? 3 : 1)), 0, 2);

// Channels.
stream.Write(BitConverter.GetBytes(channelCount), 0, 2);

// Sample rate.
stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);

// Bytes rate.
stream.Write(BitConverter.GetBytes(sampleRate * channelCount * (bitDepth / 8)), 0, 4);

// Block align.
stream.Write(BitConverter.GetBytes((ushort)channelCount * (bitDepth / 8)), 0, 2);

// Bits per sample.
stream.Write(BitConverter.GetBytes(bitDepth), 0, 2);



// Sub-chunk 2.
// Sub-chunk 2 ID.
stream.Write(Encoding.ASCII.GetBytes("data"), 0, 4);

// Sub-chunk 2 size.
stream.Write(BitConverter.GetBytes((bitDepth / 8) * totalSampleCount), 0, 4);
}

关于c# - 为内存中的流创建有效的 wav 文件头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22695723/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com