comparison transform/FeatureExtractionModelTransformer.cpp @ 1740:fe3f7f8df3a3 by-id

More work on transformers
author Chris Cannam
date Wed, 26 Jun 2019 17:25:20 +0100
parents 565575463752
children b92bdcd4954b
comparison
equal deleted inserted replaced
1739:565575463752 1740:fe3f7f8df3a3
648 } 648 }
649 if (m_abandoned) return; 649 if (m_abandoned) return;
650 650
651 auto input = ModelById::getAs<DenseTimeValueModel>(getInputModel()); 651 auto input = ModelById::getAs<DenseTimeValueModel>(getInputModel());
652 if (!input) { 652 if (!input) {
653 SVCERR << "FeatureExtractionModelTransformer::run: Input model not (no longer?) available, abandoning" << endl;
654 abandon(); 653 abandon();
655 return; 654 return;
656 } 655 }
657 656
658 sv_samplerate_t sampleRate = input->getSampleRate(); 657 sv_samplerate_t sampleRate = input->getSampleRate();
792 getFrames(channelCount, blockFrame, blockSize, buffers); 791 getFrames(channelCount, blockFrame, blockSize, buffers);
793 } 792 }
794 793
795 if (m_abandoned) break; 794 if (m_abandoned) break;
796 795
797 Vamp::Plugin::FeatureSet features = m_plugin->process 796 auto features = m_plugin->process
798 (buffers, 797 (buffers,
799 RealTime::frame2RealTime(blockFrame, sampleRate) 798 RealTime::frame2RealTime(blockFrame, sampleRate)
800 .toVampRealTime()); 799 .toVampRealTime());
801 800
802 if (m_abandoned) break; 801 if (m_abandoned) break;
803 802
804 for (int j = 0; j < (int)m_outputNos.size(); ++j) { 803 for (int j = 0; in_range_for(m_outputNos, j); ++j) {
805 for (int fi = 0; fi < (int)features[m_outputNos[j]].size(); ++fi) { 804 for (int fi = 0; in_range_for(features[m_outputNos[j]], fi); ++fi) {
806 Vamp::Plugin::Feature feature = features[m_outputNos[j]][fi]; 805 auto feature = features[m_outputNos[j]][fi];
807 addFeature(j, blockFrame, feature); 806 addFeature(j, blockFrame, feature);
808 } 807 }
809 } 808 }
810 809
811 if (blockFrame == contextStart || completion > prevCompletion) { 810 if (blockFrame == contextStart || completion > prevCompletion) {
812 for (int j = 0; j < (int)m_outputNos.size(); ++j) { 811 for (int j = 0; in_range_for(m_outputNos, j); ++j) {
813 setCompletion(j, completion); 812 setCompletion(j, completion);
814 } 813 }
815 prevCompletion = completion; 814 prevCompletion = completion;
816 } 815 }
817 816
818 blockFrame += stepSize; 817 blockFrame += stepSize;
819 818
820 } 819 }
821 820
822 if (!m_abandoned) { 821 if (!m_abandoned) {
823 Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); 822 auto features = m_plugin->getRemainingFeatures();
824 823
825 for (int j = 0; j < (int)m_outputNos.size(); ++j) { 824 for (int j = 0; in_range_for(m_outputNos, j); ++j) {
826 for (int fi = 0; fi < (int)features[m_outputNos[j]].size(); ++fi) { 825 for (int fi = 0; in_range_for(features[m_outputNos[j]], fi); ++fi) {
827 Vamp::Plugin::Feature feature = features[m_outputNos[j]][fi]; 826 auto feature = features[m_outputNos[j]][fi];
828 addFeature(j, blockFrame, feature); 827 addFeature(j, blockFrame, feature);
829 } 828 }
830 } 829 }
831 } 830 }
832 } catch (const std::exception &e) { 831 } catch (const std::exception &e) {
988 // to determine what sort of model we must be adding the features 987 // to determine what sort of model we must be adding the features
989 // to, we instead test what sort of model the constructor decided 988 // to, we instead test what sort of model the constructor decided
990 // to create. 989 // to create.
991 990
992 ModelId outputId = m_outputs[n]; 991 ModelId outputId = m_outputs[n];
993 bool found = false; 992
993 if (isOutputType<SparseOneDimensionalModel>(n)) {
994
995 auto model = ModelById::getAs<SparseOneDimensionalModel>(outputId);
996 if (!model) return;
997 model->add(Event(frame, feature.label.c_str()));
998
999 } else if (isOutputType<SparseTimeValueModel>(n)) {
1000
1001 auto model = ModelById::getAs<SparseTimeValueModel>(outputId);
1002 if (!model) return;
1003
1004 for (int i = 0; in_range_for(feature.values, i); ++i) {
1005
1006 float value = feature.values[i];
1007
1008 QString label = feature.label.c_str();
1009 if (feature.values.size() > 1) {
1010 label = QString("[%1] %2").arg(i+1).arg(label);
1011 }
1012
1013 auto targetModel = model;
1014
1015 if (m_needAdditionalModels[n] && i > 0) {
1016 targetModel = ModelById::getAs<SparseTimeValueModel>
1017 (getAdditionalModel(n, i));
1018 if (!targetModel) targetModel = model;
1019 }
1020
1021 targetModel->add(Event(frame, value, label));
1022 }
1023
1024 } else if (isOutputType<NoteModel>(n) || isOutputType<RegionModel>(n)) {
994 1025
995 if (!found) { 1026 int index = 0;
996 auto model = ModelById::getAs<SparseOneDimensionalModel>(outputId); 1027
997 if (model) { 1028 float value = 0.0;
998 found = true; 1029 if ((int)feature.values.size() > index) {
999 model->add(Event(frame, feature.label.c_str())); 1030 value = feature.values[index++];
1000 } 1031 }
1001 } 1032
1002 1033 sv_frame_t duration = 1;
1003 if (!found) { 1034 if (feature.hasDuration) {
1004 auto model = ModelById::getAs<SparseTimeValueModel>(outputId); 1035 duration = RealTime::realTime2Frame(feature.duration, inputRate);
1005 if (model) { 1036 } else {
1006 found = true; 1037 if (in_range_for(feature.values, index)) {
1007 1038 duration = lrintf(feature.values[index++]);
1008 for (int i = 0; in_range_for(feature.values, i); ++i) { 1039 }
1009 1040 }
1010 float value = feature.values[i]; 1041
1011 1042 auto noteModel = ModelById::getAs<NoteModel>(outputId);
1012 QString label = feature.label.c_str(); 1043 if (noteModel) {
1013 if (feature.values.size() > 1) { 1044
1014 label = QString("[%1] %2").arg(i+1).arg(label); 1045 float velocity = 100;
1015 }
1016
1017 auto targetModel = model;
1018
1019 if (m_needAdditionalModels[n] && i > 0) {
1020 targetModel = ModelById::getAs<SparseTimeValueModel>
1021 (getAdditionalModel(n, i));
1022 if (!targetModel) targetModel = model;
1023 }
1024
1025 targetModel->add(Event(frame, value, label));
1026 }
1027 }
1028 }
1029
1030 if (!found) {
1031 if (ModelById::getAs<NoteModel>(outputId) ||
1032 ModelById::getAs<RegionModel>(outputId)) {
1033 found = true;
1034
1035 int index = 0;
1036
1037 float value = 0.0;
1038 if ((int)feature.values.size() > index) { 1046 if ((int)feature.values.size() > index) {
1039 value = feature.values[index++]; 1047 velocity = feature.values[index++];
1040 } 1048 }
1041 1049 if (velocity < 0) velocity = 127;
1042 sv_frame_t duration = 1; 1050 if (velocity > 127) velocity = 127;
1043 if (feature.hasDuration) { 1051
1044 duration = RealTime::realTime2Frame(feature.duration, inputRate); 1052 noteModel->add(Event(frame, value, // value is pitch
1045 } else { 1053 duration,
1046 if (in_range_for(feature.values, index)) { 1054 velocity / 127.f,
1047 duration = lrintf(feature.values[index++]); 1055 feature.label.c_str()));
1048 } 1056 }
1049 } 1057
1050 1058 auto regionModel = ModelById::getAs<RegionModel>(outputId);
1051 auto noteModel = ModelById::getAs<NoteModel>(outputId); 1059 if (regionModel) {
1052 if (noteModel) { 1060
1053 1061 if (feature.hasDuration && !feature.values.empty()) {
1054 float velocity = 100; 1062
1055 if ((int)feature.values.size() > index) { 1063 for (int i = 0; in_range_for(feature.values, i); ++i) {
1056 velocity = feature.values[index++]; 1064
1057 } 1065 float value = feature.values[i];
1058 if (velocity < 0) velocity = 127; 1066
1059 if (velocity > 127) velocity = 127; 1067 QString label = feature.label.c_str();
1060 1068 if (feature.values.size() > 1) {
1061 noteModel->add(Event(frame, value, // value is pitch 1069 label = QString("[%1] %2").arg(i+1).arg(label);
1062 duration,
1063 velocity / 127.f,
1064 feature.label.c_str()));
1065 }
1066
1067 auto regionModel = ModelById::getAs<RegionModel>(outputId);
1068 if (regionModel) {
1069
1070 if (feature.hasDuration && !feature.values.empty()) {
1071
1072 for (int i = 0; in_range_for(feature.values, i); ++i) {
1073
1074 float value = feature.values[i];
1075
1076 QString label = feature.label.c_str();
1077 if (feature.values.size() > 1) {
1078 label = QString("[%1] %2").arg(i+1).arg(label);
1079 }
1080
1081 regionModel->add(Event(frame,
1082 value,
1083 duration,
1084 label));
1085 } 1070 }
1086 } else { 1071
1087
1088 regionModel->add(Event(frame, 1072 regionModel->add(Event(frame,
1089 value, 1073 value,
1090 duration, 1074 duration,
1091 feature.label.c_str())); 1075 label));
1092 } 1076 }
1093 } 1077 } else {
1094 } 1078
1095 } 1079 regionModel->add(Event(frame,
1096 1080 value,
1097 if (!found) { 1081 duration,
1082 feature.label.c_str()));
1083 }
1084 }
1085
1086 } else if (isOutputType<EditableDenseThreeDimensionalModel>(n)) {
1087
1098 auto model = ModelById::getAs 1088 auto model = ModelById::getAs
1099 <EditableDenseThreeDimensionalModel>(outputId); 1089 <EditableDenseThreeDimensionalModel>(outputId);
1100 if (model) { 1090 if (!model) return;
1101 found = true;
1102 1091
1103 DenseThreeDimensionalModel::Column values = feature.values; 1092 DenseThreeDimensionalModel::Column values = feature.values;
1104 1093
1105 if (!feature.hasTimestamp && m_fixedRateFeatureNos[n] >= 0) { 1094 if (!feature.hasTimestamp && m_fixedRateFeatureNos[n] >= 0) {
1106 model->setColumn(m_fixedRateFeatureNos[n], values); 1095 model->setColumn(m_fixedRateFeatureNos[n], values);
1107 } else { 1096 } else {
1108 model->setColumn(int(frame / model->getResolution()), values); 1097 model->setColumn(int(frame / model->getResolution()), values);
1109 } 1098 }
1110 } 1099 }
1111 } 1100
1112 1101 SVDEBUG << "FeatureExtractionModelTransformer::addFeature: Unknown output model type!" << endl;
1113 if (!found) {
1114 SVDEBUG << "FeatureExtractionModelTransformer::addFeature: Unknown output model type!" << endl;
1115 }
1116 } 1102 }
1117 1103
1118 void 1104 void
1119 FeatureExtractionModelTransformer::setCompletion(int n, int completion) 1105 FeatureExtractionModelTransformer::setCompletion(int n, int completion)
1120 { 1106 {
1121 #ifdef DEBUG_FEATURE_EXTRACTION_TRANSFORMER_RUN 1107 #ifdef DEBUG_FEATURE_EXTRACTION_TRANSFORMER_RUN
1122 SVDEBUG << "FeatureExtractionModelTransformer::setCompletion(" 1108 SVDEBUG << "FeatureExtractionModelTransformer::setCompletion("
1123 << completion << ")" << endl; 1109 << completion << ")" << endl;
1124 #endif 1110 #endif
1125 1111
1126 ModelId outputId = m_outputs[n]; 1112 (void)
1127 bool found = false; 1113 (setOutputCompletion<SparseOneDimensionalModel>(n, completion) ||
1128 1114 setOutputCompletion<SparseTimeValueModel>(n, completion) ||
1129 if (!found) { 1115 setOutputCompletion<NoteModel>(n, completion) ||
1130 auto model = ModelById::getAs<SparseOneDimensionalModel>(outputId); 1116 setOutputCompletion<RegionModel>(n, completion) ||
1131 if (model) { 1117 setOutputCompletion<EditableDenseThreeDimensionalModel>(n, completion));
1132 found = true; 1118 }
1133 model->setCompletion(completion, true); 1119
1134 }
1135 }
1136
1137 if (!found) {
1138 auto model = ModelById::getAs<SparseTimeValueModel>(outputId);
1139 if (model) {
1140 found = true;
1141 model->setCompletion(completion, true);
1142 }
1143 }
1144
1145 if (!found) {
1146 auto model = ModelById::getAs<NoteModel>(outputId);
1147 if (model) {
1148 found = true;
1149 model->setCompletion(completion, true);
1150 }
1151 }
1152
1153 if (!found) {
1154 auto model = ModelById::getAs<RegionModel>(outputId);
1155 if (model) {
1156 found = true;
1157 model->setCompletion(completion, true);
1158 }
1159 }
1160
1161 if (!found) {
1162 auto model = ModelById::getAs<EditableDenseThreeDimensionalModel>(outputId);
1163 if (model) {
1164 found = true;
1165 model->setCompletion(completion, true);
1166 }
1167 }
1168 }
1169