comparison BeatTracker.h @ 8:f04f87b5e643

Add agent list class, and continue plodding through
author Chris Cannam
date Fri, 30 Sep 2011 11:37:25 +0100
parents 3c11becfc81a
children 887c629502a9
comparison
equal deleted inserted replaced
7:3c11becfc81a 8:f04f87b5e643
16 #ifndef _BEAT_TRACKER_H_ 16 #ifndef _BEAT_TRACKER_H_
17 #define _BEAT_TRACKER_H_ 17 #define _BEAT_TRACKER_H_
18 18
19 #include "Event.h" 19 #include "Event.h"
20 #include "Agent.h" 20 #include "Agent.h"
21 #include "AgentList.h"
21 #include "Induction.h" 22 #include "Induction.h"
22 23
23 using std::vector; 24 using std::vector;
24 25
25 class BeatTracker 26 class BeatTracker
31 /** a list of onset events for passing to the tempo induction and beat tracking methods */ 32 /** a list of onset events for passing to the tempo induction and beat tracking methods */
32 EventList onsetList; 33 EventList onsetList;
33 34
34 /** the times of onsets (in seconds) */ 35 /** the times of onsets (in seconds) */
35 vector<double> onsets; 36 vector<double> onsets;
36
37 /** the times corresponding to each point in the <code>magnitudes</code> array */
38 vector<double> env;
39
40 /** smoothed amplitude envelope of audio signal */
41 vector<int> magnitudes;
42 37
43 public: 38 public:
44 /** Constructor: 39 /** Constructor:
45 * @param b The list of beats 40 * @param b The list of beats
46 */ 41 */
79 EventList::iterator itr = beats.end(); 74 EventList::iterator itr = beats.end();
80 --itr; 75 --itr;
81 beatTime = itr->time; 76 beatTime = itr->time;
82 } 77 }
83 if (count > 0) { // tempo given by mean of initial beats 78 if (count > 0) { // tempo given by mean of initial beats
84 double ioi = (beatTime - beats.l.getFirst().keyDown) / count; 79 double ioi = (beatTime - beats.begin()->time) / count;
85 agents = new AgentList(new Agent(ioi), null); 80 agents.push_back(Agent(ioi));
86 } else // tempo not given; use tempo induction 81 } else // tempo not given; use tempo induction
87 agents = Induction.beatInduction(events); 82 agents = Induction::beatInduction(events);
88 if (beats != null) 83 if (!beats.empty())
89 for (AgentList ptr = agents; ptr.ag != null; ptr = ptr.next) { 84 for (AgentList::iterator itr = agents.begin(); itr != agents.end();
90 ptr.ag.beatTime = beatTime; 85 ++itr) {
91 ptr.ag.beatCount = count; 86 itr->beatTime = beatTime;
92 ptr.ag.events = new EventList(beats); 87 itr->beatCount = count;
88 itr->events = beats;
93 } 89 }
94 agents.beatTrack(events, -1); 90 agents.beatTrack(events, -1);
95 Agent best = agents.bestAgent(); 91 Agent *best = agents.bestAgent();
96 if (best != null) { 92 if (best) {
97 best.fillBeats(beatTime); 93 best->fillBeats(beatTime);
98 return best.events; 94 return best->events;
99 } 95 }
100 return new EventList(); 96 return EventList();
101 } // beatTrack()/1 97 } // beatTrack()/1
102 98
103 /** Finds the mean tempo (as inter-beat interval) from an array of beat times 99 /** Finds the mean tempo (as inter-beat interval) from an array of beat times
104 * @param d An array of beat times 100 * @param d An array of beat times
105 * @return The average inter-beat interval 101 * @return The average inter-beat interval
106 */ 102 */
107 static double getAverageIBI(vector<double> d) { 103 static double getAverageIBI(vector<double> d) {
108 if ((d == null) || (d.length < 2)) 104 if (d.size() < 2)
109 return -1.0; 105 return -1.0;
110 return (d[d.length - 1] - d[0]) / (d.length - 1); 106 return (d[d.size() - 1] - d[0]) / (d.size() - 1);
111 } // getAverageIBI() 107 } // getAverageIBI()
112 108
113 /** Finds the median tempo (as inter-beat interval) from an array of beat times 109 /** Finds the median tempo (as inter-beat interval) from an array of beat times
114 * @param d An array of beat times 110 * @param d An array of beat times
115 * @return The median inter-beat interval 111 * @return The median inter-beat interval
116 */ 112 */
117 static double getMedianIBI(vector<double> d) { 113 static double getMedianIBI(vector<double> d) {
118 if ((d == null) || (d.length < 2)) 114 if (d.size() < 2)
119 return -1.0; 115 return -1.0;
120 vector<double> ibi = new double[d.length-1]; 116 vector<double> ibi;
121 for (int i = 1; i < d.length; i++) 117 ibi.resize(d.size()-1);
118 for (int i = 1; i < d.size(); i++)
122 ibi[i-1] = d[i] - d[i-1]; 119 ibi[i-1] = d[i] - d[i-1];
123 Arrays.sort(ibi); 120 std::sort(ibi.begin(), ibi.end());
124 if (ibi.length % 2 == 0) 121 if (ibi.size() % 2 == 0)
125 return (ibi[ibi.length / 2] + ibi[ibi.length / 2 - 1]) / 2; 122 return (ibi[ibi.size() / 2] + ibi[ibi.size() / 2 - 1]) / 2;
126 else 123 else
127 return ibi[ibi.length / 2]; 124 return ibi[ibi.size() / 2];
128 } // getAverageIBI() 125 } // getAverageIBI()
129 126
130 127
131 // Various get and set methods 128 // Various get and set methods
132 129
138 /** @return the array of onset times */ 135 /** @return the array of onset times */
139 vector<double> getOnsets() { 136 vector<double> getOnsets() {
140 return onsets; 137 return onsets;
141 } // getOnsets() 138 } // getOnsets()
142 139
143 /** @return the array of offset times */
144 vector<double> getOffsets() {
145 return offsets;
146 } // getOffsets()
147
148 /** @return the array of MIDI pitches */
149 vector<int> getPitches() {
150 return pitches;
151 } // getPitches()
152
153 /** Sets the onset times as a list of Events, for use by the beat tracking methods. 140 /** Sets the onset times as a list of Events, for use by the beat tracking methods.
154 * @param on The times of onsets in seconds 141 * @param on The times of onsets in seconds
155 */ 142 */
156 void setOnsetList(EventList on) { 143 void setOnsetList(EventList on) {
157 onsetList = on; 144 onsetList = on;
162 */ 149 */
163 void setOnsets(vector<double> on) { 150 void setOnsets(vector<double> on) {
164 onsets = on; 151 onsets = on;
165 } // setOnsets() 152 } // setOnsets()
166 153
167 /** Sets the array of offset times, for displaying MIDI input data.
168 * @param off The array of MIDI offset times
169 */
170 void setOffsets(vector<double> off) {
171 offsets = off;
172 // setMode(SHOW_MIDI, SHOW_AUDIO | SHOW_SPECTRO);
173 } // setOffsets()
174
175 /** Sets the array of times of amplitude envelope points, for displaying.
176 * @param envTimes The array of times in seconds corresponding to the values in <code>magnitudes</code>
177 */
178 void setEnvTimes(vector<double> envTimes) {
179 env = envTimes;
180 setMode(SHOW_AUDIO, SHOW_MIDI);
181 } // setEnvTimes()
182
183 /** Sets the array of magnitude values, for displaying.
184 * @param mag The array of amplitude envelope values
185 */
186 void setMagnitudes(vector<int> mag) {
187 magnitudes = mag;
188 } // setMagnitudes()
189
190 /** Sets the array of pitch values, for displaying MIDI input data.
191 * @param p The array of MIDI pitch values
192 */
193 void setPitches(vector<int> p) {
194 pitches = p;
195 } // setPitches()
196
197 /** Sets the list of beats. 154 /** Sets the list of beats.
198 * @param b The list of beats 155 * @param b The list of beats
199 */ 156 */
200 void setBeats(EventList b) { 157 void setBeats(EventList b) {
201 beats = b; 158 beats = b;
202 selectedBeat = null;
203 beatPtr = beats.listIterator();
204 } // setBeats() 159 } // setBeats()
205 160
206 }; // class BeatTrackDisplay 161 }; // class BeatTrackDisplay
207 162
208 163