Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Coding4Fun控件介绍(Audio)

From Wiki
Jump to: navigation, search
WP Metro Icon Multimedia.png
WP Metro Icon Tools.png
SignpostIcon XAML 40.png
SignpostIcon WP7 70px.png
Article Metadata

代码示例
兼容于
文章
WS - OtomiiLu 在 11 Oct 2012 创建
最后由 hamishwillee 在 29 Jun 2013 编辑

在Windows Phone 7的开发中,我们不仅仅拥有微软官方提供的原始的控件,还有CodePlex提供的一套Toolkit.但是,在日常开发中,这些控件往往是不够的,这里,我将会讨论如何使用另外一套第三方控件Coding4Fun.

Coding4Fun也是一套很有名的控件, 他追寻的是Microsoft Public License (Ms-PL), MS-PL 授权使用者可以自由修改、重制与散布该软体. 那么接下来,我们就进行这个控件的介绍:

引用控件

首先,我建议使用NuGet来安装整个控件. 打开Tools->Extension Manager->Online,在搜索框中输入NuGet,然后Download.

InstallNuGet.JPG

然后重启VS, 打开View->Other Windows->Package Manager Console. 在打开的Window中输入:

Install-Package Coding4Fun.Phone.Controls.Complete即可完成控件的引用,你会获得以下数据:

PM> Install-Package Coding4Fun.Phone.Controls.Complete
正在尝试解析依赖项“Coding4Fun.Phone.Audio”。
正在尝试解析依赖项“Coding4Fun.Phone.Net”。
正在尝试解析依赖项“Coding4Fun.Phone.Storage”。
正在尝试解析依赖项“Coding4Fun.Phone.Controls”。
正在尝试解析依赖项“Coding4Fun.Phone.Controls.TimeSpan”。
正在尝试解析依赖项“SilverlightToolkitWP”。
已成功安装“Coding4Fun.Phone.Audio 1.6.1”。
已成功安装“Coding4Fun.Phone.Net 1.6.1”。
已成功安装“Coding4Fun.Phone.Storage 1.6.1”。
已成功安装“Coding4Fun.Phone.Controls 1.6.1”。
已成功安装“SilverlightToolkitWP 4.2012.6.25”。
已成功安装“Coding4Fun.Phone.Controls.TimeSpan 1.6.1”。
已成功安装“Coding4Fun.Phone.Controls.Complete 1.6.1”。
已成功将“Coding4Fun.Phone.Audio 1.6.1”添加到 Coding4FunDemoInOne。
已成功将“Coding4Fun.Phone.Net 1.6.1”添加到 Coding4FunDemoInOne。
已成功将“Coding4Fun.Phone.Storage 1.6.1”添加到 Coding4FunDemoInOne。
已成功将“Coding4Fun.Phone.Controls 1.6.1”添加到 Coding4FunDemoInOne。
已成功将“SilverlightToolkitWP 4.2012.6.25”添加到 Coding4FunDemoInOne。
已成功将“Coding4Fun.Phone.Controls.TimeSpan 1.6.1”添加到 Coding4FunDemoInOne。
已成功将“Coding4Fun.Phone.Controls.Complete 1.6.1”添加到 Coding4FunDemoInOne。

同时,Coding4Fun还有另外几种命令,区别于Complete安装: 一种是不包括TimeSpan的: Install-Package Coding4Fun.Phone.Controls 一种是只有TimeSpan的: Install-Package Coding4Fun.Phone.Controls.TimeSpan

然后,我们需要通过以下代码来为我们的XAML页面添加我们需要的NameSpace:


xmlns:Coding4Fun="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls"

MicrophoneRecorder控件

首先我们介绍的是MicrophoneRecorder,主要是用于手机麦克风声音的录制,首先,我们看一下其类库:

MicrophoneRecorderDll.JPG

具体代码如下:

public class MicrophoneRecorder
{
private MemoryStream _recordStream;
private Microphone _microphone;
private byte[] _micBuffer;
 
private bool _shouldCallStopInTimeout;
 
public event EventHandler<EventArgs> BufferReady;
 
public MicrophoneRecorder()
{
InitMicrophone();
}
 
public byte[] Buffer
{
get;
private set;
}
 
public int SampleRate
{
get
{
InitMicrophone();
 
return _microphone.SampleRate;
}
}
 
public void Start()
{
_microphone.BufferReady += MicrophoneBufferReady;
 
_micBuffer = new byte[_microphone.GetSampleSizeInBytes(_microphone.BufferDuration)];
_recordStream = new MemoryStream();
Buffer = null;
 
XnaFrameworkDispatcherService.StartService();
 
_microphone.Start();
}
 
public void Start(TimeSpan timeout)
{
Start();
_shouldCallStopInTimeout = true;
 
ThreadPool.QueueUserWorkItem(
state =>
{
Thread.Sleep(timeout);
 
if(_shouldCallStopInTimeout)
Stop();
});
}
 
public void Start(int millisecondsTimeout)
{
Start(TimeSpan.FromMilliseconds(millisecondsTimeout));
}
 
public void Stop()
{
_shouldCallStopInTimeout = false;
_microphone.Stop();
 
// dump remaining audio into buffer
// verify cleanup
ProcessMicrophoneBuffer();
 
XnaFrameworkDispatcherService.StopService();
_microphone.BufferReady -= MicrophoneBufferReady;
 
_recordStream.Close();
 
Buffer = _recordStream.ToArray();
 
_recordStream.Dispose();
 
if (BufferReady != null)
BufferReady(this, new EventArgs());
}
 
private void MicrophoneBufferReady(object sender, EventArgs e)
{
// dump new data into the buffer
ProcessMicrophoneBuffer();
}
 
private void ProcessMicrophoneBuffer()
{
var size = _microphone.GetData(_micBuffer);
 
if (_recordStream.CanWrite)
_recordStream.Write(_micBuffer, 0, size);
}
 
private void InitMicrophone()
{
if (_microphone == null)
{
_microphone = Microphone.Default;
_microphone.BufferDuration = TimeSpan.FromMilliseconds(100);
}
}
}

