Exemple #1
0
gint
scorearea_keyrelease_event (GtkWidget * widget, GdkEventKey * event)
{
     if(!Denemo.keyboard_state_locked)
          {
              Denemo.keyboard_state ^= (0xf & klock_mask (event->keyval));
              if ((event->keyval == GDK_Alt_L) || (event->keyval == GDK_Alt_R))
                {
                  if ((Denemo.keyboard_state & CHORD_MASK)) //At least one note has been entered in a chord
                    next_insert_or_editable_note ();
                  Denemo.keyboard_state &= ~CHORD_MASK;
                }
              set_midi_in_status ();
        }
  //g_print("release %x state %x\n", Denemo.keyboard_state, event->state);
  // set_cursor_for(keyrelease_modify(event->state), event->keyval);
  gint state;
  if ((event->keyval == GDK_Caps_Lock) || (event->keyval == GDK_Num_Lock))
    return TRUE;
  state = (lock_mask (event->keyval) ^ event->state);

  set_cursor_for (state);
  return TRUE;
}
Exemple #2
0
void
process_midi_event (gchar * buf)
{
  if (command == MIDI_CONTROL_CHANGE && (notenumber == 0x40))
    {
      if (velocity == 0x7F)
        {//PEDAL DOWN
        if (Denemo.project->movement->cursor_appending || at_nonprinting ())
            Denemo.keyboard_state |= ADDING_MASK;
        else
            Denemo.keyboard_state |= CHORD_MASK | ADDING_MASK;
        }
      else
        {
          Denemo.keyboard_state &= ~(CHORD_MASK | ADDING_MASK);
          next_insert_or_editable_note();//next_insert_or_editable_note ();
        }
      set_midi_in_status ();
      displayhelper (Denemo.project);
    }
  if ((0xFFFFFF & *(gint *) buf) == 0)
    {
      set_midi_capture (FALSE);
      g_queue_clear (&midi_queue);
      if (divert_midi_event)
        {
          *divert_midi_event = 0;
          divert_midi_event = NULL;
          gtk_main_quit ();
        }
      //g_debug("queue emptied %d\n", g_queue_get_length(&midi_queue));
    }
  else
    {
      if (command == MIDI_NOTE_ON)
        midiaction (notenumber);
      else if (command == MIDI_CONTROL_CHANGE)
        {
          gchar *command_name = get_midi_control_command (notenumber, velocity);
          if (command_name)
            {
              execute_callback_from_name (command_name);
              g_free (command_name);
            }
          else
            {
              if (notenumber == 0x40)
                {               //Foot Pedal
                  if (velocity == 0x7F)
                    {
                    if ((Denemo.project->movement->cursor_appending) || at_nonprinting ())
                        Denemo.keyboard_state |= ADDING_MASK;
                    else
                        Denemo.keyboard_state |= CHORD_MASK | ADDING_MASK;
                    }
                  else
                    {
                      Denemo.keyboard_state &= ~(CHORD_MASK | ADDING_MASK);
                      //next_editable_note (); this causes a double advance...
                    }
                  set_midi_in_status ();
                  displayhelper (Denemo.project);
                }
            }
        }
      else if (command == MIDI_PITCH_BEND)
        {
          gchar *command_name = get_midi_pitch_bend_command ((notenumber << 8) + velocity);
          if (command_name)
            {
              execute_callback_from_name (command_name);
              g_free (command_name);
            }
        }
    }
}
Exemple #3
0
/*  take an action for the passed note. Enter/edit/check the score following the mode and keyboard state. */
static gint
midiaction (gint notenum)
{
  gboolean new_measure = Denemo.project->movement->cursoroffend;
  DenemoProject *gui = Denemo.project;
  if (gui == NULL)
    return TRUE;
  if (gui->movement == NULL)
    return TRUE;
  DenemoStaff *curstaffstruct = (DenemoStaff *) gui->movement->currentstaff->data;
  enharmonic enote, prevenote;
  gboolean have_previous;
  //g_print("midiaction Adding mask %x, Chord mask %x\n", (Denemo.keyboard_state & ADDING_MASK) , (Denemo.keyboard_state & CHORD_MASK));
  notenum2enharmonic (notenum, &enote.mid_c_offset, &enote.enshift, &enote.octave);
  if (Denemo.project->movement->cursor_appending)
    have_previous = get_current (&prevenote);
  else
    have_previous = get_previous (&prevenote);

  if (!(Denemo.keyboard_state & CHECKING_MASK))
    stage_undo (gui->movement, ACTION_STAGE_END);     //undo is a queue so this is the end :)

  if ((gui->mode & INPUTEDIT) || (Denemo.keyboard_state & CHECKING_MASK))
    {
      static gboolean beep = FALSE;
      gboolean is_tied = FALSE;
      gint measure = gui->movement->currentmeasurenum;
      if (Denemo.project->movement->currentobject)
        {
          DenemoObject *curObj = Denemo.project->movement->currentobject->data;
          if (curObj->type == CHORD)
            {
              do
                {
                  curObj = Denemo.project->movement->currentobject->data;
                  chord *thechord = (chord *) curObj->object;
                  is_tied = (!Denemo.prefs.ignore_ties) && thechord->is_tied;

//#define check_midi_note(a,b,c,d) ((a->mid_c_offset==b)&&(a->enshift==c))?playnote(a,curstaffstruct->midi_channel):gdk_beep();
                  if ((Denemo.keyboard_state & CHECKING_MASK) && thechord->notes)
                    {
                      //later - find note nearest cursor and
                      note *thenote = (note *) thechord->notes->data;
//            check_midi_note(thenote, enote.mid_c_offset + 7 *(enote.octave), enote.enshift, enote.octave);
                      if ((!curObj->isinvisible) && (thenote->mid_c_offset == (enote.mid_c_offset + 7 * (enote.octave))) && (thenote->enshift == enote.enshift))
                        {
                          gint midi = dia_to_midinote (thenote->mid_c_offset) + thenote->enshift;
                          play_note (DEFAULT_BACKEND, 0 /*port */ , curstaffstruct->midi_channel, midi, 300 /*duration */ , 0);
                        }
                      else
                        {
                          gdk_beep ();
                          break;        //do not move on to next note
                        }
                    }
                  else
                    {

                      do_one_note (enote.mid_c_offset, enote.enshift, enote.octave);

                    }
                  if (Denemo.project->movement->cursor_appending)
                    break;
                    curObj = Denemo.project->movement->currentobject->data;
                    thechord = (chord *) curObj->object;
                    is_tied = (!Denemo.prefs.ignore_ties) && thechord->is_tied;
                }
              while ((!(Denemo.keyboard_state & ADDING_MASK)) && next_editable_note () && is_tied);
            }
          else //there is a current object that is not a chord
            {
              if (gui->movement->cursor_appending)
                {
                    do_one_note (enote.mid_c_offset, enote.enshift, enote.octave);
                    next_insert_or_editable_note();
                    //in some circumstance this fails to advance to the next editable note, the following checks for that.
                    if (Denemo.project->movement->currentobject)
                        {
                            curObj = Denemo.project->movement->currentobject->data;
                            if(!curObj->isinvisible)
                               next_editable_note ();
                        }
                }
              else
                gdk_beep ();
            }
          if (gui->mode & INPUTRHYTHM)
            {
              //g_print("measure was %d now %d with appending %d\n", measure, gui->movement->currentmeasurenum, gui->movement->cursor_appending);
              if (!beep && (measure != gui->movement->currentmeasurenum) && !gui->movement->cursor_appending)
                beep = TRUE;
              else if (beep)
                signal_measure_end (), beep = FALSE;
            }
        }
      else
        {                       // no current object
          do_one_note (enote.mid_c_offset, enote.enshift, enote.octave);
          next_insert_or_editable_note();//next_editable_note ();//if we have gone back from an empty measure we need this.
        }
    }
  else
    {                           // not INPUTEDIT
      action_note_into_score (enote.mid_c_offset, enote.enshift, enote.octave);
    }
  if (!(Denemo.keyboard_state & CHECKING_MASK))
    {
      stage_undo (gui->movement, ACTION_STAGE_START);
    }
  draw_score_area();     //just for advancing the cursor.
  if (!(Denemo.keyboard_state & CHECKING_MASK))
    {
      if (Denemo.prefs.immediateplayback)
        {
          gint channel = curstaffstruct->midi_channel;

          if (have_previous && check_interval (enote.mid_c_offset, enote.enshift, prevenote.mid_c_offset, prevenote.enshift))
            channel = Denemo.prefs.pitchspellingchannel;

          play_note (DEFAULT_BACKEND, 0 /*port */ , channel, notenum, 300 /*duration */ , 0);
          if(new_measure)
            signal_measure_end();
        }
    }

  return TRUE;
}