在wave file standard用Kinect录制音频数据之后,我编写了一个WriteWavHeader()
方法,该方法适用于1个通道(PCM,采样率:16 kHz,位/样本:16)。问题是,当我尝试以立体声(nChannels = 2
)录制时,似乎轨道的速度加倍!我有什么想法吗?
static void WriteWavHeader(Stream stream, int dataLength)
{
using (var memStream = new MemoryStream(64))
{
int cbFormat = 16; //sizeof(WAVEFORMATEX)
WAVEFORMATEX format = new WAVEFORMATEX()
{
//Subchunk1Size == 16 for PCM.
wFormatTag = 1,
//NumChannels : Mono = 1, Stereo = 2, etc.
nChannels = 2,
//SampleRate 8000, 44100
nSamplesPerSec = 16000,
//ByteRate == SampleRate * NumChannels * BitsPerSample/8
nAvgBytesPerSec = 32000*2,
//BlockAlign == NumChannels * BitsPerSample/8
nBlockAlign = 2*2,
//BitsPerSample 8 bits = 8, 16 bits = 16, etc.
wBitsPerSample = 16
};
using (var binarywriter = new BinaryWriter(memStream))
{
//RIFF header
WriteString(memStream, "RIFF");
binarywriter.Write(dataLength+8 + cbFormat+8 + 4);
WriteString(memStream, "WAVE");
WriteString(memStream, "fmt ");
binarywriter.Write(cbFormat);
//WAVEFORMATEX
binarywriter.Write(format.wFormatTag);
binarywriter.Write(format.nChannels);
binarywriter.Write(format.nSamplesPerSec);
binarywriter.Write(format.nAvgBytesPerSec);
binarywriter.Write(format.nBlockAlign);
binarywriter.Write(format.wBitsPerSample);
//data header
WriteString(memStream, "data");
binarywriter.Write(dataLength);
memStream.WriteTo(stream);
}
}
}
录音方法:
public void RecordAudio()
{
//Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
int recordingLength = 5 *16000* 2 *2;
byte[] buffer = new byte[1024];
using (FileStream _fileStream = new FileStream("c:\\kinectAudio.wav", FileMode.Create))
{
WriteWavHeader(_fileStream, recordingLength);
int count, totalCount = 0;
//Start capturing audio
using (Stream audioStream = this.sensor.AudioSource.Start())
{
while ((count = audioStream.Read(buffer, 0, buffer.Length)) > 0 && totalCount < recordingLength)
{
_fileStream.Write(buffer, 0, count);
totalCount += count;
}
}
//write the real wav header
long prePosition = _fileStream.Position;
_fileStream.Seek(0, SeekOrigin.Begin);
WriteWavHeader(_fileStream, totalCount);
_fileStream.Seek(prePosition, SeekOrigin.Begin);
_fileStream.Flush();
}
}