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: Tue, 15 Sep 2009 09:03:36 +0100

On Mon, 2009-09-14 at 15:23 -0500, Jeremiah Benham wrote:
> Oh. Great. I modified my code to and now it works. Even with the 44  
> second long note. Haha.
I think the next thing you need to get sorted out is the meaning of the
(absolute) time in this system. Our single note messages are being
assigned time 0, and our playback smf structure has times assigned to
the events starting with time 0. The jack system which is doing
interrupting and asking for more data has a notion of the (absolute)
time which is encoded as the value nframes (you convert to seconds via a
conversion factor called sample rate),
 hmm there are two callbacks 
sync_callback   called when the client asks for a new position (e.g. at
the start)
process_callback called when the client needs the next lot of data

So it is the sync_callback one which needs sorting out - we need to
align the time stamps of our data with the jack time when this is
called. At the moment, libsmf complains that we are trying to seek past
the end of the song when sync_callback is called. 
As it happens, by the time the complaint is issued the
smf_seek_to_seconds() call has already rewound the smf, so we get what
is needed, but it is badly done. 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...

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.

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





reply via email to

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