Re: [android-group-japan: 21537] 正確なメトロノームを作るには?

1,843 views
Skip to first unread message
Message has been deleted

Hirokazu Fukami

unread,
Jan 8, 2013, 11:02:01 PM1/8/13
to android-g...@googlegroups.com
こんにちはfkmです。

電池にやさしくない方法ではありますが、別スレッドでThread.sleep(1)を呼びつつ
時間計測 - 再生をやる方法はどうでしょうか?

2013/1/9 actbemu <kim...@shokei.ac.jp>:
> actbemuです。はじめて書き込みます。
>
> Windows用に作った、メトロノームソフト(http://www1.vecceed.ne.jp/~bemu/va/metrodown.htm)を、Androidタブレットでも動作させたく、目下勉強中です。いろいろやっていて、以下の壁に突き当たってしまいましたのでポストします。
>
> メトロノームは定期的な割込みでクリック音を出すということで、
> http://techbooster.jpn.org/andriod/application/934/
> を参考にさせていただいて、音を出すところはSoundPoollのplayメソッドで鳴らすように考えました。(音の長さは0.1秒以下)
>
> 上記参考ページのストップウォッチアプリのコードを打ち込み、実機で動作確認したあと、ストップウォッチのラップタイムを書き換えるところで、クリック音を鳴らすようにしてみました。
>
> 実際、実機で動作させてみましたが、音の鳴る間隔がとても均一とはいえない状況でした。
> 割込み周期を100msecから、500msecに間隔を開けても均一ではなく、とても音楽家の耳には耐えられないだろうほどのばらつき(ちょっと大げさですが)でした。
>
> もっと正確な時を刻むメトロノームができないかと考えていますが、そもそも無理な話なのでしょうか?もし解決方法があれば教えていただければと思います。(C++は未経験なので、Javaの範囲で何とかなれば嬉しいです)
>
> 宜しくお願いします。
>
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msg/android-group-japan/-/QMKkd1i0W_QJ
> にアクセスしてください。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com
> にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja
> からこのグループにアクセスしてください。



--
-------------------------------------------------------------
深見 浩和(Hirokazu Fukami)

URI:http://www.fkmsoft.jp
email: f...@fkmsoft.jp

Hiroaki GOTO as GORRY

unread,
Jan 8, 2013, 11:08:55 PM1/8/13
to android-g...@googlegroups.com

後藤 浩昭(GORRY)です。

Androidでは「音楽演奏のリズム源」として使えるほどの高精度な
タイマー割り込み機能はありませんし、ポーリングでタイマーを
見張るような作りも基本ご法度です。

AudioTrackを使って「メトロノーム音をストリーミング発声する」のが
適切な方法かと思います。たとえばBPM120なら「毎分120回のクリックを
発するような音声データストリームを少しずつ生成しながらAudioTrackへ
出力する」ことになります。


In message <37966657-8874-4b50...@googlegroups.com>
"[android-group-japan: 21537] 正確なメトロノームを作るには?"
"actbemu <kim...@shokei.ac.jp>" wrote:

> actbemuです。はじめて書き込みます。
>
> Windows用に作った、メトロノームソフト(http://www1.vecceed.ne.jp/~bemu/va/metrodown.htm)を、Androidタブレットでも動作させたく、目下勉強中です。いろいろやっていて、以下の壁に突き当たってしまいましたのでポストします。
>
> メトロノームは定期的な割込みでクリック音を出すということで、
> http://techbooster.jpn.org/andriod/application/934/
> を参考にさせていただいて、音を出すところはSoundPoollのplayメソッドで鳴らすように考えました。(音の長さは0.1秒以下)
>
> 上記参考ページのストップウォッチアプリのコードを打ち込み、実機で動作確認したあと、ストップウォッチのラップタイムを書き換えるところで、クリック音を鳴らすようにしてみました。
>
> 実際、実機で動作させてみましたが、音の鳴る間隔がとても均一とはいえない状況でした。
> 割込み周期を100msecから、500msecに間隔を開けても均一ではなく、とても音楽家の耳には耐えられないだろうほどのばらつき(ちょっと大げさですが)でした。
>
> もっと正確な時を刻むメトロノームができないかと考えていますが、そもそも無理な話なのでしょうか?もし解決方法があれば教えていただければと思います。(C++は未経験なので、Javaの範囲で何とかなれば嬉しいです)
>
> 宜しくお願いします。
>
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msg/android-group-japan/-/QMKkd1i0W_QJ にアクセスしてください。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>



--
Hiroaki GOTO as "GORRY" : 後藤 浩昭
EMAIL: gorr...@gmail.com

杉田敏典

unread,
Jan 8, 2013, 11:12:17 PM1/8/13
to android-g...@googlegroups.com
杉田です。

scheduleAtFixedRate()
を使っていますか?schedule()では、一回の割り込みがかかってから次の割り込みがかかるまでの時間が一定になりません。(割り込み処理にかかった時間分だけ遅延します)
あと、メトロノーム程度の間隔なら特に問題にはならないと思いますが、タイマーの最小解像度も確認しておいたほうがいいかもしれません。
あと、音を鳴らすとき、鳴りはじめるまでに時間がかかってしまっていたりしませんか?
前の音が鳴り終わったタイミングで次に鳴らす音の前処理を済ませてしまって、次に鳴らしはじめのときには極力時間がかからないようにすれば、時間的な揺れは最小限に抑えられると思います。
--
杉田 敏典 on PC
sugi...@gmail.com


2013年1月9日 11:37 actbemu <kim...@shokei.ac.jp>:

株式会社メディアラボ 藤井正基

unread,
Jan 9, 2013, 3:47:56 AM1/9/13
to android-g...@googlegroups.com
藤井正基と申します。

私も同様の問題にぶつかった経験があります。
その時の経験を少し。(私は、JAVAをあきらめC(NDK+OpenSL ES)で
実装しました。)

JAVAで実装を行った場合、ガベージコレクションが走るとき遅延が発生します。
ですので、JAVAで均一に音を出すことは難しいです。
また、Androidはハードウェアの制約でも、100msec以上遅延してしまう場合も
あります。
(4.2で改善があるとのことですが、検証していません)

このページが、詳しいです。
http://www.gizmodo.jp/2012/07/android_osjelly_bean.html

私は、OpenSL ESとNDKを利用して実装することで遅延を軽減しました。
(解消はできませんでした(Android2.3.3)が、体感0.1秒くらいの遅延まで
抑えられました。)
言語はCです。

OpenSL ESは、このサイトが参考になるかと思います。
http://d.hatena.ne.jp/miujun/20120307
付属しているサンプルも、とても参考になります。

Cを利用するという回答ですが、ご参考まで。
> japan+un...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja
> からこのグループにアクセスしてください。


Shigeo Mutoh

unread,
Jan 9, 2013, 8:12:37 AM1/9/13
to android-g...@googlegroups.com
tmhouseこと武藤です。

丁度今私がやっていたことに近いです。

Threadを用いて、wait(間隔の時間)すればかなりの精度で等間隔に何かを
行えると思います。
Threadのプライオリティを上げた方がよいかも知れません。

actbemu

unread,
Jan 9, 2013, 8:20:04 AM1/9/13
to android-g...@googlegroups.com
fkmさん、さっそくありがとうございます。
ポーリングという方法でしょうか。
音を出すだけならまだしも、実はアニメーションも同時に行いたいのです。
となると、かなりきびしいと思います。

2013年1月9日水曜日 13時02分01秒 UTC+9 fkm:
こんにちはfkmです。

電池にやさしくない方法ではありますが、別スレッドでThread.sleep(1)を呼びつつ
時間計測 - 再生をやる方法はどうでしょうか?

2013/1/9 actbemu <kim...@shokei.ac.jp>:
> actbemuです。はじめて書き込みます。
>
> Windows用に作った、メトロノームソフト(http://www1.vecceed.ne.jp/~bemu/va/metrodown.htm)を、Androidタブレットでも動作させたく、目下勉強中です。いろいろやっていて、以下の壁に突き当たってしまいましたのでポストします。
>
> メトロノームは定期的な割込みでクリック音を出すということで、
> http://techbooster.jpn.org/andriod/application/934/
> を参考にさせていただいて、音を出すところはSoundPoollのplayメソッドで鳴らすように考えました。(音の長さは0.1秒以下)
>
> 上記参考ページのストップウォッチアプリのコードを打ち込み、実機で動作確認したあと、ストップウォッチのラップタイムを書き換えるところで、クリック音を鳴らすようにしてみました。
>
> 実際、実機で動作させてみましたが、音の鳴る間隔がとても均一とはいえない状況でした。
> 割込み周期を100msecから、500msecに間隔を開けても均一ではなく、とても音楽家の耳には耐えられないだろうほどのばらつき(ちょっと大げさですが)でした。
>
> もっと正確な時を刻むメトロノームができないかと考えていますが、そもそも無理な話なのでしょうか?もし解決方法があれば教えていただければと思います。(C++は未経験なので、Javaの範囲で何とかなれば嬉しいです)
>
> 宜しくお願いします。

actbemu

unread,
Jan 9, 2013, 8:28:12 AM1/9/13
to android-g...@googlegroups.com


GORRYさん
さっそく、ありがとうございます。
やはり厳しいですかね。でも、Google Playに外国のものですが、
けっこうしっかり精度の良いメトロノームがあったので、何かやり
ようがあるのでは、と淡い期待を抱いているのです。
音声データストリームの方法は、たぶん確実性が高いでしょうが、
テンポの変更などに対応しようと思ったら、テンポごとにデータを
用意しなくてはならないのでは?
それに、アニメーションと完全に同期させたいので、ちょっと厳し
いですね。

2013年1月9日水曜日 13時08分55秒 UTC+9 GORRY:

後藤 浩昭(GORRY)です。

Androidでは「音楽演奏のリズム源」として使えるほどの高精度な
タイマー割り込み機能はありませんし、ポーリングでタイマーを
見張るような作りも基本ご法度です。 。。

AudioTrackを使って「メトロノーム音をストリーミング発声する」のが
適切な方法かと思います。たとえばBPM120なら「毎分120回のクリックを
発するような音声データストリームを少しずつ生成しながらAudioTrackへ
出力する」ことになります。


  "[android-group-japan: 21537] 正確なメトロノームを作るには?"
  "actbemu <kim...@shokei.ac.jp>" wrote:

> actbemuです。はじめて書き込みます。
>
> Windows用に作った、メトロノームソフト(http://www1.vecceed.ne.jp/~bemu/va/metrodown.htm)を、Androidタブレットでも動作させたく、目下勉強中です。いろいろやっていて、以下の壁に突き当たってしまいましたのでポストします。
>
> メトロノームは定期的な割込みでクリック音を出すということで、
> http://techbooster.jpn.org/andriod/application/934/
> を参考にさせていただいて、音を出すところはSoundPoollのplayメソッドで鳴らすように考えました。(音の長さは0.1秒以下)
>
> 上記参考ページのストップウォッチアプリのコードを打ち込み、実機で動作確認したあと、ストップウォッチのラップタイムを書き換えるところで、クリック音を鳴らすようにしてみました。
>
> 実際、実機で動作させてみましたが、音の鳴る間隔がとても均一とはいえない状況でした。
> 割込み周期を100msecから、500msecに間隔を開けても均一ではなく、とても音楽家の耳には耐えられないだろうほどのばらつき(ちょっと大げさですが)でした。
>
> もっと正確な時を刻むメトロノームができないかと考えていますが、そもそも無理な話なのでしょうか?もし解決方法があれば教えていただければと思います。(C++は未経験なので、Javaの範囲で何とかなれば嬉しいです)
>
> 宜しくお願いします。
>
> --

actbemu

unread,
Jan 9, 2013, 8:33:50 AM1/9/13
to android-g...@googlegroups.com
tmhouseさん
ありがとうございます。
Thead.speep(xxx)
を入れたループで音を出す、ということでしょうか?
すでにこの方法もやってみたのですが、うまく等間隔になりませんでした。
プライオリティを上げる方法があるんですか?
ちょっと調べてみようかと思います。


2013年1月9日水曜日 22時12分37秒 UTC+9 TM:

actbemu

unread,
Jan 9, 2013, 8:45:40 AM1/9/13
to android-g...@googlegroups.com
藤井正基さん
貴重な情報ありがとうございます。
そういえば、Javaの特徴としてガベージコレクションを自動でやってくれる
というのをどこかで読んだような記憶があります。それが逆に災いしてい
そうだ、というのは納得できますね。

やはりOpenSL ESとNDKですか?ちょっと敷居が高いなあ、と食わず
嫌いの口癖が出てしまいます。
参考情報、あとでアクセスしてみたいと思います。
ありがとうございます。


2013年1月9日水曜日 17時47分56秒 UTC+9 藤井:

actbemu

unread,
Jan 9, 2013, 8:47:44 AM1/9/13
to android-g...@googlegroups.com
杉田さん、ありがとうございます。

たとえば、
 mTimer_sound2.schedule( timerTask_sound2, 1000, 250);
     ↓
 mTimer_sound2.scheduleAtFixedRate( timerTask_sound2, 1000, 250);

とすればよさそうですね。
今、実機が無い環境(実はホテルの一室)なので、明日以降実機で確認してみたいと思います。



2013年1月9日水曜日 13時12分17秒 UTC+9 杉田 敏典:

Shigeo Mutoh

unread,
Jan 9, 2013, 9:07:12 AM1/9/13
to android-g...@googlegroups.com
tmhouseこと武藤です。

sleepでもwaitでも同じことだと思いますが、うまく等間隔にならない
のでしたら、threadが動いている間の処理が結構重いのではないでしょうか?

たとえば一秒間隔で処理したいthraedがあったとして、擬似コードを書く
とこんな感じです。

long intervalTime = 1000;
long time = intervalTime;
while(1) {
long startTime = getCurrentMs();

// 重い処理
veryHeavyProc();

long procTime = getCurrentMs() - startTime;
time = intervalTime - procTime;
wait(time);
}

これで多少マシにはなると思いますが、veryHeavyProc()が1秒以上
かかるときはもう破綻しているので、その処理をいかに軽く終える
かが課題になろうかと思います。

そのためにveryHeavyProc()を別スレッド(AsyncTaskでも良い)を用いる
必要があるのかも知れません。

actbemu

unread,
Jan 10, 2013, 9:28:40 AM1/10/13
to android-g...@googlegroups.com
武藤さん
具体的なコードを示していただきありがとうございます。
毎回、処理にかかった時間を計測して、次のタイミングに反映させる
という考え方ですね。
将来アニメーションと同期させるとなるとかなり複雑になりそうですが…


2013年1月9日水曜日 23時07分12秒 UTC+9 TM:
Reply all
Reply to author
Forward
0 new messages