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 &noteFeatures) 1136 Silvet::emitNote(int start, int end, int note, FeatureList &noteFeatures)
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 &noteShift : m_simultaneity.notesShifts) {
1237 f.values.push_back(getNoteFrequency(noteShift.first, noteShift.second));
1238 }
1239 f.label = "";
1240 for (auto &noteShift : 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);