Generic Just Intonation Tuner

need a feature, suggest here

Re: Generic Just Intonation Tuner

Postby Broomy » Sat Nov 25, 2017 7:17 am

I've added a few combo boxes (without signal handles, I have to figure that out yet).
Would it be a good idea to construct gxtuner as follows:

Choose TET/JI:
If Tet--> Then activate combo boxes with parameters for TET (for example I could all the other TETs used in the guitarix tuner)
if JI--> Then activate combo boxes with parameters for JI

I will try to rework this piece of code for a generic JI tuner:
Code: Select all
static gboolean gtk_tuner_expose_johnston7limit(GtkWidget *widget, cairo_t *cr) {
    // ♯ ♭
    static const char* johnston7limit_note[] = {"C","D7♭-","D♭-","D-","DL-","E7♭","E♭", "E","EL","F7+","F+","F♯+","F♯L+","G","A7♭","A♭","A","AL","B7♭","B♭","B","BL"};
    float noteratio[] = {1/1.0, 28/27.0, 16/15.0, 10/9.0, 8/7.0, 7/6.0, 6/5.0, 5/4.0, 9/7.0, 21/16.0, 27/20.0, 45/32.0, 81/56.0, 3/2.0, 14/9.0, 8/5.0, 5/3.0, 12/7.0, 7/4.0, 9/5.0, 15/8.0, 27/14.0, 2/1.0};
    // Set which ratio is the reference pitch (note that the first ratio is 0 and the second ratio 1 and so on and so forth)
    float refratio = noteratio[16];
    // calculating the number of notes of the preset
    int numberofnotes = (sizeof(noteratio) / sizeof(noteratio[0]) - 1) ;
    // Frequency Octave divider
    float multiply = 1.0;
    // ratio
    float percent = 0.0;
    // Note indicator
    int display_note = 0;
    // Octave names for display
    static const char* octave[] = {"0","1","2","3","4","5","6","7"," "};
    // Octave indicator
    static int indicate_oc = 0;
   
    GxTuner *tuner = GX_TUNER(widget);
    // fetch widget size and location
    GtkAllocation *allocation = g_new0 (GtkAllocation, 1);
    gtk_widget_get_allocation(GTK_WIDGET(widget), allocation);

    double x0      = (allocation->width - 100) * 0.5;
    double y0      = (allocation->height - 60) * 0.5;

    static double grow   = 0.;

    if(allocation->width > allocation->height +(10.*grow*3)) {
        grow = (allocation->height/60.)/10.;
    } else {
        grow =  (allocation->width/100.)/10.;
    }
   
    tuner->scale_h = (allocation->height/60.)/3.;
    tuner->scale_w =  (allocation->width/100.)/3.;
    // translate widget size to standard size
    cairo_translate(cr, -x0*tuner->scale_w, -y0*tuner->scale_h);
    cairo_scale(cr, tuner->scale_w, tuner->scale_h);
    cairo_set_source_surface(cr, GX_TUNER_CLASS(GTK_WIDGET_GET_CLASS(widget))->surface_tuner, x0, y0);
    cairo_paint (cr);
    cairo_restore(cr);

    cairo_save(cr);
    cairo_translate(cr, -x0*tuner->scale_w*3., -y0*tuner->scale_h*3.);
    cairo_scale(cr, tuner->scale_w*3., tuner->scale_h*3.);
   
    // fetch Octave we are in
    float scale = -0.4;
    if (tuner->freq) {
        // this is the frequency we get from the pitch tracker
        float freq_is = tuner->freq;
        // Set reference frequency of the first note of the preset
        float ref_c = tuner->reference_pitch / refratio;
        // now check in which octave we are with the tracked frequency
        // and set the frequency octave divider
        // ref_c is now the frequency of the first note in octave,
        // but we want to check if the frequency is below the last note in octave
        // so, for example if freq_is is below ref_c we are in octave 3
        // if freq_is is below ref_c/2 we are in octave 2, etc.
    for (int n=0 ; n <= 8 ; ++n )
         { float ratiodiffhighnoteandoctave = exp((log(noteratio[numberofnotes-1])+log(noteratio[numberofnotes]))/2) ; 
            if (freq_is < (ref_c*pow(2,n-3))-(2-ratiodiffhighnoteandoctave)*(ref_c*pow(2,n-3)) && freq_is >0.0) {
                 indicate_oc = n;
                 multiply = pow(2, 4-n);
                 break;
                }
         }
    percent = (freq_is/(ref_c/multiply)) ;
    // now we chould check which ratio we have
    // we split the range using log-average
     for (int n=0 ; n <= numberofnotes ; ++n )
         { float ratiodiff = exp((log(noteratio[n])+log(noteratio[n+1]))/2) ; 
                 if (percent < ratiodiff) {
                     display_note = n;
                     scale = ((percent-noteratio[n]))/2.0;
                     break;
                 }
         }
    //fprintf(stderr, " percent == %f freq = %f ref_c = %f indicate_oc = %i \n value of numberofnotes is %i ", percent, freq_is, ref_c, indicate_oc, numberofnotes );   
        // display note
        cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2);
        cairo_set_font_size(cr, 18.0);
        cairo_move_to(cr,x0+50 -9 , y0+30 +9 );
        cairo_show_text(cr, johnston7limit_note[display_note]);
        cairo_set_font_size(cr, 8.0);
        cairo_move_to(cr,x0+54  , y0+30 +16 );
        cairo_show_text(cr, octave[indicate_oc]);
    }

    // display frequency
    char s[10];
    snprintf(s, sizeof(s), "%.1f Hz", tuner->freq);
    cairo_set_source_rgb (cr, 0.5, 0.5, 0.1);
    cairo_set_font_size (cr, 7.5);
    cairo_text_extents_t ex;
    cairo_text_extents(cr, s, &ex);
    cairo_move_to (cr, x0+98-ex.width, y0+58);
    cairo_show_text(cr, s);
    // display cent
    if(scale>-0.4) {
        if(scale>0.004) {
            // here we translate the scale factor to cents and display them
            cents = static_cast<int>((floorf(scale * 10000) / 50));
            snprintf(s, sizeof(s), "+%i", cents);
            cairo_set_source_rgb (cr, 0.05, 0.5+0.022* abs(cents), 0.1);
            gx_tuner_triangle(cr, x0+80, y0+45, -15, 10);
            cairo_set_source_rgb (cr, 0.5+ 0.022* abs(cents), 0.35, 0.1);
            gx_tuner_triangle(cr, x0+20, y0+45, 15, 10);
            gx_tuner_strobe(cr, x0, y0, static_cast<double>(cents));
        } else if(scale<-0.004) {
            cents = static_cast<int>((ceil(scale * 10000) / 50));
            snprintf(s, sizeof(s), "%i", cents);
            cairo_set_source_rgb (cr, 0.05, 0.5+0.022* abs(cents), 0.1);
            gx_tuner_triangle(cr, x0+20, y0+45, 15, 10);
            cairo_set_source_rgb (cr, 0.5+ 0.022* abs(cents), 0.35, 0.1);
            gx_tuner_triangle(cr, x0+80, y0+45, -15, 10);
            gx_tuner_strobe(cr, x0, y0, static_cast<double>(cents));
        } else {
            cents = static_cast<int>((ceil(scale * 10000) / 50));
            mini_cents = (scale * 10000) / 50;
            if (mini_cents<0)
                snprintf(s, sizeof(s), "%.2f", mini_cents);
            else
                snprintf(s, sizeof(s), "+%.2f", mini_cents);
            cairo_set_source_rgb (cr, 0.05* abs(cents), 0.5, 0.1);
            gx_tuner_triangle(cr, x0+80, y0+45, -15, 10);
            gx_tuner_triangle(cr, x0+20, y0+45, 15, 10);
            gx_tuner_strobe(cr, x0, y0, mini_cents);
        }
    } else {
        cents = 100;
        snprintf(s, sizeof(s), "+ - cent");
    }   
    cairo_set_source_rgb (cr, 0.5, 0.5, 0.1);
    cairo_set_font_size (cr, 6.0);
    cairo_text_extents(cr, s, &ex);
    cairo_move_to (cr, x0+28-ex.width, y0+58);
    cairo_show_text(cr, s);

    double ux=2., uy=2.;
    cairo_device_to_user_distance (cr, &ux, &uy);
    if (ux < uy)
        ux = uy;
    cairo_set_line_width (cr, ux + grow);

    // indicator (line)
    cairo_move_to(cr,x0+50, y0+rect_height+5);
    cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
    cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
    cairo_set_dash (cr, dash_ind, sizeof(dash_ind)/sizeof(dash_ind[0]), 1);
    cairo_line_to(cr, (log_scale(cents, scale)*2*rect_width)+x0+50, y0+(scale*scale*30)+2);
    cairo_set_source_rgb(cr,  0.5, 0.1, 0.1);
    cairo_stroke(cr);   

    g_free (allocation);
    return FALSE;
}



