andrew@16
|
1 /*
|
andrew@16
|
2 * AccompanimentSynchroniser.cpp
|
andrew@16
|
3 * MultipleAudioMathcher
|
andrew@16
|
4 *
|
andrew@16
|
5 * Created by Andrew on 06/02/2012.
|
andrew@16
|
6 * Copyright 2012 QMUL. All rights reserved.
|
andrew@16
|
7 *
|
andrew@16
|
8 */
|
andrew@16
|
9
|
andrew@16
|
10 #include "AccompanimentSynchroniser.h"
|
andrew@16
|
11
|
andrew@45
|
12 //recorded position millis is the current alignment position, sent from updateAlignment in event matcher
|
andrew@45
|
13 //time sent is the live time since start of play
|
andrew@45
|
14
|
andrew@16
|
15 AccompanimentSynchroniser::AccompanimentSynchroniser(){
|
andrew@16
|
16 sender.setup(HOST, SENDER_PORT);
|
andrew@17
|
17 counter = 0;
|
andrew@17
|
18 reset();
|
andrew@17
|
19 }
|
andrew@17
|
20
|
andrew@17
|
21 void AccompanimentSynchroniser::reset(){
|
andrew@17
|
22
|
andrew@17
|
23
|
andrew@17
|
24 playingPositionRatio = 0;
|
andrew@17
|
25 playingPositionSamples = 0;
|
andrew@17
|
26 playingPositionMillis = 0;
|
andrew@17
|
27 playingPositionTimeSent = 0;
|
andrew@17
|
28
|
andrew@17
|
29 recordedPositionMillis = 0;
|
andrew@17
|
30 recordedPositionTimeSent = 0;
|
andrew@17
|
31
|
andrew@17
|
32 speed = 1;
|
andrew@17
|
33
|
andrew@17
|
34
|
andrew@16
|
35 }
|
andrew@16
|
36
|
andrew@16
|
37 void AccompanimentSynchroniser::setPlayingRatio(const double& ratio, const double& timePlayed){
|
andrew@16
|
38 playingPositionRatio = ratio;
|
andrew@16
|
39 playingPositionSamples = ratio * fileLengthSamples;
|
andrew@16
|
40 playingPositionMillis = playingPositionSamples * 1000.0/44100.0;
|
andrew@16
|
41 playingPositionTimeSent = timePlayed;
|
andrew@16
|
42 }
|
andrew@16
|
43
|
andrew@16
|
44
|
andrew@17
|
45 void AccompanimentSynchroniser::updateRecordedPosition(const double& currentAlignmentPosition, const double& timeSent){
|
andrew@16
|
46 recordedPositionMillis = currentAlignmentPosition;
|
andrew@17
|
47 recordedPositionTimeSent = timeSent;
|
andrew@16
|
48 }
|
andrew@16
|
49
|
andrew@16
|
50
|
andrew@16
|
51 void AccompanimentSynchroniser::updateOutputSpeed(){
|
andrew@16
|
52 //we want the playing position to more closely align with the recordedPosition
|
andrew@17
|
53
|
andrew@16
|
54
|
andrew@16
|
55 double difference = recordedPositionMillis - playingPositionMillis;
|
andrew@17
|
56 // difference -= (recordedPositionTimeSent - playingPositionTimeSent);
|
andrew@16
|
57
|
andrew@17
|
58 //suppose we project that we will align in 1 seconds time
|
andrew@17
|
59 double projectedAlignmentTime = 1000;
|
andrew@16
|
60
|
andrew@16
|
61 //then our current speed projects forward
|
andrew@16
|
62 double predictedPlayingTimeIncrease = projectedAlignmentTime*speed;
|
andrew@16
|
63 difference += (projectedAlignmentTime - predictedPlayingTimeIncrease);
|
andrew@17
|
64 double tmpSpeed = speed;
|
andrew@16
|
65 speed += difference/projectedAlignmentTime;
|
andrew@16
|
66
|
andrew@16
|
67 sendSpeed(speed);
|
andrew@17
|
68
|
andrew@17
|
69 if (counter % 10 == 0){
|
andrew@17
|
70 printf("SYNC: rec pos %f play pos %f, diff %f\n", recordedPositionMillis, playingPositionMillis, recordedPositionMillis - playingPositionMillis);
|
andrew@17
|
71 printf("projected align diff %f at speed %f\n", (projectedAlignmentTime - predictedPlayingTimeIncrease), tmpSpeed);
|
andrew@17
|
72 printf("Final difference %f and speed output %f\n\n", difference, speed);
|
andrew@17
|
73 }
|
andrew@17
|
74 counter++;
|
andrew@16
|
75
|
andrew@16
|
76 }
|
andrew@16
|
77
|
andrew@16
|
78 void AccompanimentSynchroniser::sendSpeed(double const& val){
|
andrew@17
|
79 if (val > -3 && val < 4){
|
andrew@17
|
80 ofxOscMessage m;
|
andrew@17
|
81 m.setAddress( "/setSpeed" );
|
andrew@17
|
82 m.addFloatArg( val );
|
andrew@17
|
83 sender.sendMessage( m );
|
andrew@17
|
84 }
|
andrew@16
|
85 } |