手机同时播放两个音乐之探讨一[JavaME]

[JavaME]手机同时播放两个音乐

 

 

 

 

 

 

 

探讨一

 

 

 

 

 

 

 

摘要:

 

本文档以及后续文档试图一步一步地探讨如何在手机上同时播放两个声音文件,譬如一个是背景音乐,一个是按键触发的游戏音效。请慢慢看下去,我们尽量糅合进各方汇集的一些经验。

 

 

 

 

 

 

 

1背景

 

摘要:本章 简单描述手机同时播放两个音乐的背景。 

 

 

 

1.1. 常见于各大J2ME论坛的这个问题

最近看到,不断地有人再询问同一类型的问题:

 

 

 

 

 

 

 

“如何同步播放两个音乐?”

 

 

 

 

 

 

 

“如何在播放背景音效的同时,还能够播放其他声音?”

 

 

 

大家众说纷纭,不过有一部分的先行者已经琢磨出了实际可行之法。譬如,migjava曾经谈及“索尼爱立信V800, Z800, K750, W800K600移动电话支持同时播放两个声音”。

 

 

 

 

 

 

 

由于并不是所有机型支持,这个问题不是一个能够用一揽子解决方法搞定的问题,换而言之,就算你能在一种类型的手机上验证成功,也仍然会在其他厂商的手机上烦恼不已。

 

 

 

 

 

 

 

原因是我们所用到的MMAPI是一个仍然带有很大局限性的玩具,各大厂商实现它的方法各异,你很难找到一个统一指导。即使是同一个厂商,譬如说Nokia,你也不能指望有什么你不会遇到。

 

 

 

 

 

 

 

我们编纂一下很多方面的抱怨,如下所示:

 

 

 

 

 

 

 

1.2. 每个厂商都会给你带来烦恼

厂商之间的格式差别 

 

 

 

 

 

 

 

 

Midiwav的编码格式在Nokia上和其他厂家(譬如motorrolasiemens),所以逼迫你不得不在不同厂家机型上使用不同的wav文件。

 

 

 

 

 

 

 

 

摩托罗拉V300-V500-V600同时播放音乐的讲究 

 

 

 

 

 

 

 

 

标题所指明的这几款手机,唯一支持的同步播放音乐的办法是,midiwav声音混合播放。

 

 

 

 

 

 

 

即使是这样,也存在着一个限制:

 

 

 

 

 

 

 

应用程序必须先播放midi(可以作为背景音乐),然后再播放wavwav文件还必须是以下的格式:

 

 

 

 

 

 

 

n         PCM 8000KHZ

 

 

 

 

 

 

 

n         8Bit

 

 

 

 

 

 

 

n         Mono

 

 

 

除了上面这种方法,只要是一个新的media被播放,上一个Player必须被停止而且释放资源。

 

 

 

 

 

 

 

 

 

 

 

 

 

MOTO手机中播放声音有下面几条约束 

MOTO系列手机中JAVA程序播放一个声音文件比较简单,但是用于交互式音效时就有问题了。

 

 

 

 

 

 

 

根据MOTO的一些资料显示,在MOTO手机中播放声音有下面几条约束:

 

 

 

 

 

 

 

1、除了同时播放一个MIDI和一个WAV以外,MOTO手机无法同时播放多个声音,而且必须是先播放MIDI然后播放WAV

 

 

 

 

 

 

 

2、除了MIDI或音阶序列以外,不能同时实现player的多个实例进入prefetched状态(预读取声音流);

 

 

 

 

 

 

 

3、播放新的声音之前,前一个player必须停止并释放资源(stop();deallocate())。

 

 

 

 

 

 

 

 

 

 

 

 

nokia6230i上的一些现象

当一个Playerprefetched,那么其他Player也就不再能够prefetched,除非它们都是midi或都是amr

 

 

 

 

 

 

 

如果你没有在start/prefetch一个Player之前把其他的Player停下来,那么你将得到一个MediaException

 

 

 

 

 

 

 

 

 

Dodgy MMAPI implementations 

老实说,在摩托罗拉和其他大多数手机上的MMAPI实现是“dodgy”的,大多时候你不得不忍受它。

 

 

 

 

 

 

 

 

 

Nokia 3650K700i之比 

不幸的是,老的Nokia S60系列在播放声音上十分的不可靠,一个midi文件在一部手机上播放起来可能和另外一个同系列的手机上听起来不同,特别是K700i相比而言。K700i提供了优秀的midi声效,而一个Nokia 3650基本上属于垃圾。

甚至于有人愤怒地提出:dont try background sounds/music 

 

 

I learned not to push nokia s60 sounds very far at all, the sound support is dire, my advice would be space the sound playing out (so that it isnt possible for your game to need to play 2 sounds at the same time or even one *directly* after another), dont try background sounds/music, dont try any time critical or constant sound calling (like from paint() constantly) .. Use a minimum amount of players, the limit on my ngage was 10, and i was having to prefetch but not realise for optimum results. Dont deallocate anything if you plan to reuse it. You cant reuse a player for a different sound. And finally, you cant always 100% of the time take the API commands at face value..

 

As a word of encouragement, I was pissed off with nokia sound, but so long as you dont push it too much, and keep it simple, ultimately it does end up being reliable.  

 

 

 