I will try to do the same for TET.

What is handy to do with the data required for the JI scales?
It will be arrays which contain a row of 10 integers for every note in the scale. Would be advisable to put them in another file? And what is the etiquette for doing so?

Kind regards,

Hans
User avatar
Broomy
 
Posts: 194
Joined: Thu Apr 24, 2014 7:53 am

Re: Generic Just Intonation Tuner

Postby Broomy » Sat Nov 25, 2017 8:47 pm

I've managed to create a new combo box and connect a signal handler to it.

Now I need to find a way to fill the "static const char* notes" with the right notes depending on the value provided by the combo box.
I've tried an if function but I can't get it to work. I'm a bit stuck right now.

The notes in the arrays in the if function below are nonsense and just for this example.
Code: Select all
static gboolean gtk_tuner_expose (GtkWidget *widget, cairo_t *cr) {
    GxTuner *tuner = GX_TUNER(widget);
    // here we check in which mode we are add your mode here.
    static const char* notes;
    if (tuner->mode == 1) {
        notes[12] = {"A ","A#","B ","C ","C#","D ","D#","E ","F ","F#","G ","G#"}; //this I want in "notes" when mode == 1
    } else if (tuner->mode == 2) {
        notes[12] = {"A ","Bb","B ","C ","Db","D ","Eb","E ","F ","Gb","G ","Ab"}; //this I want in "notes" when mode == 2
    }
   
   static const char* octave[9] = {"0","1","2","3","4","5","6","7"," "};
    static int indicate_oc = 0;
   more code....
   



Kind regards,

Hans
User avatar
Broomy
 
Posts: 194
Joined: Thu Apr 24, 2014 7:53 am

Re: Generic Just Intonation Tuner

Postby brummer10 » Sun Nov 26, 2017 4:36 am

You could define the note arrays as global variables in gxtuner.cpp at the beginning of the file, near
static const double dashes[].

Then define a pointer in gxtuner.h in the struct _GxTuner

const char **note;

then you could assign the pointer to the note array you like to use:

if (tuner->mode == 1) {
tuner->note = diatonic_note;
} else if (tuner->mode == 2) {
tuner->note = shruti_note

you could do the same for noteratio, refartio, etc.
User avatar
brummer10
Site Admin
 
Posts: 782
Joined: Thu Mar 26, 2009 6:57 pm

Re: Generic Just Intonation Tuner

Postby brummer10 » Sun Nov 26, 2017 9:41 am

here is a diff against the master branch which implement that:
Code: Select all
diff --git a/gxtuner.cpp b/gxtuner.cpp
index 702106f..4d52f3c 100644
--- a/gxtuner.cpp
+++ b/gxtuner.cpp
@@ -53,6 +53,13 @@ static const int tuner_height = 60;
 static const double rect_width = 100;
 static const double rect_height = 60;
 
+static const char* note[] = {"A ","A#","B ","C ","C#","D ","D#","E ","F ","F#","G ","G#"};
+static const char* johnston7limitn05_note[] = {"C","D7♭","D","E7♭","EL","F","F♯LL","G","A7♭","AL","B7♭","BL"};
+static const char* johnston7limit_note[] = {"C","D7♭-","D♭-","D-","DL-","E7♭","E♭", "E","EL","F7+","F+","F♯+","F♯L+","G","A7♭","A♭","A","AL","B7♭","B♭","B","BL"};
+static const char* johnston5limit_note[] = {"C","C+","D♭♭-","B♯♯+","C♯","C♯+","D♭-","D♭","E♭♭♭-","C♯♯+","D-","D","E♭♭-","E♭♭","F♭♭♭-","D♯","E♭-","E♭","E♭+","F♭♭","D♯♯+","E","E+","F♭","D♯♯♯+","E♯","E♯+","F","F+","G♭♭-","E♯♯+","F♯","F♯+","G♭-","G♭","A♭♭♭-","F♯♯+","G-","G","G+","A♭♭","G♯","A♭-","A♭","F♯♯♯♯++","G♯♯","G♯♯+","F♯♯♯++","A","A+","B♭♭-","G♯♯♯+","A♯","A♯+","B♭-","B♭","C♭♭-","C♭♭","A♯♯++","B","C♭-","C♭","D♭♭♭-","B♯","C-"};
+static const char* shruti_note[] = {"S ","r1","r2","R1","R2","g1","g2","G1","G2","M1","M2","m1","m2","P ","d1","d2","D1","D2","n1","n2","N1","N2"};
+static const char* diatonic_note[] = {"Do","Re","Mi","Fa","Sol","La ","Ti"};
+
 static int cents = 0;
 static float mini_cents = 0.0;
 
@@ -179,6 +186,7 @@ static void gx_tuner_init (GxTuner *tuner) {
     tuner->mode = 0;
     tuner->scale_w = 1.;
     tuner->scale_h = 1.;
+    tuner->note = note;
     //GtkWidget *widget = GTK_WIDGET(tuner);
 }
 
@@ -205,6 +213,29 @@ void gx_tuner_set_reference_pitch(GxTuner *tuner, double reference_pitch) {
 void gx_tuner_set_mode(GxTuner *tuner, int mode) {
     g_assert(GX_IS_TUNER(tuner));
     tuner->mode = mode;
+    switch(tuner->mode) {
+    case  0:
+        tuner->note = note;
+        break;
+    case 1:
+        tuner->note = shruti_note;
+        break;
+    case 2:
+        tuner->note = diatonic_note;
+        break;
+    case 3:
+        tuner->note = johnston5limit_note;
+        break;
+    case 4:
+        tuner->note = johnston7limit_note;
+        break;
+    case 5:
+        tuner->note = johnston7limitn05_note;
+        break;
+    default:
+        tuner->note = note;
+        break;
+    }
     gtk_widget_queue_draw(GTK_WIDGET(tuner));
     g_object_notify(G_OBJECT(tuner), "mode");
 }
@@ -361,7 +392,6 @@ static void gx_tuner_strobe(cairo_t *cr, double x0, double y0, double cents) {
 // copy the following block and edit it to your needs to add a new tuning mode
 static gboolean gtk_tuner_expose_diatonic(GtkWidget *widget, cairo_t *cr) {
     // Note names for display
-    static const char* diatonic_note[] = {"Do","Re","Mi","Fa","Sol","La ","Ti"};
     // ratios of notes + 2/1
     float noteratio[] = {1/1.0, 9/8.0, 5/4.0, 4/3.0, 3/2.0, 5/3.0, 15/8.0, 2/1.0};
     // Set which ratio is the reference pitch (note that the first ratio is 0 and the second ratio 1 and so on and so forth)
@@ -445,7 +475,7 @@ static gboolean gtk_tuner_expose_diatonic(GtkWidget *widget, cairo_t *cr) {
         cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2);
         cairo_set_font_size(cr, 18.0);
         cairo_move_to(cr,x0+50 -9 , y0+30 +9 );
-        cairo_show_text(cr, diatonic_note[display_note]);
+        cairo_show_text(cr, tuner->note[display_note]);
         cairo_set_font_size(cr, 8.0);
         cairo_move_to(cr,x0+54  , y0+30 +16 );
         cairo_show_text(cr, octave[indicate_oc]);
@@ -521,7 +551,6 @@ static gboolean gtk_tuner_expose_diatonic(GtkWidget *widget, cairo_t *cr) {
 }
 
 static gboolean gtk_tuner_expose_shruti(GtkWidget *widget, cairo_t *cr) {
-    static const char* shruti_note[22] = {"S ","r1","r2","R1","R2","g1","g2","G1","G2","M1","M2","m1","m2","P ","d1","d2","D1","D2","n1","n2","N1","N2"};
     float noteratio[] = {1/1.0, 256/243.0, 16/15.0, 10/9.0, 9/8.0, 32/27.0, 6/5.0, 81/64.0, 4/3.0, 27/20.0, 45/32.0, 729/512.0, 3/2.0, 128/81.0, 8/5.0, 5/3.0, 27/16.0, 16/9.0, 9/5.0, 15/8.0, 243/128.0, 2/1.0};
     float refratio = noteratio[0];
     int numberofnotes = (sizeof(noteratio) / sizeof(noteratio[0]) - 1) ;
@@ -586,7 +615,7 @@ static gboolean gtk_tuner_expose_shruti(GtkWidget *widget, cairo_t *cr) {
         cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2);
         cairo_set_font_size(cr, 18.0);
         cairo_move_to(cr,x0+50 -9 , y0+30 +9 );
-        cairo_show_text(cr, shruti_note[display_note]);
+        cairo_show_text(cr, tuner->note[display_note]);
         cairo_set_font_size(cr, 8.0);
         cairo_move_to(cr,x0+54  , y0+30 +16 );
         cairo_show_text(cr, octave[indicate_oc]);
@@ -658,7 +687,6 @@ static gboolean gtk_tuner_expose_shruti(GtkWidget *widget, cairo_t *cr) {
 }
 
 static gboolean gtk_tuner_expose_johnston5limit(GtkWidget *widget, cairo_t *cr) {
-    static const char* johnston5limit_note[] = {"C","C+","D♭♭-","B♯♯+","C♯","C♯+","D♭-","D♭","E♭♭♭-","C♯♯+","D-","D","E♭♭-","E♭♭","F♭♭♭-","D♯","E♭-","E♭","E♭+","F♭♭","D♯♯+","E","E+","F♭","D♯♯♯+","E♯","E♯+","F","F+","G♭♭-","E♯♯+","F♯","F♯+","G♭-","G♭","A♭♭♭-","F♯♯+","G-","G","G+","A♭♭","G♯","A♭-","A♭","F♯♯♯♯++","G♯♯","G♯♯+","F♯♯♯++","A","A+","B♭♭-","G♯♯♯+","A♯","A♯+","B♭-","B♭","C♭♭-","C♭♭","A♯♯++","B","C♭-","C♭","D♭♭♭-","B♯","C-"};
     float noteratio[] = {1/1.0, 81/80.0, 128/125.0, 16875/16364.0, 25/24.0, 135/128.0, 16/15.0, 27/25.0, 2048/1875.0, 1125/1024.0, 10/9.0, 9/8.0, 256/225.0, 144/125.0, 32768/28125.0, 75/64.0, 32/27.0, 6/5.0, 243/200.0, 768/625.0, 10125/8192.0, 5/4.0, 81/64.0, 32/25.0, 84375/65536.0, 125/96.0, 675/512.0, 4/3.0, 27/20.0, 512/375.0, 5625/4096.0, 25/18.0, 45/32.0, 64/45.0, 36/25.0, 8192/5625.0, 375/256.0, 40/27.0, 3/2.0, 243/160.0, 192/125.0, 25/16.0, 128/81.0, 8/5.0, 421875/262144.0, 625/384.0, 3375/2048.0, 54375/32768.0, 5/3.0, 27/16.0, 128/75.0, 28125/16385.0, 125/72.0, 225/128.0, 16/9.0, 9/5.0, 2048/1125.0, 1152/625.0, 30375/16384.0, 15/8.0, 258/135.0, 48/25.0, 32768/16875.0, 125/64.0, 160/81.0, 2/1.0};
     float refratio = noteratio[48];
     int numberofnotes = (sizeof(noteratio) / sizeof(noteratio[0]) - 1) ;
@@ -721,7 +749,7 @@ static gboolean gtk_tuner_expose_johnston5limit(GtkWidget *widget, cairo_t *cr)
         cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2);
         cairo_set_font_size(cr, 18.0);
         cairo_move_to(cr,x0+50 -9 , y0+30 +9 );
-        cairo_show_text(cr, johnston5limit_note[display_note]);
+        cairo_show_text(cr, tuner->note[display_note]);
         cairo_set_font_size(cr, 8.0);
         cairo_move_to(cr,x0+54  , y0+30 +16 );
         cairo_show_text(cr, octave[indicate_oc]);
@@ -798,7 +826,6 @@ static gboolean gtk_tuner_expose_johnston5limit(GtkWidget *widget, cairo_t *cr)
 
 static gboolean gtk_tuner_expose_johnston7limit(GtkWidget *widget, cairo_t *cr) {
     // ♯ ♭
-    static const char* johnston7limit_note[] = {"C","D7♭-","D♭-","D-","DL-","E7♭","E♭", "E","EL","F7+","F+","F♯+","F♯L+","G","A7♭","A♭","A","AL","B7♭","B♭","B","BL"};
     float noteratio[] = {1/1.0, 28/27.0, 16/15.0, 10/9.0, 8/7.0, 7/6.0, 6/5.0, 5/4.0, 9/7.0, 21/16.0, 27/20.0, 45/32.0, 81/56.0, 3/2.0, 14/9.0, 8/5.0, 5/3.0, 12/7.0, 7/4.0, 9/5.0, 15/8.0, 27/14.0, 2/1.0};
     // Set which ratio is the reference pitch (note that the first ratio is 0 and the second ratio 1 and so on and so forth)
     float refratio = noteratio[16];
@@ -881,7 +908,7 @@ static gboolean gtk_tuner_expose_johnston7limit(GtkWidget *widget, cairo_t *cr)
         cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2);
         cairo_set_font_size(cr, 18.0);
         cairo_move_to(cr,x0+50 -9 , y0+30 +9 );
-        cairo_show_text(cr, johnston7limit_note[display_note]);
+        cairo_show_text(cr, tuner->note[display_note]);
         cairo_set_font_size(cr, 8.0);
         cairo_move_to(cr,x0+54  , y0+30 +16 );
         cairo_show_text(cr, octave[indicate_oc]);
@@ -959,7 +986,6 @@ static gboolean gtk_tuner_expose_johnston7limit(GtkWidget *widget, cairo_t *cr)
 
 static gboolean gtk_tuner_expose_johnston7limitno5(GtkWidget *widget, cairo_t *cr) {
     // ♯ ♭
-    static const char* johnston7limitn05_note[] = {"C","D7♭","D","E7♭","EL","F","F♯LL","G","A7♭","AL","B7♭","BL"};
     float noteratio[] = {1/1.0, 49/48.0, 9/8.0, 7/6.0, 9/7.0, 4/3.0, 72/49.0, 3/2.0, 14/9.0, 12/7.0, 7/4.0, 27/14.0, 2/1.0};
     // Set which ratio is the reference pitch (note that the first ratio is 0 and the second ratio 1 and so on and so forth)
     float refratio = 5/3.0;
@@ -1042,7 +1068,7 @@ static gboolean gtk_tuner_expose_johnston7limitno5(GtkWidget *widget, cairo_t *c
         cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2);
         cairo_set_font_size(cr, 18.0);
         cairo_move_to(cr,x0+50 -9 , y0+30 +9 );
-        cairo_show_text(cr, johnston7limitn05_note[display_note]);
+        cairo_show_text(cr, tuner->note[display_note]);
         cairo_set_font_size(cr, 8.0);
         cairo_move_to(cr,x0+54  , y0+30 +16 );
         cairo_show_text(cr, octave[indicate_oc]);
@@ -1132,7 +1158,6 @@ static gboolean gtk_tuner_expose (GtkWidget *widget, cairo_t *cr) {
     } else if (tuner->mode == 5) {
         if (!gtk_tuner_expose_johnston7limitno5 (widget, cr)) return FALSE;
     }
-    static const char* note[12] = {"A ","A#","B ","C ","C#","D ","D#","E ","F ","F#","G ","G#"};
     static const char* octave[9] = {"0","1","2","3","4","5","6","7"," "};
     static int indicate_oc = 0;
     
@@ -1201,7 +1226,7 @@ static gboolean gtk_tuner_expose (GtkWidget *widget, cairo_t *cr) {
         cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2);
         cairo_set_font_size(cr, 18.0);
         cairo_move_to(cr,x0+50 -9 , y0+30 +9 );
-        cairo_show_text(cr, note[vis]);
+        cairo_show_text(cr, tuner->note[vis]);
         cairo_set_font_size(cr, 8.0);
         cairo_move_to(cr,x0+54  , y0+30 +16 );
         cairo_show_text(cr, octave[indicate_oc]);
diff --git a/gxtuner.h b/gxtuner.h
index a1724e8..aa16b34 100644
--- a/gxtuner.h
+++ b/gxtuner.h
@@ -56,6 +56,7 @@ struct _GxTuner
     double scale_w;
     double scale_h;
     int mode;
+    const char **note;
 };
 
 struct _GxTunerClass
User avatar
brummer10
Site Admin
 
Posts: 782
Joined: Thu Mar 26, 2009 6:57 pm

Re: Generic Just Intonation Tuner

Postby Broomy » Sun Nov 26, 2017 6:00 pm

I got it to work.

I use an if statement to choose between chromatic (mode = 0) and for all other values move to "gtk_tuner_expose_just".
Code: Select all
static gboolean gtk_tuner_expose (GtkWidget *widget, cairo_t *cr) {
    GxTuner *tuner = GX_TUNER(widget);
    // here we check in which mode we are add your mode here.
    if (tuner->mode > 0) {
        if (!gtk_tuner_expose_just (widget, cr)) return FALSE;
    }
    static const char* note[12] = {"A ","A#","B ","C ","C#","D ","D#","E ","F ","F#","G ","G#"};
    static const char* octave[9] = {"0","1","2","3","4","5","6","7"," "};
    static int indicate_oc = 0;
 


In "gtk_tuner_expose_just" I managed to make an if statement (which I will replace for a switch) to import the different notes.
Code: Select all
static gboolean gtk_tuner_expose_just(GtkWidget *widget, cairo_t *cr) {
    // ♯ ♭
    GxTuner *tuner = GX_TUNER(widget);
    if (tuner->mode < 2){
        tuner->just_note = just_note1;
        tuner->noteratio = noteratio1;
        tuner->refratio = refratio1;
        tuner->numberofnotes = numberofnotes1;
    } else if (tuner->mode > 1){
        tuner->just_note = just_note2;
        tuner->noteratio = noteratio2;
        tuner->refratio = refratio2;
        tuner->numberofnotes = numberofnotes2;
    }

I've put the data at the beginning of the file.
Code: Select all
//scale data
static const char* just_note1[] = {"S ","r1","r2","R1","R2","g1","g2","G1","G2","M1","M2","m1","m2","P ","d1","d2","D1","D2","n1","n2","N1","N2"};
static const double noteratio1[] = {1/1.0, 256/243.0, 16/15.0, 10/9.0, 9/8.0, 32/27.0, 6/5.0, 81/64.0, 4/3.0, 27/20.0, 45/32.0, 729/512.0, 3/2.0, 128/81.0, 8/5.0, 5/3.0, 27/16.0, 16/9.0, 9/5.0, 15/8.0, 243/128.0, 2/1.0};
static double refratio1 = 5/3.0;
static int numberofnotes1 = (sizeof(just_note1) / sizeof(just_note1[0]));

static const char* just_note2[] = {"C","D7♭","D","E7♭","EL","F","F♯LL","G","A7♭","AL","B7♭","BL"};
static const double noteratio2[] = {1/1.0, 49/48.0, 9/8.0, 7/6.0, 9/7.0, 4/3.0, 72/49.0, 3/2.0, 14/9.0, 12/7.0, 7/4.0, 27/14.0, 2/1.0};
static double refratio2 = 5/3.0;
static int numberofnotes2 = (sizeof(just_note2) / sizeof(just_note2[0]));   

User avatar
Broomy
 
Posts: 194
Joined: Thu Apr 24, 2014 7:53 am

Re: Generic Just Intonation Tuner

Postby Broomy » Mon Nov 27, 2017 9:10 pm

I've added signal handler for reference note textbox. I can do make and make install, but when I run it, I get:
Code: Select all
(gxtuner:7044): Gtk-CRITICAL **: gtk_container_add: assertion 'GTK_IS_CONTAINER (container)' failed

(gxtuner:7044): Gtk-CRITICAL **: gtk_box_pack: assertion 'GTK_IS_WIDGET (child)' failed
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)


I've put it in the branch.

Does it has to do with the additions I made in the cmdparser.cpp file?

Hans
User avatar
Broomy
 
Posts: 194
Joined: Thu Apr 24, 2014 7:53 am

Re: Generic Just Intonation Tuner

Postby brummer10 » Tue Nov 28, 2017 4:40 am

The JI tuner comes nicely so far. :)

Okay, so I see two minor errors, first one is that you've forgotten to create the hhbox (tuner.cpp) therefore you get the error.
Code: Select all
'GTK_IS_WIDGET (child)' failed


The second one is that when you add a new option to the cmdparser, you need to increase the
std::string optvar[10]; array in cmdparser.h to hold the new option.

Fix that and it will work.

regards
hermann
User avatar
brummer10
Site Admin
 
Posts: 782
Joined: Thu Mar 26, 2009 6:57 pm

Re: Generic Just Intonation Tuner

Postby Broomy » Tue Nov 28, 2017 5:49 am

Thanks! Hans
User avatar
Broomy
 
Posts: 194
Joined: Thu Apr 24, 2014 7:53 am

Re: Generic Just Intonation Tuner

Postby Broomy » Thu Nov 30, 2017 9:06 pm

Short heads up: Making progress with the tuner. The math is almost done. Then a happy session of obligate debugging and we're ready to try it! :mrgreen:

Hans
User avatar
Broomy
 
Posts: 194
Joined: Thu Apr 24, 2014 7:53 am

Re: Generic Just Intonation Tuner

Postby Broomy » Sat Dec 02, 2017 1:36 pm

If I want to add a string in gxtuner.cpp I just have to add "#include <string> in the header file, right?

I get error messages when I try to build the code with #include <string>, but <string.h> seems to work, but then std::string doesn't work.

I've uploaded the code.

Hans
User avatar
Broomy
 
Posts: 194
Joined: Thu Apr 24, 2014 7:53 am

PreviousNext

Return to Suggestion Box

Who is online

Users browsing this forum: No registered users and 1 guest

cron