--- pitchentry.c 2007-09-15 08:06:28.000000000 +0100 +++ ../../denemo-cvs/denemo/src/pitchentry.c 2007-08-23 15:15:57.000000000 +0100 @@ -17,10 +17,7 @@ static GtkWidget *PR_window = NULL;/* a top level window for controlling pitch-recognition entry. We do not create one of these for each view (ie each DenemoGUI object, ie each score) because there is only one audio input source being used, so we would have to cope with resource contention issues, there is just no point. */ -static DenemoGUI *PR_gui; /* the gui for which the pitch recognition has been set up */ -static gboolean PR_insert; /* whether the notes should be inserted directly in the score or put in a list for controlled insertion */ -static gboolean PR_continuous; /* whether to go on to the next measure once overlay for current measure is full */ -gint PR_click;/*volume of a audible warning of next measure or extra tones in measure */ +DenemoGUI *PR_gui; /* the gui for which the pitch recognition has been set up */ static GtkWidget *PR_notelabel = NULL; static GtkWidget *PR_deviation = NULL; static guint PR_timer;// timer id @@ -271,179 +268,7 @@ } -static void sound_click(void) { - if(PR_click) - gdk_beep(); -} - -static GList *get_tones(GList *tone_store, gint measurenum) { - GList *g = g_list_nth(tone_store, measurenum); - if(g) - return g->data; - return NULL; -} - -/* apply the tones in the currentmeasure to the notes of the currentmeasure */ - -static gboolean apply_tones(DenemoScore *si) { - gboolean ret=FALSE; -#define curstaff ((DenemoStaff*)si->currentstaff->data) - GList *store; - gint measurenum; - store = (curstaff->tone_store); - measurenode *curmeasure = curstaff->measures; - GList *store_el = NULL; - - measurenum = si->currentmeasurenum - 1; - curmeasure = si->currentmeasure; - if(curmeasure) { - store_el = get_tones(store, measurenum); - objnode *curobj = curmeasure->data; - for (; curobj && store_el; curobj = curobj->next) - { - tone* thetone; - while(store_el && (thetone = (tone*)store_el->data) && - !thetone->valid) - store_el = store_el->next; - - DenemoObject *theobj = (DenemoObject *) curobj->data; - if(theobj->type == CHORD && ((chord*)theobj->object)->notes /* not a rest */) { - find_leftmost_staffcontext (curstaff, si); - if(thetone==NULL || store_el==NULL) - ((chord*)theobj->object)->tone_node = NULL; - else { - int dclef = curstaff->leftmost_clefcontext; - int mid_c_offset = thetone->step; - ((chord*)theobj->object)->tone_node = store_el; - modify_note(((chord*)theobj->object)->notes->data, mid_c_offset, thetone->enshift, dclef); - ((chord *) theobj->object)->sum_mid_c_offset = mid_c_offset;//Damned difficult to track this down - will not work if there are >1 notes in chord - ((chord *) theobj->object)->highestpitch = mid_c_offset; - ((chord *) theobj->object)->highesty = - calculateheight (mid_c_offset, dclef); - ((chord *) theobj->object)->lowestpitch = mid_c_offset; - ((chord *) theobj->object)->lowesty = - calculateheight (mid_c_offset, dclef); - store_el = store_el->next; - }// tone available - }// note available - if(curobj->next==NULL && curmeasure->next) - ret = TRUE; - }// for objects in measure - if(store_el && !PR_continuous) - sound_click();//extra tones in measure - showwhichaccidentals ((objnode *) si->currentmeasure->data, - si->curmeasurekey, si->curmeasureaccs); - } - return ret; -} - - -/* - * enter_note_in_score - * enters the note FOUND in the score gui->si at octave OCTAVE steps above/below mid-c - */ -static void enter_note_in_score (DenemoGUI *gui, notepitch * found, gint octave) { - //printf("Cursor_y %d and staffletter = %d\n", gui->si->cursor_y, gui->si->staffletter_y); - gui->si->cursor_y = gui->si->staffletter_y = found->spec.step; - gui->si->cursor_y += 7*octave; - shiftcursor(gui, found->spec.step); - setenshift(gui->si, found->spec.alteration); - displayhelper (gui); -} - - - - - -static GList * put_tone(GList *store, gint measurenum, tone *thetone) { - // extend store if too small - gint i = measurenum + 1 - g_list_length(store); - for(;i>0;i--) { - store = g_list_append(store,NULL); - } - GList *g = g_list_nth(store, measurenum); - if(g) - g->data = g_list_append(g->data, thetone); - return store; -} - - -/* - * enter_tone_in_store - * enters the note FOUND as a tone in the tone store - */ -static void enter_tone_in_store (DenemoGUI *gui, notepitch * found, gint octave) { - gboolean nextmeasure; - tone *thetone = (tone*)g_malloc0(sizeof(tone)); - //g_print("tone %p\n", thetone); - thetone->enshift = found->spec.alteration; - thetone->step = found->spec.step + 7*octave; - thetone->octave = octave; - thetone->valid = TRUE; -#define store (((DenemoStaff*)gui->si->currentstaff->data)->tone_store) - store = put_tone(store, gui->si->currentmeasurenum - 1, thetone); - nextmeasure = apply_tones(gui->si); - displayhelper (gui); - if(PR_continuous && nextmeasure) { - sound_click(); - measureright(gui); - } - - /* gtk_widget_draw(gui->scorearea, NULL); */ -#undef store -} - - -static void clear_tone_nodes(DenemoGUI *gui ) { - // FIXME menory leak, free the curstaff->tone_store - DenemoScore *si = gui->si; -#define curstaff ((DenemoStaff*)si->currentstaff->data) - measurenode *curmeasure; - for (curmeasure = curstaff->measures;curmeasure; curmeasure = curmeasure->next) { - objnode *curobj = curmeasure->data; - for (; curobj; curobj = curobj->next) - { - DenemoObject *theobj = (DenemoObject *) curobj->data; - if(theobj->type == CHORD) { - ((chord*)theobj->object)->tone_node = NULL; - } - } - } -} - -static void free_tones(GList *tones) { - if(tones){ - g_list_foreach(tones,freeit,NULL); - g_list_free(tones); - } -} - - // clear gui->si->currentstaff->data->tone_store -static void clear_tone_store(GtkButton *button, DenemoGUI *gui ) { -#define store (((DenemoStaff*)gui->si->currentstaff->data)->tone_store) - - g_list_foreach (store, free_tones, NULL); - clear_tone_nodes(gui); - g_list_free(store); - store = NULL; -#undef store - displayhelper(gui); -} - - -gboolean delete_tone(DenemoScore *si, chord *thechord) { - GList *tone_node = thechord->tone_node; - if(tone_node) { - ((tone*)tone_node->data)->valid = FALSE; - thechord->tone_node = NULL; - apply_tones(si); - displayhelper (PR_gui); - return TRUE; - } else { - return FALSE; - } -} /* return note for the passed pitch, or NULL if not a good note; * @param pitch, the pitch being enquired about @@ -479,7 +304,7 @@ } /* look for a new note played into audio input, if - present insert it into the score/store */ + present insert it into the score */ gint pitchentry(DenemoGUI *gui) { static gint last_step=-1, last_alteration, last_octave; if(PR_window==NULL) @@ -491,6 +316,7 @@ temperament *t = (temperament*)PR_temperament; gint octave; gdouble note = get_pitch(); + static guint gap = 0; note *= transposition_required; if((notelowest_pitch)) @@ -534,26 +360,32 @@ //printf("Enter the score area to insert notes!"); return TRUE; } - + // Enter the note in the score - if(PR_insert) - enter_note_in_score(gui, found, octave); - else - enter_tone_in_store(gui, found, octave); + + //printf("Cursor_y %d and staffletter = %d\n", gui->si->cursor_y, gui->si->staffletter_y); + gui->si->cursor_y = gui->si->staffletter_y = found->spec.step; + gui->si->cursor_y += 7*octave; + shiftcursor(gui, found->spec.step); + setenshift(gui->si, found->spec.alteration); + displayhelper (gui); + gap = 0; }//note found } +#if 0 + else { + gap++; + printf("%d\n",gap); + if(gap>10) + gap=0, + last_step = -1; + } +#endif return TRUE; } - - - // toggle PR_continuous advance to next measure or not -static void toggle_continuous(GtkButton *button, DenemoGUI *gui ) { - PR_continuous = !PR_continuous; -} - static void change_silence(GtkSpinButton *widget, gpointer data){ double silence = gtk_spin_button_get_value(widget); set_silence(silence); @@ -632,33 +464,14 @@ static void toggle_repeated_notes_allowed(){ repeated_notes_allowed = !repeated_notes_allowed; } - -static void change_click_volume(GtkSpinButton *widget, DenemoGUI *gui){ - PR_click = (guint)gtk_spin_button_get_value(widget); -gtk_window_present(GTK_WINDOW(gui->window)); - //eventually make this value control the loudness of a click -} - - static void change_timer_rate(GtkSpinButton *widget, DenemoGUI *gui){ PR_time = (guint)gtk_spin_button_get_value(widget); - start_pitch_recognition(gui);//FIXME do not call the whole of start_pitch_recognition, just the timer setting bit??? + start_pitch_recognition(gui); } -static void toggle_insert(GtkButton *button) { - // switch the button to read Collect Notes/Insert Notes - // toggle PR_insert to show where the notes detected should go - PR_insert = !PR_insert; - -} - static void create_pitch_recognition_window(DenemoGUI *gui) { - GtkWidget *hbox, *hbox2; - GtkWidget *button; - GtkWidget *frame; - GtkWidget *label; if(PR_window) { g_warning("unexpected call"); return; @@ -673,69 +486,12 @@ gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (PR_window), main_vbox); - frame = gtk_frame_new( "Mode"); + GtkWidget *frame = gtk_frame_new( "Enharmonic selection"); gtk_container_add (GTK_CONTAINER (main_vbox), frame); - hbox = gtk_hbox_new (FALSE, 1); + GtkWidget *hbox = gtk_hbox_new (FALSE, 1); gtk_container_add (GTK_CONTAINER (frame), hbox); - - frame = gtk_frame_new( "Overlay Pitches"); - gtk_container_add (GTK_CONTAINER (hbox), frame); - - GtkWidget *vbox2 = gtk_vbox_new (FALSE, 1); - gtk_container_add (GTK_CONTAINER (frame), vbox2); - - hbox2 = gtk_hbox_new (FALSE, 1); - - gtk_box_pack_start (GTK_BOX (vbox2), hbox2, - TRUE, TRUE, 0); - GtkWidget *radio_button = gtk_radio_button_new_with_label(NULL, "Overlay Pitches"); - gtk_box_pack_start (GTK_BOX (hbox2), radio_button, - TRUE, TRUE, 0); - g_signal_connect (G_OBJECT (radio_button), "toggled", - G_CALLBACK (toggle_insert), NULL); - - button = gtk_button_new_with_label("Clear"); - gtk_box_pack_start (GTK_BOX (hbox2), button, - TRUE, TRUE, 0); - g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (clear_tone_store), gui); - hbox2 = gtk_hbox_new (FALSE, 1); - - gtk_box_pack_start (GTK_BOX (vbox2), hbox2, - TRUE, TRUE, 0); - button = gtk_check_button_new_with_label("Continuous"); - gtk_box_pack_start (GTK_BOX (hbox2), button, - TRUE, TRUE, 0); - PR_continuous = FALSE; - g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (toggle_continuous), gui); - - - label = gtk_label_new("Click Volume"); - gtk_box_pack_start (GTK_BOX (hbox2), label, TRUE, TRUE, 0); - GtkAdjustment *spinner_adj = - (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 1.0, - 1.0, 1.0, 1.0); - GtkWidget *spinner = gtk_spin_button_new (spinner_adj, 1.0, 1); - gtk_box_pack_start (GTK_BOX (hbox2), spinner, TRUE, TRUE, 0); - g_signal_connect (G_OBJECT (spinner), "value-changed", - G_CALLBACK (change_click_volume), gui); - - - - - button = gtk_radio_button_new_with_label_from_widget(radio_button, "Insert Notes"); - gtk_box_pack_start (GTK_BOX (hbox), button, - TRUE, TRUE, 0);/* no need for callback */ - - - - frame = gtk_frame_new( "Enharmonic selection"); - gtk_container_add (GTK_CONTAINER (main_vbox), frame); - hbox = gtk_hbox_new (FALSE, 1); - gtk_container_add (GTK_CONTAINER (frame), hbox); - label = gtk_label_new(""); - button = gtk_button_new_with_label("flatten"); + GtkWidget *label = gtk_label_new(""); + GtkWidget *button = gtk_button_new_with_label("flatten"); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (button), "clicked", @@ -771,15 +527,15 @@ hbox = gtk_hbox_new (FALSE, 1); gtk_container_add (GTK_CONTAINER (frame), hbox); - hbox2 = gtk_hbox_new (FALSE, 1); + GtkWidget *hbox2 = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (hbox), hbox2, TRUE, TRUE, 0); label = gtk_label_new("Silence"); gtk_box_pack_start (GTK_BOX (hbox2), label, TRUE, TRUE, 0); - spinner_adj = + GtkAdjustment *spinner_adj = (GtkAdjustment *) gtk_adjustment_new (-90.0, -1000.0, 100.0, 10.0, 1.0, 1.0); - spinner = gtk_spin_button_new (spinner_adj, 100.0, 0); + GtkWidget *spinner = gtk_spin_button_new (spinner_adj, 100.0, 0); gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (spinner), "value-changed", G_CALLBACK (change_silence), NULL); @@ -910,7 +666,19 @@ } +#if 0 +static void read_PRkeymap(DenemoGUI *gui) { + PR_oldkeymap = gui->prefs->the_keymap; + if(PR_rhythmkeymap==NULL) + PR_rhythmkeymap = + gui->prefs->the_keymap = create_keymap ("RhythmKeymaprc"); + gui->prefs->the_keymap = PR_rhythmkeymap; + + gchar *localrc = g_build_filename (locatedotdenemo (), "PRkeymaprc", NULL); + load_xml_keymap (localrc, gui->prefs->the_keymap); +} +#endif gint setup_pitch_recognition(DenemoGUI *gui){ if(PR_window) { gtk_window_present(GTK_WINDOW(PR_window)); @@ -957,18 +725,16 @@ void start_pitch_recognition(DenemoGUI *gui) { if(PR_timer) g_source_remove(PR_timer); - - PR_timer = g_timeout_add (PR_time, (GSourceFunc)pitchentry, gui); - if(PR_timer==0) - g_error("Timer id 0 - if valid the code needs re-writing (documentation not clear)"); - gtk_widget_add_events (gui->scorearea, GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK); - PR_enter = g_signal_connect (G_OBJECT (gui->scorearea), "enter-notify-event", - G_CALLBACK (scorearea_set_active), (gpointer)gui); - PR_leave = g_signal_connect (G_OBJECT (gui->scorearea), "leave-notify-event", - G_CALLBACK (scorearea_set_inactive), (gpointer)gui); - PR_gui = gui; + PR_timer = g_timeout_add (PR_time, (GSourceFunc)pitchentry, gui); + if(PR_timer==0) + g_error("Timer id 0 - if valid the code needs re-writing (documentation not clear)"); + gtk_widget_add_events (gui->scorearea, GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK); + PR_enter = g_signal_connect (G_OBJECT (gui->scorearea), "enter-notify-event", + G_CALLBACK (scorearea_set_active), (gpointer)gui); + PR_leave = g_signal_connect (G_OBJECT (gui->scorearea), "leave-notify-event", + G_CALLBACK (scorearea_set_inactive), (gpointer)gui); + PR_gui = gui; } - gboolean pitch_recognition_system_active(void) { return PR_window!=NULL; }