他のデバイスのマスター クロックとして機能するシーケンサーを作成しようとしています。
同期タイマーを起動して実行し、DAW を制御することができました。ただし、テンポは非常に不安定で、+-1 BPM のように激しく揺れます。
最初はアプリで標準の 24 PPQ を使用していましたが、すぐにタイミングの質の悪さに気づいたので、96 PPQ を試してみたところ、本来よりも数倍速いテンポになりました。
次のように、タイマー、メソッド scheduleAtFixedRate を使用してタイミング クロック メッセージを出力キューに追加しています。
/**
* Used every time the tempo is changed.
*
* Adds a Timer to a list. When a new Timer is added, the previous one is removed.
* Timing clock messages are added to the output queue at a rate set by the current
* Timer in the List.
*/
private void setNewTempoTimer()
{
Log.i(DEBUG_TAG, "set new tempo timer.");
if(!timerList.isEmpty())
{
timerList.getFirst().cancel();
timerList.removeFirst();
}
final Timer timer = new Timer();
timerList.add(timer);
/**
* The shortest time interval in MIDI
*/
long tick = _sixteenthNote / 6;
/**
* Starts adding messages to the output queue
*/
timer.scheduleAtFixedRate(
new TimerTask()
{
@Override
public void run()
{
if(_running)
{
setNewTimingMessage();
}
}
}, 0, tick);
}
テンポは次のように計算されます。
/**
* Calculates the length of a semiquaver in the sequencer
* @return the time of a semiquaver in milliseconds
*/
private void calculateTempo()
{
Log.i(DEBUG_TAG , "Calculated tempo.");
/**
* Fjärdedelsnot
*/
_quarterNote = Math.round(((60000/_tempo))*100000)/100000;
/**
* Sextondel
*/
_sixteenthNote = (_quarterNote/4);
_sixteenthNote = Math.round(_sixteenthNote*100000)/100000;
}
新しいタイミング メッセージは次のように設定されます。
/**
* Sets new timing message in the midi output queue
*/
private void setNewTimingMessage()
{
try
{
_midiOut.addMessageToQueue(MIDI_TIMING_CLOCK, 0,0);
}
catch (InvalidMidiDataException e)
{
e.printStackTrace();
}
Log.i(DEBUG_TAG , "Set new message.");
}
私に光を当ててください。
よろしく /M