[asterisk-commits] russell: branch russell/chan_console r95363 - /team/russell/chan_console/chan...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Dec 29 11:46:01 CST 2007
Author: russell
Date: Sat Dec 29 11:46:00 2007
New Revision: 95363
URL: http://svn.digium.com/view/asterisk?view=rev&rev=95363
Log:
And now, attempt number 3 at an approach for audio handling between asterisk
and portaudio. This approach is _much_ simpler, and just uses the blocking
read/write mode from portaudio. I wish I had realized that this was available
a long time ago. It fits the Asterisk model much better, and appears to be
working better than my previous couple of methods ...
Modified:
team/russell/chan_console/channels/chan_console.c
Modified: team/russell/chan_console/channels/chan_console.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_console/channels/chan_console.c?view=diff&rev=95363&r1=95362&r2=95363
==============================================================================
--- team/russell/chan_console/channels/chan_console.c (original)
+++ team/russell/chan_console/channels/chan_console.c Sat Dec 29 11:46:00 2007
@@ -48,14 +48,11 @@
/*** MODULEINFO
<depend>portaudio</depend>
- <depend>jack</depend>
***/
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <jack/ringbuffer.h>
#include <portaudio.h>
@@ -146,13 +143,10 @@
unsigned int overridecontext:1;
/*! Lock for this struct */
ast_mutex_t lock;
- jack_ringbuffer_t *input_rb;
- jack_ringbuffer_t *output_rb;
- struct ast_smoother *smoother;
- int fds[2];
+ pthread_t thread;
} console_pvt = {
.lock = AST_MUTEX_INIT_VALUE,
- .fds = { -1, -1 },
+ .thread = AST_PTHREADT_NULL,
};
/*! Global jitterbuffer configuration - by default, jb is disabled */
@@ -195,9 +189,35 @@
.fixup = console_fixup,
};
-static int console_callback(const void *input, void *output,
- unsigned long frame_count, const PaStreamCallbackTimeInfo *time_info,
- PaStreamCallbackFlags flags, void *userData);
+static void *stream_monitor(void *data)
+{
+ struct console_pvt *pvt = data;
+ char buf[NUM_SAMPLES * sizeof(int16_t)];
+ PaError res;
+
+ for (;;) {
+ pthread_testcancel();
+
+ res = Pa_ReadStream(pvt->stream, buf, sizeof(buf) / sizeof(int16_t));
+
+ pthread_testcancel();
+
+ if (res == paNoError) {
+ struct ast_frame f = {
+ .frametype = AST_FRAME_VOICE,
+ .subclass = AST_FORMAT_SLINEAR,
+ .src = "console_stream_monitor",
+ .data = buf,
+ .datalen = sizeof(buf),
+ .samples = sizeof(buf) / sizeof(int16_t),
+ };
+
+ ast_queue_frame(pvt->owner, &f);
+ }
+ }
+
+ return NULL;
+}
static int start_stream(struct console_pvt *pvt)
{
@@ -213,7 +233,7 @@
ast_debug(1, "Starting stream\n");
res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS,
- paInt16, SAMPLE_RATE, NUM_SAMPLES, console_callback, NULL);
+ paInt16, SAMPLE_RATE, NUM_SAMPLES, NULL, NULL);
if (res != paNoError) {
ast_log(LOG_WARNING, "Failed to open default audio device - (%d) %s\n",
res, Pa_GetErrorText(res));
@@ -226,6 +246,12 @@
ast_log(LOG_WARNING, "Failed to start stream - (%d) %s\n",
res, Pa_GetErrorText(res));
ret_val = -1;
+ goto return_unlock;
+ }
+
+ if (ast_pthread_create_background(&pvt->thread, NULL, stream_monitor, pvt)) {
+ ast_log(LOG_ERROR, "Failed to start stream monitor thread\n");
+ ret_val = -1;
}
return_unlock:
@@ -238,6 +264,10 @@
{
if (!pvt->streamstate)
return 0;
+
+ pthread_cancel(pvt->thread);
+ pthread_kill(pvt->thread, SIGURG);
+ pthread_join(pvt->thread, NULL);
ast_mutex_lock(&pvt->lock);
Pa_AbortStream(pvt->stream);
@@ -264,7 +294,6 @@
chan->readformat = AST_FORMAT_SLINEAR;
chan->writeformat = AST_FORMAT_SLINEAR;
chan->tech_pvt = pvt;
- chan->fds[0] = pvt->fds[0];
pvt->owner = chan;
@@ -359,44 +388,9 @@
static struct ast_frame *console_read(struct ast_channel *chan)
{
- struct console_pvt *pvt = chan->tech_pvt;
- struct pollfd pfd;
- int res;
- char buf[1024];
- struct ast_frame *fr, *ret_fr;
- struct ast_frame f = {
- .frametype = AST_FRAME_VOICE,
- .subclass = AST_FORMAT_SLINEAR,
- .src = "console_read",
- .data = buf,
- };
-
- pfd.fd = pvt->fds[0];
- pfd.events = POLLIN;
- pfd.revents = 0;
- while (poll(&pfd, 1, 0) == 1) {
- int blah;
- read(pvt->fds[0], &blah, sizeof(blah));
- }
-
- while ((res = jack_ringbuffer_read(pvt->input_rb, buf, sizeof(buf))) > 0) {
- f.datalen = res;
- f.samples = res / sizeof(int16_t);
-
- ast_smoother_feed(pvt->smoother, &f);
- }
-
- /* Read one frame to return, and queue up any others on the channel just
- * in case we have run behind a bit. */
-
- ret_fr = ast_smoother_read(pvt->smoother);
-
- while ((fr = ast_smoother_read(pvt->smoother))) {
- ast_queue_frame(chan, fr);
- ast_frfree(fr);
- }
-
- return ret_fr ? ret_fr : &ast_null_frame;
+ ast_debug(1, "I should not be called ...\n");
+
+ return &ast_null_frame;
}
static int console_call(struct ast_channel *c, char *dest, int timeout)
@@ -430,18 +424,9 @@
static int console_write(struct ast_channel *chan, struct ast_frame *f)
{
- struct ast_frame *fr = ast_frdup(f);
- struct console_pvt *pvt = &console_pvt;
- int res;
-
- if (!fr)
- return -1;
-
- res = jack_ringbuffer_write(pvt->output_rb, fr->data, fr->datalen);
- if (res != fr->datalen) {
- /* ast_log(LOG_WARNING, "Failed to write %d bytes to the output ringbuffer\n",
- fr->datalen); */
- }
+ struct console_pvt *pvt = &console_pvt;
+
+ Pa_WriteStream(pvt->stream, f->data, f->samples);
return 0;
}
@@ -489,61 +474,7 @@
return 0;
}
-static int handle_output(struct console_pvt *pvt, void *output, unsigned long frame_count)
-{
- size_t res;
- unsigned long total_bytes = frame_count * 2;
-
- res = jack_ringbuffer_read_space(pvt->output_rb);
- if (res < total_bytes) {
- /* ast_debug(1, "Missed a frame\n"); */
- memset(output, 0, total_bytes);
- return paContinue;
- }
-
- jack_ringbuffer_read(pvt->output_rb, output, frame_count * 2);
-
- return paContinue;
-}
-
-static int handle_input(struct console_pvt *pvt, const void *input, unsigned long frame_count)
-{
- char buf[frame_count * 2];
- int res;
- int blah = 0;
-
- if (pvt->muted) {
- memset(buf, 0, sizeof(buf));
- input = buf;
- }
-
- res = jack_ringbuffer_write(pvt->input_rb, input, frame_count * 2);
- if (res != frame_count * 2) {
- /* ast_log(LOG_WARNING, "Wanted to write %ld bytes into the input ringbuffer, "
- "but only wrote %d\n", frame_count * 2, res); */
- }
-
- write(pvt->fds[1], &blah, sizeof(blah));
-
- return paContinue;
-}
-
-static int console_callback(const void *input, void *output,
- unsigned long frame_count, const PaStreamCallbackTimeInfo *time_info,
- PaStreamCallbackFlags flags, void *userData)
-{
- int res = paContinue;
- struct console_pvt *pvt = &console_pvt;
-
- if (output)
- res = handle_output(pvt, output, frame_count);
- if (res != paAbort && input)
- res = handle_input(pvt, input, frame_count);
-
- return res;
-}
-
-/*
+/*!
* split a string in extension-context, returns pointers to malloc'ed
* strings.
* If we do not have 'overridecontext' then the last @ is considered as
@@ -551,6 +482,8 @@
* This is usually not very necessary as you can play with the dialplan,
* and it is nice not to need it because you have '@' in SIP addresses.
* Return value is the buffer address.
+ *
+ * \note came from chan_oss
*/
static char *ast_ext_ctx(struct console_pvt *pvt, const char *src, char **ext, char **ctx)
{
@@ -892,8 +825,11 @@
AST_CLI_DEFINE(cli_list_devices, "List available devices"),
};
-static void set_pvt_defaults(struct console_pvt *pvt)
-{
+static void set_pvt_defaults(struct console_pvt *pvt, int reload)
+{
+ if (!reload)
+ ast_string_field_set(pvt, name, "default");
+
ast_string_field_set(pvt, mohinterpret, "default");
ast_string_field_set(pvt, context, "default");
ast_string_field_set(pvt, exten, "s");
@@ -924,13 +860,7 @@
ast_mutex_lock(&pvt->lock);
- if (!reload) {
- if (ast_string_field_init(pvt, 32))
- goto return_unlock;
- ast_string_field_set(pvt, name, "default");
- }
-
- set_pvt_defaults(pvt);
+ set_pvt_defaults(pvt, reload);
if (!(cfg = ast_config_load(config_file, config_flags))) {
ast_log(LOG_NOTICE, "Unable to open configuration file %s!\n", config_file);
@@ -975,65 +905,22 @@
static int init_pvt(struct console_pvt *pvt)
{
+ if (ast_string_field_init(pvt, 32))
+ return -1;
+
if (ast_mutex_init(&pvt->lock)) {
ast_log(LOG_ERROR, "Failed to initialize mutex\n");
return -1;
}
- if (!(pvt->smoother = ast_smoother_new(320))) { /* 20ms frames */
- ast_log(LOG_ERROR, "Failed to create smoother\n");
- return -1;
- }
-
- if (!(pvt->input_rb = jack_ringbuffer_create(RINGBUFFER_SIZE))) {
- ast_log(LOG_ERROR, "Failed to create input ringbuffer of size %d\n",
- RINGBUFFER_SIZE);
- return -1;
- }
-
- if (!(pvt->output_rb = jack_ringbuffer_create(RINGBUFFER_SIZE))) {
- ast_log(LOG_ERROR, "Failed to create output ringbuffer of size %d\n",
- RINGBUFFER_SIZE);
- return -1;
- }
-
- if (pipe(pvt->fds)) {
- ast_log(LOG_ERROR, "Unable to create alert pipe: %s\n", strerror(errno));
- return -1;
- }
-
return 0;
}
static void destroy_pvt(struct console_pvt *pvt)
{
- int i;
-
ast_string_field_free_memory(pvt);
ast_mutex_destroy(&pvt->lock);
-
- if (pvt->smoother) {
- ast_smoother_free(pvt->smoother);
- pvt->smoother = NULL;
- }
-
- if (pvt->input_rb) {
- jack_ringbuffer_free(pvt->input_rb);
- pvt->input_rb = NULL;
- }
-
- if (pvt->output_rb) {
- jack_ringbuffer_free(pvt->output_rb);
- pvt->output_rb = NULL;
- }
-
- for (i = 0; i < 2; i++) {
- if (pvt->fds[i] > -1) {
- close(pvt->fds[i]);
- pvt->fds[i] = -1;
- }
- }
}
static int unload_module(void)
More information about the asterisk-commits
mailing list