Mercurial > hg > beatroot-vamp
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 |