aboutsummaryrefslogtreecommitdiffhomepage
path: root/applause.c
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2015-11-03 04:41:33 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2015-11-03 05:27:16 +0100
commitb74c54a02923516f4f687484484c79b0501f98b3 (patch)
tree5d3ad0a807bedd3e75d138487a0e23fc9483ddce /applause.c
parent071bc6aae2bd7675468229ed4c4998f093e65eaf (diff)
downloadapplause2-b74c54a02923516f4f687484484c79b0501f98b3.tar.gz
allow Stream:play() to be interrupted by CTRL+C
* more precisely, Stream:play() will now throw an error whenever the process receices SIGINT. * this allows us to interrupt long playbacks
Diffstat (limited to 'applause.c')
-rw-r--r--applause.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/applause.c b/applause.c
index 6b71bb1..32f1a54 100644
--- a/applause.c
+++ b/applause.c
@@ -28,6 +28,8 @@ static jack_ringbuffer_t *buffer = NULL;
static int buffer_sem;
static sig_atomic_t buffer_xrun = 0;
+static sig_atomic_t interrupted = 0;
+
static int
svsem_init(size_t value)
{
@@ -76,6 +78,21 @@ svsem_free(int id)
}
/**
+ * Handler for SIGINT signals.
+ *
+ * This handler is invoked e.g. when the user presses
+ * CTRL+C.
+ * It sets `interrupted` which is polled in the Lua play()
+ * method which allows us to interrupt long (possibly infinite)
+ * sound playback.
+ */
+static void
+sigint_handler(int signum)
+{
+ interrupted = 1;
+}
+
+/**
* The process callback for this JACK application is called in a
* special realtime thread once for each audio cycle.
*/
@@ -253,7 +270,9 @@ l_Stream_play(lua_State *L)
lua_gc(L, LUA_GCCOLLECT, 0);
lua_gc(L, LUA_GCSTOP, 0);
- for (;;) {
+ interrupted = 0;
+
+ while (!interrupted) {
jack_default_audio_sample_t sample;
/*
@@ -303,6 +322,9 @@ l_Stream_play(lua_State *L)
lua_gc(L, LUA_GCRESTART, 0);
+ if (interrupted)
+ return luaL_error(L, "SIGINT received");
+
/* any remaining stack elements are automatically popped */
return 0;
}
@@ -311,6 +333,7 @@ int
main(int argc, char **argv)
{
int buffer_size = DEFAULT_BUFFER_SIZE;
+ struct sigaction sigint_action;
static const luaL_Reg stream_methods[] = {
{"play", l_Stream_play},
@@ -325,6 +348,17 @@ main(int argc, char **argv)
if (argc > 1)
buffer_size = atoi(argv[1]);
+ /*
+ * Register sigint_handler() as the SIGINT handler.
+ * This sets `interrupted`. Currently this is only polled
+ * in the Lua play() method in order to interrupt long
+ * sound playing.
+ * Otherwise it is ignored.
+ */
+ memset(&sigint_action, 0, sizeof(sigint_action));
+ sigint_action.sa_handler = sigint_handler;
+ sigaction(SIGINT, &sigint_action, NULL);
+
L = luaL_newstate();
if (!L) {
fprintf(stderr, "Error creating Lua state.\n");