view src/AccompanimentSynchroniser.cpp @ 56:4394c9490716 tip

minor changes
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 24 Dec 2012 18:58:39 +0000
parents 2eca10a31ae2
children
line wrap: on
line source
/*
 *  AccompanimentSynchroniser.cpp
 *  MultipleAudioMathcher
 *
 *  Created by Andrew on 06/02/2012.
 *  Copyright 2012 QMUL. All rights reserved.
 *
 */

#include "AccompanimentSynchroniser.h"

//recorded position millis is the current alignment position, sent from updateAlignment in event matcher
//time sent is the live time since start of play

AccompanimentSynchroniser::AccompanimentSynchroniser(){
	sender.setup(HOST,  SENDER_PORT);
	counter = 0;
	movingAverageWeighting = 0.4;
	reset();
}

void AccompanimentSynchroniser::reset(){
	
	printf("ACC SYNC RESET\n");
	
	playingPositionRatio = 0;
	playingPositionSamples = 0;
	playingPositionMillis = 0;
	playingPositionTimeSent = 0;
	
	recordedPositionMillis = 0;
	recordedPositionTimeSent = 0;

	speed = 1;
	smoothedSpeedOutput = 1;
	difference = 0;

	sendSpeed(smoothedSpeedOutput);
	
}

void AccompanimentSynchroniser::setPlayingRatio(const double& ratio, const double& timePlayed){
	playingPositionRatio = ratio;
	playingPositionSamples = ratio * fileLengthSamples;
	playingPositionMillis = playingPositionSamples * 1000.0/44100.0;
	playingPositionTimeSent = timePlayed;
}


void AccompanimentSynchroniser::updateRecordedPosition(const double& currentAlignmentPosition, const double& timeSent){
	recordedPositionMillis = currentAlignmentPosition;
	recordedPositionTimeSent = timeSent;
}


void AccompanimentSynchroniser::updateOutputSpeed(){
	//we want the playing position to more closely align with the recordedPosition


	difference += 0.5*((recordedPositionMillis - playingPositionMillis) - difference);
//	difference -=  (recordedPositionTimeSent - playingPositionTimeSent);
	
	//suppose we project that we will align in 1 seconds time
	double projectedAlignmentTime = 1000;
	
	//then our current speed projects forward
	double predictedPlayingTimeIncrease = projectedAlignmentTime * smoothedSpeedOutput;//speed;
	difference += (projectedAlignmentTime - predictedPlayingTimeIncrease);
	double tmpSpeed = smoothedSpeedOutput;
	speed = smoothedSpeedOutput + (difference/projectedAlignmentTime);
	
	smoothedSpeedOutput = movingAverageWeighting*speed + (1- movingAverageWeighting)*tmpSpeed;
	
	sendSpeed(smoothedSpeedOutput);
	
	if (counter % 10 == 0){
		printf("SYNC: rec pos %f play pos %f, diff %f\n", recordedPositionMillis, playingPositionMillis, recordedPositionMillis - playingPositionMillis);
		printf("projected align diff %f at speed %f\n", (projectedAlignmentTime - predictedPlayingTimeIncrease), tmpSpeed);
		printf("Final difference %f and speed output %f\n\n", difference, speed);
	}
		counter++;

}

void AccompanimentSynchroniser::sendSpeed(double const& val){
	if (val > -2 && val < 2.){
		ofxOscMessage m;
		m.setAddress( "/setSpeed" );
		m.addFloatArg( val );
		sender.sendMessage( m );
		
		ofxOscMessage z;
		z.setAddress( "/syncDifference" );
		z.addFloatArg( difference );
		sender.sendMessage( z );
	} else {
		printf("TRY TO SEND START rec pos %f play %f\n", recordedPositionMillis, playingPositionMillis);
		ofxOscMessage z;
		z.setAddress( "/setToSyncPlayingPosition" );
		z.addFloatArg( recordedPositionMillis );
		sender.sendMessage( z );
		sendSpeed(1);
		smoothedSpeedOutput = 1;
		difference = 0;
	}
}