Silverlight实用窍门系列:41.Silverlight中调用麦克风模拟录音机设备,存储为WAV音频
在Silverlight 4中
支持了麦克风设置的
调用,
在本节中我们将
调用麦克风设备,然后进行录音,并且将录制的声音存取为Wav音频
文件。 第一步、首先我们从Au
dioSink类派生
一个音频接收器类:WavAu
dioSink。其
代码如下所示: public class WavAu
dioSink:Au
dioSink
{ //设置需
@H_
262_24@
在Silverlight 4中支持了麦克风设置的调用,在本节中我们将调用麦克风设备,然后进行录音,并且将录制的声音存取为Wav音频文件。
第一步、首先我们从AudioSink类派生一个音频接收器类:WavAudioSink。其代码如下所示:
public
class WavAu
dioSink:Au
dioSink
{
// 设置需要记录的内存流
private MemoryStream _stream;
// 设置当前的音频格式
private Au
dioFormat _format;
public Stream
backingStream
{
get {
return _stream; }
}
public Au
dioFormat CurrentFormat
{
get {
return _format; }
}
protected
override
void OnCaptureStarted()
{
_stream =
new MemoryStream(10
24);
}
protected
override
void OnCaptureStopped()
{
}
protected
override
void OnFormatChange(Au
dioFormat au
dioFormat)
{
if (au
dioFormat.WaveFormat
!= WaveFormatType.Pcm)
throw
new Invali
doperationException(
"WavAudioSink只支持PCM音频格式");
_format = au
dioFormat;
}
protected
override
void OnSamples(
long sampleTime,
long sampleDuration,
byte[] sampleData)
{
// 新的音频数据到达,将它们写入流
_strea
m.Write(sampleData, 0, sampleData.Length
);
}
}
第二步、然后我们将编写一个保存音频的函数类,以保存读取到的音频数据:
public
class SaveWAV
Helper
{
public
static
void SavePcmToWav(Stream
rawData, Stream output, Au
dioFormat au
dioFormat)
{
if (au
dioFormat.WaveFormat
!= WaveFormatType.Pcm)
throw
new argume
ntexception(
"Only PCM coding is supported.");
BinaryWriter bwOutput =
new BinaryWriter(output
);
// -- rIFF 块
bwOutput.Write(
"RIFF".
tocharArray()
);
// 包的总长度
// 计算的数据长度加上数据头的长度没有数据
// 写数据(44 - 4 ("RIFF") - 4 (当前数据))
bwOutput.Write((
uint)(rawData.Length + 36)
);
bwOutput.Write(
"WAVE".
tocharArray()
);
// -- FORMAT 块
bwOutput.Write(
"fmt ".
tocharArray()
);
// FORMAT 块的长度 (Binary, 总是 0x10)
bwOutput.Write((
uint)0x10
);
// 总是 0x01
bwOutput.Write((
ushort)0x01
);
// 通道数( 0x01=单声道, 0x02=立体声)
bwOutput.Write((
ushort)au
dioFormat.Ch
Annels
);
// 采样率 (Binary, Hz为单位)
bwOutput.Write((
uint)au
dioFormat.SamplesPerSecond
);
// 字节每秒
bwOutput.Write((
uint)(au
dioFormat
.bitsPerSample * au
dioFormat.SamplesPerSecond *
au
dioFormat.Ch
Annels / 8)
);
// 每个样品字节: 1=8 bit 单声道, 2=8 bit 立体声 or 16 bit 单声道, 4=16 bit 立体声
bwOutput.Write((
ushort)(au
dioFormat
.bitsPerSample * au
dioFormat.Ch
Annels / 8)
);
// 每个样品字节
bwOutput.Write((
ushort)au
dioFormat
.bitsPerSampl
E);
// -- DATA 块
bwOutput.Write(
"data".
tocharArray()
);
// DATA数据块的长度
bwOutput.Write((
uint)rawData.Length
);
// 原始PCM数据如下
// 复位rawData地位,记住它的原点位置
// 恢复底。
long originalRawDataStreamPosition =
rawData.Position;
rawData.Seek(0, SeekOrigin
.begin
);
//追加到输出流中的所有数据从rawData流
byte[] buffer =
new
byte[409
6];
int read;
// 循环读取字节数据
while ((read =
rawData.Read(buffer, 4096)) > 0)
{
bwOutput.Write(buffer,
read
);
}
//开始写入数据
rawData.Seek(originalRawDataStreamPosition, SeekOrigin
.begin
);
}
}
第三步、然后再MainPage.xaml中我们添加三个按钮,分别是开始记录音频、停止录制音频、保存音频文件三个按钮。
<
Grid x:Name=
"LayoutRoot"
BACkground=
"White">
<
Button Content=
"开始录制"
Height=
"28"
HorizontalAlignment=
"Left"
Margin=
"30,15,0"
NAME=
"btnRecord"
VerticalAlignment=
"Top"
Width=
"71"
Click=
"btnRecord_Click"
/>
<
Button Content=
"停止录制"
Height=
"28"
HorizontalAlignment=
"Left"
Margin=
"150,0"
NAME=
"btnStopRecord"
VerticalAlignment=
"Top"
Width=
"71"
Click=
"btnStopRecord_Click"
/>
<
Button Content=
"保存音频"
Height=
"28"
HorizontalAlignment=
"Left"
Margin=
"268,0"
NAME=
"btnSaveWav"
VerticalAlignment=
"Top"
Width=
"71"
Click=
"btnSaveWav_Click"
/>
<
/Grid>
第四步、最后在MainPage.xaml.cs代码中我们进行录制、停止、保存音频的操作如下所示:
public partial
class MainPage : UserControl
{
public MainPage()
{
InitializeComponent(
);
btnRecord.IsEnabled =
true;
btnStopRecord.IsEnabled =
false;
btnSaveWav.IsEnabled =
false;
}
//声明私有变量
private WavAu
dioSink _wavSink;
private Captu
resource _captu
resource;
private SaveFileDialog _saveFileDialog =
new SaveFileDialog()
{ Filter =
"Audio files (*.wav)|*.wav" };
private
void btnRecord_Click(
object sender,
routedEventArgs
E)
{
//初始化_capturesource
var au
dioDevice = CaptureDeviceCon
figuration.GetDefaultAu
dioCaptureDevice(
);
_captu
resource =
new Captu
resource()
{ Au
dioCaptureDevice = au
dioDevice };
//有默认设置的设备且可以用来录制音频
if (CaptureDeviceCon
figuration.AllowedDeviceAccess ||
CaptureDeviceCon
figuration.
requestDeviceAccess())
{
//判断当前没有开始录制音频
if (_captu
resource.State == CaptureState.Stopped)
{
//初始化WavAudioSink
_wavSink =
new WavAu
dioSink(
);
_wavSink.Captu
resource = _captu
resource;
//开始录制音频
_captu
resource.Start(
);
}
}
btnRecord.IsEnabled =
false;
btnStopRecord.IsEnabled =
true;
btnSaveWav.IsEnabled =
false;
}
private
void btnStopRecord_Click(
object sender,
routedEventArgs
E)
{
//如果当前状态为开始录制,则停止录制
if (_captu
resource.State == CaptureState.Started)
{
_captu
resource.Stop(
);
}
btnRecord.IsEnabled =
false;
btnStopRecord.IsEnabled =
false;
btnSaveWav.IsEnabled =
true;
}
private
void btnSaveWav_Click(
object sender,
routedEventArgs
E)
{
if (_saveFileDialog.ShowDialog() ==
false)
{
return;
}
//保存Wav文件
Stream stream = _saveFileDialog
.openFile(
);
SaveWAV
Helper.SavePcmToWav(_wavSink.
backingStream, stream, _wavSink.CurrentFormat
);
strea
m.Close(
);
message
Box.Show(
"你的音频已经保存");
btnRecord.IsEnabled =
true;
btnStopRecord.IsEnabled =
false;
btnSaveWav.IsEnabled =
false;
}
}
通过以上步骤我们就可以开始调用麦克风录制音频文件了,本实例采用Silverlight 4.0+VS2010编写,如需源码请点击 SL4Audio.zip 下载。其效果图如下所示:
@H_881_616@@H_881_616@@H_554_618@
本文来自程兴亮的博客,原文地址:http://www.cnblogs.com/chengxingliang/archive/2011/05/16/2046981.html