欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Windows Phone 保存录音

程序员文章站 2024-01-14 18:19:22
前面介绍了Windows Phone 录制音频https://www.2cto.com/kf/201203/122741.html ,通过访问Windows Phone的...

前面介绍了Windows Phone 录制音频https://www.2cto.com/kf/201203/122741.html ,通过访问Windows Phone的麦克风进行录制音频。录制好的音频要保存为文件,需要做相关格式转换。一般录音的格式为.WAV,下面就介绍如何将录音保存为WAV文件。
  1.在录制音频开始之前,首先要向音频流存储区audioStream中写入WAV文件头信息。即在调用microphone.Start()之前调用WriteWavHeader(audioStream, microphone.SampleRate),其中WriteWavHeader函数实现如下。
  WriteWavHeader
 1 /// <summary>
 2 /// 写wav文件头信息
 3 /// </summary>
 4 /// <param name="stream"></param>
 5 /// <param name="sampleRate"></param>
 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 /// <summary>
 2 /// 更新wav文件头信息
 3 /// </summary>
 4 /// <param name="stream"></param>
 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)
            {
                //读取失败
            }
        }

 

摘自  宇之乐