[asterisk-commits] russell: branch russell/jack r93150 - /team/russell/jack/apps/app_jack.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Dec 15 02:08:20 CST 2007
Author: russell
Date: Sat Dec 15 02:08:19 2007
New Revision: 93150
URL: http://svn.digium.com/view/asterisk?view=rev&rev=93150
Log:
commit some more progress
Modified:
team/russell/jack/apps/app_jack.c
Modified: team/russell/jack/apps/app_jack.c
URL: http://svn.digium.com/view/asterisk/team/russell/jack/apps/app_jack.c?view=diff&rev=93150&r1=93149&r2=93150
==============================================================================
--- team/russell/jack/apps/app_jack.c (original)
+++ team/russell/jack/apps/app_jack.c Sat Dec 15 02:08:19 2007
@@ -40,6 +40,7 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <jack/jack.h>
+#include <jack/ringbuffer.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
@@ -59,8 +60,8 @@
jack_client_t *client;
jack_port_t *input_port;
jack_port_t *output_port;
- ast_mutex_t lock;
- ast_cond_t cond;
+ jack_ringbuffer_t *rb;
+ struct ast_smoother *smoother;
unsigned int stop:1;
};
@@ -117,7 +118,11 @@
struct jack_data *jack_data = arg;
(void)(jack_data);
- /* XXX */
+
+ /* XXX Here we need to attempt to read nframes number of samples from the
+ * ringbuffer and write it to the output port. Then, we need to read nframes
+ * samples from the input port, resample it, put them through a 20 ms smoother,
+ * and write them to the Asterisk channel. */
return 0;
}
@@ -126,10 +131,36 @@
{
struct jack_data *jack_data = arg;
- ast_mutex_lock(&jack_data->lock);
jack_data->stop = 1;
- ast_cond_signal(&jack_data->cond);
- ast_mutex_unlock(&jack_data->lock);
+}
+
+static void destroy_jack_data(struct jack_data *jack_data)
+{
+
+ if (jack_data->input_port) {
+ jack_port_unregister(jack_data->client, jack_data->input_port);
+ jack_data->input_port = NULL;
+ }
+
+ if (jack_data->output_port) {
+ jack_port_unregister(jack_data->client, jack_data->output_port);
+ jack_data->output_port = NULL;
+ }
+
+ if (jack_data->client) {
+ jack_client_close(jack_data->client);
+ jack_data->client = NULL;
+ }
+
+ if (jack_data->rb) {
+ jack_ringbuffer_free(jack_data->rb);
+ jack_data->rb = NULL;
+ }
+
+ if (jack_data->smoother) {
+ ast_smoother_free(jack_data->smoother);
+ jack_data->smoother = NULL;
+ }
}
static int init_jack_data(struct ast_channel *chan, struct jack_data *jack_data)
@@ -141,53 +172,62 @@
chan_name = ast_strdupa(chan->name);
ast_channel_unlock(chan);
- ast_mutex_init(&jack_data->lock);
- ast_cond_init(&jack_data->cond, NULL);
-
+ if (!(jack_data->smoother = ast_smoother_new(320))) { /* 20 ms frames */
+ destroy_jack_data(jack_data);
+ return -1;
+ }
+
+ if (!(jack_data->rb = jack_ringbuffer_create(16384))) {
+ destroy_jack_data(jack_data);
+ return -1;
+ }
+
jack_data->client = jack_client_open(chan_name, 0, &status);
-
log_jack_status("Client Open Status", status);
- if (!jack_data->client)
- return -1;
-
- if (jack_set_process_callback(jack_data->client, jack_process, jack_data)) {
- ast_log(LOG_ERROR, "Failed to register process callback for jack client\n");
- return -1;
- }
-
- jack_on_shutdown(jack_data->client, jack_shutdown, jack_data);
+ if (!jack_data->client) {
+ destroy_jack_data(jack_data);
+ return -1;
+ }
jack_data->input_port = jack_port_register(jack_data->client, "input",
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0);
if (!jack_data->input_port) {
- ast_log(LOG_ERROR, "Failed to create input port for jack client\n");
+ ast_log(LOG_ERROR, "Failed to create input port for jack port\n");
+ destroy_jack_data(jack_data);
return -1;
}
jack_data->output_port = jack_port_register(jack_data->client, "output",
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0);
if (!jack_data->output_port) {
- ast_log(LOG_ERROR, "Failed to create output port for jack client\n");
- return -1;
- }
-
- /* XXX */
+ ast_log(LOG_ERROR, "Failed to create output port for jack port\n");
+ destroy_jack_data(jack_data);
+ return -1;
+ }
+
+ if (jack_set_process_callback(jack_data->client, jack_process, jack_data)) {
+ ast_log(LOG_ERROR, "Failed to register process callback with jack client\n");
+ destroy_jack_data(jack_data);
+ return -1;
+ }
+
+ jack_on_shutdown(jack_data->client, jack_shutdown, jack_data);
+
+ if (jack_activate(jack_data->client)) {
+ ast_log(LOG_ERROR, "Unable to activate jack client\n");
+ destroy_jack_data(jack_data);
+ return -1;
+ }
return 0;
}
-static void destroy_jack_data(struct jack_data *jack_data)
-{
- /* XXX Ports? */
-
- if (jack_data->client) {
- jack_client_close(jack_data->client);
- jack_data->client = NULL;
- }
-
- ast_mutex_destroy(&jack_data->lock);
- ast_cond_destroy(&jack_data->cond);
+static void queue_voice_frame(struct jack_data *jack_data, struct ast_frame *f)
+{
+ /* XXX Here we need to resample the frame from the asterisk channel into the
+ * current sample rate for Jack. Then, it should be written to the ring buffer
+ * to be read in the jack process callback. */
}
static int jack_exec(struct ast_channel *chan, void *data)
@@ -200,17 +240,34 @@
return -1;
}
- ast_mutex_lock(&jack_data.lock);
-
- if (jack_activate(jack_data.client)) {
- ast_log(LOG_ERROR, "Failed to start the jack client\n");
- return -1;
- }
-
- while (!jack_data.stop)
- ast_cond_wait(&jack_data.cond, &jack_data.lock);
-
- ast_mutex_unlock(&jack_data.lock);
+ if (ast_set_read_format(chan, AST_FORMAT_SLINEAR))
+ return -1;
+
+ if (ast_set_write_format(chan, AST_FORMAT_SLINEAR))
+ return -1;
+
+ while (!jack_data.stop) {
+ struct ast_frame *f;
+
+ ast_waitfor(chan, -1);
+
+ f = ast_read(chan);
+ if (!f)
+ continue;
+
+ switch (f->frametype) {
+ case AST_FRAME_CONTROL:
+ if (f->subclass == AST_CONTROL_HANGUP)
+ jack_data.stop = 1;
+ break;
+ case AST_FRAME_VOICE:
+ queue_voice_frame(&jack_data, f);
+ default:
+ break;
+ }
+
+ ast_frfree(f);
+ }
destroy_jack_data(&jack_data);
More information about the asterisk-commits
mailing list