大佬教程收集整理的这篇文章主要介绍了Silverlight实用系列:41.Silverlight中调用麦克风模拟录音机设备,存储为WAV音频,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在Silverlight 4中支持了麦克风设置的调用,在本节中我们将调用麦克风设备,然后进行录音,并且将录制的声音存取为Wav音频文件。
第一步、首先我们从AudioSink类派生一个音频接收器类:WavAudioSink。其代码如下所示:
- public@H_197_28@ class WavAudioSink:AudioSink @H_197_28@@H_197_28@
- { @H_197_28@
- // 设置需要记录的内存流 @H_197_28@
- private MemoryStream _stream; @H_197_28@
- // 设置当前的音频格式 @H_197_28@
- private AudioFormat _format; @H_197_28@
- @H_197_28@
- public@H_197_28@ Stream backingStream @H_197_28@@H_197_28@
- { @H_197_28@
- get { return@H_197_28@ _stream; } @H_197_28@@H_197_28@
- } @H_197_28@
- @H_197_28@
- public@H_197_28@ AudioFormat CurrentFormat @H_197_28@@H_197_28@
- { @H_197_28@
- get { return@H_197_28@ _format; } @H_197_28@@H_197_28@
- } @H_197_28@
- @H_197_28@
- protected override void OnCaptureStarted() @H_197_28@
- { @H_197_28@
- _stream = new MemoryStream(1024); @H_197_28@
- } @H_197_28@
- @H_197_28@
- protected override void OnCaptureStopped() @H_197_28@
- { @H_197_28@
- } @H_197_28@
- @H_197_28@
- protected override void OnFormatChange(AudioFormat audioFormat) @H_197_28@
- { @H_197_28@
- if (audioFormat.WaveFormat != WaveFormatType.Pcm) @H_197_28@
- throw new InvalidoperationException("WavAudioSink只支持PCM音频格式"@H_197_28@); @H_197_28@@H_197_28@
- @H_197_28@
- _format = audioFormat; @H_197_28@
- } @H_197_28@
- @H_197_28@
- protected override void OnSamples(long sampleTime, long sampleDuration, @H_197_28@
- byte[] sampleData) @H_197_28@
- { @H_197_28@
- // 新的音频数据到达,将它们写入流 @H_197_28@
- _stream.Write(sampleData, 0, sampleData.Length); @H_197_28@
- } @H_197_28@
- } @H_197_28@
第二步、然后我们将编写一个保存音频的函数类,以保存读取到的音频数据:
- public@H_197_28@ class SaveWAVHelper @H_197_28@@H_197_28@
- { @H_197_28@
- public@H_197_28@ @H_197_28@static@H_197_28@ void SavePcmToWav(Stream rawData, Stream @H_197_28@output@H_197_28@, AudioFormat audioFormat) @H_197_28@@H_197_28@
- { @H_197_28@
- if (audioFormat.WaveFormat != WaveFormatType.Pcm) @H_197_28@
- throw new argumentexception("Only PCM coding is supported."@H_197_28@); @H_197_28@@H_197_28@
- @H_197_28@
- BinaryWriter bwOutput = new BinaryWriter(output@H_197_28@); @H_197_28@@H_197_28@
- @H_197_28@
- // -- rIFF 块@H_197_28@ @H_197_28@@H_197_28@
- bwOutput.Write("RIFF"@H_197_28@.tocharArray()); @H_197_28@@H_197_28@
- // 包的总长度 @H_197_28@
- // 计算的数据长度加上数据头的长度没有数据 @H_197_28@
- // 写数据(44 - 4 ("RIFF"@H_197_28@) - 4 (当前数据)) @H_197_28@@H_197_28@
- bwOutput.Write((uint)(rawData.Length + 36)); @H_197_28@
- bwOutput.Write("WAVE"@H_197_28@.tocharArray()); @H_197_28@@H_197_28@
- @H_197_28@
- // -- FORMAT 块@H_197_28@ @H_197_28@@H_197_28@
- bwOutput.Write("fmt "@H_197_28@.tocharArray()); @H_197_28@@H_197_28@
- // FORMAT 块的长度 (Binary@H_197_28@, 总是 0x10) @H_197_28@@H_197_28@
- bwOutput.Write((uint)0x10); @H_197_28@
- // 总是 0x01 @H_197_28@
- bwOutput.Write((ushort)0x01); @H_197_28@
- // 通道数( 0x01=单声道, 0x02=立体声) @H_197_28@
- bwOutput.Write((ushort)audioFormat.ChAnnels); @H_197_28@
- // 采样率 (Binary@H_197_28@, Hz为单位) @H_197_28@@H_197_28@
- bwOutput.Write((uint)audioFormat.SamplesPerSecond); @H_197_28@
- // 字节每秒 @H_197_28@
- bwOutput.Write((uint)(audioFormat.bitsPerSample * audioFormat.SamplesPerSecond * @H_197_28@
- audioFormat.ChAnnels / 8)); @H_197_28@
- // 每个样品字节: 1=8 bit@H_197_28@ 单声道, 2=8 @H_197_28@bit@H_197_28@ 立体声 @H_197_28@or@H_197_28@ 16 @H_197_28@bit@H_197_28@ 单声道, 4=16 @H_197_28@bit@H_197_28@ 立体声 @H_197_28@@H_197_28@
- bwOutput.Write((ushort)(audioFormat.bitsPerSample * audioFormat.ChAnnels / 8)); @H_197_28@
- // 每个样品字节 @H_197_28@
- bwOutput.Write((ushort)audioFormat.bitsPerSamplE); @H_197_28@
- @H_197_28@
- // -- DATA 块@H_197_28@ @H_197_28@@H_197_28@
- bwOutput.Write("data"@H_197_28@.tocharArray()); @H_197_28@@H_197_28@
- // DATA数据块的长度 @H_197_28@
- bwOutput.Write((uint)rawData.Length); @H_197_28@
- // 原始PCM数据如下 @H_197_28@
- // 复位rawData地位,记住它的原点位置 @H_197_28@
- // 恢复底。 @H_197_28@
- long originalRawDataStreamPosition = rawData.Position; @H_197_28@
- rawData.Seek(0, SeekOrigin.Begin@H_197_28@); @H_197_28@@H_197_28@
- //追加到输出流中的所有数据从rawData流 @H_197_28@
- byte[] buffer = new byte[4096]; @H_197_28@
- int@H_197_28@ @H_197_28@read@H_197_28@; @H_197_28@@H_197_28@
- // 循环读取字节数据 @H_197_28@
- while ((read@H_197_28@ = rawData.@H_197_28@Read@H_197_28@(buffer, 4096)) > 0) @H_197_28@@H_197_28@
- { @H_197_28@
- bwOutput.Write(buffer, read@H_197_28@); @H_197_28@@H_197_28@
- } @H_197_28@
- //开始写入数据 @H_197_28@
- rawData.Seek(originalRawDataStreamPosition, SeekOrigin.Begin@H_197_28@); @H_197_28@@H_197_28@
- } @H_197_28@
- } @H_197_28@
第三步、然后再MainPage.xaml中我们添加三个按钮,分别是开始记录音频、停止录制音频、保存音频文件三个按钮。
- <Grid x:@H_197_28@Name@H_197_28@=@H_197_28@"LayoutRoot"@H_197_28@ BACkground=@H_197_28@"White"@H_197_28@> @H_197_28@@H_197_28@
- <Button Content="开始录制"@H_197_28@ Height=@H_197_28@"28"@H_197_28@ HorizontalAlignment=@H_197_28@"Left"@H_197_28@ @H_197_28@@H_197_28@
- @H_212_26@margin="30,15,0"@H_197_28@ @H_197_28@Name@H_197_28@=@H_197_28@"btnRecord"@H_197_28@ VerticalAlignment=@H_197_28@"Top"@H_197_28@ @H_197_28@@H_197_28@
- Width="71"@H_197_28@ Click=@H_197_28@"btnRecord_Click"@H_197_28@ /> @H_197_28@@H_197_28@
- <Button Content="停止录制"@H_197_28@ Height=@H_197_28@"28"@H_197_28@ HorizontalAlignment=@H_197_28@"Left"@H_197_28@ @H_197_28@@H_197_28@
- @H_212_26@margin="150,0"@H_197_28@ @H_197_28@Name@H_197_28@=@H_197_28@"btnStopRecord"@H_197_28@ VerticalAlignment=@H_197_28@"Top"@H_197_28@ @H_197_28@@H_197_28@
- Width="71"@H_197_28@ Click=@H_197_28@"btnStopRecord_Click"@H_197_28@ /> @H_197_28@@H_197_28@
- <Button Content="保存音频"@H_197_28@ Height=@H_197_28@"28"@H_197_28@ HorizontalAlignment=@H_197_28@"Left"@H_197_28@ @H_197_28@@H_197_28@
- @H_212_26@margin="268,0"@H_197_28@ @H_197_28@Name@H_197_28@=@H_197_28@"btnSaveWav"@H_197_28@ VerticalAlignment=@H_197_28@"Top"@H_197_28@ @H_197_28@@H_197_28@
- Width="71"@H_197_28@ Click=@H_197_28@"btnSaveWav_Click"@H_197_28@ /> @H_197_28@@H_197_28@
- </Grid> @H_197_28@
第四步、最后在MainPage.xaml.cs代码中我们进行录制、停止、保存音频的操作如下所示:
- public@H_197_28@ @H_197_28@partial@H_197_28@ class MainPage : UserControl @H_197_28@@H_197_28@
- { @H_197_28@
- public@H_197_28@ MainPage() @H_197_28@@H_197_28@
- { @H_197_28@
- InitializeComponent(); @H_197_28@
- @H_197_28@
- btnRecord.IsEnabled = true@H_197_28@; @H_197_28@@H_197_28@
- btnStopRecord.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- btnSaveWav.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- } @H_197_28@
- @H_197_28@
- //声明私有变量 @H_197_28@
- private WavAudioSink _wavSink; @H_197_28@
- private Capturesource _capturesource; @H_197_28@
- private SaveFileDialog _saveFileDialog = new SaveFileDialog() @H_197_28@
- { Filter = "Audio files (*.wav)|*.wav"@H_197_28@ }; @H_197_28@@H_197_28@
- @H_197_28@
- private void btnRecord_Click(object sender, routedEventArgs E) @H_197_28@
- { @H_197_28@
- @H_197_28@
- //初始化_capturesource @H_197_28@
- var audioDevice = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice(); @H_197_28@
- _capturesource = new Capturesource() { AudioCaptureDevice = audioDevice }; @H_197_28@
- @H_197_28@
- //有默认设置的设备且可以用来录制音频 @H_197_28@
- if (CaptureDeviceConfiguration.AllowedDeviceAccess || @H_197_28@
- CaptureDeviceConfiguration.@R_874_10613@estDeviceAccess()) @H_197_28@
- { @H_197_28@
- //判断当前没有开始录制音频 @H_197_28@
- if (_capturesource.State == CaptureState.Stopped) @H_197_28@
- { @H_197_28@
- //初始化WavAudioSink @H_197_28@
- _wavSink = new WavAudioSink(); @H_197_28@
- _wavSink.Capturesource = _capturesource; @H_197_28@
- //开始录制音频 @H_197_28@
- _capturesource.Start(); @H_197_28@
- @H_197_28@
- } @H_197_28@
- } @H_197_28@
- @H_197_28@
- btnRecord.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- btnStopRecord.IsEnabled = true@H_197_28@; @H_197_28@@H_197_28@
- btnSaveWav.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- } @H_197_28@
- @H_197_28@
- private void btnStopRecord_Click(object sender, routedEventArgs E) @H_197_28@
- { @H_197_28@
- //如果当前状态为开始录制,则停止录制 @H_197_28@
- if (_capturesource.State == CaptureState.Started) @H_197_28@
- { @H_197_28@
- _capturesource.Stop(); @H_197_28@
- } @H_197_28@
- @H_197_28@
- btnRecord.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- btnStopRecord.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- btnSaveWav.IsEnabled = true@H_197_28@; @H_197_28@@H_197_28@
- } @H_197_28@
- @H_197_28@
- private void btnSaveWav_Click(object sender, routedEventArgs E) @H_197_28@
- { @H_197_28@
- if (_saveFileDialog.ShowDialog() == false@H_197_28@) @H_197_28@@H_197_28@
- { @H_197_28@
- return@H_197_28@; @H_197_28@@H_197_28@
- } @H_197_28@
- //保存Wav文件 @H_197_28@
- Stream stream = _saveFileDialog.openFile(); @H_197_28@
- SaveWAVHelper.SavePcmToWav(_wavSink.backingStream, stream, _wavSink.CurrentFormat); @H_197_28@
- @H_197_28@
- stream.Close@H_197_28@(); @H_197_28@@H_197_28@
- @H_197_28@
- messageBox.Show("你的音频已经保存"@H_197_28@); @H_197_28@@H_197_28@
- @H_197_28@
- btnRecord.IsEnabled = true@H_197_28@; @H_197_28@@H_197_28@
- btnStopRecord.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- btnSaveWav.IsEnabled = false@H_197_28@; @H_197_28@@H_197_28@
- } @H_197_28@
- } @H_197_28@
通过以上步骤我们就可以开始调用麦克风录制音频文件了,本实例采用Silverlight 4.0+VS2010编写,如需源码请点击 SL4Audio.zip 下载。其效果图如下所示:
以上是大佬教程为你收集整理的Silverlight实用系列:41.Silverlight中调用麦克风模拟录音机设备,存储为WAV音频全部内容,希望文章能够帮你解决Silverlight实用系列:41.Silverlight中调用麦克风模拟录音机设备,存储为WAV音频所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。