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