[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