1 /*
2 * midi.c
3 *
4 * for Denemo, a gtk+ frontend to GNU Lilypond
5 * Copyright (C) 2000-2005 Brian Delaney
6 * Copyright (C) 2011 Dominic Sacré
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 */
13
14 #include <denemo/denemo.h>
15 #include "audio/midi.h"
16 #include "audio/audiointerface.h"
17 #include "smf.h"
18 #include "export/exportmidi.h"
19 #include "display/draw.h"
20 #include "core/view.h"
21 #include "audio/pitchentry.h"
22 #include "audio/instrumentname.h"
23 #include "printview/svgview.h"
24
25 #include <glib.h>
26 #include <math.h>
27 #include <string.h>
28 #include <assert.h>
29
30 #define SHAVING (0.01) //seconds to shave off a note start time to ensure stopping before noteon is sent, and starting with noteon first note may depend of speed of machine??? FIXME
31
32
33 static volatile gboolean playing = FALSE;
34
35 static double last_draw_time;
36
37 // huh?
38 static gboolean midi_capture_on = FALSE; //any midi events not caught by midi_divert will be dropped if this is true
39
40 static gdouble play_until = G_MAXDOUBLE;
41
42 /* MIDI in handling diversion to scheme scripts of MIDI in data */
43 static gint *divert_midi_event;
44 static gint divert_midi_id = 0; //id of the DenemoProject which wants to intercept midi events
45
46 static GQueue midi_queue = G_QUEUE_INIT;
47 static gint
put_get_midiqueue(gint midi)48 put_get_midiqueue (gint midi)
49 {
50 if (g_queue_is_empty (&midi_queue))
51 return midi;
52 g_queue_push_tail (&midi_queue, GINT_TO_POINTER (midi));
53 return GPOINTER_TO_INT( g_queue_pop_head (&midi_queue) );
54 }
55
56 static void
put_midiqueue(gint midi)57 put_midiqueue (gint midi)
58 {
59 g_queue_push_tail (&midi_queue, GINT_TO_POINTER (midi));
60 }
61
62 static gint
get_midiqueue(void)63 get_midiqueue (void)
64 {
65 return GPOINTER_TO_INT( g_queue_pop_head (&midi_queue) );
66 }
67
68 /*End of MIDI in handling diversion to scheme scripts of MIDI in data */
69
70 void
update_position(smf_event_t * event)71 update_position (smf_event_t * event)
72 {
73 DenemoMovement *si = Denemo.project->movement;
74
75 if (event)
76 {
77 if (((event->midi_buffer[0] & 0xf0) == MIDI_NOTE_ON) && ((event->time_seconds - last_draw_time) > Denemo.prefs.display_refresh))
78 {
79 last_draw_time = event->time_seconds;
80 queue_redraw_playhead (event);
81 }
82 }
83 else
84 {
85 if (si)
86 {
87 si->playingnow = NULL;
88 si->playhead = 0;
89 queue_redraw_all ();
90 }
91 }
92 }
93
94 static void
safely_add_track(smf_t * smf,smf_track_t * track)95 safely_add_track (smf_t * smf, smf_track_t * track)
96 {
97 track->smf = NULL;
98 smf_add_track (smf, track);
99 }
100
101 static void
safely_track_remove_from_smf(smf_track_t * track)102 safely_track_remove_from_smf (smf_track_t * track)
103 {
104 if (track->smf != NULL && (track->track_number>=1))
105 smf_track_remove_from_smf (track);
106 track->smf = NULL;
107 }
108
109 static GString *callback_script = NULL;
110 void
start_playing(gchar * callback)111 start_playing (gchar * callback)
112 {
113 smf_t *smf = Denemo.project->movement->smf;
114 if (callback && *callback)
115 callback_script = g_string_new (callback);
116 if (Denemo.project->movement->recorded_midi_track)
117 safely_add_track (Denemo.project->movement->smf, Denemo.project->movement->recorded_midi_track);
118
119 set_start_and_end_objects_for_draw ();
120 smf_rewind (smf);
121 gdouble start = (Denemo.project->movement->start_time/get_playback_speed()) - SHAVING;
122 if(smf_seek_to_seconds (smf, (start>0.0)?start:0.0))
123 g_warning("smf_seek_to_seconds %f failed", start);
124
125 initialize_until_time ();
126
127 initialize_playhead ();
128
129 playing = TRUE;
130 last_draw_time = -1.0;//needed to trigger drawing first note
131 }
132
133 static gboolean
stop_play_callback(gchar * thescript)134 stop_play_callback (gchar * thescript)
135 {
136 call_out_to_guile (thescript);
137 g_free (thescript);
138 return FALSE;
139 }
140
do_set_playbutton(gboolean paused)141 static gboolean do_set_playbutton (gboolean paused)
142 {
143 set_playbutton (paused);
144 return FALSE;
145 }
146 static gboolean
update_playbutton_callback(gboolean paused)147 update_playbutton_callback (gboolean paused)
148 {
149
150 g_main_context_invoke (NULL, (GSourceFunc)do_set_playbutton, GINT_TO_POINTER(paused));
151
152 return FALSE;
153 }
154
155 static void
finish_recording(void)156 finish_recording (void)
157 {
158 if ((Denemo.project->midi_destination & MIDIRECORD))
159 {
160 Denemo.project->midi_destination ^= MIDIRECORD;
161 g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc) show_midi_record_control, NULL, NULL);
162 }
163 }
164 void
stop_playing()165 stop_playing ()
166 {
167 update_position (NULL);
168 g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc) update_playbutton_callback, GINT_TO_POINTER (is_paused ()), NULL);
169 playing = FALSE;
170 play_until = -G_MAXDOUBLE;
171 if (Denemo.project->movement && Denemo.project->movement->recorded_midi_track)
172 {
173 safely_track_remove_from_smf (Denemo.project->movement->recorded_midi_track);
174 finish_recording ();
175 }
176 if (callback_script)
177 {
178 g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc) stop_play_callback, g_string_free (callback_script, FALSE), NULL);
179 callback_script = NULL;
180 }
181 }
182
183 void
toggle_paused()184 toggle_paused ()
185 {
186 if (play_until < 0.0)
187 play_until = G_MAXDOUBLE;
188 else
189 play_until = -G_MAXDOUBLE;
190 }
191
192 gboolean
is_playing()193 is_playing ()
194 {
195 return playing;
196 }
197
198 gboolean
is_paused()199 is_paused ()
200 {
201 return play_until < 0.0;
202 }
203
204 gdouble
get_playuntil(void)205 get_playuntil (void)
206 {
207 return play_until;
208 }
209
210 void
update_playback_start_time(double adjust)211 update_playback_start_time (double adjust)
212 {
213 if (Denemo.project && Denemo.project->movement)
214 {
215 Denemo.project->movement->start_time += adjust;
216 }
217 }
218
219 double
get_start_time()220 get_start_time ()
221 {
222 if (Denemo.project && Denemo.project->movement && (Denemo.project->movement->start_time > 0.0))
223 {
224 return Denemo.project->movement->start_time;
225 }
226 else
227 {
228 return 0.0;
229 }
230 }
231
232
233 double
get_end_time()234 get_end_time ()
235 {
236 if (Denemo.project && Denemo.project->movement && Denemo.project->movement->smf)
237 {
238 if (Denemo.project->movement->end_time < 0.0)
239 Denemo.project->movement->end_time = smf_get_length_seconds (Denemo.project->movement->smf);
240 return Denemo.project->movement->end_time;
241 }
242 else
243 {
244 return 0.0;
245 }
246 }
247
248
249 smf_event_t *
get_smf_event(double until_time)250 get_smf_event (double until_time)
251 {
252 if (Denemo.project == NULL || Denemo.project->movement == NULL || Denemo.project->movement->smf == NULL)
253 return NULL;
254 smf_t *smf = Denemo.project->movement->smf;
255
256 if (until_time > Denemo.project->movement->end_time)
257 {
258 until_time = Denemo.project->movement->end_time;
259 }
260
261 for (;;)
262 {
263 smf_event_t *event = smf_peek_next_event (smf);
264
265 if (event == NULL || event->time_seconds >= until_time)
266 {
267 return NULL;
268 }
269
270 if (smf_event_is_metadata (event))
271 {
272 // consume metadata event and continue with the next one
273 event = smf_get_next_event (smf);
274 continue;
275 }
276
277 // consume the event
278 event = smf_get_next_event (smf);
279 return event;
280 }
281 }
282
283
284
285
286 gdouble
get_time()287 get_time ()
288 {
289 GTimeVal tv;
290 double seconds;
291
292 g_get_current_time (&tv);
293
294 seconds = tv.tv_sec + tv.tv_usec / 1000000.0;
295 return seconds;
296 }
297
298
299 void
generate_midi(void)300 generate_midi (void)
301 {
302 if ((Denemo.project->movement->smf == NULL) || (Denemo.project->movement->smfsync != Denemo.project->movement->changecount))
303 {
304 exportmidi (NULL, Denemo.project->movement);
305 }
306
307 if (Denemo.project->movement->smf == NULL)
308 {
309 g_critical ("Loading SMF failed.");
310 }
311 }
312
313
314 /* return the time of the last event on the list events */
315 gdouble
get_midi_off_time(GList * events)316 get_midi_off_time (GList * events)
317 {
318 smf_event_t *event = g_list_last (events)->data;
319 return event->time_seconds;
320 }
321
322 /* return the time of the first event on the list events */
323 gdouble
get_midi_on_time(GList * events)324 get_midi_on_time (GList * events)
325 {
326 smf_event_t *event = events->data;
327 return event->time_seconds;
328 }
329
330
331 //finds the first note which comes ON after the passed time
332 DenemoObject *
get_obj_for_start_time(smf_t * smf,gdouble time)333 get_obj_for_start_time (smf_t * smf, gdouble time)
334 {
335 if (time < 0.0)
336 time = 0.0;
337 static smf_event_t *event;
338 smf_event_t *initial = smf_peek_next_event (smf);
339 gdouble total = smf_get_length_seconds (smf);
340 time = (time > total ? total : time);
341 if(smf_seek_to_seconds (smf, time))
342 g_debug("smf_seek_to_seconds failed");
343 do
344 {
345 event = smf_get_next_event (smf);
346 }
347 while (event && (((event->midi_buffer[0] & 0xF0) == MIDI_NOTE_OFF) || !event->user_pointer));
348 if (initial && smf_seek_to_event (smf, initial))
349 g_debug("smf_seek_to_event failed"); //if (event) g_debug("sought for endObj %f found %f\n", time, event->time_seconds);
350 if (event)
351 return (DenemoObject *) (event->user_pointer);
352 return get_object_for_time (time, TRUE);
353 }
354 //finds the first note which comes OFF after the passed time
355 DenemoObject *
get_obj_for_end_time(smf_t * smf,gdouble time)356 get_obj_for_end_time (smf_t * smf, gdouble time)
357 {
358 if (time < 0.0)
359 time = 0.0;
360 static smf_event_t *event = NULL;
361 smf_event_t *initial = smf_peek_next_event (smf);
362 gdouble total = smf_get_length_seconds (smf);
363 time = (time > total ? total : time);
364 if(smf_seek_to_seconds (smf, time))
365 g_debug("smf_seek_to_seconds failed");
366 do
367 {
368 event = smf_get_next_event (smf);
369 }
370 while (event && (((event->midi_buffer[0] & 0xF0) == MIDI_NOTE_ON) || !event->user_pointer));
371 if (initial && smf_seek_to_event (smf, initial))
372 g_debug("smf_seek_to_event failed");//if (event) g_debug("sought for startObj %f found %f\n", time, event->time_seconds);
373 if (event)
374 return (DenemoObject *) (event->user_pointer);
375 //midi is generated by LilyPond, no user_pointer, get timings from events.txt
376 return get_object_for_time (time, FALSE);
377 }
378
379
380
381 /**
382 * action_note_into_score
383 enters ( or (if mode==INPUTEDIT and appending) edits the note at the cursor)
384 * the parameters specify which note
385 * @mid_c_offset
386 * @enshift enharmonic adjustment -1 is one flat etc..
387 * @octave
388 */
389 static void
action_note_into_score(gint mid_c_offset,gint enshift,gint octave)390 action_note_into_score (gint mid_c_offset, gint enshift, gint octave)
391 {//g_print ("action note into score\n");
392 DenemoProject *gui = Denemo.project;
393 gui->last_source = INPUTMIDI;
394 gui->movement->cursor_y = gui->movement->staffletter_y = mid_c_offset;
395 gui->movement->cursor_y += 7 * octave;
396 //shiftcursor (gui, mid_c_offset);
397 //setenshift (gui->movement, enshift);
398 edit_pitch (mid_c_offset, enshift);
399 displayhelper (gui);
400 }
401
402 static void
add_or_delete_note_to_chord(gint mid_c_offset,gint enshift,gint octave)403 add_or_delete_note_to_chord (gint mid_c_offset, gint enshift, gint octave)
404 {//g_print ("add or delete note to chord\n");
405 DenemoProject *gui = Denemo.project;
406 DenemoObject *curObj;
407 gui->last_source = INPUTMIDI;
408 gui->movement->cursor_y = gui->movement->staffletter_y = mid_c_offset;
409 gui->movement->cursor_y += 7 * octave;
410 if(insert_or_delete_chordnote (enshift))
411 setenshift (gui->movement, enshift);
412 displayhelper (gui);
413 }
414
415 typedef struct enharmonic
416 {
417 gint mid_c_offset;
418 gint enshift;
419 gint octave;
420 } enharmonic;
421
422
new_midi_recording(void)423 void new_midi_recording (void) {
424 DenemoRecording *recording;
425 if(Denemo.project->movement->recording && (Denemo.project->movement->recording->type==DENEMO_RECORDING_MIDI))
426 {
427 //FIXME a better name for the mutex which originally was just for midi data, but will work for audio data too.
428 recording = Denemo.project->movement->recording;
429 g_static_mutex_lock (&smfmutex);
430 Denemo.project->movement->recording = NULL;
431 g_static_mutex_unlock (&smfmutex);
432 g_free (recording->filename);
433 g_free (recording);
434 g_list_free_full (recording->notes, g_free);
435 }
436 recording = (DenemoRecording *) g_malloc (sizeof (DenemoRecording));
437 recording->type = DENEMO_RECORDING_MIDI;
438 recording->samplerate = 44100;
439 Denemo.project->movement->recording = recording;
440 }
441
442 //Add the passed midi to a recording in Denemo.project->movement
443 static void
record_midi(gchar * buf,gdouble time)444 record_midi (gchar * buf, gdouble time)
445 {
446 buf[0] |= 0xF; //here force the channel to 15
447 smf_event_t *event = smf_event_new_from_pointer (buf, 3);
448 if (event && smf_event_is_valid (event))
449 {
450 if (Denemo.project->movement->recorded_midi_track && ((smf_track_t *) Denemo.project->movement->recorded_midi_track)->smf)
451 {
452
453 smf_track_add_event_seconds (Denemo.project->movement->recorded_midi_track, event, time);
454 if(Denemo.project->movement->recording && noteon_key(event))
455 {
456 DenemoRecordedNote *note = g_malloc0(sizeof(DenemoRecordedNote));
457 note->timing = event->time_seconds * Denemo.project->movement->recording->samplerate;
458 notenum2enharmonic (noteon_key(event), &(note->mid_c_offset), &(note->enshift), &(note->octave));
459 note->event = event;
460 Denemo.project->movement->recording->notes = g_list_append (Denemo.project->movement->recording->notes, note);
461 }
462 }
463 else
464 {
465 smf_event_delete (event);
466 gdk_beep ();
467 }
468 }
469 }
470
471 static void
do_one_note(gint mid_c_offset,gint enshift,gint notenum)472 do_one_note (gint mid_c_offset, gint enshift, gint notenum)
473 {//g_print("do one note Adding mask %x, Chord mask %x\n", (Denemo.keyboard_state & ADDING_MASK) , (Denemo.keyboard_state & CHORD_MASK));
474 if ((Denemo.keyboard_state & ADDING_MASK) && (Denemo.keyboard_state & CHORD_MASK))
475 {
476
477 add_or_delete_note_to_chord (mid_c_offset, enshift, notenum);
478 }
479 else
480 {
481 DenemoObject *curobj = NULL;
482 //check for non-printing notes - back up to the first non-printing note.
483 gboolean non_printing_note = FALSE;
484 PushPosition (NULL, NULL);
485 while (cursor_to_prev_note ())
486 {
487 curobj = Denemo.project->movement->currentobject->data;
488 if (!curobj->isinvisible)
489 break;
490 else
491 non_printing_note = TRUE;
492 }
493 if (Denemo.project->movement->currentobject)
494 {
495 curobj = Denemo.project->movement->currentobject->data;
496 if (non_printing_note)
497 {
498 if (!curobj->isinvisible)
499 cursor_to_next_note ();
500 (void)pop_position ();//Discard the pushed position
501 }
502 else
503 PopPosition (NULL, NULL);// go to where we started, as there are no non-printing notes
504 }
505 else
506 PopPosition (NULL, NULL);// go to where we started, as there are no non-printing notes
507 action_note_into_score (mid_c_offset, enshift, notenum);
508
509 if (Denemo.keyboard_state & ADDING_MASK)
510 Denemo.keyboard_state |= CHORD_MASK;
511 set_midi_in_status ();
512 }
513 }
514
515
516 static gboolean
get_current(enharmonic * enote)517 get_current (enharmonic * enote)
518 {
519 DenemoObject *curObj = NULL;
520 if (Denemo.project->movement->currentobject)
521 {
522 curObj = Denemo.project->movement->currentobject->data;
523 if (curObj && curObj->type == CHORD)
524 {
525 chord *thechord = (chord *) curObj->object;
526 if (thechord->notes)
527 {
528 note *thenote = (note *) thechord->notes->data;
529 enote->mid_c_offset = offsettonumber (thenote->mid_c_offset);
530 enote->enshift = thenote->enshift;
531 return TRUE;
532 }
533 }
534 }
535 return FALSE;
536 }
537
538 static gboolean
get_previous(enharmonic * enote)539 get_previous (enharmonic * enote)
540 {
541 DenemoObject *curObj = NULL;
542 if (Denemo.project->movement->currentobject)
543 {
544 if (Denemo.project->movement->currentobject->prev)
545 curObj = Denemo.project->movement->currentobject->prev->data;
546 else
547 {
548 if (Denemo.project->movement->currentmeasure->prev && Denemo.project->movement->currentmeasure->prev->data)
549 {
550 DenemoMeasure *m = (DenemoMeasure*)Denemo.project->movement->currentmeasure->prev->data;
551 curObj = m->objects?g_list_last (m->objects)->data:NULL;
552 }
553 }
554 }
555 if (curObj && curObj->type == CHORD)
556 {
557 chord *thechord = (chord *) curObj->object;
558 if (thechord->notes)
559 {
560 note *thenote = (note *) thechord->notes->data;
561 enote->mid_c_offset = offsettonumber (thenote->mid_c_offset);
562 enote->enshift = thenote->enshift;
563 return TRUE;
564 }
565 }
566 return FALSE;
567 }
568
569
at_nonprinting(void)570 static gboolean at_nonprinting (void)
571 {
572 DenemoStaff *curstaffstruct = (DenemoStaff *) Denemo.project->movement->currentstaff->data;
573 DenemoObject *curObj = Denemo.project->movement->currentobject->data;
574 return (curObj->type == CHORD && curObj->isinvisible);
575 }
576
577 /* take an action for the passed note. Enter/edit/check the score following the mode and keyboard state. */
578 static gint
midiaction(gint notenum)579 midiaction (gint notenum)
580 {
581 gboolean new_measure = Denemo.project->movement->cursoroffend;
582 DenemoProject *gui = Denemo.project;
583 if (gui == NULL)
584 return TRUE;
585 if (gui->movement == NULL)
586 return TRUE;
587 DenemoStaff *curstaffstruct = (DenemoStaff *) gui->movement->currentstaff->data;
588 enharmonic enote, prevenote;
589 gboolean have_previous;
590 //g_print("midiaction Adding mask %x, Chord mask %x\n", (Denemo.keyboard_state & ADDING_MASK) , (Denemo.keyboard_state & CHORD_MASK));
591 notenum2enharmonic (notenum, &enote.mid_c_offset, &enote.enshift, &enote.octave);
592 if (Denemo.project->movement->cursor_appending)
593 have_previous = get_current (&prevenote);
594 else
595 have_previous = get_previous (&prevenote);
596
597 if (!(Denemo.keyboard_state & CHECKING_MASK))
598 stage_undo (gui->movement, ACTION_STAGE_END); //undo is a queue so this is the end :)
599
600 if ((gui->mode & INPUTEDIT) || (Denemo.keyboard_state & CHECKING_MASK))
601 {
602 static gboolean beep = FALSE;
603 gboolean is_tied = FALSE;
604 gint measure = gui->movement->currentmeasurenum;
605 if (Denemo.project->movement->currentobject)
606 {
607 DenemoObject *curObj = Denemo.project->movement->currentobject->data;
608 if (curObj->type == CHORD)
609 {
610 do
611 {
612 curObj = Denemo.project->movement->currentobject->data;
613 chord *thechord = (chord *) curObj->object;
614 is_tied = thechord->is_tied;
615
616 //#define check_midi_note(a,b,c,d) ((a->mid_c_offset==b)&&(a->enshift==c))?playnote(a,curstaffstruct->midi_channel):gdk_beep();
617 if ((Denemo.keyboard_state & CHECKING_MASK) && thechord->notes)
618 {
619 //later - find note nearest cursor and
620 note *thenote = (note *) thechord->notes->data;
621 // check_midi_note(thenote, enote.mid_c_offset + 7 *(enote.octave), enote.enshift, enote.octave);
622 if ((!curObj->isinvisible) && (thenote->mid_c_offset == (enote.mid_c_offset + 7 * (enote.octave))) && (thenote->enshift == enote.enshift))
623 {
624 gint midi = dia_to_midinote (thenote->mid_c_offset) + thenote->enshift;
625 play_note (DEFAULT_BACKEND, 0 /*port */ , curstaffstruct->midi_channel, midi, 300 /*duration */ , 0);
626 }
627 else
628 {
629 gdk_beep ();
630 break; //do not move on to next note
631 }
632 }
633 else
634 {
635
636 do_one_note (enote.mid_c_offset, enote.enshift, enote.octave);
637
638 }
639 if (Denemo.project->movement->cursor_appending)
640 break;
641 curObj = Denemo.project->movement->currentobject->data;
642 thechord = (chord *) curObj->object;
643 is_tied = thechord->is_tied;
644 }
645 while ((!(Denemo.keyboard_state & ADDING_MASK)) && next_editable_note () && is_tied);
646 }
647 else //there is a current object that is not a chord
648 {
649 if (gui->movement->cursor_appending)
650 {
651 do_one_note (enote.mid_c_offset, enote.enshift, enote.octave);
652 next_insert_or_editable_note();
653 //in some circumstance this fails to advance to the next editable note, the following checks for that.
654 if (Denemo.project->movement->currentobject)
655 {
656 curObj = Denemo.project->movement->currentobject->data;
657 if(!curObj->isinvisible)
658 next_editable_note ();
659 }
660 }
661 else
662 gdk_beep ();
663 }
664 if (gui->mode & INPUTRHYTHM)
665 {
666 //g_print("measure was %d now %d with appending %d\n", measure, gui->movement->currentmeasurenum, gui->movement->cursor_appending);
667 if (!beep && (measure != gui->movement->currentmeasurenum) && !gui->movement->cursor_appending)
668 beep = TRUE;
669 else if (beep)
670 signal_measure_end (), beep = FALSE;
671 }
672 }
673 else
674 { // no current object
675 do_one_note (enote.mid_c_offset, enote.enshift, enote.octave);
676 next_insert_or_editable_note();//next_editable_note ();//if we have gone back from an empty measure we need this.
677 }
678 }
679 else
680 { // not INPUTEDIT
681 action_note_into_score (enote.mid_c_offset, enote.enshift, enote.octave);
682 }
683 if (!(Denemo.keyboard_state & CHECKING_MASK))
684 {
685 stage_undo (gui->movement, ACTION_STAGE_START);
686 }
687 draw_score_area(); //just for advancing the cursor.
688 if (!(Denemo.keyboard_state & CHECKING_MASK))
689 {
690 if (Denemo.prefs.immediateplayback)
691 {
692 gint channel = curstaffstruct->midi_channel;
693
694 if (have_previous && check_interval (enote.mid_c_offset, enote.enshift, prevenote.mid_c_offset, prevenote.enshift))
695 channel = Denemo.prefs.pitchspellingchannel;
696
697 play_note (DEFAULT_BACKEND, 0 /*port */ , channel, notenum, 300 /*duration */ , 0);
698 if(new_measure)
699 signal_measure_end();
700 }
701 }
702
703 return TRUE;
704 }
705
706
707 gboolean
set_midi_capture(gboolean set)708 set_midi_capture (gboolean set)
709 {
710 gboolean ret = midi_capture_on;
711 midi_capture_on = set;
712 if (!set)
713 divert_midi_id = 0;
714 return ret;
715 }
716
717
718 #define command ((*buf)&0xF0)
719 #define notenumber ((*(buf+1))&0x7F)
720 #define velocity ((*(buf+2))&0x7F)
721 void
adjust_midi_velocity(gchar * buf,gint percent)722 adjust_midi_velocity (gchar * buf, gint percent)
723 {
724 if ((command == MIDI_NOTE_ON) && buf[2])
725 buf[2] = 127 - (gint) ((127 - buf[2]) * percent / 100.0);
726 }
727
add_after_touch(gchar * buf)728 void add_after_touch (gchar * buf)
729 {
730 if (Denemo.prefs.damping)
731 {
732 static gdouble times[0x7F]; //takes no account of channel, really only good for one channel.
733 if (command == MIDI_NOTE_ON)
734 {
735 times[notenumber] = get_time ();
736 }
737 if (command == MIDI_NOTE_OFF)
738 {
739 //g_debug("after %f seconds\n", get_time()-times[notenumber]);
740
741 buf[0] = MIDI_NOTE_ON; //or the channel here
742 buf[2] = 60 / exp ((get_time () - times[notenumber]) * 1); //scale according to the time
743 return;
744 }
745 }
746 }
747
748 void
process_midi_event(gchar * buf)749 process_midi_event (gchar * buf)
750 {
751 if (command == MIDI_CONTROL_CHANGE && (notenumber == 0x40))
752 {
753 if (velocity == 0x7F)
754 {//PEDAL DOWN
755 if (Denemo.project->movement->cursor_appending || at_nonprinting ())
756 Denemo.keyboard_state |= ADDING_MASK;
757 else
758 Denemo.keyboard_state |= CHORD_MASK | ADDING_MASK;
759 }
760 else
761 {
762 Denemo.keyboard_state &= ~(CHORD_MASK | ADDING_MASK);
763 next_insert_or_editable_note();//next_insert_or_editable_note ();
764 }
765 set_midi_in_status ();
766 displayhelper (Denemo.project);
767 }
768 if ((0xFFFFFF & *(gint *) buf) == 0)
769 {
770 set_midi_capture (FALSE);
771 g_queue_clear (&midi_queue);
772 if (divert_midi_event)
773 {
774 *divert_midi_event = 0;
775 divert_midi_event = NULL;
776 gtk_main_quit ();
777 }
778 //g_debug("queue emptied %d\n", g_queue_get_length(&midi_queue));
779 }
780 else
781 {
782 if (command == MIDI_NOTE_ON)
783 midiaction (notenumber);
784 else if (command == MIDI_CONTROL_CHANGE)
785 {
786 gchar *command_name = get_midi_control_command (notenumber, velocity);
787 if (command_name)
788 {
789 execute_callback_from_name (command_name);
790 g_free (command_name);
791 }
792 else
793 {
794 if (notenumber == 0x40)
795 { //Foot Pedal
796 if (velocity == 0x7F)
797 {
798 if ((Denemo.project->movement->cursor_appending) || at_nonprinting ())
799 Denemo.keyboard_state |= ADDING_MASK;
800 else
801 Denemo.keyboard_state |= CHORD_MASK | ADDING_MASK;
802 }
803 else
804 {
805 Denemo.keyboard_state &= ~(CHORD_MASK | ADDING_MASK);
806 //next_editable_note (); this causes a double advance...
807 }
808 set_midi_in_status ();
809 displayhelper (Denemo.project);
810 }
811 }
812 }
813 else if (command == MIDI_PITCH_BEND)
814 {
815 gchar *command_name = get_midi_pitch_bend_command ((notenumber << 8) + velocity);
816 if (command_name)
817 {
818 execute_callback_from_name (command_name);
819 g_free (command_name);
820 }
821 }
822 }
823 }
824
825
826 void
initialize_until_time(void)827 initialize_until_time (void)
828 {
829 if ((Denemo.project->midi_destination & MIDIPLAYALONG) && Denemo.project->movement->currentobject)
830 {
831 DenemoObject *obj = Denemo.project->movement->currentobject->data;
832 if (obj->type == CHORD)
833 {
834 chord *thechord = obj->object;
835 if (thechord->notes)
836 {
837 play_until = obj->earliest_time - SHAVING; //g_debug("initial until %f\n", play_until);
838 }
839 }
840 }
841 else
842 play_until = G_MAXDOUBLE;
843 }
844
845 //test if the midi event in buf is a note-on for the current note
846 //if so set play_until
847 //advance cursor to next note
848 static void
advance_until_time(gchar * buf)849 advance_until_time (gchar * buf)
850 {
851 if (Denemo.project->movement->currentobject)
852 {
853 DenemoObject *obj = Denemo.project->movement->currentobject->data;
854 if (obj->type != CHORD)
855 if (cursor_to_next_chord ())
856 obj = Denemo.project->movement->currentobject->data;
857
858 if (Denemo.project->movement->currentobject && obj->type == CHORD)
859 {
860 chord *thechord = obj->object;
861 if (thechord->notes)
862 {
863 note *thenote = thechord->notes->data;
864 if (((buf[0] & 0xf0) == MIDI_NOTE_ON) && buf[2] && buf[1] == (dia_to_midinote (thenote->mid_c_offset) + thenote->enshift))
865 {
866 gdouble thetime = get_time ();
867 Denemo.project->movement->start_player = thetime - obj->earliest_time;
868
869 if (thechord->is_tied && cursor_to_next_note ())
870 {
871 obj = Denemo.project->movement->currentobject->data;
872 }
873 //IF THE NEXT OBJ IS A REST ADVANCE OVER IT/THEM
874 do
875 {
876 if (!cursor_to_next_note ()) //if(!cursor_to_next_chord())
877 {
878 play_until = G_MAXDOUBLE;
879 break;
880 }
881 else
882 {
883 obj = Denemo.project->movement->currentobject->data;
884 thechord = obj->object;
885 play_until = obj->earliest_time - SHAVING;
886 //g_debug("play until %f\n", play_until);
887 }
888 }
889 while (!thechord->notes);
890 }
891 }
892 }
893 else
894 g_warning ("Not on a chord");
895 }
896 else
897 g_warning ("Not on an object");
898 }
899
900 static void
adjust_midi_channel(gchar * buf)901 adjust_midi_channel (gchar * buf)
902 {
903 DenemoStaff *curstaffstruct = (DenemoStaff *) Denemo.project->movement->currentstaff->data;
904 gint channel = curstaffstruct->midi_channel;
905 if ((buf[0] & SYS_EXCLUSIVE_MESSAGE1) == MIDI_NOTE_ON)
906 {
907 buf[0] = MIDI_NOTE_ON | channel;
908 }
909 else if ((buf[0] & SYS_EXCLUSIVE_MESSAGE1) == MIDI_NOTE_OFF)
910 {
911 buf[0] = MIDI_NOTE_OFF | channel;
912 }
913 }
914
915 //Event generated by MIDI controller or Scheme script
916 //adjusts the note-on volume by preferred dynamic compression and plays the passed event on default backend
917 void
play_adjusted_midi_event(gchar * buf)918 play_adjusted_midi_event (gchar * buf)
919 {
920 adjust_midi_velocity (buf, 100 - Denemo.prefs.dynamic_compression);
921 add_after_touch (buf);
922 adjust_midi_channel (buf);
923 //g_print ("play adj midibytes 0x%hhX 0x%hhX 0x%hhX\n", *(buf+0), *(buf+1), *(buf+2));
924 play_midi_event (DEFAULT_BACKEND, 0, (guchar*) buf);
925 }
926
927 #define EDITING_MASK (GDK_SHIFT_MASK)
928 //these are event generated by a MIDI controller or Scheme script
929 void
handle_midi_event(gchar * buf)930 handle_midi_event (gchar * buf)
931 {
932 //g_debug("%x : ready %d %x queue %d\n", midi_capture_on, divert_midi_event!=NULL, (0xFFFFFF & *(gint*)buf), g_queue_get_length(&midi_queue));
933 if (midi_capture_on && divert_midi_id == Denemo.project->id)
934 {
935 // this is only good for one endianness - FIXME ??
936 if (divert_midi_event)
937 {
938 *divert_midi_event = (0xFFFFFF & put_get_midiqueue (*(gint *) buf));
939 divert_midi_event = NULL;
940 gtk_main_quit ();
941 }
942 else
943 {
944 put_midiqueue (*(gint *) buf);
945 }
946 return; //this *is* reached
947 }
948 if ((Denemo.project->midi_destination & MIDIRECORD) || (Denemo.project->midi_destination & (MIDIPLAYALONG | MIDICONDUCT)))
949 {
950 if (Denemo.project->midi_destination & MIDIRECORD)
951 record_midi (buf, get_playback_time ());
952 if (Denemo.project->midi_destination & (MIDIPLAYALONG))
953 advance_until_time (buf);//FIXME is this thread-safe????
954 else
955 play_adjusted_midi_event (buf);//play_midi_event (DEFAULT_BACKEND, 0, (guchar *) buf);
956 }
957 else
958 {
959 if ((Denemo.keyboard_state == (GDK_SHIFT_MASK | GDK_LOCK_MASK)) || Denemo.keyboard_state == (GDK_CONTROL_MASK) || Denemo.keyboard_state == (ADDING_MASK) || Denemo.keyboard_state == ((ADDING_MASK) | (CHORD_MASK)) || Denemo.keyboard_state == (GDK_CONTROL_MASK | GDK_LOCK_MASK) || (Denemo.keyboard_state == 0))
960 process_midi_event (buf);
961 else if (Denemo.keyboard_state == (GDK_SHIFT_MASK) || Denemo.keyboard_state == (GDK_LOCK_MASK))
962 {
963 play_adjusted_midi_event (buf);
964 }
965 }
966 }
967
968
969 gboolean
intercept_midi_event(gint * midi)970 intercept_midi_event (gint * midi)
971 {
972 if (divert_midi_event)
973 {
974 infodialog (_("Not exiting the previous MIDI capture loop"));
975 g_warning ("Cannot return to script");
976 // divert_midi_event = NULL;
977 // return FALSE;
978 set_midi_capture (FALSE);
979 g_queue_clear (&midi_queue);
980 return FALSE;
981 }
982 if (g_queue_is_empty (&midi_queue))
983 {
984 divert_midi_event = midi;
985 divert_midi_id = Denemo.project->id;
986 set_midi_capture (TRUE);
987 gtk_main ();
988 divert_midi_event = NULL;
989 return TRUE;
990 }
991 else
992 {
993 *midi = (0xFFFFFF & get_midiqueue ());
994 //g_debug("getting from queue %x\n", *midi);
995 }
996 return TRUE;
997 }
998
999
1000 gint
get_midi_channel(DenemoStaff * staff)1001 get_midi_channel (DenemoStaff * staff)
1002 {
1003 if (!strcmp (staff->midi_instrument->str, "drums"))
1004 {
1005 return 9;
1006 }
1007 else
1008 {
1009 gint tracknumber = Denemo.project->movement->currentstaffnum - 1;
1010 tracknumber = (tracknumber >= 9) ? tracknumber + 1 : tracknumber;
1011 return tracknumber & 0xF;
1012 }
1013 }
1014
1015
1016 gint
get_midi_prognum(DenemoStaff * staff)1017 get_midi_prognum (DenemoStaff * staff)
1018 {
1019 if (staff->midi_channel == 9)
1020 {
1021 return 0;
1022 }
1023 else
1024 {
1025 return select_program (staff->midi_instrument->str);
1026 }
1027 }
1028
1029
1030 gint
get_midi_port(DenemoStaff * staff)1031 get_midi_port (DenemoStaff * staff)
1032 {
1033 return staff->midi_port;
1034 }
1035
1036
1037
1038 /* change the MIDI output tuning */
1039 void
change_tuning(gdouble * cents)1040 change_tuning (gdouble * cents)
1041 {
1042 guchar buffer[] = {
1043 0xF0, 0x7F, // Universal Real-Time SysEx header
1044
1045 0x7F, //<device ID> ID of target device (7F = all devices)
1046
1047 0x08, // sub-ID#1 = "MIDI Tuning Standard"
1048
1049 0x08, // sub-ID#2 = "scale/octave tuning 1-byte form (Real-Time)"
1050
1051 0x03, /* channel/options byte 1
1052 bits 0 to 1 = channel 15 to 16
1053 bit 2 to 6 = reserved for future expansion */
1054
1055 0x7F, // channel byte 2 - bits 0 to 6 = channel 8 to 14
1056
1057 0x7F, // channel byte 3 - bits 0 to 6 = channel 1 to 7
1058 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1059 /* [ss] 12 byte tuning offset of 12 semitones from C to B
1060 00H means -64 cents
1061 40H means 0 cents (equal temperament)
1062 7FH means +63 cents */
1063
1064 0xF7 // EOX
1065 };
1066 gint i;
1067 for (i = 0; i < 12; i++)
1068 buffer[i + 8] = 64 + (cents[i] + 0.5);
1069 play_midi_event (DEFAULT_BACKEND, 0, buffer);
1070 }
1071
1072 //return the midi key of the passed event if note on, else 0
1073
1074 int
noteon_key(smf_event_t * event)1075 noteon_key (smf_event_t * event)
1076 {
1077 if ((event->midi_buffer[0] & SYS_EXCLUSIVE_MESSAGE1) == MIDI_NOTE_ON)
1078 return event->midi_buffer[1];
1079 return 0;
1080 }
1081