Mercurial > hg > silvet
comparison src/Silvet.cpp @ 337:3c6f5d2d33e8 simultaneities
An abortive attempt at this (doesn't compile)
author | Chris Cannam |
---|---|
date | Sat, 27 Jun 2015 14:37:13 +0100 |
parents | d25e4aee73d7 |
children |
comparison
equal
deleted
inserted
replaced
336:d25e4aee73d7 | 337:3c6f5d2d33e8 |
---|---|
283 d.sampleRate = processingSampleRate / (m_cq ? m_cq->getColumnHop() : 62); | 283 d.sampleRate = processingSampleRate / (m_cq ? m_cq->getColumnHop() : 62); |
284 d.hasDuration = false; | 284 d.hasDuration = false; |
285 m_onOffsetsOutputNo = list.size(); | 285 m_onOffsetsOutputNo = list.size(); |
286 list.push_back(d); | 286 list.push_back(d); |
287 | 287 |
288 d.identifier = "simultaneities"; | |
289 d.name = "Simultaneities"; | |
290 d.description = "Events indicating which notes are active together. Whenever a note begins, it is collected with any other notes which begin during a short period of time immediately after, and the set of currently playing notes is reported as an event with the timestamp of the first note. Each feature has a variable number of values, depending on how many simultaneous notes are active."; | |
291 d.unit = "Hz"; | |
292 d.hasFixedBinCount = false; | |
293 d.binNames.clear(); | |
294 d.hasKnownExtents = false; | |
295 d.isQuantized = false; | |
296 d.sampleType = OutputDescriptor::VariableSampleRate; | |
297 d.sampleRate = processingSampleRate / (m_cq ? m_cq->getColumnHop() : 62); | |
298 d.hasDuration = false; | |
299 m_simultaneitiesOutputNo = list.size(); | |
300 list.push_back(d); | |
301 | |
288 d.identifier = "timefreq"; | 302 d.identifier = "timefreq"; |
289 d.name = "Time-frequency distribution"; | 303 d.name = "Time-frequency distribution"; |
290 d.description = "Filtered constant-Q time-frequency distribution as used as input to the expectation-maximisation algorithm."; | 304 d.description = "Filtered constant-Q time-frequency distribution as used as input to the expectation-maximisation algorithm."; |
291 d.unit = ""; | 305 d.unit = ""; |
292 d.hasFixedBinCount = true; | 306 d.hasFixedBinCount = true; |
553 for (int i = 0; i < getPack(0).templateNoteCount; ++i) { | 567 for (int i = 0; i < getPack(0).templateNoteCount; ++i) { |
554 m_postFilter.push_back(new MedianFilter<double>(postFilterLength)); | 568 m_postFilter.push_back(new MedianFilter<double>(postFilterLength)); |
555 } | 569 } |
556 m_pianoRoll.clear(); | 570 m_pianoRoll.clear(); |
557 m_inputGains.clear(); | 571 m_inputGains.clear(); |
572 m_simultaneity = Simultaneity(); | |
558 m_columnCount = 0; | 573 m_columnCount = 0; |
559 m_resampledCount = 0; | 574 m_resampledCount = 0; |
560 m_startTime = RealTime::zeroTime; | 575 m_startTime = RealTime::zeroTime; |
561 m_haveStartTime = false; | 576 m_haveStartTime = false; |
562 } | 577 } |
645 fs[m_onsetsOutputNo].push_back(f); | 660 fs[m_onsetsOutputNo].push_back(f); |
646 } | 661 } |
647 | 662 |
648 for (const auto &f : events.onOffsets) { | 663 for (const auto &f : events.onOffsets) { |
649 fs[m_onOffsetsOutputNo].push_back(f); | 664 fs[m_onOffsetsOutputNo].push_back(f); |
665 } | |
666 | |
667 for (const auto &f : events.simultaneities) { | |
668 fs[m_simultaneitiesOutputNo].push_back(f); | |
650 } | 669 } |
651 } | 670 } |
652 | 671 |
653 return fs; | 672 return fs; |
654 } | 673 } |
809 fs[m_onsetsOutputNo].push_back(f); | 828 fs[m_onsetsOutputNo].push_back(f); |
810 } | 829 } |
811 | 830 |
812 for (const auto &f : events.onOffsets) { | 831 for (const auto &f : events.onOffsets) { |
813 fs[m_onOffsetsOutputNo].push_back(f); | 832 fs[m_onOffsetsOutputNo].push_back(f); |
833 } | |
834 | |
835 for (const auto &f : events.simultaneities) { | |
836 fs[m_simultaneitiesOutputNo].push_back(f); | |
814 } | 837 } |
815 } | 838 } |
816 } | 839 } |
817 | 840 |
818 pair<vector<double>, vector<int> > | 841 pair<vector<double>, vector<int> > |
1048 // only keep notes >= 100ms or thereabouts | 1071 // only keep notes >= 100ms or thereabouts |
1049 double durationThrSec = 0.1; | 1072 double durationThrSec = 0.1; |
1050 int durationThreshold = floor(durationThrSec / columnDuration); // in cols | 1073 int durationThreshold = floor(durationThrSec / columnDuration); // in cols |
1051 if (durationThreshold < 1) durationThreshold = 1; | 1074 if (durationThreshold < 1) durationThreshold = 1; |
1052 | 1075 |
1053 FeatureList noteFeatures, onsetFeatures, onOffsetFeatures; | 1076 FeatureList noteFeatures, onsetFeatures, onOffsetFeatures, simultaneousFeatures; |
1054 | 1077 |
1055 if (width < durationThreshold + 1) { | 1078 if (width < durationThreshold + 1) { |
1056 return { noteFeatures, onsetFeatures, onOffsetFeatures }; | 1079 return { noteFeatures, onsetFeatures, onOffsetFeatures, simultaneousFeatures }; |
1057 } | 1080 } |
1058 | 1081 |
1059 for (map<int, double>::const_iterator ni = m_pianoRoll[width-1].begin(); | 1082 for (map<int, double>::const_iterator ni = m_pianoRoll[width-1].begin(); |
1060 ni != m_pianoRoll[width-1].end(); ++ni) { | 1083 ni != m_pianoRoll[width-1].end(); ++ni) { |
1061 | 1084 |
1104 } | 1127 } |
1105 } | 1128 } |
1106 | 1129 |
1107 // cerr << "returning " << noteFeatures.size() << " complete note(s) " << endl; | 1130 // cerr << "returning " << noteFeatures.size() << " complete note(s) " << endl; |
1108 | 1131 |
1109 return { noteFeatures, onsetFeatures, onOffsetFeatures }; | 1132 return { noteFeatures, onsetFeatures, onOffsetFeatures, simultaneousFeatures }; |
1110 } | 1133 } |
1111 | 1134 |
1112 void | 1135 void |
1113 Silvet::emitNote(int start, int end, int note, FeatureList ¬eFeatures) | 1136 Silvet::emitNote(int start, int end, int note, FeatureList ¬eFeatures) |
1114 { | 1137 { |
1200 onOffsetFeatures.push_back(makeOffsetFeature(end, | 1223 onOffsetFeatures.push_back(makeOffsetFeature(end, |
1201 note, | 1224 note, |
1202 shift)); | 1225 shift)); |
1203 } | 1226 } |
1204 | 1227 |
1228 void | |
1229 Silvet::emitSimultaneity(int start, FeatureList &simultaneousFeatures) | |
1230 { | |
1231 Feature f; | |
1232 f.hasTimestamp = true; | |
1233 f.timestamp = getColumnTimestamp(start); | |
1234 f.hasDuration = false; | |
1235 f.values.clear(); | |
1236 for (auto ¬eShift : m_simultaneity.notesShifts) { | |
1237 f.values.push_back(getNoteFrequency(noteShift.first, noteShift.second)); | |
1238 } | |
1239 f.label = ""; | |
1240 for (auto ¬eShift : m_simultaneity.notesShifts) { | |
1241 if (f.label != "") f.label += ","; | |
1242 f.label += getNoteName(noteShift.first, noteShift.second); | |
1243 } | |
1244 simultaneousFeatures.push_back(f); | |
1245 } | |
1246 | |
1205 RealTime | 1247 RealTime |
1206 Silvet::getColumnTimestamp(int column) | 1248 Silvet::getColumnTimestamp(int column) |
1207 { | 1249 { |
1208 double columnDuration = 1.0 / m_colsPerSec; | 1250 double columnDuration = 1.0 / m_colsPerSec; |
1209 int postFilterLatency = int(m_postFilter[0]->getSize() / 2); | 1251 int postFilterLatency = int(m_postFilter[0]->getSize() / 2); |