加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 23:43:07 所属栏目:百科 来源:网络整理
导读:我有raw-headerless wav音频数据作为MemoryStreams. Stream rawAudioStream = Producer.GetRawAudioFileStream(...); 我知道那些流数据格式: // WaveFormat(int rate,int bits,int channels);WaveFormat waveformat = new WaveFormat(8000,16,1); 我想要的
我有raw-headerless wav音频数据作为MemoryStreams.

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

我知道那些流数据格式:

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

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

我怎样才能做到这一点?

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

var waveformat = new WaveFormat(8000,1);

var reader = new RawSourceWaveStream(rawAudioMemStream,waveformat);

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

rawAudioMemStream.Close();

解决方法

下面的代码将Wav标头写入MemoryStream的开头.这意味着您首先需要将标题写入流中,然后您可以编写样本.否则,您的流开头的样本将被元数据覆盖,

// 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"),4);

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

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



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

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

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

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

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

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

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

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



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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读