Mercurial > hg > svcore
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 |