denemo-devel
[Top][All Lists]
Advanced

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

Re: [Denemo-devel] Real time playback in Denemo


From: Richard Shann
Subject: Re: [Denemo-devel] Real time playback in Denemo
Date: Wed, 04 Jan 2012 11:19:50 +0000

On Tue, 2012-01-03 at 00:13 -0600, Jeremiah Benham wrote:
> On 01/02/2012 05:36 AM, Richard Shann wrote:
> > On Sun, 2012-01-01 at 14:41 -0600, Jeremiah Benham wrote:
> >> Are we going to have a release before we start this?
> > I think we should. Playback should mark release 1.0 I think.
> > What housekeeping things are there outstanding before a release
> > candidate is created?
> 
> I am getting these warnings on startup. I don't know if you see it or not:
> (denemo:8292): Gtk-CRITICAL **: gtk_menu_item_get_submenu: assertion 
> `GTK_IS_MENU_ITEM (menu_item)' failed
> 
> (denemo:8292): Gtk-CRITICAL **: gtk_container_foreach: assertion 
> `GTK_IS_CONTAINER (container)' failed
> 
> (denemo:8292): Gtk-CRITICAL **: gtk_menu_item_get_submenu: assertion 
> `GTK_IS_MENU_ITEM (menu_item)' failed
> 
> (denemo:8292): Gtk-CRITICAL **: gtk_container_foreach: assertion 
> `GTK_IS_CONTAINER (container)' failed
> 
> (denemo:8292): Gtk-CRITICAL **: gtk_container_foreach: assertion 
> `GTK_IS_CONTAINER (container)' failed
> 
> (denemo:8292): Gtk-CRITICAL **: gtk_menu_shell_insert: assertion 
> `GTK_IS_MENU_SHELL (menu_shell)' failed
> 
When you removed the built-in commands you left them in the denemoui.xml
menu builder, which seems to have been the source of that.

> 
> Should we create scheme alternatives to the built-ins for dynamics? Some 
> of these would require multiple glyphs FFF, ppp, etc...
I only see non-built-in dynamics (at Directives->Dynamics) and the
built-in cresc etc. If there are others I don't think we need them,
though whether having the dynamics as standalone objects is good or not
I can't really say (I don't have occasion to use them)

> 
> It is not a big deal but the ornaments and articulations with the 
> override above always have glyph x number of pixels above the note. 
> Intead it should somehow be x number of pixels above the top line. This 
> is true unless note stem is > height of top staff line. The problem with 
> it now is if someone puts a fermata on a middle c, the fermata would 
> appear around the 1st or 2nd staff line.

hmm, yes I was noticing that myself recently - some things, like
staccato need to stay with the notehead, other things not. Needs some
more thought, and probably another override (sigh).

Richard



