windows phone7中多线程实例

来源:互联网 发布:管家婆t9软件怎么样 编辑:程序博客网 时间:2024/05/16 01:24

windows phone 7中的多线程与windows中的多线程编程没什么区别,参照C#中thread类的用法,很容易实现多线程。

我遇到的问题是:wp7需要从音频口读取单片机传过来的数据(详见前面的博客),同时利用右声道向外播放声音(特定的波形),从而为单片机板子供电(供电这块还不知道好不好使,目前只是做手机这边,看能不能发出波形来)。

之前测试过了,录音的程序好使,需要做的就是在这个程序的基础上,利用thread类增加一个线程,使得程序启动之后就不断地向右声道发送波形!

首先:手机的音频口怎么向外发波形呢?我采用了最笨的办法,利用soundeffect的实例从声音buffer中读取数据并play(这一部分在录音全纪录那篇博客中讲的很清楚了)。而buffer中的数据是我自己构造的。声音经过麦克采集,AD转换之后,得到的原始数据实际上是麦克的电压值与32767~-32768之间的线性映射,在存储的时候,把每个数分成高8位和低8位,分别存储。我需要音频口输出方波,且要求峰峰值尽量的大,这样就可以组织如下的数组:

private byte[] wave = {255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128}
其中,“255,127”实际上是一个值的低八位和高八位,即7FFF(32767),同理“0,128”是8000(-32768),很明显,之所以选这两个数是因为这两个数代表了最大和最小。这样就在输出时经过DA变换,出来的波形就是一个方波,上面的数组仅两个周期,一般要多得多。手机麦克的采样频率是16000Hz,那么如果要得到1KHz的方波,每个周期被采样16次,每个数又分为两个数来存,这样一共需要32000个数才能形成1秒钟的波形。当然我们不用真的写一个32000数的大数组,因为我们有更好的方法:多线程。

创建一个线程,使得程序在开始运行之后即不断地播放声音,如果声音buffer里的数很少,加入有64个(上面那个数组),则这个线程很快就会结束,这样设置一个定时器,设置很短的定时,比如33ms,没到定时器中断时,就检查这个线程的状态,如果已经结束,就再次创建并启动。循环往复,看上去就像是不断地播放波形!

在mainpage的构造函数最后加上以下语句

            Thread energyThread = new Thread(new ThreadStart(energySound));//创建一个线程            energyThread.Start();//启动            energyIsPlaying = true;//将播放状态进行置位,目的是在定时器到时间时判断是否停下来了。
这是energySound的代码:

        private void energySound()        {            Energy energy_output = new Energy();//Energy类实例化            energy_output.joint();            SoundEffect energy_sound = new SoundEffect((byte[])energy_output.target, microphone.SampleRate, AudioChannels.Mono);            energy_soundInstance = energy_sound.CreateInstance();            energyIsPlaying = true;            energy_soundInstance.Play();//播放        }
定时器的设置:

            DispatcherTimer dt = new DispatcherTimer();            dt.Interval = TimeSpan.FromMilliseconds(33);//设置为33ms,每33ms就更新一次UI元素            dt.Tick += new EventHandler(dt_Tick);//当定时器到时间的时候,时间处理函数为dt_Tick            dt.Start();//启动定时器
dt_Tick的代码:

        void dt_Tick(object sender, EventArgs e)        {            try            {                FrameworkDispatcher.Update();            }            catch { }            if (energy_soundInstance.State != SoundState.Playing)            {                energyIsPlaying = false;//如果能量播放已经结束了,就将播放标志置为false            }            if (energyIsPlaying == false)//一旦标志为false,就重新创建线程,重新启动,循环往复            {                Thread energyThread = new Thread(new ThreadStart(energySound));                energyThread.Start();                energyIsPlaying = true;            }        }
Energy类的代码:

public class Energy    {        private byte[] wave = {255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128,                               255,127,255,127,255,127,255,127,255,127,255,127,255,127,255,127,                               0,128,0,128,0,128,0,128,0,128,0,128,0,128,0,128};        public byte[] Wave        {            get            {                return wave;            }        }        public void joint()        {            source = wave;            for (int cnt = 0; cnt < 660; cnt++)            {                source.CopyTo(target, cnt*480);            }            //return target;        }        Array source = Array.CreateInstance(typeof(byte), 480);        public Array target = Array.CreateInstance(typeof(byte), 320000);    }
这是我最开始写的代码,如上所述,没必要把这个数组整的这么大,写得小一点就行,后面的数值相应的改动。joint方法是为了获得一个更大更大的数组,呵呵。这看上去很笨,但很容易理解。

经过测试,在不影响录音和数据处理的情况下,实现了左右声道波形的输出。

存在的问题:

1、波形噪声很大。我在PC上制作了一个方波音频文件,同步到手机上用音乐播放器播放,示波器中观察到的波形非常干净、稳定。而我用这种方法播放出来的噪声却很大。

2、波形的幅值也很小。

3、左右声道都有波形,还不知道怎么设置。在soundEffect中用mono,是单声道,但测试的时候两个声道都有信号,另外,麦克里的信号对声道的影响也非常大,总之噪声非常大。






原创粉丝点击