denemo-devel
[Top][All Lists]
Advanced

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

Re: [Denemo-devel] Jackmidi Status?


From: Richard Shann
Subject: Re: [Denemo-devel] Jackmidi Status?
Date: Mon, 28 Sep 2009 18:09:15 +0100

On Mon, 2009-09-28 at 08:33 -0500, Jeremiah Benham wrote:
> On Fri, 25 Sep 2009 17:52:11 +0100
> Richard Shann <address@hidden> wrote:
> 
> 
> > > > (define (PlayNote pitch) (d-OutputMIDI (string-append "0x9$ "
> > > > pitch " %%%")))
> 
> Ok. I have implemented this in denemo.scm. It requires two parameters
> though. (d-PlayNote pitch duration).
this should be called (PlayNote ...) not d-
because it is not to be found written in C but in denemo.scm


>  I have yet to implement this "0x9$
> " and " %%%" yet because I have not placed the string substitution in
> the code yet. 
> 
> Unfortunately I can't do this for some reason:
> (d-PlayNote "60" 1000)
> (d-PlayNote "63" 1000)
The reason is you have no buffering so on the second call BufferEmpty is
still FALSE because there has not been enough time for jack to empty
global_midi_buffer.

if you put an else for this bit of code

 if (BufferEmpty==TRUE){ 
  global_midi_buffer.buffer[0] = buffer[0];
 global_midi_buffer.buffer[1] = buffer[1];
   global_midi_buffer.buffer[2] = buffer[2];
 BufferEmpty=FALSE;
 }   
else whoops! overrun
I think you will see this.

