denemo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MIDI (was Re: [Denemo-devel] Anacrusis script needed)


From: Richard Shann
Subject: Re: MIDI (was Re: [Denemo-devel] Anacrusis script needed)
Date: Mon, 14 Sep 2009 09:36:01 +0100

One important aspect not covered here is calling the jack_playpitch from
a script - it depends on the gtk_main_loop running to fire the timer and
so schedule the note off event.
So if you are calling from a script you won't get a note off until you
call d-Getxxx and friends.
Some thought needed about how scripts interact with the gtk main loop.
Richard


On Sat, 2009-09-12 at 16:14 +0100, Richard Shann wrote:
> On Sat, 2009-09-12 at 07:45 -0500, Jeremiah Benham wrote:
> > Here is an attempt to implement what you were suggesting Richard. I am
> > having troubles with it. I repeatedly gives note on events and then
> > crashes denemo for some reason. 
> 
> You don't give the declaration of BufferReady, it must be volatile I
> think.
> You don't set up a timer, (I think you are relying on the timing of the
> jack interrupts instead), set one up and remember to return TRUE (or is
> it FALSE?) to make it a once-only timer, pass in the off-message to
> correspond with the on message.
> 
> Here is the same ideas in detail:
> 
> static volatile gboolean BufferReady=TRUE;//Switch the logic of the name
> around, ie call it BufferNotReady - depends who for - ready for what!
> perhaps BufferEmpty would be best name.
> > 
> > void
> > jack_playpitch(gint key, gint duration, gint volume, gint channel){
> >  if (!BufferReady){
> >    AllSoundOff=TRUE;
> >  }
> >  if (BufferReady){
> >     loop_index = 0;
> >     global_midi_buffer[0] = NOTE_ON;
> >     global_midi_buffer[1] = key; //freq
> >     global_midi_buffer[2] = volume;
> >     global_duration = duration;
> >     BufferReady=FALSE;
> >   }
> Here set up the timer to go off after duration with data the NOTEOFF
> message
> > }
> > 
> > static void
> > send_midi_event(jack_nframes_t nframes){
> >   unsigned char *buffer;
> >   gint i=0;
> >   gint channel;
> >   void *port_buffers[MAX_NUMBER_OF_TRACKS];
> >   if (AllSoundOff){
> >     for (channel=0;channel<16;channel++){
> >       buffer = jack_midi_event_reserve(port_buffers[i], 0, 3);
> >       buffer[0] = MIDI_CONTROLLER | channel;
> >       buffer[1] = MIDI_ALL_NOTE_OFF;
> >       buffer[2] = 0;
> >       global_duration = loop_index = 0;
> >       AllSoundOff=FALSE;
> >     }
> >   }
> > 
> >   if (!BufferReady)
> >    if (output_ports[i]){
> >      port_buffers[i] = jack_port_get_buffer(output_ports[i], nframes);
> >      jack_midi_clear_buffer(port_buffers[i]);
> >      buffer = jack_midi_event_reserve(port_buffers[i], 0, 3);
> >      buffer[0] = global_midi_buffer[0];
> >      buffer[1] = global_midi_buffer[1];
> >      buffer[2] = global_midi_buffer[2];
> >      BufferReady=TRUE;
> >    }
> > }
> > 
> > static void
> static gboolean a g_timer call back (or is it gtk_timer??)
> > timer_callback(jack_nframes_t nframes){
> in this timer callback put the message into global_buffer in the same
> way as the original ON message, ie testing BufferReady.
> and return making it a once only timer.
> 
> >   gint i;
> >   for (i=0;i<nframes;i++)
> >     if (global_duration != 0){
> >       if ((loop_index++ >= global_duration) && BufferReady){
> >        global_midi_buffer[0] = NOTE_OFF;
> >        /*global_midi_buffer[1] = same*/
> >        global_midi_buffer[2] = 0;
> >        BufferReady=FALSE;
> >        global_duration = loop_index = 0;
> >       }   
> >       if ((loop_index > global_duration) && !BufferReady){
> >         global_duration = loop_index = 0;
> >         AllSoundOff=TRUE;
> >       }
> >     }
> > }
> > 
> > Also in process_callback I put this:
> > if (Denemo.gui->si && output_ports && Denemo.prefs.immediateplayback){
> >           send_midi_event(nframes);
> it might be better to put the code for send_midi_event directly here and
> put a warning at the start about it being called under interrupt, so no
> printf's mallocs, g_list_appends or anything function calls really,
> unless you are quite sure.
> >           timer_callback(nframes);
> don't do this timer_callback
> 
> >         }
> > 
> > 
> > Thanks for your help,
> > Jeremiah
> > 
> 
> 
> 
> _______________________________________________
> Denemo-devel mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/denemo-devel





reply via email to

[Prev in Thread] Current Thread [Next in Thread]