当我更改wav文件的waveFormat时,"数据"标识符向右移动。表示da chunk开头的数据标识符必须位于0x24位置,但在我使用NAudio库更改waveFormat后,它会移动到0x26位置。
WAV格式
这是我用来更改waveFormat的代码:
private void TurnTo16bitsAudio(string path)
{
NAudio.Wave.WaveFileReader wave = new NAudio.Wave.WaveFileReader(@path);
System.Console.WriteLine(wave.WaveFormat);
if (wave.WaveFormat.BitsPerSample >= 16 && wave.WaveFormat.Channels<2)
{
wave.Dispose();
return;
}
var newFormat = new WaveFormat(44100, 16, 1);
var conversionStream = new WaveFormatConversionStream(newFormat, wave);
WaveFileWriter.CreateWaveFile(@path + '1', conversionStream);
wave.Dispose();
wave = new NAudio.Wave.WaveFileReader(@path + '1');
conversionStream = new WaveFormatConversionStream(newFormat, wave);
WaveFileWriter.CreateWaveFile(@path, conversionStream);
wave.Dispose();
conversionStream.Dispose();
System.IO.File.Delete(@path + '1');
}
有可能使用NAudio更改wav标头或更改waveFormat而不会删除&#34;数据&#34;标识符
答案 0 :(得分:1)
WaveFormat 类中的序列化方法永远不会在 Subchunk1Size 字段中输出0x10。最小值为0x12。
public virtual void Serialize(BinaryWriter writer)
{
writer.Write((int)(18 + extraSize)); // wave format length
writer.Write((short)Encoding);
writer.Write((short)Channels);
writer.Write((int)SampleRate);
writer.Write((int)AverageBytesPerSecond);
writer.Write((short)BlockAlign);
writer.Write((short)BitsPerSample);
writer.Write((short)extraSize);
}
额外的2个字节用于ExtraParamSize,当编码设置为WaveFormatEncoding.Pcm(其值== 0)时,将忽略该字节。 这与引入WAVEFORMATEX时Microsoft(Windows 2000及更高版本)完成的WAV格式的更改有关。
在这里你可以找到关于subchunk1size 16/18不同大小问题的答案: C++ read wav file, subchunk1size = 18
有关WAVEFORMATEX结构的详细信息: https://msdn.microsoft.com/library/windows/hardware/ff538799
如果你真的想在没有extraSize字段的情况下强制创建wav标题,你可以扩展WaveFormat类。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 2)]
class CustomWaveFormat : WaveFormat
{
public CustomWaveFormat(int rate, int bits, int channels)
: base(rate, bits, channels)
{
extraSize = 0;
}
public override void Serialize(BinaryWriter writer)
{
writer.Write((int)16); // wave format length
writer.Write((short)Encoding);
writer.Write((short)Channels);
writer.Write((int)SampleRate);
writer.Write((int)AverageBytesPerSecond);
writer.Write((short)BlockAlign);
writer.Write((short)BitsPerSample);
}
}
用法:
...
var newFormat = new CustomWaveFormat(44100, 16, 1);
using (var conversionStream = new WaveFormatConversionStream(newFormat, waveFileReader))
{
WaveFileWriter.CreateWaveFile("example_new.wav", conversionStream);
}
...