通过一个XnaFrameworkDispatcherService来开始Frame的Update,因为只有Frame在Update的情况下,才可以进行声音的录制。 然后把录制到的内容写入一个byte[]。 一个标准的XnaFrameworkDispatcherService代码:

    public class XNAFrameworkDispatcherService : IApplicationService
{
private DispatcherTimer frameworkDispatcherTimer;
public XNAFrameworkDispatcherService()
{
this.frameworkDispatcherTimer = new DispatcherTimer();
this.frameworkDispatcherTimer.Interval = TimeSpan.FromTicks(333333);
this.frameworkDispatcherTimer.Tick += frameworkDispatcherTimer_Tick;
FrameworkDispatcher.Update();
}
void frameworkDispatcherTimer_Tick(object sender, EventArgs e) { FrameworkDispatcher.Update(); }
void IApplicationService.StartService(ApplicationServiceContext context) { this.frameworkDispatcherTimer.Start(); }
void IApplicationService.StopService() { this.frameworkDispatcherTimer.Stop(); }
}

然后,我将会程序提供两种功能,一种是按住即可录音的功能,还有种是,录音3分钟的功能. 首先,我们来设计页面:

        <Grid x:Name="ContentPanel" Margin="12,0,12,0">
<StackPanel>
<MediaElement Name="playBack" />
<Button ManipulationStarted="StartRecordingManipulationStarted"
ManipulationCompleted="StopRecordingManipulationCompleted">
点击并按住不放,进行录音
</Button>
<Button Click="RecordForThreeSecondsClick">
点击后录音3秒
</Button>
</StackPanel>
</Grid>
</Grid>

截图:

MicrophoneRecorderScreen.JPG

然后,因为需要把数据存储到隔离存储中,所以我们需要提供隔离存储帮助类,如下:

#region 隔离存储帮助类
private void PlayFile()
{
Dispatcher.BeginInvoke(() =>
{
using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
 
using (var stream = new IsolatedStorageFileStream(_currentFileName, FileMode.Open, storageFile))
{
playBack.SetSource(stream);
DeleteOldFile();
playBack.Play();
}
}
});
}
 
private void WriteFile(byte[] bytes)
{
using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
_fileIndex++;
_currentFileName = _fileIndex + ".wav";
 
using (var stream = storageFile.CreateFile(_currentFileName))
{
stream.Write(bytes, 0, bytes.Length);
}
}
}
 
private void DeleteOldFile()
{
using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
var currentFileName = (_fileIndex - 1) + ".wav";
 
if (storageFile.FileExists(currentFileName))
storageFile.DeleteFile(currentFileName);
}
}
#endregion

然后,存储方法和完成Buffer操作后的回调:

        #region 回调和存储
private void StartStopBufferReady(object sender, EventArgs e)
{
_micRecorder.BufferReady -= StartStopBufferReady;
 
SaveAndPlay();
}
 
private void SaveAndPlay()
{
using(var tempBuffer = new MemoryStream())
{
Wav.WriteHeader(tempBuffer, _micRecorder.SampleRate);
 
Debug.WriteLine(tempBuffer.Length);
Debug.WriteLine(_micRecorder.Buffer.Length);
 
Wav.SeekPastHeader(tempBuffer);
 
Debug.WriteLine(tempBuffer.Position);
tempBuffer.Write(_micRecorder.Buffer, 0, _micRecorder.Buffer.Length);
Wav.UpdateHeader(tempBuffer);
 
Debug.WriteLine(tempBuffer.Length);
 
WriteFile(tempBuffer.ToArray());
}
 
PlayFile();
}
#endregion

最后,提供开始录制/停止录制和录制固定的时间的方法:

		#region 开始录制/停止录制
private void StartRecordingManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
_micRecorder.BufferReady += StartStopBufferReady;
_micRecorder.Start();
}
 
private void StopRecordingManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
_micRecorder.Stop();
}
#endregion
 
#region 录制固定的时间
private void RecordForThreeSecondsClick(object sender, RoutedEventArgs e)
{
_micRecorder = new MicrophoneRecorder();
_micRecorder.BufferReady += StartStopBufferReady;
_micRecorder.Start(TimeSpan.FromSeconds(3));
}
#endregion

如此,这个项目就完成了,希望可以帮到您。

结论

这个控件的Audio系列控件给我提供了很好的Audio的支持,希望可以帮助到您. 最后,附上项目源代码,希望可以帮到您:

File:Coding4FunAudio.zip

This page was last modified on 29 June 2013, at 00:49.
302 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×