标签:style class code tar ext color
1: public class SpeakLouder
2: {3: private WavFormat _wavFormat=new WavFormat(); //文件格式
4: private byte[] _audioData; //语音数据
5: private SpeechSynthesizer _speech; //文本转语音
6: private string _pb;//文本转语音参数
7: 8: /// <summary>
9: /// 文本转语音的说话器
10: /// </summary>
11: public SpeechSynthesizer Speech
12: {13: set { _speech = value; }
14: } 15: 16: /// <summary>
17: /// 说话器的帮助参数
18: /// </summary>
19: public string Prompt
20: {21: set { _pb = value; }
22: } 23: 24: 25: /// <summary>
26: /// 执行播放操作
27: /// </summary>
28: /// <param name="speech">文本转语音的说话对象</param>
29: /// <param name="pb">文本转语音的speak参数</param>
30: /// <param name="scale">语音放大倍数</param>
31: public void Play(SpeechSynthesizer speech, string pb, double scale)
32: { 33: _speech = speech; 34: _pb = pb; 35: Analyze(); 36: WaveScale(scale); 37: WriteWavFile(); 38: } 39: 40: #region Analyze 分析音频文件
41: /// <summary>
42: /// 分析音频文件
43: /// </summary>
44: private void Analyze()
45: {46: MemoryStream _stream = null;
47: BinaryReader br = null;
48: try
49: {50: //构造读取流
51: _stream = new MemoryStream();
52: _speech.SetOutputToWaveStream(_stream); 53: _speech.Speak(_pb); 54: 55: br = new BinaryReader(_stream);
56: 57: _stream.Position = 22; 58: _wavFormat.Channels = br.ReadInt16(); 59: _stream.Position = 24; 60: _wavFormat.SampleRate = br.ReadInt32(); 61: _stream.Position = 28; 62: _wavFormat.ByteRate = br.ReadInt32(); 63: _stream.Position = 34; 64: _wavFormat.BitsPerSample = br.ReadInt16(); 65: _stream.Position = 44;66: int dataByteSize = (int)(_stream.Length - 44);
67: _audioData = new byte[dataByteSize];
68: _stream.Read(_audioData, 0, dataByteSize); 69: }70: catch (Exception ex)
71: {72: Akloger.Error("解析刷卡语音出错:" + ex);
73: }74: finally
75: {76: if (br != null)
77: { 78: br.Close(); 79: br.Dispose(); 80: }81: if (_stream != null)
82: { 83: _stream.Close(); 84: _stream.Dispose(); 85: } 86: } 87: }88: #endregion
89: 90: #region WriteWavFile 写文件
91: /// <summary>
92: /// 写文件
93: /// </summary>
94: /// <param name="wavFormat">文件格式</param>
95: /// <param name="audioData">音频数据</param>
96: /// <param name="startIndex">audioData数组开始索引位置</param>
97: /// <param name="length">写入audioData数组长度</param>
98: private void WriteWavFile()
99: {100: MemoryStream fs = null;
101: BinaryWriter bw = null;
102: try
103: {104: fs = new MemoryStream();
105: bw = new BinaryWriter(fs);
106: fs.Position = 0;107: bw.Write(new char[4] { ‘R‘, ‘I‘, ‘F‘, ‘F‘ });
108: bw.Write((int)(_audioData.Length + 44 - 8));
109: bw.Write(new char[8] { ‘W‘, ‘A‘, ‘V‘, ‘E‘, ‘f‘, ‘m‘, ‘t‘, ‘ ‘ });
110: bw.Write((int)16);
111: bw.Write((short)1);
112: bw.Write((short)_wavFormat.Channels);
113: bw.Write(_wavFormat.SampleRate);114: bw.Write((int)(_wavFormat.SampleRate * ((_wavFormat.BitsPerSample * _wavFormat.Channels) / 8)));
115: bw.Write((short)((_wavFormat.BitsPerSample * _wavFormat.Channels) / 8));
116: bw.Write((short)_wavFormat.BitsPerSample);
117: bw.Write(new char[4] { ‘d‘, ‘a‘, ‘t‘, ‘a‘ });
118: bw.Write(_audioData.Length); 119: bw.Write(_audioData, 0, _audioData.Length); 120: 121: //播放声音
122: fs.Position = 0;123: SoundPlayer _player = new SoundPlayer();
124: _player.Stream = null;
125: _player.Stream = fs; 126: _player.PlaySync(); 127: 128: 129: }catch (Exception ex)
130: {131: Akloger.Error("保存刷卡语音出错:" + ex);
132: }133: finally
134: {135: if (bw != null)
136: { 137: bw.Close(); 138: bw.Dispose(); 139: }140: if (fs != null)
141: { 142: fs.Close(); 143: fs.Dispose(); 144: } 145: } 146: }147: #endregion
148: 149: #region WaveScale 放大音频音量
150: /// <summary>
151: /// 放大音频音量
152: /// </summary>
153: /// <param name="scale">音量放大倍数</param>
154: private void WaveScale(double scale)
155: {156: //总播放时间
157: // long totalTime = _wavFile.PlayTime;
158: 159: //采样位数
160: // 16 bit 纵坐标为采样系数 细化为 2^16= 65535份 16位二进制表示 [ 0000 0000 0000 0000 ]
161: // 即为2Byte (每单位时间内产生 2Byte 的音频数据)
162: 163: int byteNumPerSample = _wavFormat.BitsPerSample / 8;
164: 165: //采样频率
166: // 11025Hz 横坐标为采样频率 单位时间为: 1/11025 s
167: //单位时间内产生的的音频数据大小为 2Byte * 11025Hz * 声道数
168: 169: //字节数组 音频数据
170: byte[] audioDatas = _audioData;
171: 172: 173: // i 的值为每次衰减处理时的 字节读取位置 (索引)
174: for (int i = 0; i < audioDatas.Length; i += byteNumPerSample)
175: { 176: 177: 178: //单位时间内的字节数为1 即采用8bit采样位数 每次只需要对一个字节进行衰减
179: if (byteNumPerSample == 1)
180: {181: //获取需要衰减的字节值
182: var audioData = (double)audioDatas[i];
183: 184: var temp = audioData * 1;185: if (temp < -32767.5)
186: { 187: temp = -32768; 188: }189: else if (temp > (float)32766.5)
190: { 191: temp = 32767; 192: }193: //进行衰减线性处理
194: byte changedAudioData = (byte)temp;
195: 196: //对原来的值进行更改
197: audioDatas[i] = changedAudioData; 198: }199: else if (byteNumPerSample == 2)
200: {201: //16bit 量化 每单位时间产生2Byte数据 因此取 2Byte 的数据进行衰减处理
202: byte[] audioData = new byte[2];
203: Array.Copy(audioDatas, i, audioData, 0, 2); 204: 205: //单个样点幅值
206: double sample = 0;
207: 208: //转换为整数进行线性处理
209: sample = (double)BitConverter.ToInt16(audioData, 0) * scale;
210: if (sample < -32767.5)
211: { 212: sample = -32768; 213: }214: else if (sample > (double)32766.5)
215: { 216: sample = 32767; 217: }218: //转换为字节存储
219: byte[] buffer = BitConverter.GetBytes(Convert.ToInt16(sample));
220: if (!BitConverter.IsLittleEndian)
221: Array.Reverse(buffer); 222: 223: Array.Copy(buffer, 0, audioDatas, i, 2); 224: } 225: } 226: _audioData = audioDatas; 227: }228: #endregion
229: 230: } 231: 232: #region WavFormat 头文件信息
233: /// <summary>
234: /// WAV 文件格式
235: /// </summary>
236: public class WavFormat
237: {238: /// <summary>
239: /// 采样位数
240: /// </summary>
241: public int BitsPerSample;
242: /// <summary>
243: /// 声道数
244: /// </summary>
245: public int Channels;
246: /// <summary>
247: /// 采样率
248: /// </summary>
249: public int SampleRate;
250: /// <summary>
251: /// 传输速率(播放速率)
252: /// </summary>
253: public long ByteRate;
254: }255: #endregion
标签:style class code tar ext color
原文地址:http://www.cnblogs.com/maomao999/p/3707861.html