在wav.file中编写Header wav [英] Writting Header wav in wav.file
本文介绍了在wav.file中编写Header wav的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
当我写
bwl.Write(缓冲区);
我的Subchunk2Size比初始文件大......
使用( var wfr = new WaveFileReader(fs))
{
var outputFormat = new WaveFormat( 8000 , 16 , 1 跨度>);
使用( var pcmStream = new WaveFormatConversionStream(outputFormat,wfr))
{
使用( var ms = new MemoryStream())
{
BinaryWriter bwl = new BinaryWriter(ms );
var bytesRead = -1;
while (bytesRead!= 0 )
{
var buffer = new byte [pcmStream.WaveFormat。 AverageBytesPerSecond];
bytesRead = pcmStream.Read(buffer, 0 ,pcmStream.WaveFormat.AverageBytesPerSecond);
int length =( int )fs.Length - 8 跨度>;
program.channels = 1 ;
program.samplerate = 8000 ;;
program.BitsPerSample = 16 ; // br.ReadInt16();
program.DataLength =( int )ms.Length - 44 跨度>;
bwl.Write( new char [ 4 ] {' R',' 我',' F ',' F'});
bwl.Write(length);
bwl.Write( new char [ 8 ] {' W',' A',' V',' E',' < span class =code-string> f',' m',' t',' '});
bwl.Write(( int ) 16 );
bwl.Write(( short ) 1 );
bwl.Write(program.channels);
bwl.Write(program.samplerate);
bwl.Write(( int )(program.samplerate *((program.BitsPerSample * program.channels)/ 8 跨度>)));
bwl.Write(( short )((program.BitsPerSample * program.channels)/ 8 ));
bwl.Write(program.BitsPerSample);
bwl.Write( new char [ 4 ] {' d',' a',' t',' a'});
// bw.Write(Header.DataLength);
bwl.Write (缓冲);
System.IO.File.WriteAllBytes( @ C:Desktop\waveConvertBuff.wav ,ms.GetBuffer());
}
bwl.Close();
fs.Close();
ms.Close();
}
}
我的waveConvertBuff.wav长度大约是74h hoiur但玩的时候初始长度是正确的(4秒)
为什么?
解决方案
我最近开发并调试了这部分Wave写作,可以和你分享:
命名空间 Wave {
使用系统;
使用 System.IO;
使用 Encoding = System.Text.Encoding;
public partial class WaveWriter:BinaryWriter,IDisposable {
public WaveWriter( string fileName )
: base ( new FileStream(fileName,FileMode.Create,FileAccess.Write)) {
Initialize( new WaveParameterWriter());
} // WaveWriter
public WaveWriter( string fileName, uint rate,短位,短个频道)
: base ( new FileStream(fileName,FileMode.Create,FileAccess.Write)){
Initialize( new WaveParameterWriter(rate,比特,频道));
} // WaveWriter
public WaveWriter(Stream stream): base (stream){Initialize( new WaveParameterWriter()); }
public WaveWriter(流码流, uint 率, 位,短个频道)
: base (stream){
Initialize( new WaveParameterWriter(rate,bits,channels));
} // WaveWriter
void Initialize(WaveParameterWriter parameterWriter){
this .waveParameterWriter = parameterWriter;
WriteRiffHeader();
} // 初始化
void WriteRiffHeader(){
Func< string, byte [] > serialize =(id)= > { return Encoding.ASCII.GetBytes(id) ; };
写(serialize(DefinitionSet.ChunkId)); // chunk ID
Write(audioDataSize + DefinitionSet.ChunkHeaderSize); // chunk Size
Write(serialize(DefinitionSet.Format)); // format
写(serialize(DefinitionSet.SubChunkOneId)); // Subchunk1 ID
Write(DefinitionSet.SubChunkOneSize); // subchunk1 size(18 for PCM)
Write(DefinitionSet.AudioFormatPcm); // 音频格式,1代表PCM
// 变量参数:NumChannels,SampleRate,ByteRate,BlockAlign,BitsPerSample:
waveParameterWriter.Write(此跨度>);
Write(DefinitionSet.ExtraParameterSizePcm); // 额外参数大小,0表示PCM
写入(serialize(DefinitionSet.SubChunkTwoId)) ; // // Subchunk2 ID
Write(audioDataSize); // subchunk2 size
audioStreamStart = this .BaseStream.Position;
} // WriteRiffHeader
void IDisposable.Dispose(){Close(); }
public 覆盖 void 关闭(){
如果(isClosed) return ;
audioDataSize =( uint )( this .BaseStream.Position - audioStreamStart);
Seek( 0 ,SeekOrigin.Begin);
WriteRiffHeader();
isClosed = true ;
base .Close();
} // 关闭
long audioStreamStart;
WaveParameterWriter waveParameterWriter;
uint audioDataSize;
bool isClosed;
密封 类 WaveParameterWriter {
internal WaveParameterWriter(): this (DefinitionSet.DefaultRate,DefinitionSet.DefaultBitsPerSample,DefinitionSet.DefaultChannels){}
内部 WaveParameterWriter( uint rate, short 位,短个频道){
此 .channels = channels;
此 .sampleRate = rate;
this .bitsPerSample = bits;
此 .blockAlign =( short )(渠道*(bits / 8 跨度>));
this .byteRate =( uint )(sampleRate * blockAlign);
} // WaveHeaderWriter
内部 void 写入(BinaryWriter writer){
writer.Write(channels);
writer.Write(sampleRate);
writer.Write(byteRate);
writer.Write(blockAlign);
writer.Write(bitsPerSample);
} // 写
简短的频道;
uint sampleRate;
uint byteRate;
short blockAlign;
short bitsPerSample;
} // 类WaveHeaderWriter
} // 类WaveWriter
} // namespace Wave
它基于以下定义:
使用系统;
使用 System.Collections.Generic;
命名空间 Wave {
public partial class WaveWriter {
static < span class =code-keyword> class DefinitionSet {
// 请参阅https://ccrma.stanford.edu/courses/422/projects/WaveFormat
internal const string ChunkId = RIFF 跨度>;
internal const uint ChunkHeaderSize = 38 ;
internal const string 格式= WAVE;
internal const string SubChunkOneId = fmt;
内部 const uint SubChunkOneSize = 18 ;
内部 const 简短 AudioFormatPcm = 1 ;
// 变量参数:NumChannels,SampleRate,ByteRate,BlockAlign,BitsPerSample
内部 const 简短 ExtraParameterSizePcm = 0 跨度>;
internal const string SubChunkTwoId = data;
internal const uint DefaultRate = 44100 ;
内部 const 简短 DefaultBitsPerSample = 16 ;
内部 const 简短 DefaultChannels = 2 ;
} // class DefinitionSet
} // class WaveWriter
} // 命名空间Wave
我测试的很漂亮好;它很有用。
首先,我使用了这篇文档: https://ccrma.stanford.edu/courses/422/projects/WaveFormat [ ^ ]。
-SA
< blockquote>你的课很酷,昨天我错过了阅读我的波形标题,这是一个写数据的问题。长度比原来大!!
When i write
bwl.Write(buffer);
my Subchunk2Size is bigger than the initial file...
using (var wfr = new WaveFileReader(fs))
{
var outputFormat = new WaveFormat(8000, 16, 1);
using (var pcmStream = new WaveFormatConversionStream(outputFormat, wfr))
{
using (var ms = new MemoryStream())
{
BinaryWriter bwl = new BinaryWriter(ms);
var bytesRead = -1;
while (bytesRead != 0)
{
var buffer = new byte[pcmStream.WaveFormat.AverageBytesPerSecond];
bytesRead = pcmStream.Read(buffer, 0, pcmStream.WaveFormat.AverageBytesPerSecond);
int length = (int)fs.Length - 8;
program.channels = 1;
program.samplerate = 8000;;
program.BitsPerSample = 16;// br.ReadInt16();
program.DataLength = (int)ms.Length - 44;
bwl.Write(new char[4] { 'R', 'I', 'F', 'F' });
bwl.Write(length);
bwl.Write(new char[8] { 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ' });
bwl.Write((int)16);
bwl.Write((short)1);
bwl.Write(program.channels);
bwl.Write(program.samplerate);
bwl.Write((int)(program.samplerate * ((program.BitsPerSample * program.channels) / 8)));
bwl.Write((short)((program.BitsPerSample * program.channels) / 8));
bwl.Write(program.BitsPerSample);
bwl.Write(new char[4] { 'd', 'a', 't', 'a' });
//bw.Write(Header.DataLength);
bwl.Write(buffer);
System.IO.File.WriteAllBytes(@"C:Desktop\waveConvertBuff.wav", ms.GetBuffer());
}
bwl.Close();
fs.Close();
ms.Close();
}
}
my waveConvertBuff.wav lenght is about 74h hoiur but when playing the initial length is correct (4 seconds)
Why?
解决方案
I recently developed and debugged this part of Wave writing, can share with you:
namespace Wave { using System; using System.IO; using Encoding = System.Text.Encoding; public partial class WaveWriter : BinaryWriter, IDisposable { public WaveWriter(string fileName) : base(new FileStream(fileName, FileMode.Create, FileAccess.Write)) { Initialize(new WaveParameterWriter()); } //WaveWriter public WaveWriter(string fileName, uint rate, short bits, short channels) : base(new FileStream(fileName, FileMode.Create, FileAccess.Write)) { Initialize(new WaveParameterWriter(rate, bits, channels)); } //WaveWriter public WaveWriter(Stream stream) : base(stream) { Initialize(new WaveParameterWriter()); } public WaveWriter(Stream stream, uint rate, short bits, short channels) : base(stream) { Initialize(new WaveParameterWriter(rate, bits, channels)); } //WaveWriter void Initialize(WaveParameterWriter parameterWriter) { this.waveParameterWriter = parameterWriter; WriteRiffHeader(); } //Initialize void WriteRiffHeader() { Func<string, byte[]> serialize = (id) => { return Encoding.ASCII.GetBytes(id); }; Write(serialize(DefinitionSet.ChunkId)); // chunk ID Write(audioDataSize + DefinitionSet.ChunkHeaderSize); // chunk Size Write(serialize(DefinitionSet.Format)); // format Write(serialize(DefinitionSet.SubChunkOneId)); // Subchunk1 ID Write(DefinitionSet.SubChunkOneSize); //subchunk1 size (18 for PCM) Write(DefinitionSet.AudioFormatPcm); // Audio Format, 1 for PCM // variable parameters: NumChannels, SampleRate, ByteRate, BlockAlign, BitsPerSample: waveParameterWriter.Write(this); Write(DefinitionSet.ExtraParameterSizePcm); // extra parameter size, 0 for PCM Write(serialize(DefinitionSet.SubChunkTwoId)); // // Subchunk2 ID Write(audioDataSize); //subchunk2 size audioStreamStart = this.BaseStream.Position; } //WriteRiffHeader void IDisposable.Dispose() { Close(); } public override void Close() { if (isClosed) return; audioDataSize = (uint)(this.BaseStream.Position - audioStreamStart); Seek(0, SeekOrigin.Begin); WriteRiffHeader(); isClosed = true; base.Close(); } //Close long audioStreamStart; WaveParameterWriter waveParameterWriter; uint audioDataSize; bool isClosed; sealed class WaveParameterWriter { internal WaveParameterWriter() : this(DefinitionSet.DefaultRate, DefinitionSet.DefaultBitsPerSample, DefinitionSet.DefaultChannels) { } internal WaveParameterWriter(uint rate, short bits, short channels) { this.channels = channels; this.sampleRate = rate; this.bitsPerSample = bits; this.blockAlign = (short)(channels * (bits / 8)); this.byteRate = (uint)(sampleRate * blockAlign); } //WaveHeaderWriter internal void Write(BinaryWriter writer) { writer.Write(channels); writer.Write(sampleRate); writer.Write(byteRate); writer.Write(blockAlign); writer.Write(bitsPerSample); } //Write short channels; uint sampleRate; uint byteRate; short blockAlign; short bitsPerSample; } //class WaveHeaderWriter } //class WaveWriter } //namespace Wave
It is based on the following definitions:
using System; using System.Collections.Generic; namespace Wave { public partial class WaveWriter { static class DefinitionSet { // see https://ccrma.stanford.edu/courses/422/projects/WaveFormat internal const string ChunkId = "RIFF"; internal const uint ChunkHeaderSize = 38; internal const string Format = "WAVE"; internal const string SubChunkOneId = "fmt "; internal const uint SubChunkOneSize = 18; internal const short AudioFormatPcm = 1; // variable parameters: NumChannels, SampleRate, ByteRate, BlockAlign, BitsPerSample internal const short ExtraParameterSizePcm = 0; internal const string SubChunkTwoId = "data"; internal const uint DefaultRate = 44100; internal const short DefaultBitsPerSample = 16; internal const short DefaultChannels = 2; } //class DefinitionSet } //class WaveWriter } //namespace Wave
I tested it pretty well; it works.
Primarily, I used this piece of documentation: https://ccrma.stanford.edu/courses/422/projects/WaveFormat[^].
—SA
Your class is prety cool, yesterday i missed up in reading my wave Header, it's when a write the data the problem. The length is bigger than original!!
这篇关于在wav.file中编写Header wav的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文