comparison Chordino.cpp @ 86:e5c16976513d consonance

implemented note output for estimated chords
author matthiasm
date Sun, 28 Nov 2010 23:10:57 +0900
parents 4270f3039ab0
children 7af5312e66f8
comparison
equal deleted inserted replaced
85:ccc0d4b3f867 86:e5c16976513d
28 #include <algorithm> 28 #include <algorithm>
29 29
30 const bool debug_on = false; 30 const bool debug_on = false;
31 31
32 Chordino::Chordino(float inputSampleRate) : 32 Chordino::Chordino(float inputSampleRate) :
33 NNLSBase(inputSampleRate) 33 NNLSBase(inputSampleRate),
34 m_chorddict(0),
35 m_chordnotes(0),
36 m_chordnames(0)
34 { 37 {
35 if (debug_on) cerr << "--> Chordino" << endl; 38 if (debug_on) cerr << "--> Chordino" << endl;
39 // get the *chord* dictionary from file (if the file exists)
40 m_chordnames = chordDictionary(&m_chorddict, &m_chordnotes);
41
36 } 42 }
37 43
38 Chordino::~Chordino() 44 Chordino::~Chordino()
39 { 45 {
40 if (debug_on) cerr << "--> ~Chordino" << endl; 46 if (debug_on) cerr << "--> ~Chordino" << endl;
179 d7.sampleType = OutputDescriptor::VariableSampleRate; 185 d7.sampleType = OutputDescriptor::VariableSampleRate;
180 d7.hasDuration = false; 186 d7.hasDuration = false;
181 d7.sampleRate = (m_stepSize == 0) ? m_inputSampleRate/2048 : m_inputSampleRate/m_stepSize; 187 d7.sampleRate = (m_stepSize == 0) ? m_inputSampleRate/2048 : m_inputSampleRate/m_stepSize;
182 list.push_back(d7); 188 list.push_back(d7);
183 m_outputChords = index++; 189 m_outputChords = index++;
190
191 OutputDescriptor chordnotes;
192 chordnotes.identifier = "chordnotes";
193 chordnotes.name = "Note Representation of Chord Estimate";
194 chordnotes.description = "A simple represenation of the estimated chord with bass note (if applicable) and chord notes.";
195 chordnotes.unit = "MIDI units";
196 chordnotes.hasFixedBinCount = true;
197 chordnotes.binCount = 1;
198 chordnotes.hasKnownExtents = true;
199 chordnotes.minValue = 0;
200 chordnotes.maxValue = 127;
201 chordnotes.isQuantized = true;
202 chordnotes.quantizeStep = 1;
203 chordnotes.sampleType = OutputDescriptor::VariableSampleRate;
204 chordnotes.hasDuration = true;
205 chordnotes.sampleRate = (m_stepSize == 0) ? m_inputSampleRate/2048 : m_inputSampleRate/m_stepSize;
206 list.push_back(chordnotes);
207 m_outputChordnotes = index++;
184 208
185 OutputDescriptor d8; 209 OutputDescriptor d8;
186 d8.identifier = "harmonicchange"; 210 d8.identifier = "harmonicchange";
187 d8.name = "Harmonic Change Value"; 211 d8.name = "Harmonic Change Value";
188 d8.description = "An indication of the likelihood of harmonic change. Depends on the chord dictionary. Calculation is different depending on whether the Viterbi algorithm is used for chord estimation, or the simple chord estimate."; 212 d8.description = "An indication of the likelihood of harmonic change. Depends on the chord dictionary. Calculation is different depending on whether the Viterbi algorithm is used for chord estimation, or the simple chord estimate.";
486 510
487 count++; 511 count++;
488 } 512 }
489 cerr << "done." << endl; 513 cerr << "done." << endl;
490 514
515 vector<Feature> oldnotes;
491 516
492 // bool m_useHMM = true; // this will go into the chordino header file. 517 // bool m_useHMM = true; // this will go into the chordino header file.
493 if (m_useHMM == 1.0) { 518 if (m_useHMM == 1.0) {
494 cerr << "[Chordino Plugin] HMM Chord Estimation ... "; 519 cerr << "[Chordino Plugin] HMM Chord Estimation ... ";
495 int oldchord = nChord-1; 520 int oldchord = nChord-1;
518 543
519 chordchange[0] = 0; 544 chordchange[0] = 0;
520 for (int iFrame = 1; iFrame < chordpath.size(); ++iFrame) { 545 for (int iFrame = 1; iFrame < chordpath.size(); ++iFrame) {
521 // cerr << chordpath[iFrame] << endl; 546 // cerr << chordpath[iFrame] << endl;
522 if (chordpath[iFrame] != oldchord ) { 547 if (chordpath[iFrame] != oldchord ) {
548 // chord
523 Feature chord_feature; // chord estimate 549 Feature chord_feature; // chord estimate
524 chord_feature.hasTimestamp = true; 550 chord_feature.hasTimestamp = true;
525 chord_feature.timestamp = timestamps[iFrame]; 551 chord_feature.timestamp = timestamps[iFrame];
526 chord_feature.label = m_chordnames[chordpath[iFrame]]; 552 chord_feature.label = m_chordnames[chordpath[iFrame]];
527 fsOut[m_outputChords].push_back(chord_feature); 553 fsOut[m_outputChords].push_back(chord_feature);
528 oldchord = chordpath[iFrame]; 554 oldchord = chordpath[iFrame];
555 // chord notes
556 for (int iNote = 0; iNote < oldnotes.size(); ++iNote) { // finish duration of old chord
557 oldnotes[iNote].duration = oldnotes[iNote].duration + timestamps[iFrame];
558 fsOut[m_outputChordnotes].push_back(oldnotes[iNote]);
559 }
560 oldnotes.clear();
561 for (int iNote = 0; iNote < m_chordnotes[chordpath[iFrame]].size(); ++iNote) { // prepare notes of current chord
562 Feature chordnote_feature;
563 chordnote_feature.hasTimestamp = true;
564 chordnote_feature.timestamp = timestamps[iFrame];
565 chordnote_feature.values.push_back(m_chordnotes[chordpath[iFrame]][iNote]);
566 chordnote_feature.hasDuration = true;
567 chordnote_feature.duration = -timestamps[iFrame]; // this will be corrected at the next chord
568 oldnotes.push_back(chordnote_feature);
569 }
529 } 570 }
530 /* calculating simple chord change prob */ 571 /* calculating simple chord change prob */
531 for (int iChord = 0; iChord < nChord; iChord++) { 572 for (int iChord = 0; iChord < nChord; iChord++) {
532 chordchange[iFrame-1] += delta[(iFrame-1)*nChord + iChord] * log(delta[(iFrame-1)*nChord + iChord]/delta[iFrame*nChord + iChord]); 573 chordchange[iFrame-1] += delta[(iFrame-1)*nChord + iChord] * log(delta[(iFrame-1)*nChord + iChord]/delta[iFrame*nChord + iChord]);
533 } 574 }
676 // cerr << chordchange[count] << endl; 717 // cerr << chordchange[count] << endl;
677 if (oldChord != maxChord) { 718 if (oldChord != maxChord) {
678 oldChord = maxChord; 719 oldChord = maxChord;
679 chord_feature.label = m_chordnames[maxChordIndex]; 720 chord_feature.label = m_chordnames[maxChordIndex];
680 fsOut[m_outputChords].push_back(chord_feature); 721 fsOut[m_outputChords].push_back(chord_feature);
722 for (int iNote = 0; iNote < oldnotes.size(); ++iNote) { // finish duration of old chord
723 oldnotes[iNote].duration = oldnotes[iNote].duration + chord_feature.timestamp;
724 fsOut[m_outputChordnotes].push_back(oldnotes[iNote]);
725 }
726 oldnotes.clear();
727 for (int iNote = 0; iNote < m_chordnotes[maxChordIndex].size(); ++iNote) { // prepare notes of current chord
728 Feature chordnote_feature;
729 chordnote_feature.hasTimestamp = true;
730 chordnote_feature.timestamp = chord_feature.timestamp;
731 chordnote_feature.values.push_back(m_chordnotes[maxChordIndex][iNote]);
732 chordnote_feature.hasDuration = true;
733 chordnote_feature.duration = -chord_feature.timestamp; // this will be corrected at the next chord
734 oldnotes.push_back(chordnote_feature);
735 }
681 } 736 }
682 count++; 737 count++;
683 } 738 }
684 } 739 }
685 Feature chord_feature; // last chord estimate 740 Feature chord_feature; // last chord estimate
686 chord_feature.hasTimestamp = true; 741 chord_feature.hasTimestamp = true;
687 chord_feature.timestamp = timestamps[timestamps.size()-1]; 742 chord_feature.timestamp = timestamps[timestamps.size()-1];
688 chord_feature.label = "N"; 743 chord_feature.label = "N";
689 fsOut[m_outputChords].push_back(chord_feature); 744 fsOut[m_outputChords].push_back(chord_feature);
745
746 for (int iNote = 0; iNote < oldnotes.size(); ++iNote) { // finish duration of old chord
747 oldnotes[iNote].duration = oldnotes[iNote].duration + timestamps[timestamps.size()-1];
748 fsOut[m_outputChordnotes].push_back(oldnotes[iNote]);
749 }
750
690 cerr << "done." << endl; 751 cerr << "done." << endl;
691 752
692 for (int iFrame = 0; iFrame < nFrame; iFrame++) { 753 for (int iFrame = 0; iFrame < nFrame; iFrame++) {
693 Feature chordchange_feature; 754 Feature chordchange_feature;
694 chordchange_feature.hasTimestamp = true; 755 chordchange_feature.hasTimestamp = true;