> 
> Jeremiah
> 
> >
> > Richard
> >
> >
> >> Jeremiah
> >>
> >> Sent from my Samsung smartphone on AT&T
> >>
> >> Richard Shann<address@hidden>  wrote:
> >>
> >>> I think the next big step for Denemo will be to get the playback working
> >>> in its own thread.
> >>>
> >>> Below are some ideas for how to do this, first there are some notes
> >>> which you can cut out if you already know how the soc code is working.
> >>>
> >>> 8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8>< 
> >>>  8><  8><  8><
> >>> I have studied the soc branch code and made the following notes:
> >>>
> >>> The playback works by using two threads, one is the
> >>> process_thread_func() of the backend chosen (I see alsabackend.c and
> >>> dummybackend.c so far) and the other is the queue_thread_func() in
> >>> audiointerface.c
> >>>
> >>> The process_thread_func() creates a mutex and then runs a loop:
> >>> the loop gets the system time g_get_current_time() and to it adds 5ms (a
> >>> compiler constant called PLAYBACK_INTERVAL). This time is then used for
> >>> a timed wait on a condition with the mutex, that is a call to
> >>> g_cond_timed_wait(). This means that the thread waits for the condition
> >>> process_cond to be signalled or until the 5ms have elapsed.
> >>> The g_cond_timed_wait() unlocks the mutex before the thread sleeps and
> >>> locks it when it continues.
> >>> ***Question*** is it ok that the mutex has not been locked for the first
> >>> time (and correspondingly, at the end g_mutex_free() is called without
> >>> unlocking the mutex, is that ok?).
> >>>
> >>> Next a check is made for quitting the loop - this is done by making an
> >>> atomic access to an int which is set by the alsa_seq_destroy() call.
> >>> ***Question*** does that need to be an atomic access? The int in
> >>> question is just a boolean, so in C it just means that if any of the
> >>> bits are set it is true. So it really doesn't matter if another thread
> >>> is halfway through setting it.
> >>>
> >>> Next is code which I think is for MIDI input - I ignore this here.
> >>>
> >>> Now the playback code continues by getting the current time and
> >>> subtracting a value called playback_start_time. This latter value is set
> >>> up when starting the playing by getting the system time and subtracting
> >>> a value "playback_time" which is kept in audiointerface.c and controlled
> >>> by calls to the function update_playback_time() and initialized by
> >>> midi_play() to Denemo.gui->si->start_time. This last is the time in
> >>> seconds from the start of the piece which the user has set as the time
> >>> to start from (e.g. via d-SetPlaybackInterval etc).
> >>> So for the case of playing an entire movement, this is zero, and the
> >>> playback_start_time is the system time when the play was initiated.
> >>>
> >>> Back to the loop which the process_thread_func() runs...
> >>>
> >>> The difference between the current time and the playback_start_time is
> >>> called the playback_time and is time in seconds along the midi track
> >>> where the next event should be taken from.
> >>>
> >>> After a check for reset (I ignore that here) an event is read from the
> >>> queue. This is the call read_event_from_queue() in audiointerface.c.
> >>> This is called with a parameter called until_time which is set to the
> >>> playback_time plus 5ms (the PLAYBACK_INTERVAL value again). After
> >>> checking for stop play conditions (discuss later) this calls into
> >>> eventqueue.c for the function event_queue_read_output(). This checks the
> >>> midi event time is<  the until_time and returns TRUE and the event if so
> >>> otherwise FALSE.
> >>> Further events are read until this call to get an event from the queue
> >>> fails.
> >>> Finally before the loop begins again the playback_time that the backend
> >>> has, is "sent back" to audiointerface.c via update_playback_time().
> >>>
> >>> 8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8><  8>< 
> >>>  8><  8><  8><
> >>>
> >>> This code lacks the flexibility to speed up, slow down or pause the
> >>> playback - once the playback_start_time has been fixed the midi events
> >>> following that time will be sent out by referencing the current system
> >>> time.
> >>> This could be changed so that instead of executing g_get_current_time()
> >>> the time is obtained from a thread which manages the requests from the
> >>> user to pause, change tempo etc.
> >>>
> >>> Currently, I think there are two examples of how to do this in Denemo.
> >>> The first was the one I wrote to allow live change of tempo - very
> >>> useful for getting the right tempo by adjusting the slider while the
> >>> music is playing. The second I wrote to allow the playback to follow a
> >>> user playing along with it.
> >>> Only the first of these is easy enough to understand that I still have
> >>> it in my head: when the tempo slider is moved all the elapsed times that
> >>> are obtained are scaled. To make this work, the playback_start_time has
> >>> to be re-calculated - so it is as if we had been playing since then at
> >>> the new tempo and had just reached the current playback time. In this
> >>> way we do not have to keep a history of all the tempo changes.
> >>> The second method of controlling the playback was for following the
> >>> player (or conductor). In this case the user is setting a time at which
> >>> the playback should pause (unless the user has updated it meanwhile).
> >>> I am not sure if these could be unified.
> >>>
> >>> What would the new time-control thread look like? Well, for all the
> >>> paused time it could add up the total of pauses so far and subtract
> >>> these from the time value it returns. While actually in a pause, I guess
> >>> it would just keep returning the same time - only when the pause is
> >>> ended would it increment the total amount of pause time and subtract
> >>> that from the time value it would otherwise return. I guess it could
> >>> also manage the tempo change signal, adjusting the playback_start_time
> >>> and scaling the times it returns. Perhaps though, it should be returning
> >>> not absolute times but times since start? So it would be returning 0
> >>> during a pause and a scaled difference of (g_get_current_time() -
> >>> playback_start_time) and the total_pause_time. (?)
> >>>
> >>> I would welcome comments.
> >>>
> >>> Richard Shann
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> _______________________________________________
> >>> Denemo-devel mailing list
> >>> address@hidden
> >>> https://lists.gnu.org/mailman/listinfo/denemo-devel
> >
> 





reply via email to

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