comparison PyPlugin.cpp @ 18:e9cf443b18f5

* Add duration support (Vamp 2.0)
author cannam
date Fri, 10 Jul 2009 15:14:24 +0000
parents 3af6b5990ad8
children 1ae350e97f93
comparison
equal deleted inserted replaced
17:5b8167619b76 18:e9cf443b18f5
1 /* -*- c-basic-offset: 8 indent-tabs-mode: t -*- */
1 /* 2 /*
2 Vamp 3 Vamp
3 4
4 An API for audio analysis and feature extraction plugins. 5 An API for audio analysis and feature extraction plugins.
5 6
64 using std::cerr; 65 using std::cerr;
65 using std::endl; 66 using std::endl;
66 using std::map; 67 using std::map;
67 68
68 // Maps to associate strings with enum values 69 // Maps to associate strings with enum values
69 static std::map<std::string, eOutDescriptors> outKeys; 70 static std::map<std::string, o::eOutDescriptors> outKeys;
70 static std::map<std::string, eSampleTypes> sampleKeys; 71 static std::map<std::string, eSampleTypes> sampleKeys;
71 static std::map<std::string, eFeatureFields> ffKeys; 72 static std::map<std::string, eFeatureFields> ffKeys;
72 static std::map<std::string, p::eParmDescriptors> parmKeys; 73 static std::map<std::string, p::eParmDescriptors> parmKeys;
73 74
74 Mutex PyPlugin::m_pythonInterpreterMutex; 75 Mutex PyPlugin::m_pythonInterpreterMutex;
278 279
279 //quering process implementation type 280 //quering process implementation type
280 char legacyMethod[]="process"; 281 char legacyMethod[]="process";
281 char numpyMethod[]="processN"; 282 char numpyMethod[]="processN";
282 283
283 if (PyObject_HasAttrString(m_pyInstance,legacyMethod) & 284 if (PyObject_HasAttrString(m_pyInstance,legacyMethod) &&
284 m_processType == 0) 285 m_processType == 0)
285 { 286 {
286 m_processType = legacyProcess; 287 m_processType = legacyProcess;
287 m_pyProcess = PyString_FromString(legacyMethod); 288 m_pyProcess = PyString_FromString(legacyMethod);
288 } 289 }
289 290
290 if (PyObject_HasAttrString(m_pyInstance,numpyMethod) & 291 if (PyObject_HasAttrString(m_pyInstance,numpyMethod) &&
291 m_processType == 0) 292 m_processType == 0)
292 { 293 {
293 m_processType = numpyProcess; 294 m_processType = numpyProcess;
294 m_pyProcess = PyString_FromString(numpyMethod); 295 m_pyProcess = PyString_FromString(numpyMethod);
295 } 296 }
296 297
514 PyObject *pyDict, *pyKey, *pyValue; 515 PyObject *pyDict, *pyKey, *pyValue;
515 516
516 //Parse Output List 517 //Parse Output List
517 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pyList); ++i) { 518 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pyList); ++i) {
518 519
519 //Get i-th VAMP output descriptor (Borrowed Reference) 520 //Get i-th Vamp output descriptor (Borrowed Reference)
520 pyDict = PyList_GET_ITEM(pyList,i); 521 pyDict = PyList_GET_ITEM(pyList,i);
521 522
522 //We only care about dictionaries holding output descriptors 523 //We only care about dictionaries holding output descriptors
523 if ( !PyDict_Check(pyDict) ) continue; 524 if ( !PyDict_Check(pyDict) ) continue;
524 525
528 //Python Sequence Iterator 529 //Python Sequence Iterator
529 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue)) 530 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue))
530 { 531 {
531 switch (outKeys[PyString_AsString(pyKey)]) 532 switch (outKeys[PyString_AsString(pyKey)])
532 { 533 {
533 case not_found : 534 case o::not_found :
534 cerr << "Unknown key in VAMP OutputDescriptor: " << PyString_AsString(pyKey) << endl; 535 cerr << "Unknown key in Vamp OutputDescriptor: " << PyString_AsString(pyKey) << endl;
535 break; 536 break;
536 case identifier: 537 case o::identifier:
537 od.identifier = PyString_AsString(pyValue); 538 od.identifier = PyString_AsString(pyValue);
538 break; 539 break;
539 case name: 540 case o::name:
540 od.name = PyString_AsString(pyValue); 541 od.name = PyString_AsString(pyValue);
541 break; 542 break;
542 case description: 543 case o::description:
543 od.description = PyString_AsString(pyValue); 544 od.description = PyString_AsString(pyValue);
544 break; 545 break;
545 case unit: 546 case o::unit:
546 od.unit = PyString_AsString(pyValue); 547 od.unit = PyString_AsString(pyValue);
547 break; 548 break;
548 case hasFixedBinCount: 549 case o::hasFixedBinCount:
549 od.hasFixedBinCount = (bool) PyInt_AS_LONG(pyValue); 550 od.hasFixedBinCount = (bool) PyInt_AS_LONG(pyValue);
550 break; 551 break;
551 case binCount: 552 case o::binCount:
552 od.binCount = (size_t) PyInt_AS_LONG(pyValue); 553 od.binCount = (size_t) PyInt_AS_LONG(pyValue);
553 break; 554 break;
554 case binNames: 555 case o::binNames:
555 od.binNames = PyList_To_StringVector(pyValue); 556 od.binNames = PyList_To_StringVector(pyValue);
556 break; 557 break;
557 case hasKnownExtents: 558 case o::hasKnownExtents:
558 od.hasKnownExtents = (bool) PyInt_AS_LONG(pyValue); 559 od.hasKnownExtents = (bool) PyInt_AS_LONG(pyValue);
559 break; 560 break;
560 case minValue: 561 case o::minValue:
561 od.minValue = (float) PyFloat_AS_DOUBLE(pyValue); 562 od.minValue = (float) PyFloat_AS_DOUBLE(pyValue);
562 break; 563 break;
563 case maxValue: 564 case o::maxValue:
564 od.maxValue = (float) PyFloat_AS_DOUBLE(pyValue); 565 od.maxValue = (float) PyFloat_AS_DOUBLE(pyValue);
565 break; 566 break;
566 case isQuantized: 567 case o::isQuantized:
567 od.isQuantized = (bool) PyInt_AS_LONG(pyValue); 568 od.isQuantized = (bool) PyInt_AS_LONG(pyValue);
568 break; 569 break;
569 case quantizeStep: 570 case o::quantizeStep:
570 od.quantizeStep = (float) PyFloat_AS_DOUBLE(pyValue); 571 od.quantizeStep = (float) PyFloat_AS_DOUBLE(pyValue);
571 break; 572 break;
572 case sampleType: 573 case o::sampleType:
573 od.sampleType = (OutputDescriptor::SampleType) sampleKeys[PyString_AsString(pyValue)]; 574 od.sampleType = (OutputDescriptor::SampleType) sampleKeys[PyString_AsString(pyValue)];
574 break; 575 break;
575 case sampleRate: 576 case o::sampleRate:
576 od.sampleRate = (float) PyFloat_AS_DOUBLE(pyValue); 577 od.sampleRate = (float) PyFloat_AS_DOUBLE(pyValue);
577 // od.sampleRate = m_inputSampleRate / m_stepSize; 578 // od.sampleRate = m_inputSampleRate / m_stepSize;
578 cerr << od.sampleRate << endl; 579 cerr << od.sampleRate << endl;
579 break; 580 break;
581 case o::hasDuration:
582 od.hasDuration = (bool)PyInt_AS_LONG(pyValue);
583 break;
580 default : 584 default :
581 cerr << "Invalid key in VAMP OutputDescriptor: " << PyString_AsString(pyKey) << endl; 585 cerr << "Invalid key in Vamp OutputDescriptor: " << PyString_AsString(pyKey) << endl;
582 } 586 }
583 } // while dict 587 } // while dict
584 list.push_back(od); 588 list.push_back(od);
585 } // for list 589 } // for list
586 Py_CLEAR(pyList); 590 Py_CLEAR(pyList);
617 PyObject *pyDict, *pyKey, *pyValue; 621 PyObject *pyDict, *pyKey, *pyValue;
618 622
619 //Parse Output List 623 //Parse Output List
620 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pyList); ++i) { 624 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pyList); ++i) {
621 625
622 //Get i-th VAMP output descriptor (Borrowed Reference) 626 //Get i-th Vamp output descriptor (Borrowed Reference)
623 pyDict = PyList_GET_ITEM(pyList,i); 627 pyDict = PyList_GET_ITEM(pyList,i);
624 628
625 //We only care about dictionaries holding output descriptors 629 //We only care about dictionaries holding output descriptors
626 if ( !PyDict_Check(pyDict) ) continue; 630 if ( !PyDict_Check(pyDict) ) continue;
627 631
631 //Python Sequence Iterator 635 //Python Sequence Iterator
632 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue)) 636 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue))
633 { 637 {
634 switch (parmKeys[PyString_AsString(pyKey)]) 638 switch (parmKeys[PyString_AsString(pyKey)])
635 { 639 {
636 case not_found : 640 case p::not_found :
637 cerr << "Unknown key in VAMP OutputDescriptor: " << PyString_AsString(pyKey) << endl; 641 cerr << "Unknown key in Vamp OutputDescriptor: " << PyString_AsString(pyKey) << endl;
638 break; 642 break;
639 case p::identifier: 643 case p::identifier:
640 pd.identifier = PyString_AsString(pyValue); 644 pd.identifier = PyString_AsString(pyValue);
641 break; 645 break;
642 case p::name: 646 case p::name:
659 break; 663 break;
660 case p::isQuantized: 664 case p::isQuantized:
661 pd.isQuantized = (bool) PyInt_AS_LONG(pyValue); 665 pd.isQuantized = (bool) PyInt_AS_LONG(pyValue);
662 break; 666 break;
663 default : 667 default :
664 cerr << "Invalid key in VAMP OutputDescriptor: " << PyString_AsString(pyKey) << endl; 668 cerr << "Invalid key in Vamp OutputDescriptor: " << PyString_AsString(pyKey) << endl;
665 } 669 }
666 } // while dict 670 } // while dict
667 list.push_back(pd); 671 list.push_back(pd);
668 } // for list 672 } // for list
669 Py_CLEAR(pyList); 673 Py_CLEAR(pyList);
890 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue)) 894 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue))
891 { 895 {
892 emptyFeature = false; 896 emptyFeature = false;
893 switch (ffKeys[PyString_AsString(pyKey)]) 897 switch (ffKeys[PyString_AsString(pyKey)])
894 { 898 {
895 case not_found : 899 case unknown:
896 cerr << "Unknown key in VAMP FeatureSet: " 900 cerr << "Unknown key in Vamp FeatureSet: "
897 << PyString_AsString(pyKey) << endl; 901 << PyString_AsString(pyKey) << endl;
898 break; 902 break;
899 case hasTimestamp: 903 case hasTimestamp:
900 feature.hasTimestamp = (bool) PyInt_AS_LONG(pyValue); 904 feature.hasTimestamp = (bool) PyInt_AS_LONG(pyValue);
901 break; 905 break;
908 cerr << "Timestamp: " 912 cerr << "Timestamp: "
909 << (long)PyLong_AsLong(pyValue) << ", ->" 913 << (long)PyLong_AsLong(pyValue) << ", ->"
910 << feature.timestamp.toString() << endl; 914 << feature.timestamp.toString() << endl;
911 #endif 915 #endif
912 break; 916 break;
917 case hasDuration:
918 feature.hasDuration = (bool) PyInt_AS_LONG(pyValue);
919 break;
920 case duration:
921 feature.duration =
922 Vamp::RealTime::frame2RealTime(
923 PyLong_AsLong(pyValue),
924 (unsigned int) m_inputSampleRate );
925 #ifdef _DEBUG
926 cerr << "Duration: "
927 << (long)PyLong_AsLong(pyValue) << ", ->"
928 << feature.duration.toString() << endl;
929 #endif
930 break;
913 case values: 931 case values:
914 feature.values = PyList_As_FloatVector(pyValue); 932 feature.values = PyList_As_FloatVector(pyValue);
915 break; 933 break;
916 case label: 934 case label:
917 feature.label = PyString_AsString(pyValue); 935 feature.label = PyString_AsString(pyValue);
918 break; 936 break;
919 default : 937 default :
920 cerr << "Invalid key in VAMP FeatureSet: " 938 cerr << "Invalid key in Vamp FeatureSet: "
921 << PyString_AsString(pyKey) << endl; 939 << PyString_AsString(pyKey) << endl;
922 } // switch 940 } // switch
923 941
924 } // while 942 } // while
925 if (emptyFeature) cerr << "Warning: This feature is empty or badly formatted." << endl; 943 if (emptyFeature) cerr << "Warning: This feature is empty or badly formatted." << endl;
992 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue)) 1010 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyValue))
993 { 1011 {
994 emptyFeature = false; 1012 emptyFeature = false;
995 switch (ffKeys[PyString_AsString(pyKey)]) 1013 switch (ffKeys[PyString_AsString(pyKey)])
996 { 1014 {
997 case not_found : 1015 case unknown :
998 cerr << "Unknown key in VAMP FeatureSet: " 1016 cerr << "Unknown key in Vamp FeatureSet: "
999 << PyString_AsString(pyKey) << endl; 1017 << PyString_AsString(pyKey) << endl;
1000 break; 1018 break;
1001 case hasTimestamp: 1019 case hasTimestamp:
1002 feature.hasTimestamp = (bool) PyInt_AS_LONG(pyValue); 1020 feature.hasTimestamp = (bool) PyInt_AS_LONG(pyValue);
1003 break; 1021 break;
1010 cerr << "Timestamp: " 1028 cerr << "Timestamp: "
1011 << (long)PyLong_AsLong(pyValue) << ", ->" 1029 << (long)PyLong_AsLong(pyValue) << ", ->"
1012 << feature.timestamp.toString() << endl; 1030 << feature.timestamp.toString() << endl;
1013 #endif 1031 #endif
1014 break; 1032 break;
1033 case hasDuration:
1034 feature.hasDuration = (bool) PyInt_AS_LONG(pyValue);
1035 break;
1036 case duration:
1037 feature.duration =
1038 Vamp::RealTime::frame2RealTime(
1039 PyLong_AsLong(pyValue),
1040 (unsigned int) m_inputSampleRate );
1041 #ifdef _DEBUG
1042 cerr << "Duration: "
1043 << (long)PyLong_AsLong(pyValue) << ", ->"
1044 << feature.duration.toString() << endl;
1045 #endif
1046 break;
1015 case values: 1047 case values:
1016 feature.values = PyList_As_FloatVector(pyValue); 1048 feature.values = PyList_As_FloatVector(pyValue);
1017 break; 1049 break;
1018 case label: 1050 case label:
1019 feature.label = PyString_AsString(pyValue); 1051 feature.label = PyString_AsString(pyValue);
1032 PyPlugin::initMaps() const 1064 PyPlugin::initMaps() const
1033 { 1065 {
1034 1066
1035 if (isMapInitialised) return true; 1067 if (isMapInitialised) return true;
1036 1068
1037 outKeys["identifier"] = identifier; 1069 outKeys["identifier"] = o::identifier;
1038 outKeys["name"] = name; 1070 outKeys["name"] = o::name;
1039 outKeys["description"] = description; 1071 outKeys["description"] = o::description;
1040 outKeys["unit"] = unit; 1072 outKeys["unit"] = o::unit;
1041 outKeys["hasFixedBinCount"] = hasFixedBinCount; 1073 outKeys["hasFixedBinCount"] = o::hasFixedBinCount;
1042 outKeys["binCount"] = binCount; 1074 outKeys["binCount"] = o::binCount;
1043 outKeys["binNames"] = binNames; 1075 outKeys["binNames"] = o::binNames;
1044 outKeys["hasKnownExtents"] = hasKnownExtents; 1076 outKeys["hasKnownExtents"] = o::hasKnownExtents;
1045 outKeys["minValue"] = minValue; 1077 outKeys["minValue"] = o::minValue;
1046 outKeys["maxValue"] = maxValue; 1078 outKeys["maxValue"] = o::maxValue;
1047 outKeys["isQuantized"] = isQuantized; 1079 outKeys["isQuantized"] = o::isQuantized;
1048 outKeys["quantizeStep"] = quantizeStep; 1080 outKeys["quantizeStep"] = o::quantizeStep;
1049 outKeys["sampleType"] = sampleType; 1081 outKeys["sampleType"] = o::sampleType;
1050 outKeys["sampleRate"] = sampleRate; 1082 outKeys["sampleRate"] = o::sampleRate;
1083 outKeys["hasDuration"] = o::hasDuration;
1051 1084
1052 sampleKeys["OneSamplePerStep"] = OneSamplePerStep; 1085 sampleKeys["OneSamplePerStep"] = OneSamplePerStep;
1053 sampleKeys["FixedSampleRate"] = FixedSampleRate; 1086 sampleKeys["FixedSampleRate"] = FixedSampleRate;
1054 sampleKeys["VariableSampleRate"] = VariableSampleRate; 1087 sampleKeys["VariableSampleRate"] = VariableSampleRate;
1055 1088
1056 ffKeys["hasTimestamp"] = hasTimestamp; 1089 ffKeys["hasTimestamp"] = hasTimestamp;
1057 ffKeys["timeStamp"] = timeStamp; 1090 ffKeys["timeStamp"] = timeStamp;
1091 ffKeys["hasDuration"] = hasDuration;
1092 ffKeys["duration"] = duration;
1058 ffKeys["values"] = values; 1093 ffKeys["values"] = values;
1059 ffKeys["label"] = label; 1094 ffKeys["label"] = label;
1060 1095
1061 parmKeys["identifier"] = p::identifier; 1096 parmKeys["identifier"] = p::identifier;
1062 parmKeys["name"] = p::name; 1097 parmKeys["name"] = p::name;