> Only the first note gets turned on/off. The second note is ignored.
> 
> >  I think I previously mentioned that we should have a (d-CreateTimer
> > ms "scheme") 
> 
> I have implemented this also. I call it (d-OneShotTimer ms "scheme").
> It still needs a little work because if the "scheme" does not execute
> properly it will crash denemo. I don't know how to fix this yet. 
> 
> >which starts a gtk timer to go off (one shot) in ms
> > milliseconds calling eval_scheme_string(scheme) (or whatever it is
> > called - call_out_to_scheme is it?). This would be for use in
> > event-driven applications, like the new game interface. 
> 
> How would this be used in the new game interface besides calling the
> end of game after $x amount of time?
> 
> > where I have called the timer function d-OneShotTimer as perhaps we
> > may want to create timers that carry on calling back. Or perhaps we
> > should call it (d-EvalAfterMs ms "scheme") which evaluates "scheme"
> > after ms milliseconds? 
> 
> I have yet to implement this but I will wait until (d-OneShotTimer ...
> does not crash denemo. 
> 
> >Oh, and the syntax is surely wrong for the
> > parameters, it must be (define (PlayNote ((pitch 60) (duration
> > 1000)) ... but you get the idea, I hope.
> 
> I assume the ((pitch 60) (duration 1000)) is inside 
> (let ((pitch 60) (duration 1000)). Or... Is this some way of creating
> defaults in case the is the wrong number of arguments? So if
> (d-PlayNote) is called with no arguments then it will play note 60 for
> 1000ms? I know in python this is extremely easy to do. I don't know
> about scheme. 
> 
> If the procedure (d-PlayNote) in denemo.scm is not
> correct let me know. 
> 
> > For scripts that keep on running we need a non-blocking call to the
> > gtk_main loop. The call needed is
> > 
> > gtk_main_iteration_do(FALSE);
> > 
> > So we would wire (d-CheckForEvent) to call this, which if done
> > repeatedly will keep the Denemo interface alive (it means the user can
> > change things while the script is running, if you have left the menus
> > visible or keyboard shortcuts on etc the user can do things while the
> > note is playing). So a loop sleeping for 1/100 second and running this
> > d-CheckEvent will allow the noteoff event timer to fire.
> 
> I don't really understand how the above works. So I create an interface
> (is this what it is called) called by (d-CheckForEvent) in view.c. It
> runs gtk_main_iteration_do(FALSE);. Then when and how do I use
> (d-CheckForEvent)? 
> 
> > Again (d-CheckForEvent) is just a name off the top of my head. The
> > script writer needs to understand that it is looking for and actioning
> > any events pending - I think it only does one of the events(?). So
> > perhaps CheckForEvent doesn't imply that the event will be actioned?
> > Naming suggestions welcome!
> > 
> > Does this cover everything? The point is it is no use calling a
> > routine that does the note on and sets up the timer if you are then
> > going to carry on inside your script, never giving the main loop a
> > chance to run and hence find that the timer has expired.
> > 
> > Summary:
> >       * A create timer command that evaluates some passed in scheme
> >         after some milliseconds
> >       * A check and action any events pending command to keep the main
> >         loop running during a script
> 
> I believe the main loop is still running. 
not while your script is running, unless it calls d-GetUserInput or
similar.

> The menu's are active when I
> have called executed (d-OneShotTimer duration "scheme").
executed d-OneShotTimer and gone on to do what? Until you do something
to allow the main loop to run, it won't.

>  Running
> (sleep 1) is the only thing I know of that prevents action until the
> sleep is over. 



> 
> >       * the d-OutputMidi command that outputs the bytes contained in a
> >         string, with substitution of chanel for $ and volume for %%%
> > Is that ok?
> 
> No. There is still something I am missing. The problem I am having now
> (besides debuging improper input) is that (d-PlayNote pitch duration)
> will only play one note per script.
see first comment.
>  I don't know how to play a series
> of notes nor do I know how to play a triad. Perhaps the timer can be
> used to schedule future notes. Like:
> (d-OneShotTimer 0 "(d-PlayNote "0x3c" 1000)")
> (d-OneShotTimer 1000 "(d-PlayNote "0x3e" 1000)")
you won't need this

Richard


> 
> Except that I will have to "\"" the quotations around 0x3c etc....
> 
> Jeremiah
> 
> > 
> > 
> > Richard
> > 
> > 
> > > Would the script writer do: 
> > > 
> > > (PlayNote "0x3C")
> > > (sleep 1)
> > > (d-OutputMIDI "0x80 0x3c 0")
> > > 
> > > And then a triad?:
> > > 
> > > (PlayNote "0x3C")
> > > (PlayNote "0x40")
> > > (PlayNote "0x43")
> > > 
> > > (sleep 1)
> > > 
> > > (d-OutputMIDI "0x80 0x3c 0")
> > > (d-OutputMIDI "0x80 0x40 0")
> > > (d-OutputMIDI "0x80 0x43 0")
> > > 
> > > The problem with this method is that the denemo interface will hang
> > > for 1 second here awaiting wake from sleep. Maybe that is not a
> > > problem or an issue. 
> > > 
> > > We could have the d-OutputMIDI recognize 0x90 and call the function
> > > that is currently wired up to d-PlayMidiKey so that the timer
> > > callback turns the note off. In this way the user has no control of
> > > the duration. If not how we described above, how are we going to
> > > control duration.   
> > > 
> > > So we are going to have three c functions for this. 
> > >   *jackmidi::SendMidiMessage - for sending arbitrary midi messages
> > >   *jackmidi::immediate_playback - used only when users enter notes
> > > in the gui for immediate playback.
> > >   *scheme_output_midi - interface for scheme to send data to
> > > jackmidi::SendMidiMessage  
> > > 
> > > Then we have one scheme procedure:
> > >   *d-PlayNote - This is a scheme wrapper for d-OutputMIDI for easy
> > > note playback 
> > > 
> > > If the above is correct then I am confused about a way to control
> > > duration of note (unless this is controlled via the sleep method
> > > mentioned above). 
> > > 
> > > Jeremiah
> > > 
> > > > richard
> > > > 
> > > > 
> > > > 
> > > > >  If  
> > > > > the argument us left blank it should default to current
> > > > > volume/channel.
> > > > > 
> > > > > > Which is what you would script into a
> > > > > > DenemoDirective midibytes field. Of course, this can then all
> > > > > > be hidden
> > > > > > inside
> > > > > > (PlayNote "0x3c")
> > > > > 
> > > > > If everything is on one set of quoted than the size of the
> > > > > string can determine outcome of an if/else. If length of string
> > > > > == 2 default to staffs channel/volume. If string == 6 then use
> > > > > the script parameters, this is assuming it is all hex. Putting
> > > > > a decimal will create a size of 6-9 depending on how many
> > > > > digits are used.
> > > > > 
> > > > > I must go now
> > > > > Jeremiah
> > > > > 
> > > > > >
> > > > > > Incidentally, we should reserve (d-Something...) to mean a
> > > > > > procedure not
> > > > > > to be found in denemo.scm, init.scm etc, that is, a command
> > > > > > (even though some would never appear in menus).
> > > > > >
> > > > > >> I think some midi messages are 4 byte. I am not sure which
> > > > > >> ones off the
> > > > > >> top of my head though. I think we can start with three and
> > > > > >> if there is a
> > > > > >> demand for 4 byte we can add that. Perhaps d-OutputMIDI can
> > > > > >> take an optional 4th byte.
> > > > > >>
> > > > > >> for d-PlayNote we could do (d-PlayNote "0x3c"). This would
> > > > > >> use the selected staffs channel/volume etc.. If the user
> > > > > >> wanted to change that
> > > > > >> they would use a different script to change the staff
> > > > > >> properties. So if
> > > > > >> they wanted to play a note on every channel they would do
> > > > > >> something like.
> > > > > >>
> > > > > >> (d-StaffPropertiesMidiChannel "2")
> > > > > >> (d-PlayNote "0x3c")
> > > > > >>
> > > > > >> This can be placed in a loop or whatever. We can also have
> > > > > >> maybe a more
> > > > > >> complicated (d-PlayNote "notenum" "duration").
> > > > > >>
> > > > > >> I also wonder if it would be better for complicated things
> > > > > >> like StaffProperties if we used regex or something that way
> > > > > >> it looks like this:
> > > > > >>
> > > > > >> (d-StafProperties "midi_channel=1 midi_volume=127")
> > > > > >> Then all the other values are left alone. Perhaps something
> > > > > >> like:
> > > > > >>
> > > > > >> (d-StaffProperties "help")
> > > > > >> can list variables to set.
> > > > > > This is the real nitty gritty: at the moment we write
> > > > > > (d-StaffProperties "prop1=value\0prop2=value...")
> > > > > >
> > > > > > where there is no way of discovering the names prop1 etc
> > > > > > (they are hardwired into the callback of the StaffProperties
> > > > > > command). This last we can fix, I think, at least with a bit
> > > > > > of macho macro work in the GET_PARAM stuff (in utils.h);
> > > > > > essentially responding to the "help" string by returning the
> > > > > > list of parameter names (which already appear as the macro
> > > > > > arguments). However we still have those NULLs separating the
> > > > > > strings. Again, with more work on the macros we could make
> > > > > > them detect the type of the param
> > > > > > passed, so that commands could take a list argument. The list
> > > > > > would be a
> > > > > > list of strings "prop1=value". Again, that just requires a
> > > > > > bit a macho macro work in utils.h, we could keep the present
> > > > > > code for backward compatibility.
> > > > > > I think that is the way to go.
> > > > > >>
> > > > > >> Sorry I am just kind of brainstorming here.
> > > > > > Thanks
> > > > > > Richard
> > > > > >
> > > > > >
> > > > > >>
> > > > > >> 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]