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: Fri, 25 Sep 2009 17:52:11 +0100

On Fri, 2009-09-25 at 10:14 -0500, Jeremiah Benham wrote:
> On Fri, 2009-09-25 at 08:40 +0100, Richard Shann wrote:
> 
> > So the proc PlayNote would be
> > 
> > (define (PlayNote pitch) (d-OutputMIDI (string-append "0x9$ " pitch " 
> > %%%")))
> > 
> > which would be called as
> > 
> > (PlayNote "60")
> > 
> > or (PlayNote "0x3C") if people wished.
> > 
> > (the define above is E&OE - I haven't checked the syntax!)
> 
> So this is all getting clearer now. There are still a few things I am
> unsure about. Earlier you described two functions. The first is for
> immediate playback. The second is for an arbitrary midi message.
> Currently d-PlayMidiKey is wired to the immediate playback function. You
> mentioned renaming d-PlayMidiKey to d-PlayNote. The above sounds to me
> like you are describing one c function for arbitrary midi message and a
> scheme procedure that calls that c function to do immediate playback for
> script writers. If this is true, what will control the note duration?
Yes, I was not thinking so clearly there:

 I think I previously mentioned that we should have a (d-CreateTimer ms
"scheme") 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. It wouldn't be
useful for scripts that keep control (since the gtk main loop would not
run). So I should have written
(define (PlayNote pitch duration) 
        (d-OutputMIDI (string-append "0x9$ " pitch " %%%"))
        (d-OneShotTimer duration "(d-OutputMIDI (string-append "0x8$ " pitch "
%%%"))
        )

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? 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.


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.

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
      * the d-OutputMidi command that outputs the bytes contained in a
        string, with substitution of chanel for $ and volume for %%%
Is that ok?


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]