view src/AccompanimentSynchroniser.cpp @ 53:5274e3b5479d

Smoothed output, added tempo distribution variation to match the output
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 14 Aug 2012 21:45:12 +0100
parents d23685b9e766
children 2eca10a31ae2
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(){
	
	
	playingPositionRatio = 0;
	playingPositionSamples = 0;
	playingPositionMillis = 0;
	playingPositionTimeSent = 0;
	
	recordedPositionMillis = 0;
	recordedPositionTimeSent = 0;
	
	speed = 1;
	smoothedSpeedOutput = 1;
	difference = 0;
	
}

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 > -3 && val < 4){
		ofxOscMessage m;
		m.setAddress( "/setSpeed" );
		m.addFloatArg( val );
		sender.sendMessage( m );
		
		ofxOscMessage z;
		z.setAddress( "/syncDifference" );
		z.addFloatArg( difference );
		sender.sendMessage( z );
	}
}