Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

chordengine.cpp

Go to the documentation of this file.
00001 //
00002 // ChordEngine class to calculate chords
00003 //
00004 
00005 // Copyright (c) 2001 Camilo Mesias
00006 // camilo@mesias.co.uk
00007 //
00008 // derived from JavaScript code by Jim Cranwell, used with permission
00009 //
00010 // This program is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public License
00012 // as published by the Free Software Foundation; either version 2
00013 // of the License, or (at your option) any later version.
00014 //
00015 // This program is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU General Public License
00021 // along with this program; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 
00025 #include <stdio.h>
00026 
00027 #include <string.h>
00028 
00029 #include "chordengine.h"
00030 
00031 ChordEngine::ChordEngine(){
00032 
00033   string[0] = OPEN;
00034   string[1] = OPEN;
00035   string[2] = OPEN;
00036   string[3] = OPEN;
00037   string[4] = OPEN;
00038   string[5] = OPEN;
00039 
00040   base_note = 0;
00041   chord_type = 0;
00042   fret_pos = OPEN;
00043   span_size = 1;
00044   variation = 7;
00045   tuning = 0;
00046 
00047   js_tunit(tuning);
00048   js_whatchord(chord_type);
00049   js_vboy(variation);
00050 
00051   label_text[0] = 0;
00052 }
00053 
00054 int ChordEngine::finger(int f){
00055     return string[f];
00056 }
00057 #define BREAK (401)
00058 void ChordEngine::calculate(){
00059 
00060   sprintf(label_text, "%s %s %s%s",
00061           notes[base_note],
00062           (chord_type)?keys[chord_type]:"",
00063           (fret_pos==OPEN)?"":"fret-",
00064           (fret_pos)?frets[fret_pos]:"");
00065 
00066   string[0] =
00067     string[1] =
00068     string[2] =
00069     string[3] =
00070     string[4] =
00071     string[5] = MUTED;
00072 
00073   for (int in=0;in<6;in++){
00074     notename[in]=0;
00075   }
00076 
00077   js_tunit(tuning);
00078   //  js_MMM[0] = 4;
00079   //js_MMM[1] = 9;
00080   //js_MMM[2] = 2;
00081   //js_MMM[3] = 7;
00082   //js_MMM[4] = 11;
00083   //js_MMM[5] = 4;
00084   
00085   int js_D = base_note;
00086   
00087   int js_Q = span_size;
00088   
00089   js_Q += 2;
00090   
00091   int js_V = variation;
00092   
00093   int js_FR = fret_pos;
00094   
00095   int js_G = 0;
00096   
00097   int js_A = 0;
00098   
00099   if (js_FR){
00100     js_G = 8;
00101   }
00102   
00103   js_L = 1;
00104   js_Y = 1;
00105   js_Z = 1;
00106   
00107   js_vboy(variation);
00108   
00109   js_Y += js_Q;
00110   int js_K = 0;
00111   int js_W = js_D - js_Z;
00112   int js_H = -js_Z;
00113   int js_N[6] = {0, 0, 0, 0, 0, 0};
00114   int js_TCK[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00115   int js_E = 0;
00116   int js_X = 0;
00117   
00118   for (int j=0; j<41; j++){
00119     js_A = 0;
00120     for (int b=0; b<7; b++){
00121       if (js_N[b] == 1){
00122         js_A++;
00123       }
00124       if ((js_A==6)||(j>39)){
00125         for (int i=0; i<12; i++){
00126           if (js_TCK[i] != js_T[i]){
00127             memset((void *)js_N, 0, 6*sizeof(int));
00128             memset((void *)js_TCK, 0, 12*sizeof(int));
00129             js_V++;
00130             js_X++;
00131             if (js_V>23){
00132               js_V = 0;
00133             }
00134             js_vboy(js_V);
00135             j = 0;
00136             i = BREAK;
00137             b = BREAK;
00138             if (js_X > 23){
00139               js_N[0] = js_N[1] = js_N[2] = js_N[3] = js_N[4] = js_N[5] = 1;
00140               j = BREAK;
00141             }
00142           }
00143         }
00144       }
00145     }
00146     int js_S = 0;
00147     js_W = (js_W + js_Z)%12;
00148     js_H = (js_H + js_Z)%12;
00149     
00150     while (js_S < js_Y){
00151       js_S++;
00152       if (js_E > js_Q){
00153         js_E = 0;
00154         js_K = (js_K + js_L)%6;
00155       }
00156       if (js_E<0){
00157         js_E = js_Q;
00158         js_K = (js_K + js_L)%6;
00159       }
00160       if (js_T[js_H] == 0){
00161         for (int c=0;c<13;c++){
00162           js_W = (js_W+js_Z)%12;
00163           js_H = (js_H+js_Z)%12;
00164           if (js_T[js_H] == 1){
00165             c=BREAK;
00166           }
00167         }
00168       }
00169       if (js_N[js_K] == 1){
00170         for(int b=0; b<7; b++){
00171           js_K = (js_K+js_L)%6;
00172           if(js_N[js_K] == 0){
00173             b = BREAK;
00174           }
00175           if(b==6){
00176             js_S = BREAK;
00177           }
00178         }
00179       }
00180 
00181       // js_K is the index of the string
00182       // js_MMM is the base note played by that string in the current tuning
00183       // js_FR is the fret position
00184       // js_E
00185       // js_F represents the note made by this string here
00186       // js_N[] records if we have found a finger position for this string
00187       // js_W - represents the note we want????
00188 
00189       int js_F = (js_MMM[js_K]+js_E+js_FR)%12;
00190       
00191       if ((js_W==js_F)&&(js_N[js_K]==0)){
00192         
00193         int js_EG = js_E+js_G;
00194         
00195         string[js_K] = js_EG;
00196         notename[js_K] = notes[js_W];
00197         
00198         js_N[js_K] = 1;
00199         js_TCK[js_H] = 1;
00200         js_S = BREAK;
00201       }
00202       js_E += js_VM;
00203       
00204     }
00205     
00206   }
00207 
00208 }
00209 
00210 
00211 const int ChordEngine::alt_tunings[][6] = {
00212   {4, 9,2,7,11,4},
00213   {4,11,4,8,11,4},
00214   {4, 9,4,9, 1,4},
00215   {4, 9,2,6,11,4},
00216   {4, 9,2,7, 0,5},
00217   {2, 9,2,7, 9,2},
00218   {2, 7,0,7, 0,2},
00219   {2, 9,2,6, 9,2},
00220   {2, 9,2,7,11,4},
00221   {2, 7,2,7,11,2},
00222   {2, 9,2,9, 0,2},
00223   {0, 7,0,7, 9,4},
00224   {5, 9,2,7,11,4},
00225   {7,10,2,7,10,2},
00226 };
00227 
00228 void ChordEngine::js_tunit(int t){
00229   int max=0;
00230   int octave=0;
00231   for (int i=0;i<6;i++){
00232     js_MMM[i] = ChordEngine::alt_tunings[t][i];
00233     if (js_MMM[i] < max){
00234       octave += 12;
00235     }
00236     max = js_MMM[i];
00237     note_indices[i] = octave + js_MMM[i];
00238   }
00239 }
00240 
00241 const int ChordEngine::chordbases[][12] = {
00242   {1,0,0,0,1,0,0,1,0,0,0,0}, // maj
00243   {1,0,0,1,0,0,0,1,0,0,0,0}, // min
00244   {1,0,0,0,1,0,0,1,0,0,1,0}, // 7th
00245   {1,0,0,1,0,0,0,1,0,0,1,0}, // m7
00246   {1,0,0,0,1,0,0,1,0,0,0,1}, // maj7
00247   {1,0,0,0,1,0,0,1,0,1,0,0}, // 6th
00248   {1,0,0,1,0,0,0,1,0,1,0,0}, // m6th
00249   {1,0,0,0,1,0,0,0,1,0,0,0}, // aug
00250   {1,0,0,1,0,0,1,0,0,1,0,0}, // dim
00251   {1,0,0,0,0,1,0,1,0,0,0,0}, // sus4
00252   {1,0,0,0,0,1,0,1,0,0,1,0}, // 7sus4
00253   {1,0,1,0,1,0,0,1,0,0,1,0}, // 9th
00254   {1,0,1,0,1,0,0,1,0,0,0,0}, // add9
00255   {1,0,1,1,0,0,0,1,0,0,1,0}, // m9th
00256   {1,1,0,0,1,0,0,1,0,0,0,1}, // maj9
00257   {1,0,1,0,0,0,0,1,0,0,0,0}, // sus2
00258   {1,0,1,0,0,0,0,1,0,0,1,0}, // 7sus2
00259   {1,0,1,0,0,1,0,1,0,0,1,0}, // 11th
00260   {1,0,1,1,0,1,0,1,0,0,1,0}, // m11th
00261   {1,0,0,0,1,0,0,1,0,1,1,0}, // 13th
00262   {1,0,0,1,0,0,0,1,0,1,1,0}, // m13th
00263   {1,0,0,1,0,0,0,1,0,1,0,1}, // maj13
00264   {1,0,1,0,1,0,0,1,0,1,0,0}, // 6/9
00265   {1,0,0,0,1,0,1,0,0,0,0,0}, // flat5
00266   {1,0,0,1,1,0,0,0,0,0,1,0}, // 7#9
00267   {1,0,0,1,0,0,1,0,0,0,1,0}, // Ø7
00268   {1,0,0,0,0,0,0,1,0,0,0,0}, // 5
00269 };
00270 
00271 void ChordEngine::js_whatchord(int c){
00272   for (int i=0;i<12;i++){
00273     js_T[i] = ChordEngine::chordbases[c][i];
00274   }  
00275 }
00276 
00277 void ChordEngine::js_vboy(int v){
00278   js_L = ((v/3)%2)?5:1;
00279   js_Y = ((v/6)%2)?45:4;
00280   js_Z = (v%3 == 0)?1:(v%3 == 1)?7:11;
00281   js_VM = ((v/12)%2)?-1:1;
00282 }
00283 
00284 const char* ChordEngine::notes[] = {"C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B", 0};
00285 
00286 const char* ChordEngine::keys[] = {"maj", "min", "7th", "m7", "maj7", "6th", "m6th", "aug", "dim", "sus4", "7sus4", "9th", "add9", "m9th", "maj9", "sus2", "7sus2", "11th", "m11th", "13th", "m13th", "maj13", "6|9", "flat5", "7#9", "Ø7", "5", 0};
00287 
00288 const char* ChordEngine::frets[] = {"open", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th", "16th", 0};
00289 
00290 const char* ChordEngine::variations[] = {"V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", 0};
00291 
00292 const char* ChordEngine::tunings[] = {"EADGBE", "EBEG#BE", "EAEAC#E", "EADF#BE", "EADGCF", "DADGAD", "DGCGCD", "DADF#AD", "DADGBE", "DGDGBD", "DADACD", "CGCGAE", "FADGBE", "Gminor",0};
00293 
00294 
00295 
00296 
00297 

Generated on Sat Nov 5 16:17:34 2005 for OPIE by  doxygen 1.4.2