Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1071582
  • 博文数量: 403
  • 博客积分: 10272
  • 博客等级: 上将
  • 技术积分: 4407
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 14:22
文章分类

全部博文(403)

文章存档

2012年(403)

分类: 嵌入式

2012-03-11 16:57:00

 前面介绍了Windows Phone 录制音频,通过访问Windows Phone的麦克风进行录制音频。录制好的音频要保存为文件,需要做相关格式转换。一般录音的格式为.WAV,下面就介绍如何将录音保存为WAV文件。
  1.在录制音频开始之前,首先要向音频流存储区audioStream中写入WAV文件头信息。即在调用microphone.Start()之前调用WriteWavHeader(audioStream, microphone.SampleRate),其中WriteWavHeader函数实现如下。
WriteWavHeader
1 ///
2 /// 写wav文件头信息
3 ///

4 ///
5 ///
6 public void WriteWavHeader(Stream stream, int sampleRate)
7 {
8 const int bitsPerSample = 16;
9 const int bytesPerSample = bitsPerSample / 8;
10 var encoding = System.Text.Encoding.UTF8;
11
12 // ChunkID Contains the letters "RIFF" in ASCII form (0x52494646 big-endian form).
13 stream.Write(encoding.GetBytes("RIFF"), 0, 4);
14
15 // NOTE this will be filled in later
16 stream.Write(BitConverter.GetBytes(0), 0, 4);
17
18 // Format Contains the letters "WAVE"(0x57415645 big-endian form).
19 stream.Write(encoding.GetBytes("WAVE"), 0, 4);
20
21 // Subchunk1ID Contains the letters "fmt " (0x666d7420 big-endian form).
22 stream.Write(encoding.GetBytes("fmt "), 0, 4);
23
24 // Subchunk1Size 16 for PCM. This is the size of therest of the Subchunk which follows this number.
25 stream.Write(BitConverter.GetBytes(16), 0, 4);
26
27 // AudioFormat PCM = 1 (i.e. Linear quantization) Values other than 1 indicate some form of compression.
28 stream.Write(BitConverter.GetBytes((short)1), 0, 2);
29
30 // NumChannels Mono = 1, Stereo = 2, etc.
31 stream.Write(BitConverter.GetBytes((short)1), 0, 2);
32
33 // SampleRate 8000, 44100, etc.
34 stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
35
36 // ByteRate = SampleRate * NumChannels * BitsPerSample/8
37 stream.Write(BitConverter.GetBytes(sampleRate * bytesPerSample), 0, 4);
38
39 // BlockAlign NumChannels * BitsPerSample/8 The number of bytes for one sample including all channels.
40 stream.Write(BitConverter.GetBytes((short)(bytesPerSample)), 0, 2);
41
42 // BitsPerSample 8 bits = 8, 16 bits = 16, etc.
43 stream.Write(BitConverter.GetBytes((short)(bitsPerSample)), 0, 2);
44
45 // Subchunk2ID Contains the letters "data" (0x64617461 big-endian form).
46 stream.Write(encoding.GetBytes("data"), 0, 4);
47
48 // NOTE to be filled in later
49 stream.Write(BitConverter.GetBytes(0), 0, 4);
50 }

  2.在录制音频结束的时候,才能确认录音文件大小的长度,此时需要修改WAV文件头部分信息。即在调用microphone.Stop()之后调用UpdateWavHeader(audioStream),其中UpdateWavHeader函数实现如下。

UpdateWavHeader
1 ///
2 /// 更新wav文件头信息
3 ///

4 ///
5 public void UpdateWavHeader(Stream stream)
6 {
7 if (!stream.CanSeek) throw new Exception("Can't seek stream to update wav header");
8
9 var oldPos = stream.Position;
10
11 // ChunkSize 36 + SubChunk2Size
12 stream.Seek(4, SeekOrigin.Begin);
13 stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
14
15 // Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data.
16 stream.Seek(40, SeekOrigin.Begin);
17 stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
18
19 stream.Seek(oldPos, SeekOrigin.Begin);
20 }

  3.通过以上处理后的audioStream流已经是格式化后的WAV流。接下来只需要将audioStream流写入独立存储中(yu.wav)。

View Code
//将数据流转换为byte,recording中即为音频数据
byte[] recording = audioStream.ToArray();
//独立存储文件处理
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
//打开文件
using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("yu.wav", FileMode.Create, myIsolatedStorage))
{
fileStream.Write(recording, 0, recording.Length);
}
}
catch (Exception ex)
{
//读取失败
}
}

阅读(517) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~