SuperpoweredAdvancedAudioPlayer
имеет встроенную синхронизацию ударов, которая работает хорошо. Но я хочу синхронизировать игрока с абсолютной позицией моего метронома и попытался сделать это, установив эту позицию с игроками setPosition (double ms, bool andStop, bool synchronisedStart)
метод в каждом цикле обработки. Это работает до тех пор, пока игрок играет в исходном ударов в минуту. Когда я меняю темп и воспроизведение становится растянутым по времени, я получаю искаженный звук.
Я попытался установить позицию в положение мастера, а также в рассчитанную позицию игрока в исходном темпе (masterPositionMs
* playerBpm
/ masterBpm
). Я также попробовал это с включением и выключением синхронизации ударов.
Что я делаю неправильно? Есть ли лучший способ сделать абсолютную синхронизацию?
bool MyAudioSession::process(short int *in_out, unsigned int numberOfInputSamples) {
float currentBPM = metronome->getBpm();
double msElapsedSinceLastMasterBeat = metronome->getMsElapsedSinceLastBeat();
double msPositionMaster = metronome->getPositionMs();
bool silence = true;
if(metronome->process(stereoOutputBuffer, !silence, numberOfInputSamples, volMetronome))
silence = false;
for (int i = 0; i < audioPlayers.size(); i++) {
if(audioPlayers[i]->playing) {
audioPlayers[i]->setPosition(
(msPositionMaster * audioPlayers[i]->bpm / currentBPM) + audioPlayers[i]->firstBeatMs,
!metronome->isPlaying(),
SYNCHRONISED_START);
}
if(audioPlayers[i]->process(stereoOutputBuffer, !silence, numberOfInputSamples, audioPlayers[i]->volume, currentBPM, msElapsedSinceLastMasterBeat))
silence = false;
}
[...]
Нет необходимости в setPosition, плеер будет синхронизироваться с следующим тактом. Просто вызовите play (true) для повторной синхронизации.
Других решений пока нет …