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?
Richard > > Jeremiah > > Sent from my Samsung smartphone on AT&T > > Richard Shann <[email protected]> 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 > >[email protected] > >https://lists.gnu.org/mailman/listinfo/denemo-devel _______________________________________________ Denemo-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/denemo-devel
