Skip to content

Commit

Permalink
implemented anonymous fd based latency callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
navicore committed Apr 3, 2013
1 parent 1ad8589 commit 2cb64a8
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 171 deletions.
3 changes: 3 additions & 0 deletions corelib/JacksRbClient.h
Expand Up @@ -24,6 +24,7 @@ extern "C" {

#include "config.h"
#include "JacksEvent.h"
#include "JacksRbPort.h"
#include <jack/jack.h>
#include <jack/session.h>
#include <jack/transport.h>
Expand Down Expand Up @@ -61,6 +62,8 @@ extern char *JacksRbClient_get_name(T);

extern jack_nframes_t JacksRbClient_get_rb_size(T);

extern JacksRbPort JacksRbClient_registerPort(T, char *, unsigned long);

#undef T
#endif

Expand Down
105 changes: 77 additions & 28 deletions corelib/JacksRbPort.c
Expand Up @@ -17,14 +17,15 @@
*/

#include "config.h"
#include "JacksRbPort.h"
#include "JacksRbClient.h"
#include "JacksRbPort.h"
#include <jack/jack.h>
#include <jack/types.h>
#include <jack/session.h>
#include <jack/transport.h>
#include <jack/ringbuffer.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
Expand All @@ -34,7 +35,9 @@
#define T JacksRbPort

struct T {
int lat_cb_fd[2];
int playback_lat_cb_fd[2];
int capture_lat_cb_fd[2];
bool lat_cb_is_init;
jack_nframes_t rb_size;
jack_port_t *jport;
JacksRbClient jackclient;
Expand All @@ -47,18 +50,24 @@ struct T {
const size_t jacks_sample_size = sizeof(jack_default_audio_sample_t);

// contructor/wrapper for existing ports the user looks up
T JacksRbPort_new(jack_port_t *jport, JacksRbClient jackclient, jack_nframes_t rb_size) {
//T JacksRbPort_new(jack_port_t *jport, JacksRbClient jackclient, jack_nframes_t rb_size) {
T JacksRbPort_new(jack_port_t *jport, void * jackclientp, jack_nframes_t rb_size) {

JacksRbClient jackclient = (JacksRbClient) jackclientp;

T _this_ = malloc(sizeof *_this_);
if (_this_ == NULL) {
fprintf (stderr, "JacksRbPort_new: can not alloc event\n");
return NULL;
}

_this_->lat_cb_is_init = false;
_this_->rb_size = rb_size;
_this_->jport = jport;
_this_->lat_cb_fd[0] = 0;
_this_->lat_cb_fd[1] = 0;
_this_->capture_lat_cb_fd[0] = 0;
_this_->capture_lat_cb_fd[1] = 0;
_this_->playback_lat_cb_fd[0] = 0;
_this_->playback_lat_cb_fd[1] = 0;
_this_->jackclient = jackclient;
_this_->framebuf = malloc(rb_size);

Expand All @@ -69,9 +78,10 @@ T JacksRbPort_new(jack_port_t *jport, JacksRbClient jackclient, jack_nframes_t r
// contstructor for ports the user creates
T JacksRbPort_new_port(const char *name,
unsigned long options,
JacksRbClient jackclient,
void * jackclientp,
jack_nframes_t rb_size) {

JacksRbClient jackclient = (JacksRbClient) jackclientp;
//todo: midi option
jack_port_t *jport = jack_port_register(JacksRbClient_get_client(jackclient), name,
JACK_DEFAULT_AUDIO_TYPE, options, 0);
Expand All @@ -86,57 +96,96 @@ void JacksRbPort_free(T *_this_p_) {
free(_this_);
}

static void JacksRbPort_latency_listener_fd(jack_latency_callback_mode_t mode, void *arg) {
static void latency_listener_fd(jack_latency_callback_mode_t mode, void *arg) {
T _this_ = (T) arg;

write(_this_->lat_cb_fd[0], "b", 1);
if (mode == JackCaptureLatency) {
if (_this_->capture_lat_cb_fd[0] != 0) {
int rc = write(_this_->capture_lat_cb_fd[0], "b", 1);
}
} else if (mode == JackPlaybackLatency) {
if (_this_->playback_lat_cb_fd[0] != 0) {
int rc = write(_this_->playback_lat_cb_fd[0], "b", 1);
}
} else {
fprintf (stderr, "ERROR! unknown latency mode\n");
}
}
static void JacksRbPort_latency_listener(jack_latency_callback_mode_t mode, void *arg) {

static void latency_listener(jack_latency_callback_mode_t mode, void *arg) {
T _this_ = (T) arg;

raise(SIGUSR2);
}
void JacksRbPort_wakeup_fd(T _this_) {
JacksRbPort_latency_listener_fd(0, _this_);
void JacksRbPort_wakeup_latency_callbacks(T _this_) {
latency_listener_fd(JackPlaybackLatency, _this_);
latency_listener_fd(JackCaptureLatency, _this_);
}
void JacksRbPort_wakeup_sig_latency_cb(T _this_) {
latency_listener(0, _this_);
}
void JacksRbPort_wakeup(T _this_) {
JacksRbPort_latency_listener(0, _this_);

//register latency callback
static int register_lat_cb(T _this_) {
int rc = jack_set_latency_callback(
JacksRbClient_get_client(_this_->jackclient),
latency_listener_fd,
_this_);
if (rc != 0) {
fprintf (stderr, "set latency fd callback failed\n");
} else {
_this_->lat_cb_is_init = true;
fprintf (stderr, "fd latency callback is set\n");
}
return rc;
}

int JacksRbPort_init_latency_listener_fd(T _this_) {
int JacksRbPort_init_capture_latency_listener(T _this_) {

//fail if fd already set
if (_this_->lat_cb_fd[0] != 0) {
fprintf (stderr, "latency callback allready registered\n");
return -1;
if (_this_->capture_lat_cb_fd[1] != 0) {
fprintf (stderr, "capture latency fd already init\n");
return _this_->capture_lat_cb_fd[1];
}

int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, _this_->lat_cb_fd);
int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, _this_->capture_lat_cb_fd);
if (rc != 0) {
fprintf (stderr, "init unix domain socket pair failed\n");
return -1;
}

//register latency callback
rc = jack_set_latency_callback(
JacksRbClient_get_client(_this_->jackclient),
JacksRbPort_latency_listener_fd,
_this_);
if (rc != 0) {
if (!_this_->lat_cb_is_init && register_lat_cb(_this_) != 0) {
fprintf (stderr, "set latency fd callback failed\n");
return -1;
}
return _this_->capture_lat_cb_fd[1];
}

int JacksRbPort_init_playback_latency_listener(T _this_) {

if (_this_->playback_lat_cb_fd[1] != 0) {
fprintf (stderr, "playback latency fd already init\n");
return _this_->playback_lat_cb_fd[1];
}

fprintf (stderr, "fd latency callback is set\n");
return _this_->lat_cb_fd[1];
int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, _this_->playback_lat_cb_fd);
if (rc != 0) {
fprintf (stderr, "init unix domain socket pair failed\n");
return -1;
}

if (!_this_->lat_cb_is_init && register_lat_cb(_this_) != 0) {
fprintf (stderr, "set latency fd callback failed\n");
return -1;
}
return _this_->playback_lat_cb_fd[1];
}

int JacksRbPort_init_latency_listener(T _this_) {

//register latency callback
int rc = jack_set_latency_callback(
JacksRbClient_get_client(_this_->jackclient),
JacksRbPort_latency_listener,
latency_listener,
_this_);
if (rc != 0) {
fprintf (stderr, "set latency callback failed\n");
Expand Down
18 changes: 10 additions & 8 deletions corelib/JacksRbPort.h
Expand Up @@ -24,33 +24,35 @@ extern "C" {
#define _JS_RB_PORT_H_

#include "config.h"
#include "JacksRbClient.h"
//#include "JacksRbClient.h"
#include <jack/jack.h>
#include <assert.h>

#define T JacksRbPort
typedef struct T *T;

extern T JacksRbPort_new(jack_port_t *, JacksRbClient, jack_nframes_t);
//extern T JacksRbPort_new(jack_port_t *, JacksRbClient, jack_nframes_t);
extern T JacksRbPort_new(jack_port_t *, void *, jack_nframes_t);

extern T JacksRbPort_new_port(const char *,
unsigned long, JacksRbClient, jack_nframes_t);
//extern T JacksRbPort_new_port(const char *, unsigned long, JacksRbClient, jack_nframes_t);
extern T JacksRbPort_new_port(const char *, unsigned long, void *, jack_nframes_t);

extern void JacksRbPort_free(T *);

extern int JacksRbPort_connect(T, T);

extern int JacksRbPort_write_to_ringbuffer(T, jack_nframes_t);

extern sample_t* JacksRbPort_read_from_ringbuffer(T, int*);
extern jack_default_audio_sample_t* JacksRbPort_read_from_ringbuffer(T, int*);

extern void* JacksRbPort_get_port(T);

extern int JacksRbPort_init_latency_listener(T);
extern int JacksRbPort_init_latency_listener_fd(T);
extern int JacksRbPort_init_capture_latency_listener(T);
extern int JacksRbPort_init_playback_latency_listener(T);

extern void JacksRbPort_wakeup(T); //ejs test
extern void JacksRbPort_wakeup_fd(T); //ejs test
extern void JacksRbPort_wakeup_sig_latency_cb(T); //ejs test
extern void JacksRbPort_wakeup_latency_callbacks(T); //ejs test

#undef T
#endif
Expand Down
23 changes: 15 additions & 8 deletions modules/Jacks.i
Expand Up @@ -144,6 +144,7 @@ typedef struct {

int rc = JacksRbPort_connect($self->impl, _that_->impl);
if (rc) throw_exception("can not connect ports");
return rc;
}

JsLatencyRange *getLatencyRange(enum JackLatencyCallbackMode mode) {
Expand All @@ -166,17 +167,23 @@ typedef struct {
jack_port_set_latency_range((jack_port_t *) JacksRbPort_get_port($self->impl),
mode, &range);
}
void wakeupFd() {
JacksRbPort_wakeup_fd($self->impl);
void wakeupLatencyCallbacks() {
JacksRbPort_wakeup_latency_callbacks($self->impl);
}
void wakeupSigLatencyCallback() {
JacksRbPort_wakeup_sig_latency_cb($self->impl);
}
void wakeup() {
JacksRbPort_wakeup($self->impl);
int initCaptureLatencyListener() {

int fd = JacksRbPort_init_capture_latency_listener($self->impl);
if (fd < 0) throw_exception("can not init capture latency callback");
return fd;
}
int initLatencyListenerFd() {
int initPlaybackLatencyListener() {

int fd = JacksRbPort_init_latency_listener_fd($self->impl);
if (fd < 0) throw_exception("can not init fd latency callback");
return fd; //note, I doubt this will work... just stubbing it out for now.
int fd = JacksRbPort_init_playback_latency_listener($self->impl);
if (fd < 0) throw_exception("can not init playback latency callback");
return fd;
}
int initLatencyListener() {

Expand Down

0 comments on commit 2cb64a8

Please sign in to comment.