別の音楽アプリで音楽を聞きながら、ゲームをしたいの考察
現在、ゲーム中の効果音に対して
- AudioManager.STREAM_MUSIC
で音量の調整等をしているのですけど、
これだと
- 音楽プレイヤーの音がゲームのボリュームに引きづられるで嬉しくない
みたいなクレームがPlayコメントに。。。。
これにたいして相談した処
あの場合はAudio focusを使うのが良い気がする。 / URL
って形で教えてもらったのですが
をみると、
- AudioFocusを取得して自分以外の音を止める
- AudioFocusが取得されたのを検知して自分の音量を下げる
って利用方法みたいで、
ようは
- 電話がかかってきた時にゲームの音量を小さくする
等には使えると思うのですがそれ以外ではちょっと意味合い違うかなと*1
.@alterakey さんに以前アドバイスいただいた AudioFocus 調べてるけど、自分の音を鳴らすために他の音を中断したりとかにしか使えないような気がする。。あとは相手側が他のアプリがgain時に自分の音を小さくする対応を入れたりとか。個別音声音量制御は無理?
2013-06-30 10:08:59 via YoruFukurou to @alterakey
で調べていくと別の音量を使えばいいという形に到達してしまうみたい。
で
- AudioManager. STREAM_MUSIC => AudioManager. STREAM_ALARM
を使う形で検討してみる
音量制御に関しては
int streamType = AudioManager.STREAM_ALARM; audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE); org_musicVol = audio.getStreamVolume(streamType); set_musicVol = PrefUtil.get_int("set_musicVol", -1); if (set_musicVol == -1) { // 最大音量の1/4を閾値にする int sep_musicVol = audio.getStreamMaxVolume(streamType) / 4; set_musicVol = org_musicVol; if (sep_musicVol > org_musicVol){ //音が小さすぎたらとりあえず1/3ぐらいにセット set_musicVol = audio.getStreamMaxVolume(streamType) * / 3; } } //音量変更 audio.setStreamVolume(streamType, set_musicVol, 0); //ボタン制御ボリュームを指定の音源に変える setVolumeControlStream(streamType);
@Override protected void onDestroy() { if (audio == null) audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE); // 最新の値取得 set_musicVol = audio.getStreamVolume(streamType); PrefUtil.put_int("set_musicVol", set_musicVol); //音量を戻す audio.setStreamVolume(streamType, org_musicVol, 0);
でいける感じ。
MediaPlayer)
mp = MediaPlayer.create(this, R.raw.bgm); mp.setAudioStreamType(AudioManager.STREAM_ALARM);//これを追加 mp.setLooping(true); mp.start();
訂正追記)
実は MediaPlayer.create(Context,resID) が setAudioStreamTypeが動かない*3な状況が発覚したので再調査。
private MediaPlayer mp = null; public void load_bgm(int resID, float volume, boolean loop_f) { reset_bgm(); try { Uri uri = Uri.parse("android.resource://" + context.getPackageName() +"/" + resID); mp = new MediaPlayer(); mp.setDataSource(context, uri); //mp = MediaPlayer.create(context, resID); mp.setVolume(volume, volume); mp.setLooping(loop_f); mp.setAudioStreamType(AudioManager.STREAM_ALARM); } catch (Exception e) { LogUtil.error(TAG, "load_bgm", e); } } private void reset_bgm() { if (mp == null)return; try{ mp.stop(); mp.reset(); } catch (Exception e) { LogUtil.error(TAG, "release_bgm", e); } mp = null; }
な形にすればOK。
の話。
追記2)
端末によりSD/ローカル にある音声ファイル がsetDataSourceに指定してもサイズで再生できない事があるらしい。
で対策として以下な話となる
android うーん。音声のstreaming再生に関して調べてたけどAsyncPlayer はdupricatedっぽいんだよな。MediaPlayer&Proxyでがんばれな話も出てくるけどその場合はsocket鯖用意した上での話っぽいし。。
でも
一つ目は target 8以下ではduplicatedなんだよな。
二つ目は ローカルでSocket鯖を自前で作って疑似ストリーミング受信できる形にしてしまおうって話
あたりだと APIで回避されてたりするのかしら。。。(汗
SoundPool)
//soundPool = new SoundPool(SE_MAX, AudioManager.STREAM_MUSIC, 0); //=> soundPool = new SoundPool(SE_MAX, AudioManager.STREAM_ALARM, 0);
検索してると下記のような情報も出てくるけど
の記述の
AudioManager::setMode(AudioManager.MODE_IN_CALL);
で制御ってどこらへんに関わってくるのだろう?
うーん。奥が深い。
Sony のAndroid Warkman SDK だと複数音に重低音エフェクトとか
かけられるらしいんだけど、ココらへんに関しても調べてみたいなーという感じです
の 外部Bluetoothスピーカ 等でも鳴らしてみたいけど
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
な対応は要るんだろうな−(汗
権限表示が要らないIOSがすごく羨ましい。。。*4
他には
- JetPlayer
- AndroidでmidiとかJetCreatorとかで鍵盤アプリとか作成 - hidecheckの日記
- midファイルをjetファイルに書き出して使用 ?
- AudioTrack
が有るみたいですけど、単に効果音とかだと使わないかも。
音ゲーとか作るときなんでしょうか・・・・(汗
備考)
AudioTrackは正直使えないです。。

現場で使える〔逆引き+実践〕 Androidプログラミングテクニック
- 作者: 日本システム開発株式会社,石原正樹,松尾源,磯村禎孝,森靖晃,奥谷修治
- 出版社/メーカー: 技術評論社
- 発売日: 2012/07/19
- メディア: 単行本(ソフトカバー)
- 購入: 1人 クリック: 24回
- この商品を含むブログ (7件) を見る
ってエラーが出てその音声に関しては作成できない=>音ならない状況
audiotrack obtainbuffer() track disabled restarting
AudioTrack 色々と試してみたけど、読込バッファオーバーエラーが出る =>解決方法無 =>SoundPool&oggで遣るほうがいいよ?とStackOverFlowに出てくるんだけど(確かにそれで解決)何なんでしょうかね。。。(汗
試しに差し替えてみたのは
のピアノ音声・・。うーんですわね。。(苦笑
TTSの話のメモ)
TTSも音源リソースの設定ができる。
これ2系だと audio.setStreamVolume で動いてる機種があって見落としてたんですが
4系後半だとTTS用の音源が分かれているようで明示的に指定しないと駄目。
mTts.setSpeechRate(1.0f);// しゃべる速さ(遅い<=>速い) mTts.setPitch(1.0f);// 声の音程(低い<=>高い) HashMap<String, String> params = new HashMap<String, String>(); params.put(TextToSpeech.Engine.KEY_PARAM_VOLUME, String.valueOf(1.0)); params.put(TextToSpeech.Engine.KEY_PARAM_PAN, String.valueOf(0.0)); params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));//☆ mTts.speak(ttsText, TextToSpeech.QUEUE_FLUSH, params);
みたいな形で☆のパラメータを明示的に追加。
の話
マナーモードの対応)
最近一部のマナーモードが設定できない機種で誤爆したのでメモ
public boolean isCanPlaySnd() { if (audio == null) audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); int mode = audio.getRingerMode(); switch (mode) { case AudioManager.RINGER_MODE_SILENT: case AudioManager.RINGER_MODE_VIBRATE: //Xoom判定 if( "MOTO".equals(Build.BRAND) && "MZ604".equals(Build.MODEL) ){ int vol = audio.getStreamVolume(AudioManager.STREAM_ALARM); if(vol>0)break; } //Nexus7判定 if (Build.BRAND.equals("google") && Build.MODEL.equals("Nexus 7")) { int vol = audio.getStreamVolume(AudioManager.STREAM_ALARM); if(vol>0)break; } // マナーモードなので何もしない boolean bPlugged = headsetStateReceiver.isPlugged(); if (bPlugged) break; // イヤフォンの場合は鳴らす return false; // break; default: break; } return true; }
ようは
マナーモードが設定できない機種 で
AudioManager.STREAM_MUSIC で 0に設定されてると
getRingerMode()で AudioManager.RINGER_MODE_SILENT が飛んでくるというアホ仕様。
普通にマナーモードが設定できる機種は問題ないみたい。うーん。なんだかね。。。(汗
波形とか表示のメモ)
参考)