Webアプリを作ってみたの続き。
今回作ろうとしたアプリは、太鼓の譜面の記録/管理/再生をすると言うもの。
データの記録、管理自体はそんなに難しい事は無いんだけれど、
譜面にあわせて音を再生しようと言うところが今回苦戦したところ。
なんにせよ、WindowsPCではChrome、FireFoxで問題なく動作するところまではできたんだけど・・・
肝心のiPhoneで動かない。
音声データをData URI schemeにしてみたり、色々やってみたけどどうにもムリ。
具体的なソースはこんな感じ。(だいぶ省略しています)
[code lang=”javascript” line=”1″]
//soundデータ定義リスト
var sound_data_list = {
1: new Audio(“/djember/audio/base.mp3”),
2: new Audio(“/djember/audio/ton.mp3”),
3: new Audio(“/djember/audio/clap.mp3”)
}
$(function() {
// 再生ボタンクリック
$(‘#test_btn’).click(function() {
var label = $(‘#play_btn_label’);
label.html(‘Stop’);
var score_measure = 4;
var score_tempo = 70
var part = new Array();
part[‘part_length’] = ‘2’;
part[‘part_notes’] = [1,0,2,2,0,0,3,0];
timeoutTimer = new Array();
playRhythm(score_measure, score_tempo, part);
label.html(‘Play’);
});
// スコアに合わせて、音を1回だけ再生
function playRhythm(score_measure, score_tempo, part) {
var timing = 0;
for (var pos = 0; pos < (part['part_length'] * score_measure); pos++) {
// タイミングを合わせて音を鳴らす
timer = setTimeout(playSound, timing, part['part_notes'][pos]);
timeoutTimer[timer] = timer;
timing += getTiming(score_measure, score_tempo);
}
}
// soundIdに対応する音を1回鳴らす関数
function playSound(soundId) {
// blank(休符)なら鳴らさない
if (soundId == 0) {
return;
}
// 再生
sound_data_list[soundId].play();
// 次回再生用に、音声を再生成
sound_data_list[soundId] = new Audio(sound_data_list[soundId].src);
}
// テンポにあわせたタイミングを計算
// measure 3:3/4拍子、4:4/4拍子
// tempo 1分間の拍数
function getTiming(measure, tempo) {
return 60000/tempo/measure;
}
});
[/code]
あらかじめ、音声ファイルをオブジェクト化(sound_data_list)しておき、
テンポと拍子から1音を再生するタイミングを算出(getTiming)。
それを、setTimeoutを使ってタイミングを合わせて(playRhythm)
1音ずつ再生(playSound)している。
音声を再生する際、次の音声再生時に遅延しないように、
再度オブジェクト化しておくところがポイント(らしい。要らんような気もするが・・)
どうやら、残念な事にiPhoneでは同時に1音しか鳴らせず、
また、事前に複数音声をロードしておくと、正しく鳴らなくなる事があるとか。
情報の元ネタはこちら
iPhoneでHTML5のaudio要素を使うときに気をつけたいこと - RIAxDNP
この問題に2日近くとられたよ・・・
その内サポートされる事を祈って、しばらくは再生機能はPCだけに留めておくかぁ。
Androidも試してみたいところだけれど、手元に機械が無いので試せず。
むぅ・・。
コメント