On 07/20/2010 06:54 PM, Robin Gareus wrote:
On 07/20/2010 09:17 AM, Patrick Shirkey wrote:
On 07/20/2010 09:45 AM, Robin Gareus wrote:
On 07/20/2010 01:06 AM, Louigi Verona wrote:
Hey guys!
Some time ago I have asked someone to look into Kluppe and add a
couple of
features.
My request was not ignored and Patrick Shirkey was kind enough to
volunteer
to try to help.
However, he came upon a difficulty and that is - *how do you set up an
asynchronous timer in C?*
It depends what you need that timer for.
The timer is needed to countdown the period between stopping and
restarting the loop. The methods I have tried all halt the playback on a
single frame and the ui also becomes unresponsive while the timer is in
process.
That sounds like it needs to be be quite accurate, or not?
It just needs to work ;-)
All I would
like to do is pass a zero byte to the audio signal handling
code while the timer is in progress. The rest of the interface should
stay active.
A simple approach might be to just set a counter and have the
audio-process count it down (in audio-samples). Once it reaches zero:
play again.
The problem is how to set a counter that doesn't block the rest of the
app while it is in process.
In gtk there's a g_timeout_add(). easy to use.
Will check that one. Might do the trick.
Don't forget to read the note:
http://library.gnome.org/devel/glib/unstable/glib-The-Main-Event-Loop.html#…
It's not very accurate but Example code is easy to come by.
To
writing your own:
`apropos pthread` and more specifically `man pthread_create`.
Otherwise will look into this.
usleep() sleeps at least, and select() sleeps at
most a certain period
of time.
http://freej.dyne.org/codedoc/fps_8cpp_source.html line 132ff
has examples of both.
Tried both of these options and they cause the app to pause with an
annoying buzz while the timer is in effect.
In that case you should get x-runs. Otherwise it may well be that you
simply don't zero the audio-output. It's hard to tell what's going on
w/o seeing the source.
I am not seeing xruns.
As for the GUI being unresponsive: The key part is to
use usleep() in a
separate thread.
Here are two simple examples using pthread to do so:
http://rg42.org/_media/wiki/async-timer.c # use a byte to indicate
http://rg42.org/_media/wiki/async-timer2.c # use a MUTEX
Thanks for those. They are pretty much what I was looking for. Don't
know why but that info was really hard for me to locate via google when
I last looked.
If you have the inclination you can see where I got to with this code
because I have uploaded a new version here:
http://djcj.org/code/kluppe-0.6.14-playbackdelay-v2.tar.bz2
The core mod is in src/common/looperdata.c:1355
Basic operation is to create a new track, import a buffer file, load the
buffer, set the playback delay to > 0 and press play. When it gets to
the end of the loop range it will stop for the number of seconds in the
playback delay spinbox.
It's now at least partially working. Needs some finetuning with multiple
tracks but at least that annoying buzz has gone and the ui stays
responsive. I'll spend some more time on it in the next few days no
doubt. But if anyone else feels like giving it a tweak then be my guest.
I'm sure Louigi will be keen to test out any improvements.
Funny but it took me longer tonight to get jack working properly than it
did to add that code and make it do something useful :-/
Here's what I did in case anyone else comes across it at a later date:
+++++++++++++++
if(data->playbackdelay > 0){
printf ("in lcss: set playbackdelay =
%f\n",data->playbackdelay);
if (async_timeout == 0){
async_timeout = data->playbackdelay;
pthread_mutex_init(&timer_lock, NULL);
pthread_mutex_lock(&timer_lock);
rv = pthread_create(&thread_id_tt, NULL,
timer_thread, &async_timeout);
vol = data->vol;
looperdata_set_vol(data,0);
if (rv) {
printf("thread creation failed.\n");
// break;
}
}
// test if the timer is still running:
if (!pthread_mutex_trylock(&timer_lock)) {
pthread_mutex_unlock(&timer_lock);
// timer finished
data->playindex += data->loopstart - data->loopend;
looperdata_set_vol(data,vol);
// clean-up
pthread_join(thread_id_tt, NULL);
pthread_mutex_destroy(&timer_lock);
async_timeout = 0;
// break;
}
}
+++++++++++++=
Cheers.
--
Patrick Shirkey
Boost Hardware Ltd