windows phone7中多线程实例

本文介绍了在Windows Phone 7中如何进行多线程编程,特别是在音频口读取单片机数据的同时,通过右声道播放定制波形。作者通过创建线程和定时器来实现连续播放,并面临波形噪声大、幅值小以及声道控制等技术挑战。
摘要由CSDN通过智能技术生成

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,是单声道,但测试的时候两个声道都有信号,另外,麦克里的信号对声道的影响也非常大,总之噪声非常大。






评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值