2 演示程序-TwinsMusic探索一

 

TwinsMusicMainMenu 
    我们首先提供一个利用一个
Player数组在不同线程中播放音效的例子,以体会下面几点:

l        这个程序在WTK2.3 beta的模拟器中是可以通过测试的,可以在播放背景midi音效的同时,按键触发播放midi或者wav音效;

l        在真机上的测试则不同。

以后,我们将陆续提供各种方式的实现,以充分探讨这一问题,我们不单单需要正确的解决方法,还需要了解哪些方法是在真机上不可行的。

 

 

 

 

 

 

 

       2.1. 程序说明

首先,程序启动之后,我们自行编写了一个StringKeyItem,它扩展了CustomItem,所以它可以帮助你的Form高级UI接收用户手机按键。它还打印了当前机型是否支持混音,如上图所示,模拟器是支持混音的,所以同时播放两个声音是没有问题的。但是我的Nokia7610上则清楚地表明它不支持混音!

 

 

 

 

 

 

 

Form初始化的时候,就建立一个线程,播放背景音效“jazz.mid”。

 

 

 

 

 

 

 

同时,Form当前的焦点在StringKeyItem上,所以用户按键能够被StringKeyItem所截获,如下面代码所示:

 

 

 

 

 

 

 

 代码演示如何接收用户按键事件

 

 

 

 

 

 

 

 

public class StringKeyItem extends CustomItem{

 

 

 

 

 

 

 

...

 

 

 

 

 

 

 

protected void keyPressed( int keyCode )

 

 

 

 

 

 

 

{

 

 

 

 

 

 

 

    System.out.println("Key code=" + keyCode);

 

 

 

 

 

 

 

   

 

 

 

 

 

 

 

    int GameKeyCode = getGameAction( keyCode );

 

 

 

 

 

 

 

    int AudioPlayMusicKey = Audio.BEEP;

 

 

 

 

 

 

 

    switch(GameKeyCode)

 

 

 

 

 

 

 

    {

 

 

 

 

 

 

 

        case Canvas.FIRE:

 

 

 

 

 

 

 

        case Canvas.KEY_NUM7:

 

 

 

 

 

 

 

        case Canvas.KEY_NUM8:

 

 

 

 

 

 

 

        case Canvas.KEY_NUM9:

 

 

 

 

 

 

 

                    {

 

 

 

 

 

 

 

                AudioPlayMusicKey = Audio.MESSAGE;

 

 

 

 

 

 

 

                break;

 

 

 

 

 

 

 

                    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

按键触发了另一个线程播放音效:

 

 

 

 

 

 

 

 代码演示根据按键播放不同的音效

 

 

 

 

 

 

 

 

// 根据按键播放音乐

 

 

 

 

 

 

 

Audio.playSound(m_nKeyCode);

 

 

 

 

 

 

 

 

 

Audio是我们封装的一个播放类。

 

 

 

       2.2. 使用说明

我是在Nokia真机上测试的,启动程序之后,就立即开始播放背景音效“jazz.mid”,但是每当一个按键按下,jazz.midi就会被打断,并自动重新播放,但是按键所对应的音效并没有被正确播放。

 

 

 

 

 

 

 

我们将背景音效改为amr格式,也依然如此。 

 

 

 

 

 

 

 

 

但是一旦我们选择命令“停止背景音”,然后再按键,就会清楚地听到按键音效,说明那个播放前台音效的线程还是可以正常播放音乐的,只要没有其他的player在播放。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3 资源

 

 

 

 

 

 

 

 

 

 

网络资源:

 

网络资源:

 

 

 

 

 

 

1《[JavaME]手机同时播放两个音乐 探讨一

 

 

 

 

 

 

 

2:下载midletTwinsMusic-Effect1-deployed.rar ,大约26KB。代码TwinsMusic-Effect1.rar,大约65KB

 

 

 

 

 

 

 

3http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=547,索爱部分机型支持同时播放多个声音;

 

 

 

 

 

 

 

4Working with the Mobile Media API Part 2.pdf

 

 

 

 

 

 

 

5Sound_Implementation_on_V300-V500-V600.pdf

 

 

 

 

 

 

 

6CH_BriefIntroductiontoMMAPIv1_0.pdf

 

 

 

 

 

 

 

7:《Sound_Whitepaper.pdfhttp://trix2.cellmania.com/downloads/downloads/pdf/Sound_Whitepaper.pdf

 

 

 

 

 

 

 

8:《MG_E680_V1_2.pdfhttp://trix2.cellmania.com/downloads/downloads/pdf/MG_E680_V1_2.pdf,关于e680media开发指导》;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

郑昀@ultrapower

 

 

 

 

 

 

 

 

试验品名称

 

 

 

 

 

 

 

 

试验品版本

 

 

 

 

 

 

 

 

Keyword: Mobile MMAPI Media 媒体播放 j2me

 

 

 

 

 

 

 

 

TwinsMusic

 

 

 

 

 

 

 

 

0.0.1 BETA

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

但是一旦我们选择命令“停止背景音”,然后再按键,就会清楚地听到按键音效,说明那个播放前台音效的线程还是可以正常播放音乐的,只要没有其他的player在播放。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3 资源

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=535144


你可能感兴趣的:(JavaME)