【wp7】简易的语音报时懒人闹钟

先附上工程地址:http://download.csdn.net/detail/felicitia/5303422

当年赶出来的windows phone的小程序,这次UID实验又拿出来弄了个报时。。话说之前感觉很喜欢的拖拽现在好讨厌,好在UI已经确定了,只是加上了语音报时的功能。声音不是很连贯,没办法自己录的也没有掐头去尾,效果不是很好,不过silverlight里面使用XNA的东西还是很方便的,都怪自己没有早点试一试啊!下面说说遇到的问题~
1、遇到最大的问题就是之前采用MediaElement,加载了多个声音元素之后出现了非常诡异的事情!应该播放背景音乐“蓝精灵”的时候会播放“叮”,甚至把“叮”的资源改为“蓝精灵”也不行!这时候会播放“分”之类的,总之就是不播放“蓝精灵”。后来根据观察,发现错乱的播放依次是与加载顺序相反的,而“蓝精灵”的加载是第一个,故一直不播放。查了资料发现,MediaElement会在设置资源的sourse属性的时候自动播放,则应该是每加载一个就播放一个,而后面的占用了前面的资源,使得听起来就是最后的那个音乐,造成错乱的效果。一点就到机房了,居然6点10分还没检查!这个大bug我要恨死你啦!
耽误了太久的时间,后来采用了XNA的effect。本来以为silverlight不支持XNA,必须建成XNA的项目,结果引用之后就可以了。但effect的属性很少,没有state,也不好控制。此时play后面的音乐的时候前面的还没有停止,所以造成声音的叠加。
最后采用了effectInstance的实例,根据state来判断。比如:
while (SoundState.Playing == dingInstance.State) ;
即可使该声音播放完在进行接下来的播放。但是由于自己录音的效果不好,首尾都有空白的部分,导致声音不连贯,一个一个去掉过于麻烦,后来又采用了现成休眠的办法。比如:
Thread.Sleep(500); (需要using System.Threading;)
来使声音尽量连贯。
说下effectInstance的使用吧。首先采用effect的话不能控制声音的暂停,获取状态等,适合播放较短的声音。如果创建了实例方法就灵活一些,具体代码如下:
首先引用Microsoft.Xna.Framework
然后using Microsoft.Xna.Framework.Audio;using Microsoft.Xna.Framework;
声明:
 Stream stream = null;
        SoundEffect effect = null;
        SoundEffectInstance effectInstance = null;

定义:
 stream = TitleContainer.OpenStream("Sounds/blue.wav");
  FrameworkDispatcher.Update();
            effect = SoundEffect.FromStream(stream);
    effectInstance = effect.CreateInstance();

直接使用实例的方法即可。注意声音必须是wav格式的,并且生成方式是content(内容)。
2、时间选择控件。采用TimePicker。需要引用Microsoft.Phone.Controls和Microsoft.Phone.Controls.Toolkit;
在xaml文件的跟标签中加上属性xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit";
布局中:
<toolkit:TimePicker x:Name="timePicker" Header="时间选择" Height="154" Width="442" FontSize="24" Margin="19,156,19,458" Grid.RowSpan="2" DataContext="{Binding}" />
3、重力感应的加速度传感器的使用,需要using Microsoft.Devices.Sensors;
声明变量:
     public Accelerometer accelerometer;
构造函数中:
accelerometer = new Accelerometer();
            accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingEventArgs>(AccelerometerDataChanged);
            accelerometer.Start();

重写函数(各个值是从-1到1,可以打开模拟器模拟,能看到具体的值):
/*判断加速度是否满足条件*/
        public void AccelerometerDataChanged(object sender, AccelerometerReadingEventArgs e)
        {
            if (e.X < -0.7)
            {
                left = 1;
            }
            if (left == 1 && e.X > 0.7)
            {
                left = 0;
                count++;
            }
        }


4、固定时间触发的函数。
声明定时器:
DispatcherTimer tmrSecond = null;
构造函数中:
tmrSecond = new DispatcherTimer();
            tmrSecond.Interval = TimeSpan.FromSeconds(1);
            tmrSecond.Tick += OnSecondTick;
   	    tmrSecond.Start();

在onSecondTick函数中写需要执行的代码:
        public void OnSecondTick(object sender, EventArgs args)
        {
            textBox1.Text = tmp + DateTime.Now.Second + " 秒 ";
            /*音量递增*/
            if (effectInstance.Volume > 0.9)
            {
                effectInstance.Volume = 1f;
            }
            if (effectInstance.Volume != 1)
            {
                effectInstance.Volume += 0.1f;
            }
            if (count > 0)
            {
                duration--;
                count = 0;
            }
            /*满足条件的时间达到闹铃的时间*/
            if (duration == 0)
            {
                PageTitle.Text = "你真棒~!";
                image.Source = myImage;
                effect.Dispose();
                tmrSecond.Stop();
                var appStorage = IsolatedStorageFile.GetUserStoreForApplication();
                string name = "alarm.txt";
                using (var file = appStorage.OpenFile(name, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
                {
                    using (var writer = new StreamWriter(file))
                    {
                        writer.WriteLine("False");
                        writer.WriteLine(MainPage.srHour);
                        writer.WriteLine(MainPage.srMinute);
                        writer.WriteLine(MainPage.srDuration);
                    }
                }
            }
        }

5、独立存储,以添加闹钟为例,点击保存时的函数:
 private void save_Click(object sender, RoutedEventArgs e)
        {
            DateTime time = (DateTime)timePicker.Value; 
            var appStorage = IsolatedStorageFile.GetUserStoreForApplication();
            string name = "alarm.txt";
            using (var file = appStorage.OpenFile(name, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
            {
                using (var writer = new StreamWriter(file))
                {
                    writer.WriteLine(switcher.IsChecked);
                    writer.WriteLine(time.Hour.ToString());
                    writer.WriteLine(time.Minute.ToString());
                    writer.WriteLine(Math.Ceiling(duration.Value * 10));
                }
            }
            NavigationService.GoBack();
        }

6、导航到其他页面:
 private void Setting_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/LazyClock;component/Look.xaml", UriKind.Relative));
        }
7、返回上一页面:
  private void back_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.GoBack();
        }



程序使用简要说明:

本程序实现了一个简易的闹钟,无法再后台运行,只能设定一次响铃时间内或者修改,删除。但是用独立存储保证二次打开时会记录之前保存的闹钟信息。主界面中可以设置时间,每秒钟会判断是否到达响铃时间,如果到达,则语音报时,之后跳转到响铃的页面。根据设定的时间,需要采用重力感应用力摇晃手机,摇晃到规定的时间声音才会暂停。背景音乐是渐强的。

最后是效果截图:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值