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: Tue, 15 Sep 2009 22:23:48 -0500

On Tue, 15 Sep 2009 09:03:36 +0100
Richard Shann <address@hidden> wrote:

 And after playback we can't do the
> immediate playing back of notes,  presumably because we are assigning
> time 0 to them and we have already given data for later times...
>

Here is a patch that fixes that. It is not any kind of solution
because it crashes denemo if transport is set to on and denemo is not
run inside gdb but it is at least a clue on how it can be fixed. It
works fine in gdb or if transport is not enabled. 

> Where is Jack getting its notion of the (absolute) time from? We need
> to declare the time of our data to be relative to that.

I don't think that is the issue. But it is declared like this:
 
t = seconds_to_nframes(event->time_seconds - start_time) +
playback_started - song_position + nframes - last_frame_time; buffer =

start_time and song_position in every case I tested is always 0.
event->time_seconds is when smf says that the event started in seconds.
playback_started is the jack frame number assigned at the beginning by 
playback_started = jack_frame_time(jack_client);
last_frame time is assigned with the same function but only directly
before calling the jack_midi_event_reserve.

jack_midi_event_reserve(port_buffers[track_number], t,
event->midi_buffer_length);

This second argument to jack_midi_event_reserve is the sample offset. 
This all runs in a for(;;) loop. If t>nframes it breaks and gets
processed later. 

Jeremiah


> Richard
> 
> 
> 
> 
> > 
> > Jeremiah
> > 
> > 
> > 
> > On Sep 14, 2009, at 12:30 PM, Richard Shann
> > <address@hidden> wrote:
> > 
> > > On Mon, 2009-09-14 at 11:57 -0500, Jeremiah Benham wrote:
> > >> On Mon, 14 Sep 2009 16:51:23 +0100
> > >> Richard Shann <address@hidden> wrote:
> > >>
> > >>> On Mon, 2009-09-14 at 14:39 +0100, Richard Shann wrote:
> > >>>> There is some investigating still to do - why does it repeat
> > >>>> noteon madly if no noteoff is given etc, but it seems usable.
> > >>>> I don't understand all the stuff about nframes etc there is a
> > >>>> loop which is is going thru
> > >>>>  for(n=0;n<nframes;n++){
> > >>>> in send_midi_event which can only fire once - also i is just a
> > >>>> synonym for 0 here...
> > >>>>
> > >>> OK, I have looked at this. The loop is spurious, and puts the
> > >>> noteon message in multiple times, which is what you hear if
> > >>> your noteoff is not scheduled for 44 seconds. The noteon is
> > >>> being put as having a time n, by this
> > >>>
> > >>>    buffer = jack_midi_event_reserve(port_buffers[i], n, 3);
> > >>>
> > >>
> > >> I tried that but it did not work.
> > > hmm, I have the duration reduced to 100ms though, so perhaps that
> > > is why
> > > it is working for me. In fact I have the following now:
> > >
> > > static void
> > > send_midi_event(jack_nframes_t nframes){
> > >  unsigned char *buffer;
> > >  gint n;
> > >  void *port_buffer;
> > >
> > >      if (output_ports[0]){
> > >    port_buffer = jack_port_get_buffer(output_ports[0], nframes);
> > >    jack_midi_clear_buffer(port_buffer);
> > >    if (BufferEmpty==FALSE){
> > >      buffer = jack_midi_event_reserve(port_buffer, 0, 3);
> > >      if (buffer == NULL) {
> > >        warn_from_jack_thread_context("jack_midi_event_reserve  
> > > failed, NOTE LOST.");
> > >        return;
> > >      }
> > >      buffer[0] = global_midi_buffer[0];
> > >      buffer[1] = global_midi_buffer[1];
> > >      buffer[2] = global_midi_buffer[2];
> > >      BufferEmpty=TRUE;
> > >      warn_from_jack_thread_context("Setting TRUE\n");
> > >    }
> > >      }
> > > }
> > >
> > > This has the jack_midi_clear_buffer done regardless of whether we
> > > have new data for it - if it still contains the old data that
> > > could explain the repeated notes.
> > > This is working fine for me - I haven't tried the 44 second note  
> > > though.
> > > Can you try this?
> > > Richard
> > >
> > >
> > >> Through trial and error I have only
> > >> found that this works:
> > >>
> > >>
> > >> static void
> > >> send_midi_event(jack_nframes_t nframes){
> > >>  unsigned char *buffer;
> > >>  gint i=0;
> > >>
> > >>  void *port_buffers[MAX_NUMBER_OF_TRACKS];
> > >>  if (global_midi_buffer[0] >=0){
> > >>     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];
> > >>     global_midi_buffer[0] = 0;
> > >>     BufferEmpty=TRUE;
> > >>   }
> > >>  }
> > >> }
> > >>
> > >> I have removed the loop even though it was not causing it. Was I
> > >> believe was causing it was the BufferEmpty even though it was
> > >> set to static volatile gboolean.
> > >>
> > >>> we only want to put it in at time 0.
> > >>>
> > >>> Shall I check something in along these lines?
> > >>
> > >> I would say no unless you have tested it and it works.
> > >>
> > >> Jeremiah
> > >>
> > >>> Richard
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> _______________________________________________
> > >>> 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_immediate_playback.patch
Description: Text Data


reply via email to

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