andrew@16: /* andrew@16: * AccompanimentSynchroniser.cpp andrew@16: * MultipleAudioMathcher andrew@16: * andrew@16: * Created by Andrew on 06/02/2012. andrew@16: * Copyright 2012 QMUL. All rights reserved. andrew@16: * andrew@16: */ andrew@16: andrew@16: #include "AccompanimentSynchroniser.h" andrew@16: andrew@45: //recorded position millis is the current alignment position, sent from updateAlignment in event matcher andrew@45: //time sent is the live time since start of play andrew@45: andrew@16: AccompanimentSynchroniser::AccompanimentSynchroniser(){ andrew@16: sender.setup(HOST, SENDER_PORT); andrew@17: counter = 0; andrew@53: movingAverageWeighting = 0.4; andrew@17: reset(); andrew@17: } andrew@17: andrew@17: void AccompanimentSynchroniser::reset(){ andrew@17: andrew@55: printf("ACC SYNC RESET\n"); andrew@17: andrew@17: playingPositionRatio = 0; andrew@17: playingPositionSamples = 0; andrew@17: playingPositionMillis = 0; andrew@17: playingPositionTimeSent = 0; andrew@17: andrew@17: recordedPositionMillis = 0; andrew@17: recordedPositionTimeSent = 0; andrew@55: andrew@17: speed = 1; andrew@53: smoothedSpeedOutput = 1; andrew@53: difference = 0; andrew@55: andrew@55: sendSpeed(smoothedSpeedOutput); andrew@17: andrew@16: } andrew@16: andrew@16: void AccompanimentSynchroniser::setPlayingRatio(const double& ratio, const double& timePlayed){ andrew@16: playingPositionRatio = ratio; andrew@16: playingPositionSamples = ratio * fileLengthSamples; andrew@16: playingPositionMillis = playingPositionSamples * 1000.0/44100.0; andrew@16: playingPositionTimeSent = timePlayed; andrew@16: } andrew@16: andrew@16: andrew@17: void AccompanimentSynchroniser::updateRecordedPosition(const double& currentAlignmentPosition, const double& timeSent){ andrew@16: recordedPositionMillis = currentAlignmentPosition; andrew@17: recordedPositionTimeSent = timeSent; andrew@16: } andrew@16: andrew@16: andrew@16: void AccompanimentSynchroniser::updateOutputSpeed(){ andrew@16: //we want the playing position to more closely align with the recordedPosition andrew@17: andrew@53: andrew@55: difference += 0.5*((recordedPositionMillis - playingPositionMillis) - difference); andrew@17: // difference -= (recordedPositionTimeSent - playingPositionTimeSent); andrew@16: andrew@17: //suppose we project that we will align in 1 seconds time andrew@17: double projectedAlignmentTime = 1000; andrew@16: andrew@16: //then our current speed projects forward andrew@53: double predictedPlayingTimeIncrease = projectedAlignmentTime * smoothedSpeedOutput;//speed; andrew@16: difference += (projectedAlignmentTime - predictedPlayingTimeIncrease); andrew@53: double tmpSpeed = smoothedSpeedOutput; andrew@53: speed = smoothedSpeedOutput + (difference/projectedAlignmentTime); andrew@16: andrew@53: smoothedSpeedOutput = movingAverageWeighting*speed + (1- movingAverageWeighting)*tmpSpeed; andrew@53: andrew@53: sendSpeed(smoothedSpeedOutput); andrew@17: andrew@17: if (counter % 10 == 0){ andrew@17: printf("SYNC: rec pos %f play pos %f, diff %f\n", recordedPositionMillis, playingPositionMillis, recordedPositionMillis - playingPositionMillis); andrew@17: printf("projected align diff %f at speed %f\n", (projectedAlignmentTime - predictedPlayingTimeIncrease), tmpSpeed); andrew@17: printf("Final difference %f and speed output %f\n\n", difference, speed); andrew@17: } andrew@17: counter++; andrew@16: andrew@16: } andrew@16: andrew@16: void AccompanimentSynchroniser::sendSpeed(double const& val){ andrew@55: if (val > -2 && val < 2.){ andrew@17: ofxOscMessage m; andrew@17: m.setAddress( "/setSpeed" ); andrew@17: m.addFloatArg( val ); andrew@17: sender.sendMessage( m ); andrew@53: andrew@53: ofxOscMessage z; andrew@53: z.setAddress( "/syncDifference" ); andrew@53: z.addFloatArg( difference ); andrew@53: sender.sendMessage( z ); andrew@55: } else { andrew@55: printf("TRY TO SEND START rec pos %f play %f\n", recordedPositionMillis, playingPositionMillis); andrew@55: ofxOscMessage z; andrew@55: z.setAddress( "/setToSyncPlayingPosition" ); andrew@55: z.addFloatArg( recordedPositionMillis ); andrew@55: sender.sendMessage( z ); andrew@55: sendSpeed(1); andrew@55: smoothedSpeedOutput = 1; andrew@55: difference = 0; andrew@17: } andrew@16: }