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: Jeremiah Benham
Subject: Re: MIDI (was Re: [Denemo-devel] Anacrusis script needed)
Date: Mon, 14 Sep 2009 05:37:57 -0500

On Mon, 14 Sep 2009 09:36:01 +0100
Richard Shann <address@hidden> wrote:

I seem to be a bit stuck. I am attaching a diff. Let me now if it
appears I am overlooking something.

Jeremiah



> 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
> 
> 
> 
> _______________________________________________
> Denemo-devel mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/denemo-devel

Attachment: denemo_jackmidi.patch
Description: Text Data


reply via email to

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