Mercurial > hg > nnls-chroma
comparison chromamethods.cpp @ 90:b095d83585c9 matthiasm-plugin
internal chord dictionary loads if external not given
author | Matthias Mauch <mail@matthiasmauch.net> |
---|---|
date | Thu, 02 Dec 2010 00:19:01 +0900 |
parents | 7af5312e66f8 |
children | b56dde3417d4 f60702c928e2 |
comparison
equal
deleted
inserted
replaced
89:7af5312e66f8 | 90:b095d83585c9 |
---|---|
275 path.push_back(envPath.substr(index)); | 275 path.push_back(envPath.substr(index)); |
276 | 276 |
277 return path; | 277 return path; |
278 } | 278 } |
279 | 279 |
280 | |
281 | |
282 static vector<string> staticChordnames() { | |
283 vector<string> chordnames; | |
284 chordnames.push_back("");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0 | |
285 chordnames.push_back("");// =0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0 | |
286 chordnames.push_back("m");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0 | |
287 chordnames.push_back("m");//=0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0 | |
288 chordnames.push_back("dim7");//=0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0 | |
289 chordnames.push_back("dim7");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0 | |
290 chordnames.push_back("6");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0 | |
291 chordnames.push_back("7");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0 | |
292 chordnames.push_back("maj7");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1 | |
293 chordnames.push_back("m7");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0 | |
294 chordnames.push_back("m6");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0 | |
295 chordnames.push_back("");//=0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0 | |
296 chordnames.push_back("");//=0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0 | |
297 chordnames.push_back("");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0 | |
298 chordnames.push_back("aug");//=1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 | |
299 chordnames.push_back("");//=0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0 | |
300 chordnames.push_back("");//=0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0 | |
301 chordnames.push_back("7");//=0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0 | |
302 return chordnames; | |
303 } | |
304 | |
305 static vector<float> staticChordvalues() { | |
306 vector<float> chordvalues; | |
307 float chordvaluearray[] = {1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0, | |
308 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0, | |
309 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0, | |
310 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0, | |
311 0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0, | |
312 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0, | |
313 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0, | |
314 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0, | |
315 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1, | |
316 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, | |
317 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0, | |
318 0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0, | |
319 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0, | |
320 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0, | |
321 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0, | |
322 0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0, | |
323 0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0, | |
324 0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0}; | |
325 for (int iChord = 0; iChord < 18; ++iChord) { | |
326 for (int iNote = 0; iNote < 24; iNote++) { | |
327 chordvalues.push_back(chordvaluearray[24*iChord+iNote]); | |
328 } | |
329 } | |
330 return chordvalues; | |
331 } | |
332 | |
280 vector<string> chordDictionary(vector<float> *mchorddict, vector<vector<int> > *m_chordnotes, float boostN) { | 333 vector<string> chordDictionary(vector<float> *mchorddict, vector<vector<int> > *m_chordnotes, float boostN) { |
281 | 334 |
282 typedef tokenizer<char_separator<char> > Tok; | 335 typedef tokenizer<char_separator<char> > Tok; |
283 char_separator<char> sep(",; ","="); | 336 char_separator<char> sep(",; ","="); |
284 | 337 |
285 string chordDictBase("chord.dict"); | 338 string chordDictBase("chord.dict"); |
286 string chordDictFilename; | 339 string chordDictFilename; |
287 | 340 |
288 vector<string> ppath = getPluginPath(); | 341 vector<string> ppath = getPluginPath(); |
342 | |
343 bool hasExternalDictinoary = true; | |
344 | |
289 for (int i = 0; i < ppath.size(); ++i) { | 345 for (int i = 0; i < ppath.size(); ++i) { |
290 chordDictFilename = ppath[i] + "/" + chordDictBase; | 346 chordDictFilename = ppath[i] + "/" + chordDictBase; |
291 cerr << "Looking for chord.dict in " << chordDictFilename << "..." ; | 347 cerr << "Looking for chord.dict in " << chordDictFilename << "..." ; |
292 fstream fin; | 348 fstream fin; |
293 fin.open(chordDictFilename.c_str(),ios::in); | 349 fin.open(chordDictFilename.c_str(),ios::in); |
296 fin.close(); | 352 fin.close(); |
297 cerr << " success." << endl; | 353 cerr << " success." << endl; |
298 break; | 354 break; |
299 } else { | 355 } else { |
300 if (i < ppath.size()-1) cerr << " (not found yet) ..." << endl; | 356 if (i < ppath.size()-1) cerr << " (not found yet) ..." << endl; |
301 else cerr << "* ERROR: failed to find chord dictionary." << endl; | 357 else { |
358 cerr << "* ERROR: failed to find chord dictionary." << endl; | |
359 hasExternalDictinoary = false; | |
360 } | |
302 } | 361 } |
303 } | 362 } |
304 | 363 |
305 iostreams::stream<iostreams::file_source> chordDictFile(chordDictFilename); | 364 iostreams::stream<iostreams::file_source> chordDictFile(chordDictFilename); |
306 string line; | 365 string line; |
307 // int iElement = 0; | 366 // int iElement = 0; |
308 int nChord = 0; | 367 int nChord = 0; |
309 | 368 |
369 vector<string> tempChordNames = staticChordnames(); | |
370 vector<float> tempChordDict = staticChordvalues();; | |
310 vector<string> loadedChordNames; | 371 vector<string> loadedChordNames; |
311 vector<float> loadedChordDict; | 372 vector<float> loadedChordDict; |
312 if (chordDictFile.is_open()) { | 373 if (hasExternalDictinoary && chordDictFile.is_open()) { |
374 cerr << "-----------------> " << tempChordNames.size() << endl; | |
375 tempChordDict.clear(); | |
376 tempChordNames.clear(); | |
313 while (std::getline(chordDictFile, line)) { // loop over lines in chord.dict file | 377 while (std::getline(chordDictFile, line)) { // loop over lines in chord.dict file |
314 // first, get the chord definition | 378 // first, get the chord definition |
315 string chordType; | 379 string chordType; |
316 vector<float> tempPCVector; | 380 vector<float> tempPCVector; |
317 // cerr << line << endl; | 381 // cerr << line << endl; |
318 if (!line.empty() && line.substr(0,1) != "#") { | 382 if (!line.empty() && line.substr(0,1) != "#") { |
319 Tok tok(line, sep); | 383 Tok tok(line, sep); |
320 for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter) { // loop over line elements | 384 for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter) { // loop over line elements |
321 string tempString = *tok_iter; | 385 string tempString = *tok_iter; |
322 // cerr << tempString << endl; | 386 // cerr << tempString << endl; |
323 if (tok_iter == tok.begin()) { // either the chord name or a colon | 387 if (tok_iter == tok.begin()) { // either the chord name or a colon |
324 if (tempString == "=") { | 388 if (tempString == "=") { |
325 chordType = ""; | 389 chordType = ""; |
326 } else { | 390 } else { |
327 chordType = tempString; | 391 chordType = tempString; |
328 tok_iter++; // is this cheating ? :) | 392 tok_iter++; |
329 } | 393 } |
330 } else { | 394 } else { |
331 tempPCVector.push_back(lexical_cast<float>(*tok_iter)); | 395 tempChordDict.push_back(lexical_cast<float>(*tok_iter)); |
332 } | 396 } |
397 } | |
398 tempChordNames.push_back(chordType); | |
399 } | |
400 } | |
401 } | |
402 | |
403 | |
404 | |
405 for (int iType = 0; iType < tempChordNames.size(); ++iType) { | |
406 // now make all 12 chords of every type | |
407 for (unsigned iSemitone = 0; iSemitone < 12; iSemitone++) { | |
408 vector<int> tempchordnotes; | |
409 // add bass slash notation | |
410 string slashNotation = ""; | |
411 for (unsigned kSemitone = 1; kSemitone < 12; kSemitone++) { | |
412 if (tempChordDict[24*iType+(kSemitone) % 12] > 0.99) { | |
413 slashNotation = bassnames[iSemitone][kSemitone]; | |
333 } | 414 } |
334 | 415 } |
335 // now make all 12 chords of every type | 416 if (slashNotation=="") tempchordnotes.push_back(MIDI_basenote + (iSemitone+12) % 12); |
336 for (unsigned iSemitone = 0; iSemitone < 12; iSemitone++) { | 417 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) { // bass pitch classes |
337 vector<int> tempchordnotes; | 418 // cerr << ((kSemitone - iSemitone + 12) % 12) << endl; |
338 // add bass slash notation | 419 float bassValue = 0; |
339 string slashNotation = ""; | 420 if (tempChordDict[24*iType+(kSemitone - iSemitone + 12) % 12]==1) { |
340 for (unsigned kSemitone = 1; kSemitone < 12; kSemitone++) { | 421 bassValue = 1; |
341 if (tempPCVector[(kSemitone) % 12] > 0.99) { | 422 tempchordnotes.push_back(MIDI_basenote + (kSemitone+12) % 12); |
342 slashNotation = bassnames[iSemitone][kSemitone]; | 423 } else { |
343 } | 424 if (tempChordDict[24*iType+((kSemitone - iSemitone + 12) % 12) + 12] == 1) bassValue = 0.5; |
344 } | |
345 if (slashNotation=="") tempchordnotes.push_back(MIDI_basenote + (iSemitone+12) % 12); | |
346 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) { // bass pitch classes | |
347 // cerr << ((kSemitone - iSemitone + 12) % 12) << endl; | |
348 float bassValue = 0; | |
349 if (tempPCVector[(kSemitone - iSemitone + 12) % 12]==1) { | |
350 bassValue = 1; | |
351 tempchordnotes.push_back(MIDI_basenote + (kSemitone+12) % 12); | |
352 } else { | |
353 if (tempPCVector[((kSemitone - iSemitone + 12) % 12) + 12] == 1) bassValue = 0.5; | |
354 } | |
355 loadedChordDict.push_back(bassValue); | |
356 } | |
357 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) { // chord pitch classes | |
358 loadedChordDict.push_back(tempPCVector[((kSemitone - iSemitone + 12) % 12) + 12]); | |
359 if (tempPCVector[((kSemitone - iSemitone + 12) % 12) + 12] > 0) tempchordnotes.push_back(MIDI_basenote + (kSemitone+12+6) % 12 - 6 + 24); | |
360 } | |
361 ostringstream os; | |
362 if (slashNotation.empty()) { | |
363 os << notenames[12+iSemitone] << chordType; | |
364 } else { | |
365 os << notenames[12+iSemitone] << chordType << "/" << slashNotation; | |
366 } | |
367 // cerr << os.str() << endl; | |
368 loadedChordNames.push_back(os.str()); | |
369 | |
370 m_chordnotes->push_back(tempchordnotes); | |
371 // for (int iNote = 0; iNote < tempchordnotes.size(); ++iNote) { | |
372 // cerr << tempchordnotes[iNote] << " "; | |
373 // } | |
374 // cerr << endl; | |
375 } | 425 } |
376 } | 426 loadedChordDict.push_back(bassValue); |
377 } | 427 } |
378 // N type | 428 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) { // chord pitch classes |
379 loadedChordNames.push_back("N"); | 429 loadedChordDict.push_back(tempChordDict[24*iType+((kSemitone - iSemitone + 12) % 12) + 12]); |
380 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) loadedChordDict.push_back(0.5); | 430 if (tempChordDict[24*iType+((kSemitone - iSemitone + 12) % 12) + 12] > 0) tempchordnotes.push_back(MIDI_basenote + (kSemitone+12+6) % 12 - 6 + 24); |
381 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) loadedChordDict.push_back(1.0); | 431 } |
382 vector<int> tempchordvector; | 432 ostringstream os; |
383 m_chordnotes->push_back(tempchordvector); | 433 if (slashNotation.empty()) { |
384 float exponent = 2.0; | 434 os << notenames[12+iSemitone] << tempChordNames[iType]; |
385 // float m_boostN = 1.1; | |
386 // cerr << " N BOOST : " << boostN << endl << endl; | |
387 for (int iChord = 0; iChord < loadedChordDict.size()/24; iChord++) { | |
388 float sum = 0; | |
389 float stand = 0; | |
390 for (int iST = 0; iST < 24; ++iST) { | |
391 sum += loadedChordDict[24 * iChord + iST]; | |
392 } | |
393 for (int iST = 0; iST < 24; ++iST) { | |
394 // loadedChordDict[24 * iChord + iST] -= sum/24; | |
395 stand += pow(abs(loadedChordDict[24 * iChord + iST]),exponent)/24; | |
396 } | |
397 if (iChord < loadedChordDict.size()/24 - 1) { | |
398 stand = pow(stand,(float)1.0/exponent); | |
399 } else { | 435 } else { |
400 stand = pow(stand,(float)1.0/exponent) / boostN; | 436 os << notenames[12+iSemitone] << tempChordNames[iType] << "/" << slashNotation; |
401 } | 437 } |
402 for (int iST = 0; iST < 24; ++iST) { | 438 // cerr << os.str() << endl; |
403 loadedChordDict[24 * iChord + iST] /= stand; | 439 loadedChordNames.push_back(os.str()); |
404 } | |
405 | 440 |
441 m_chordnotes->push_back(tempchordnotes); | |
442 // for (int iNote = 0; iNote < tempchordnotes.size(); ++iNote) { | |
443 // cerr << tempchordnotes[iNote] << " "; | |
444 // } | |
445 // cerr << endl; | |
446 } | |
447 } | |
448 | |
449 | |
450 // N type | |
451 loadedChordNames.push_back("N"); | |
452 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) loadedChordDict.push_back(0.5); | |
453 for (unsigned kSemitone = 0; kSemitone < 12; kSemitone++) loadedChordDict.push_back(1.0); | |
454 vector<int> tempchordvector; | |
455 m_chordnotes->push_back(tempchordvector); | |
456 float exponent = 2.0; | |
457 // float m_boostN = 1.1; | |
458 // cerr << " N BOOST : " << boostN << endl << endl; | |
459 for (int iChord = 0; iChord < loadedChordDict.size()/24; iChord++) { | |
460 float sum = 0; | |
461 float stand = 0; | |
462 for (int iST = 0; iST < 24; ++iST) { | |
463 sum += loadedChordDict[24 * iChord + iST]; | |
464 } | |
465 for (int iST = 0; iST < 24; ++iST) { | |
466 // loadedChordDict[24 * iChord + iST] -= sum/24; | |
467 stand += pow(abs(loadedChordDict[24 * iChord + iST]),exponent)/24; | |
468 } | |
469 if (iChord < loadedChordDict.size()/24 - 1) { | |
470 stand = pow(stand,(float)1.0/exponent); | |
471 } else { | |
472 stand = pow(stand,(float)1.0/exponent) / boostN; | |
473 } | |
474 for (int iST = 0; iST < 24; ++iST) { | |
475 loadedChordDict[24 * iChord + iST] /= stand; | |
406 } | 476 } |
407 | 477 |
408 | 478 } |
409 | 479 |
410 nChord = 0; | 480 |
411 for (int i = 0; i < loadedChordNames.size(); i++) { | 481 |
412 nChord++; | 482 nChord = 0; |
413 } | 483 for (int i = 0; i < loadedChordNames.size(); i++) { |
414 chordDictFile.close(); | 484 nChord++; |
415 | 485 } |
416 | 486 chordDictFile.close(); |
417 // mchorddict = new float[nChord*24]; | 487 |
418 for (int i = 0; i < nChord*24; i++) { | 488 |
419 mchorddict->push_back(loadedChordDict[i]); | 489 // mchorddict = new float[nChord*24]; |
420 } | 490 for (int i = 0; i < nChord*24; i++) { |
421 | 491 mchorddict->push_back(loadedChordDict[i]); |
422 } else {// use default from chorddict.cpp | 492 } |
423 // mchorddict = new float[nChorddict]; | 493 |
424 for (int i = 0; i < nChorddict; i++) { | |
425 mchorddict->push_back(chorddict[i]); | |
426 } | |
427 | |
428 nChord = nChorddict/24; | |
429 // mchordnames = new string[nChorddict/24]; | |
430 char buffer1 [50]; | |
431 for (int i = 0; i < nChorddict/24; i++) { | |
432 if (i < nChorddict/24 - 1) { | |
433 sprintf(buffer1, "%s%s", notenames[i % 12 + 12], chordtypes[i]); | |
434 } else { | |
435 sprintf(buffer1, "N"); | |
436 } | |
437 ostringstream os; | |
438 os << buffer1; | |
439 loadedChordNames.push_back(os.str()); | |
440 | |
441 } | |
442 | |
443 } | |
444 // cerr << "before leaving" << chordnames[1] << endl; | 494 // cerr << "before leaving" << chordnames[1] << endl; |
445 return loadedChordNames; | 495 return loadedChordNames; |
446 } | 496 } |
497 | |
498 |