[Freeswitch-branches] [commit] r5662 - freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio
Freeswitch SVN
cseket at freeswitch.org
Fri Aug 24 13:50:57 EDT 2007
Author: cseket
Date: Fri Aug 24 13:50:56 2007
New Revision: 5662
Modified:
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/ (props changed)
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h
Log:
merge from trunk and try to fix MODENDP-20
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile Fri Aug 24 13:50:56 2007
@@ -1,22 +1,29 @@
-CFLAGS += -I.
-LDFLAGS += -lportaudio -L$(PREFIX)
-MYOBJS = pablio.o pa_ringbuffer.o
+BASE=../../../..
-all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
+PA_DIR=$(BASE)/libs/portaudio
-depends:
- MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install portaudio --prefix=$(PREFIX) --with-pic
-%.o: %.c
- $(CC) -fPIC $(CFLAGS) -c -o $@ $<
+PALA=$(PA_DIR)/lib/libportaudio.la
+LOCAL_CFLAGS=-I. -I$(PA_DIR)/include -D__EXTENSION__=1
-$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c $(MYOBJS)
- $(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o
- $(CC) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(MODNAME).o $(MYOBJS) $(LDFLAGS)
+LOCAL_INSERT_LDFLAGS=if test $$osarch = "Darwin" ; then echo "-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon" ; fi ;
+LOCAL_LIBADD=$(PALA)
+LOCAL_OBJS=pablio.o pa_ringbuffer.o
+LOCAL_SOURCES=pablio.c pa_ringbuffer.c
+PX_DIR=$(BASE)/libs/portmixer
+PXA=$(PX_DIR)/libportmixer.a
+LOCAL_CFLAGS+=-I$(PX_DIR)/include
+LOCAL_LIBADD+=$(PXA)
-clean:
- rm -fr *.$(DYNAMIC_LIB_EXTEN) *.o *~
+include $(BASE)/build/modmake.rules
-install:
- cp -f $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(PREFIX)/mod
+$(PALA): $(PA_DIR) $(PA_DIR)/.update
+ cd $(PA_DIR) && $(MAKE)
+ $(TOUCH_TARGET)
+
+$(PXA): $(PX_DIR) $(PX_DIR)/.update
+ cd $(PX_DIR) && $(MAKE)
+ $(TOUCH_TARGET)
+
+$(LOCAL_OBJS): $(LOCAL_SOURCES)
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c Fri Aug 24 13:50:56 2007
@@ -6,7 +6,7 @@
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
+ * the License. You may obtain a copy of the License `
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
@@ -29,32 +29,34 @@
* mod_portaudio.c -- PortAudio Endpoint Module
*
*/
-#include <switch.h>
+#include "switch.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "pablio.h"
#include <string.h>
+#include <portmixer.h>
#define MY_EVENT_RINGING "portaudio::ringing"
-static const char modname[] = "mod_portaudio";
+SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown);
+SWITCH_MODULE_DEFINITION(mod_portaudio, mod_portaudio_load, mod_portaudio_shutdown, NULL);
static switch_memory_pool_t *module_pool = NULL;
-//static int running = 1;
+static switch_endpoint_interface_t *channel_endpoint_interface;
#define SAMPLE_TYPE paInt16
-//#define SAMPLE_TYPE paFloat32
-typedef short SAMPLE;
+typedef int16_t SAMPLE;
-typedef switch_status_t (*pa_command_t)(char **argv, int argc, switch_stream_handle_t *stream);
+typedef switch_status_t (*pa_command_t) (char **argv, int argc, switch_stream_handle_t *stream);
typedef enum {
- GFLAG_NONE = 0,
- GFLAG_EAR = (1 << 0),
- GFLAG_MOUTH = (1 << 1),
- GFLAG_RING = (1 << 2)
+ GFLAG_NONE = 0,
+ GFLAG_EAR = (1 << 0),
+ GFLAG_MOUTH = (1 << 1),
+ GFLAG_RING = (1 << 2)
} GFLAGS;
typedef enum {
@@ -75,17 +77,16 @@
switch_core_session_t *session;
switch_caller_profile_t *caller_profile;
char call_id[50];
- int sample_rate;
- int codec_ms;
+ int sample_rate;
+ int codec_ms;
switch_mutex_t *flag_mutex;
- char *hold_file;
- switch_file_handle_t fh;
- switch_file_handle_t *hfh;
+ char *hold_file;
+ switch_file_handle_t fh;
+ switch_file_handle_t *hfh;
switch_frame_t hold_frame;
- unsigned char holdbuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
+ unsigned char holdbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_codec_t write_codec;
- switch_timer_t timer;
- struct private_object *next;
+ struct private_object *next;
};
typedef struct private_object private_t;
@@ -96,9 +97,9 @@
char *cid_name;
char *cid_num;
char *dialplan;
- char *ring_file;
- char *hold_file;
- char *timer_name;
+ char *ring_file;
+ char *hold_file;
+ char *timer_name;
int ringdev;
int indev;
int outdev;
@@ -114,12 +115,14 @@
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_frame_t read_frame;
- switch_frame_t cng_frame;
- unsigned char databuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
- unsigned char cngbuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
- private_t *call_list;
- int ring_interval;
- GFLAGS flags;
+ switch_frame_t cng_frame;
+ unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+ unsigned char cngbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+ private_t *call_list;
+ int ring_interval;
+ GFLAGS flags;
+ switch_timer_t timer;
+ PxMixer *mixer;
} globals;
@@ -128,126 +131,125 @@
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_name, globals.cid_name)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_num, globals.cid_num)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ring_file, globals.ring_file)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_hold_file, globals.hold_file)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_timer_name, globals.timer_name)
-
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_name, globals.cid_name)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_num, globals.cid_num)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ring_file, globals.ring_file)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_hold_file, globals.hold_file)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_timer_name, globals.timer_name)
#define is_master(t) switch_test_flag(t, TFLAG_MASTER)
-static void add_pvt(private_t *tech_pvt, int master);
-static void remove_pvt(private_t *tech_pvt);
-static switch_status_t channel_on_init(switch_core_session_t *session);
-static switch_status_t channel_on_hangup(switch_core_session_t *session);
-static switch_status_t channel_on_ring(switch_core_session_t *session);
-static switch_status_t channel_on_loopback(switch_core_session_t *session);
-static switch_status_t channel_on_transmit(switch_core_session_t *session);
-static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
- switch_caller_profile_t *outbound_profile,
- switch_core_session_t **new_session, switch_memory_pool_t **pool);
-static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
- switch_io_flag_t flags, int stream_id);
-static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
- switch_io_flag_t flags, int stream_id);
-static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
-static switch_status_t engage_device(int samplerate, int codec_ms);
-static switch_status_t engage_ring_device(int sample_rate, int channels);
-static void deactivate_ring_device(void);
-static int dump_info(void);
-static switch_status_t load_config(void);
-static int get_dev_by_name(char *name, int in);
-static int get_dev_by_number(int number, int in);
-static switch_status_t pa_cmd(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
-static switch_status_t padep(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
-
+ static void add_pvt(private_t * tech_pvt, int master);
+ static void remove_pvt(private_t * tech_pvt);
+ static switch_status_t channel_on_init(switch_core_session_t *session);
+ static switch_status_t channel_on_hangup(switch_core_session_t *session);
+ static switch_status_t channel_on_ring(switch_core_session_t *session);
+ static switch_status_t channel_on_loopback(switch_core_session_t *session);
+ static switch_status_t channel_on_transmit(switch_core_session_t *session);
+ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
+ switch_caller_profile_t *outbound_profile,
+ switch_core_session_t **new_session, switch_memory_pool_t **pool);
+ static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id);
+ static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id);
+ static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
+ static switch_status_t engage_device(int samplerate, int codec_ms);
+ static switch_status_t engage_ring_device(int sample_rate, int channels);
+ static void deactivate_ring_device(void);
+ static int dump_info(void);
+ static switch_status_t load_config(void);
+ static int get_dev_by_name(char *name, int in);
+ static int get_dev_by_number(int number, int in);
+ static switch_status_t pa_cmd(const char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
/*
State methods they get called when the state changes to the specific state
returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
*/
-static switch_status_t channel_on_init(switch_core_session_t *session)
+ static switch_status_t channel_on_init(switch_core_session_t *session)
{
switch_channel_t *channel;
private_t *tech_pvt = NULL;
switch_time_t last;
int waitsec = globals.ring_interval * 1000000;
- switch_file_handle_t fh = {0};
- char *val, *ring_file = NULL, *hold_file = NULL;
- int16_t abuf[2048];
+ switch_file_handle_t fh = { 0 };
+ char *val, *ring_file = NULL, *hold_file = NULL;
+ int16_t abuf[2048];
- tech_pvt = switch_core_session_get_private(session);
+ tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
-
+
last = switch_time_now() - waitsec;
- if ((val = switch_channel_get_variable(channel, "pa_hold_file"))) {
- hold_file = val;
- } else {
- hold_file = globals.hold_file;
- }
-
- if (hold_file) {
- tech_pvt->hold_file = switch_core_session_strdup(session, hold_file);
- }
+
+ if ((val = switch_channel_get_variable(channel, "pa_hold_file"))) {
+ hold_file = val;
+ } else {
+ hold_file = globals.hold_file;
+ }
+
+ if (hold_file) {
+ tech_pvt->hold_file = switch_core_session_strdup(session, hold_file);
+ }
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n", switch_channel_get_name(channel),
- switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER));
-
-
-
- if (engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms) != SWITCH_STATUS_SUCCESS) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- return SWITCH_STATUS_FALSE;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- add_pvt(tech_pvt, PA_SLAVE);
-
- ring_file = globals.ring_file;
- if ((val = switch_channel_get_variable(channel, "pa_ring_file"))) {
- ring_file = val;
- }
-
- if (switch_test_flag((&globals), GFLAG_RING)) {
- ring_file = NULL;
- }
- switch_set_flag_locked((&globals), GFLAG_RING);
- if (ring_file) {
- if (switch_core_file_open(&fh,
- ring_file,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
- NULL) == SWITCH_STATUS_SUCCESS) {
-
- if (engage_ring_device(fh.samplerate, fh.channels) != SWITCH_STATUS_SUCCESS) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ring Error!\n");
- switch_core_file_close(&fh);
- return SWITCH_STATUS_GENERR;
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open %s, disabling ring file!\n", ring_file);
- ring_file = NULL;
- }
- }
- }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n",
+ switch_channel_get_name(channel), switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER));
+
+
+
+ if (engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
+ add_pvt(tech_pvt, PA_SLAVE);
+
+ ring_file = globals.ring_file;
+ if ((val = switch_channel_get_variable(channel, "pa_ring_file"))) {
+ ring_file = val;
+ }
+
+ if (switch_test_flag((&globals), GFLAG_RING)) {
+ ring_file = NULL;
+ }
+ switch_set_flag_locked((&globals), GFLAG_RING);
+ if (ring_file) {
+ if (switch_core_file_open(&fh,
+ ring_file,
+ globals.read_codec.implementation->number_of_channels,
+ globals.read_codec.implementation->samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
+
+ if (engage_ring_device(fh.samplerate, fh.channels) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ring Error!\n");
+ switch_core_file_close(&fh);
+ return SWITCH_STATUS_GENERR;
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open %s, disabling ring file!\n", ring_file);
+ ring_file = NULL;
+ }
+ }
+ }
switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
switch_channel_mark_ring_ready(channel);
-
+
while (switch_channel_get_state(channel) == CS_INIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
+ switch_size_t olen = globals.timer.samples;
+
if (switch_time_now() - last >= waitsec) {
char buf[512];
switch_event_t *event;
-
+
snprintf(buf, sizeof(buf), "BRRRRING! BRRRRING! call %s\n", tech_pvt->call_id);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) {
@@ -256,49 +258,46 @@
switch_channel_event_set_data(channel, event);
switch_event_fire(&event);
}
-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", buf);
last = switch_time_now();
- if (ring_file) {
- unsigned int pos = 0;
- switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
- for (;;) {
- switch_size_t olen = 1024;
- switch_core_file_read(&fh, abuf, &olen);
- if (olen == 0) {
- break;
- }
- WriteAudioStream(globals.ring_stream, abuf, (long)olen);
- }
- }
- }
-
- switch_yield(globals.read_codec.implementation->microseconds_per_frame);
-
- }
- switch_clear_flag_locked((&globals), GFLAG_RING);
- }
-
- if (ring_file) {
- deactivate_ring_device();
- switch_core_file_close(&fh);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- switch_core_timer_destroy(&tech_pvt->timer);
- }
+ }
+
+ if (ring_file) {
+ if (switch_core_timer_next(&globals.timer) != SWITCH_STATUS_SUCCESS) {
+ switch_core_file_close(&fh);
+ break;
+ }
+ switch_core_file_read(&fh, abuf, &olen);
+ if (olen == 0) {
+ unsigned int pos = 0;
+ switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
+ }
+ if (globals.ring_stream) {
+ WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.timer);
+ }
+ }
+ }
+ switch_clear_flag_locked((&globals), GFLAG_RING);
+ }
+
+ if (ring_file) {
+ deactivate_ring_device();
+ switch_core_file_close(&fh);
+ }
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- if (!switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
- switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER);
- return SWITCH_STATUS_SUCCESS;
- }
+ if (!switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER);
+ return SWITCH_STATUS_SUCCESS;
+ }
}
- switch_set_flag_locked(tech_pvt, TFLAG_IO);
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
-
- return SWITCH_STATUS_SUCCESS;
+ switch_set_flag_locked(tech_pvt, TFLAG_IO);
+
+ /* Move Channel's State Machine to RING */
+ switch_channel_set_state(channel, CS_RING);
+
+ return SWITCH_STATUS_SUCCESS;
}
@@ -344,6 +343,11 @@
globals.audio_stream = NULL;
}
switch_mutex_unlock(globals.device_lock);
+ if (globals.mixer) {
+ Px_CloseMixer(globals.mixer);
+ globals.mixer = NULL;
+ }
+
}
@@ -359,72 +363,72 @@
-static void add_pvt(private_t *tech_pvt, int master)
+static void add_pvt(private_t * tech_pvt, int master)
{
- private_t *tp;
- uint8_t in_list = 0;
+ private_t *tp;
+ uint8_t in_list = 0;
+
+ switch_mutex_lock(globals.pvt_lock);
+
+ if (switch_strlen_zero(tech_pvt->call_id)) {
+ snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id);
+ switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
+ switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec);
+ switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec);
+ }
+
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ if (tp == tech_pvt) {
+ in_list = 1;
+ }
+ if (master) {
+ switch_clear_flag_locked(tp, TFLAG_MASTER);
+ }
+ }
- switch_mutex_lock(globals.pvt_lock);
- if (switch_strlen_zero(tech_pvt->call_id)) {
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
- switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec);
- }
-
- for (tp = globals.call_list; tp; tp = tp->next) {
- if (tp == tech_pvt) {
- in_list = 1;
- }
- if (master) {
- switch_clear_flag_locked(tp, TFLAG_MASTER);
- }
- }
-
-
- if (master) {
- if (!in_list) {
- tech_pvt->next = globals.call_list;
- globals.call_list = tech_pvt;
- }
- switch_set_flag_locked(tech_pvt, TFLAG_MASTER);
-
- } else if (!in_list) {
- for (tp = globals.call_list; tp && tp->next; tp = tp->next);
- if (tp) {
- tp->next = tech_pvt;
- } else {
- globals.call_list = tech_pvt;
- }
- }
+ if (master) {
+ if (!in_list) {
+ tech_pvt->next = globals.call_list;
+ globals.call_list = tech_pvt;
+ }
+ switch_set_flag_locked(tech_pvt, TFLAG_MASTER);
+
+ } else if (!in_list) {
+ for (tp = globals.call_list; tp && tp->next; tp = tp->next);
+ if (tp) {
+ tp->next = tech_pvt;
+ } else {
+ globals.call_list = tech_pvt;
+ }
+ }
switch_mutex_unlock(globals.pvt_lock);
}
-static void remove_pvt(private_t *tech_pvt)
+static void remove_pvt(private_t * tech_pvt)
{
- private_t *tp, *last = NULL;
+ private_t *tp, *last = NULL;
switch_mutex_lock(globals.pvt_lock);
- for (tp = globals.call_list; tp; tp = tp->next) {
- switch_clear_flag_locked(tp, TFLAG_MASTER);
- if (tp == tech_pvt) {
- if (last) {
- last->next = tp->next;
- } else {
- globals.call_list = tp->next;
- }
- }
- last = tp;
- }
-
- if (globals.call_list) {
- switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No more channels, deactivating audio\n");
- deactivate_audio_device();
- }
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ switch_clear_flag_locked(tp, TFLAG_MASTER);
+ if (tp == tech_pvt) {
+ if (last) {
+ last->next = tp->next;
+ } else {
+ globals.call_list = tp->next;
+ }
+ }
+ last = tp;
+ }
+
+ if (globals.call_list) {
+ switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No more channels, deactivating audio\n");
+ deactivate_audio_device();
+ }
switch_mutex_unlock(globals.pvt_lock);
}
@@ -440,17 +444,17 @@
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
- remove_pvt(tech_pvt);
+ remove_pvt(tech_pvt);
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
switch_set_flag_locked(tech_pvt, TFLAG_HUP);
switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
- if (tech_pvt->hfh) {
- tech_pvt->hfh = NULL;
- switch_core_file_close(&tech_pvt->fh);
- }
+ if (tech_pvt->hfh) {
+ tech_pvt->hfh = NULL;
+ switch_core_file_close(&tech_pvt->fh);
+ }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
@@ -468,14 +472,14 @@
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
- switch (sig) {
- case SWITCH_SIG_KILL:
- switch_set_flag_locked(tech_pvt, TFLAG_HUP);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- break;
- default:
- break;
- }
+ switch (sig) {
+ case SWITCH_SIG_KILL:
+ switch_set_flag_locked(tech_pvt, TFLAG_HUP);
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ break;
+ default:
+ break;
+ }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
@@ -538,8 +542,7 @@
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
- switch_io_flag_t flags, int stream_id)
+static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id)
{
switch_channel_t *channel = NULL;
private_t *tech_pvt = NULL;
@@ -553,109 +556,90 @@
assert(tech_pvt != NULL);
if (!globals.audio_stream) {
- return SWITCH_STATUS_FALSE;
- }
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+ goto cng;
+ }
- if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- goto cng;
- }
-
- if (!is_master(tech_pvt)) {
- if (tech_pvt->hold_file) {
- if (!tech_pvt->hfh) {
- int codec_ms = tech_pvt->codec_ms ? tech_pvt->codec_ms : globals.codec_ms;
- int sample_rate = tech_pvt->sample_rate ? tech_pvt->sample_rate : globals.sample_rate;
-
- if (switch_core_codec_init(&tech_pvt->write_codec,
- "L16",
- NULL,
- sample_rate,
- codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- switch_core_codec_destroy(&globals.read_codec);
- tech_pvt->hold_file = NULL;
- goto cng;
- }
-
- if (switch_core_file_open(&tech_pvt->fh,
- tech_pvt->hold_file,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_core_codec_destroy(&tech_pvt->write_codec);
- tech_pvt->hold_file = NULL;
- goto cng;
- }
-
- if (switch_core_timer_init(&tech_pvt->timer,
- globals.timer_name,
- codec_ms,
- globals.read_codec.implementation->samples_per_frame,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
- switch_core_file_close(&tech_pvt->fh);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- goto cng;
- }
-
- tech_pvt->hfh = &tech_pvt->fh;
- tech_pvt->hold_frame.data = tech_pvt->holdbuf;
- tech_pvt->hold_frame.buflen = sizeof(tech_pvt->holdbuf);
- tech_pvt->hold_frame.rate = sample_rate;
- tech_pvt->hold_frame.codec = &tech_pvt->write_codec;
- }
-
- goto hold;
- }
- cng:
- switch_yield(globals.read_codec.implementation->microseconds_per_frame);
- *frame = &globals.cng_frame;
+ if (!is_master(tech_pvt)) {
+ if (tech_pvt->hold_file) {
+ if (!tech_pvt->hfh) {
+ int sample_rate = tech_pvt->sample_rate ? tech_pvt->sample_rate : globals.sample_rate;
+ if (switch_core_file_open(&tech_pvt->fh,
+ tech_pvt->hold_file,
+ globals.read_codec.implementation->number_of_channels,
+ globals.read_codec.implementation->samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
+ switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
+ tech_pvt->hold_file = NULL;
+ goto cng;
+ }
+
+ tech_pvt->hfh = &tech_pvt->fh;
+ tech_pvt->hold_frame.data = tech_pvt->holdbuf;
+ tech_pvt->hold_frame.buflen = sizeof(tech_pvt->holdbuf);
+ tech_pvt->hold_frame.rate = sample_rate;
+ tech_pvt->hold_frame.codec = &globals.write_codec;
+ }
+
+ goto hold;
+ }
+ cng:
+ switch_yield(globals.read_codec.implementation->microseconds_per_frame);
+ *frame = &globals.cng_frame;
return SWITCH_STATUS_SUCCESS;
- hold:
+ hold:
- {
- switch_size_t olen = globals.read_codec.implementation->samples_per_frame;
- if (switch_core_timer_next(&tech_pvt->timer) != SWITCH_STATUS_SUCCESS) {
- switch_core_file_close(&tech_pvt->fh);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- goto cng;
+ {
+ switch_size_t olen = globals.read_codec.implementation->samples_per_frame;
+ if (switch_core_timer_next(&globals.timer) != SWITCH_STATUS_SUCCESS) {
+ switch_core_file_close(&tech_pvt->fh);
+ goto cng;
+ }
+ switch_core_file_read(tech_pvt->hfh, tech_pvt->hold_frame.data, &olen);
+
+ if (olen == 0) {
+ unsigned int pos = 0;
+ switch_core_file_seek(tech_pvt->hfh, &pos, 0, SEEK_SET);
+ goto cng;
}
- switch_core_file_read(tech_pvt->hfh, tech_pvt->hold_frame.data, &olen);
-
- if (olen == 0) {
- unsigned int pos = 0;
- switch_core_file_seek(tech_pvt->hfh, &pos, 0, SEEK_SET);
- goto cng;
- }
-
-
- tech_pvt->hold_frame.datalen = (uint32_t)(olen * sizeof(int16_t));
- tech_pvt->hold_frame.samples = (uint32_t)olen;
- *frame = &tech_pvt->hold_frame;
-
- }
- return SWITCH_STATUS_SUCCESS;
- }
+
+ tech_pvt->hold_frame.datalen = (uint32_t) (olen * sizeof(int16_t));
+ tech_pvt->hold_frame.samples = (uint32_t) olen;
+ tech_pvt->hold_frame.timestamp = globals.timer.samplecount;
+ *frame = &tech_pvt->hold_frame;
+
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+ }
switch_mutex_lock(globals.device_lock);
- if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_frame)) != 0) {
+ if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data,
+ globals.read_codec.implementation->samples_per_frame,
+ &globals.timer)) == 0) {
+ switch_mutex_unlock(globals.device_lock);
+ goto cng;
+ } else {
globals.read_frame.datalen = samples * 2;
globals.read_frame.samples = samples;
+
+ switch_core_timer_check(&globals.timer);
+ globals.read_frame.timestamp = globals.timer.samplecount;
*frame = &globals.read_frame;
- if (!switch_test_flag((&globals), GFLAG_MOUTH)) {
- memset(globals.read_frame.data, 255, globals.read_frame.datalen);
- }
+ if (!switch_test_flag((&globals), GFLAG_MOUTH)) {
+ memset(globals.read_frame.data, 255, globals.read_frame.datalen);
+ }
status = SWITCH_STATUS_SUCCESS;
}
@@ -664,8 +648,7 @@
return status;
}
-static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
- switch_io_flag_t flags, int stream_id)
+static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id)
{
switch_channel_t *channel = NULL;
private_t *tech_pvt = NULL;
@@ -677,21 +660,22 @@
assert(tech_pvt != NULL);
if (!globals.audio_stream) {
- return SWITCH_STATUS_FALSE;
- }
+ return SWITCH_STATUS_FALSE;
+ }
- if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (!is_master(tech_pvt) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_SUCCESS;
- }
+ if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (!is_master(tech_pvt) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
+ return SWITCH_STATUS_SUCCESS;
+ }
if (globals.audio_stream) {
- if (switch_test_flag((&globals), GFLAG_EAR)) {
- WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)));
- }
+ if (switch_test_flag((&globals), GFLAG_EAR)) {
+ WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)),
+ &globals.timer);
+ }
status = SWITCH_STATUS_SUCCESS;
}
@@ -717,16 +701,19 @@
{
switch_channel_t *channel;
private_t *tech_pvt;
-
+
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
-
+
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
switch (msg->message_id) {
- case SWITCH_MESSAGE_INDICATE_PROGRESS:
+ case SWITCH_MESSAGE_INDICATE_ANSWER:
+ channel_answer_channel(session);
+ break;
+ case SWITCH_MESSAGE_INDICATE_PROGRESS:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage Early Media\n");
switch_set_flag_locked(tech_pvt, TFLAG_IO);
@@ -737,55 +724,7 @@
return SWITCH_STATUS_SUCCESS;
}
-static switch_api_interface_t send_dtmf_interface = {
- /*.interface_name */ "padtmf",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ NULL
-};
-
-static switch_api_interface_t answer_call_interface = {
- /*.interface_name */ "paoffhook",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &send_dtmf_interface
-};
-
-static switch_api_interface_t channel_info_interface = {
- /*.interface_name */ "painfo",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &answer_call_interface
-};
-
-static switch_api_interface_t channel_hup_interface = {
- /*.interface_name */ "pahup",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &channel_info_interface
-};
-
-static switch_api_interface_t channel_call_interface = {
- /*.interface_name */ "pacall",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &channel_hup_interface
-};
-
-static switch_api_interface_t channel_api_interface = {
- /*.interface_name */ "pa",
- /*.desc */ "PortAudio",
- /*.function */ pa_cmd,
- /*.syntax */ "<command> [<args>]",
- /*.next */ &channel_call_interface
-};
-
-static const switch_state_handler_table_t channel_event_handlers = {
+static switch_state_handler_table_t channel_event_handlers = {
/*.on_init */ channel_on_init,
/*.on_ring */ channel_on_ring,
/*.on_execute */ channel_on_execute,
@@ -794,56 +733,38 @@
/*.on_transmit */ channel_on_transmit
};
-static const switch_io_routines_t channel_io_routines = {
+static switch_io_routines_t channel_io_routines = {
/*.outgoing_channel */ channel_outgoing_channel,
- /*.answer_channel */ channel_answer_channel,
/*.read_frame */ channel_read_frame,
/*.write_frame */ channel_write_frame,
/*.kill_channel */ channel_kill_channel,
/*.waitfor_read */ channel_waitfor_read,
/*.waitfor_write */ channel_waitfor_write,
/*.send_dtmf */ channel_send_dtmf,
- /*.receive_message*/ channel_receive_message
-};
-
-static const switch_endpoint_interface_t channel_endpoint_interface = {
- /*.interface_name */ "portaudio",
- /*.io_routines */ &channel_io_routines,
- /*.event_handlers */ &channel_event_handlers,
- /*.private */ NULL,
- /*.next */ NULL
-};
-
-static const switch_loadable_module_interface_t channel_module_interface = {
- /*.module_name */ modname,
- /*.endpoint_interface */ &channel_endpoint_interface,
- /*.timer_interface */ NULL,
- /*.dialplan_interface */ NULL,
- /*.codec_interface */ NULL,
- /*.application_interface */ NULL,
- /*.api_interface */ &channel_api_interface
+ /*.receive_message */ channel_receive_message
};
/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
*/
-static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile,
+static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
+ switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool)
{
- if ((*new_session = switch_core_session_request(&channel_endpoint_interface, pool)) != 0) {
+ if ((*new_session = switch_core_session_request(channel_endpoint_interface, pool)) != 0) {
private_t *tech_pvt;
switch_channel_t *channel;
switch_caller_profile_t *caller_profile;
switch_core_session_add_stream(*new_session, NULL);
if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
+ memset(tech_pvt, 0, sizeof(*tech_pvt));
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
channel = switch_core_session_get_channel(*new_session);
switch_core_session_set_private(*new_session, tech_pvt);
tech_pvt->session = *new_session;
- globals.flags = GFLAG_EAR | GFLAG_MOUTH;
+ globals.flags = GFLAG_EAR | GFLAG_MOUTH;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
switch_core_session_destroy(new_session);
@@ -852,9 +773,9 @@
if (outbound_profile) {
char name[128];
- char *id = !switch_strlen_zero(outbound_profile->caller_id_number) ? outbound_profile->caller_id_number : "na";
+ char *id = !switch_strlen_zero(outbound_profile->caller_id_number) ? outbound_profile->caller_id_number : "na";
snprintf(name, sizeof(name), "PortAudio/%s", id);
-
+
switch_channel_set_name(channel, name);
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
@@ -877,30 +798,28 @@
}
-SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
+SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
{
+ switch_status_t status;
+ switch_api_interface_t *api_interface;
- switch_status_t status;
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
+ module_pool = pool;
Pa_Initialize();
if (dump_info()) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
return SWITCH_STATUS_TERM;
- }
+ }
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
+ return status;
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Input Device: %d, Output Device: %d, Ring Device: %d Sample Rate: %d MS: %d\n",
- globals.indev, globals.outdev, globals.ringdev, globals.sample_rate, globals.codec_ms);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+ "Input Device: %d, Output Device: %d, Ring Device: %d Sample Rate: %d MS: %d\n", globals.indev,
+ globals.outdev, globals.ringdev, globals.sample_rate, globals.codec_ms);
switch_core_hash_init(&globals.call_hash, module_pool);
@@ -920,10 +839,16 @@
globals.cng_frame.data = globals.cngbuf;
globals.cng_frame.buflen = sizeof(globals.cngbuf);
globals.cng_frame.datalen = sizeof(globals.cngbuf);
- switch_set_flag((&globals.cng_frame), SFF_CNG);
+ switch_set_flag((&globals.cng_frame), SFF_CNG);
/* connect my internal structure to the blank pointer passed to me */
- *module_interface = &channel_module_interface;
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ channel_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
+ channel_endpoint_interface->interface_name = "portaudio";
+ channel_endpoint_interface->io_routines = &channel_io_routines;
+ channel_endpoint_interface->state_handler = &channel_event_handlers;
+
+ SWITCH_ADD_API(api_interface, "pa", "PortAudio", pa_cmd, "<command> [<args>]");
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
@@ -934,7 +859,7 @@
{
char *cf = "portaudio.conf";
switch_xml_t cfg, xml, settings, param;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
@@ -942,7 +867,7 @@
}
memset(&globals, 0, sizeof(globals));
- globals.indev = globals.outdev = globals.ringdev = -1;
+ globals.indev = globals.outdev = globals.ringdev = -1;
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
@@ -952,7 +877,7 @@
if (!strcmp(var, "debug")) {
globals.debug = atoi(val);
} else if (!strcmp(var, "ring-interval")) {
- globals.ring_interval = atoi(val);
+ globals.ring_interval = atoi(val);
} else if (!strcmp(var, "ring-file")) {
set_global_ring_file(val);
} else if (!strcmp(var, "hold-file")) {
@@ -987,7 +912,7 @@
} else {
globals.ringdev = get_dev_by_name(val, 0);
}
- }
+ }
}
}
@@ -1006,44 +931,44 @@
if (!globals.ring_interval) {
globals.ring_interval = 5;
}
-
- if (!globals.timer_name) {
- set_global_timer_name("soft");
- }
-
- if (globals.indev < 0) {
- globals.indev = get_dev_by_name(NULL, 1);
- if (globals.indev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device!\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
- status = SWITCH_STATUS_GENERR;
- }
- }
-
- if (globals.outdev < 0) {
- globals.outdev = get_dev_by_name(NULL, 0);
- if (globals.outdev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device!\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
- status = SWITCH_STATUS_GENERR;
- }
- }
-
- if (globals.ringdev < 0) {
- if (globals.outdev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ring device configured using output device!\n");
- globals.ringdev = globals.outdev;
- }
- }
+
+ if (!globals.timer_name) {
+ set_global_timer_name("soft");
+ }
+
+ if (globals.indev < 0) {
+ globals.indev = get_dev_by_name(NULL, 1);
+ if (globals.indev > -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device!\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+ status = SWITCH_STATUS_GENERR;
+ }
+ }
+
+ if (globals.outdev < 0) {
+ globals.outdev = get_dev_by_name(NULL, 0);
+ if (globals.outdev > -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device!\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+ status = SWITCH_STATUS_GENERR;
+ }
+ }
+
+ if (globals.ringdev < 0) {
+ if (globals.outdev > -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ring device configured using output device!\n");
+ globals.ringdev = globals.outdev;
+ }
+ }
switch_xml_free(xml);
return status;
}
-SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown)
{
if (globals.read_codec.implementation) {
switch_core_codec_destroy(&globals.read_codec);
@@ -1053,6 +978,7 @@
switch_core_codec_destroy(&globals.write_codec);
}
+ switch_core_timer_destroy(&globals.timer);
Pa_Terminate();
return SWITCH_STATUS_SUCCESS;
@@ -1061,18 +987,18 @@
static int get_dev_by_number(int number, int in)
{
- int numDevices = Pa_GetDeviceCount();
+ int numDevices = Pa_GetDeviceCount();
const PaDeviceInfo *pdi;
- if (number > -1 && number < numDevices && (pdi = Pa_GetDeviceInfo(number))) {
- if (in && pdi->maxInputChannels) {
- return number;
- } else if (!in && pdi->maxOutputChannels) {
- return number;
- }
- }
-
- return -1;
+ if (number > -1 && number < numDevices && (pdi = Pa_GetDeviceInfo(number))) {
+ if (in && pdi->maxInputChannels) {
+ return number;
+ } else if (!in && pdi->maxOutputChannels) {
+ return number;
+ }
+ }
+
+ return -1;
}
static int get_dev_by_name(char *name, int in)
@@ -1088,15 +1014,15 @@
}
for (i = 0; i < numDevices; i++) {
- int match = 0;
+ int match = 0;
pdi = Pa_GetDeviceInfo(i);
-
+
if (switch_strlen_zero(name)) {
- match = 1;
- } else if (strstr(pdi->name, name)) {
- match = 1;
- }
-
+ match = 1;
+ } else if (strstr(pdi->name, name)) {
+ match = 1;
+ }
+
if (match) {
if (in && pdi->maxInputChannels) {
return i;
@@ -1106,248 +1032,253 @@
}
}
- if (switch_strlen_zero(name)) {
- return -1;
- }
+ if (switch_strlen_zero(name)) {
+ return -1;
+ }
return get_dev_by_name(NULL, in);
}
/*******************************************************************/
-static void PrintSupportedStandardSampleRates(const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters)
+static void PrintSupportedStandardSampleRates(const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters)
{
- int i, printCount, cr = 7;
- PaError err;
- static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
- 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1};
-
- printCount = cr;
- for(i=0; standardSampleRates[i] > 0; i++) {
- err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
- if (err == paFormatIsSupported) {
- if (printCount == cr) {
- printCount = 0;
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n\t%0.2f", standardSampleRates[i]);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, ", %0.2f", standardSampleRates[i]);
- }
- printCount++;
- }
- }
- if (!printCount) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, " None\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n");
- }
+ int i, printCount, cr = 7;
+ PaError err;
+ static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
+ 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1
+ };
+
+ printCount = cr;
+ for (i = 0; standardSampleRates[i] > 0; i++) {
+ err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
+ if (err == paFormatIsSupported) {
+ if (printCount == cr) {
+ printCount = 0;
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n\t%0.2f", standardSampleRates[i]);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, ", %0.2f", standardSampleRates[i]);
+ }
+ printCount++;
+ }
+ }
+ if (!printCount) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, " None\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n");
+ }
}
+
/*******************************************************************/
static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *stream)
{
- int i, numDevices;
- const PaDeviceInfo *deviceInfo;
-
- numDevices = Pa_GetDeviceCount();
- if (numDevices < 0) {
+ int i, numDevices;
+ const PaDeviceInfo *deviceInfo;
+
+ numDevices = Pa_GetDeviceCount();
+ if (numDevices < 0) {
return SWITCH_STATUS_SUCCESS;
- }
- for(i=0; i<numDevices; i++) {
- deviceInfo = Pa_GetDeviceInfo(i);
- stream->write_function(stream, "%d;%s;%d;%d\n", i, deviceInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
+ }
+ for (i = 0; i < numDevices; i++) {
+ deviceInfo = Pa_GetDeviceInfo(i);
+ stream->write_function(stream, "%d;%s;%d;%d\n", i, deviceInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
}
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static int dump_info(void)
{
- int i, numDevices, defaultDisplayed;
- const PaDeviceInfo *deviceInfo;
- PaStreamParameters inputParameters, outputParameters;
- PaError err;
- const char *line = "--------------------------------------------------------------------------------\n";
-
+ int i, numDevices, defaultDisplayed;
+ const PaDeviceInfo *deviceInfo;
+ PaStreamParameters inputParameters, outputParameters;
+ PaError err;
+ const char *line = "--------------------------------------------------------------------------------\n";
+
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "PortAudio version number = %d\nPortAudio version text = '%s'\n",
- Pa_GetVersion(), Pa_GetVersionText());
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+ "PortAudio version number = %d\nPortAudio version text = '%s'\n", Pa_GetVersion(), Pa_GetVersionText());
if (globals.audio_stream) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
return 0;
}
-
- numDevices = Pa_GetDeviceCount();
- if (numDevices < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
- err = numDevices;
- goto error;
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices);
- for(i=0; i<numDevices; i++) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
- deviceInfo = Pa_GetDeviceInfo(i);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Device #%d ", i);
-
- /* Mark global and API specific default devices */
- defaultDisplayed = 0;
- if (i == Pa_GetDefaultInputDevice()) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Input");
- defaultDisplayed = 1;
-
- } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
-
- const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name);
- defaultDisplayed = 1;
- }
-
- if (i == Pa_GetDefaultOutputDevice()) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Output");
- defaultDisplayed = 1;
-
- } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
-
- const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name);
- defaultDisplayed = 1;
- }
-
- if (defaultDisplayed) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "** | ");
- }
- /* print device info fields */
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels );
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels );
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
-
- /* poll for standard sample rates */
- inputParameters.device = i;
- inputParameters.channelCount = deviceInfo->maxInputChannels;
- inputParameters.sampleFormat = paInt16;
- inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
- inputParameters.hostApiSpecificStreamInfo = NULL;
-
- outputParameters.device = i;
- outputParameters.channelCount = deviceInfo->maxOutputChannels;
- outputParameters.sampleFormat = paInt16;
- outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
- outputParameters.hostApiSpecificStreamInfo = NULL;
-
- if (inputParameters.channelCount > 0) {
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:",
- inputParameters.channelCount);
- PrintSupportedStandardSampleRates(&inputParameters, NULL);
- }
-
- if (outputParameters.channelCount > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:",
- outputParameters.channelCount);
- PrintSupportedStandardSampleRates(NULL, &outputParameters);
- }
-
- if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "full-duplex 16 bit %d channel input, %d channel output rates:",
- inputParameters.channelCount, outputParameters.channelCount);
- PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
- }
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
-
- return 0;
-
- error:
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "An error occured while using the portaudio stream\n");
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error number: %d\n", err);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error message: %s\n", Pa_GetErrorText(err));
- return err;
+
+ numDevices = Pa_GetDeviceCount();
+ if (numDevices < 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
+ err = numDevices;
+ goto error;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices);
+ for (i = 0; i < numDevices; i++) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+ deviceInfo = Pa_GetDeviceInfo(i);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Device #%d ", i);
+
+ /* Mark global and API specific default devices */
+ defaultDisplayed = 0;
+ if (i == Pa_GetDefaultInputDevice()) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Input");
+ defaultDisplayed = 1;
+
+ } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
+
+ const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name);
+ defaultDisplayed = 1;
+ }
+
+ if (i == Pa_GetDefaultOutputDevice()) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Output");
+ defaultDisplayed = 1;
+
+ } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
+
+ const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name);
+ defaultDisplayed = 1;
+ }
+
+ if (defaultDisplayed) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "** | ");
+ }
+ /* print device info fields */
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
+
+ /* poll for standard sample rates */
+ inputParameters.device = i;
+ inputParameters.channelCount = deviceInfo->maxInputChannels;
+ inputParameters.sampleFormat = paInt16;
+ inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
+ inputParameters.hostApiSpecificStreamInfo = NULL;
+
+ outputParameters.device = i;
+ outputParameters.channelCount = deviceInfo->maxOutputChannels;
+ outputParameters.sampleFormat = paInt16;
+ outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+
+ if (inputParameters.channelCount > 0) {
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:", inputParameters.channelCount);
+ PrintSupportedStandardSampleRates(&inputParameters, NULL);
+ }
+
+ if (outputParameters.channelCount > 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:", outputParameters.channelCount);
+ PrintSupportedStandardSampleRates(NULL, &outputParameters);
+ }
+
+ if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+ "full-duplex 16 bit %d channel input, %d channel output rates:", inputParameters.channelCount,
+ outputParameters.channelCount);
+ PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
+ }
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+
+ return 0;
+
+ error:
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "An error occured while using the portaudio stream\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error number: %d\n", err);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error message: %s\n", Pa_GetErrorText(err));
+ return err;
}
static switch_status_t engage_device(int sample_rate, int codec_ms)
{
- PaStreamParameters inputParameters, outputParameters;
+ PaStreamParameters inputParameters, outputParameters;
PaError err;
- if (!globals.audio_stream) {
- if (!sample_rate) {
- sample_rate = globals.sample_rate;
- }
- if (!codec_ms) {
- codec_ms = globals.codec_ms;
- }
-
- if (switch_core_codec_init(&globals.read_codec,
- "L16",
- NULL,
- sample_rate,
- codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- return SWITCH_STATUS_FALSE;
- } else {
- if (switch_core_codec_init(&globals.write_codec,
- "L16",
- NULL,
- sample_rate,
- codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- switch_core_codec_destroy(&globals.read_codec);
- return SWITCH_STATUS_FALSE;
- }
- }
-
- globals.read_frame.rate = sample_rate;
- globals.read_frame.codec = &globals.read_codec;
-
-
-
- switch_mutex_lock(globals.device_lock);
- /* LOCKED ***************************************************************************************************/
- inputParameters.device = globals.indev;
- inputParameters.channelCount = 1;
- inputParameters.sampleFormat = SAMPLE_TYPE;
- inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
- inputParameters.hostApiSpecificStreamInfo = NULL;
-
- outputParameters.device = globals.outdev;
- outputParameters.channelCount = 1;
- outputParameters.sampleFormat = SAMPLE_TYPE;
- outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
- outputParameters.hostApiSpecificStreamInfo = NULL;
- err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff);
- /* UNLOCKED **************************************************************************************************/
- switch_mutex_unlock(globals.device_lock);
-
-
- if (err != paNoError) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device!\n");
- switch_core_codec_destroy(&globals.read_codec);
- switch_core_codec_destroy(&globals.write_codec);
-
- return SWITCH_STATUS_FALSE;
- }
- }
+ if (!globals.audio_stream) {
+ if (!sample_rate) {
+ sample_rate = globals.sample_rate;
+ }
+ if (!codec_ms) {
+ codec_ms = globals.codec_ms;
+ }
+
+ if (switch_core_codec_init(&globals.read_codec,
+ "L16",
+ NULL, sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+ NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ return SWITCH_STATUS_FALSE;
+ } else {
+ if (switch_core_codec_init(&globals.write_codec,
+ "L16",
+ NULL,
+ sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+ NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ return SWITCH_STATUS_FALSE;
+ }
+ }
+
+ if (switch_core_timer_init(&globals.timer,
+ globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_frame,
+ module_pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ switch_core_codec_destroy(&globals.write_codec);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ globals.read_frame.rate = sample_rate;
+ globals.read_frame.codec = &globals.read_codec;
- return SWITCH_STATUS_SUCCESS;
+
+
+ switch_mutex_lock(globals.device_lock);
+ /* LOCKED ************************************************************************************************** */
+ inputParameters.device = globals.indev;
+ inputParameters.channelCount = 1;
+ inputParameters.sampleFormat = SAMPLE_TYPE;
+ inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
+ inputParameters.hostApiSpecificStreamInfo = NULL;
+
+ outputParameters.device = globals.outdev;
+ outputParameters.channelCount = 1;
+ outputParameters.sampleFormat = SAMPLE_TYPE;
+ outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+ err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
+ globals.read_codec.implementation->samples_per_frame);
+ /* UNLOCKED ************************************************************************************************* */
+ switch_mutex_unlock(globals.device_lock);
+
+ globals.mixer = Px_OpenMixer(&globals.audio_stream, 0);
+
+
+ if (err != paNoError) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device!\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ switch_core_codec_destroy(&globals.write_codec);
+
+ return SWITCH_STATUS_FALSE;
+ }
+ }
+
+
+
+ return SWITCH_STATUS_SUCCESS;
}
@@ -1355,35 +1286,35 @@
static switch_status_t engage_ring_device(int sample_rate, int channels)
{
- //int codec_ms = 20;
- PaStreamParameters outputParameters;
+ PaStreamParameters outputParameters;
PaError err;
- if (!globals.ring_stream) {
- if (!sample_rate) {
- sample_rate = globals.sample_rate;
- }
-
- switch_mutex_lock(globals.device_lock);
- /* LOCKED ***************************************************************************************************/
- outputParameters.device = globals.ringdev;
- outputParameters.channelCount = channels;
- outputParameters.sampleFormat = SAMPLE_TYPE;
- outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
- outputParameters.hostApiSpecificStreamInfo = NULL;
- err = OpenAudioStream(&globals.ring_stream, NULL, &outputParameters, sample_rate, paClipOff);
- /* UNLOCKED **************************************************************************************************/
- switch_mutex_unlock(globals.device_lock);
-
-
- if (err != paNoError) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device!\n");
- return SWITCH_STATUS_FALSE;
- }
- }
+ if (!globals.ring_stream) {
+ if (!sample_rate) {
+ sample_rate = globals.sample_rate;
+ }
+
+ switch_mutex_lock(globals.device_lock);
+ /* LOCKED ************************************************************************************************** */
+ outputParameters.device = globals.ringdev;
+ outputParameters.channelCount = channels;
+ outputParameters.sampleFormat = SAMPLE_TYPE;
+ outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+ err = OpenAudioStream(&globals.ring_stream, NULL, &outputParameters, sample_rate, paClipOff,
+ globals.read_codec.implementation->samples_per_frame);
+ /* UNLOCKED ************************************************************************************************* */
+ switch_mutex_unlock(globals.device_lock);
+
+
+ if (err != paNoError) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Engage ring device! rate: %d channels %d\n", sample_rate, channels);
- return SWITCH_STATUS_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Engage ring device! rate: %d channels %d\n", sample_rate, channels);
+ return SWITCH_STATUS_SUCCESS;
}
@@ -1391,64 +1322,64 @@
static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- char *dtmf = argv[0];
+ char *dtmf = argv[0];
- if (switch_strlen_zero(dtmf)) {
- stream->write_function(stream, "No DTMF Supplied!\n");
- } else {
- switch_mutex_lock(globals.pvt_lock);
- if (globals.call_list) {
- switch_channel_t *channel = switch_core_session_get_channel(globals.call_list->session);
- switch_channel_queue_dtmf(channel, dtmf);
- }
- switch_mutex_unlock(globals.pvt_lock);
- }
+ if (switch_strlen_zero(dtmf)) {
+ stream->write_function(stream, "No DTMF Supplied!\n");
+ } else {
+ switch_mutex_lock(globals.pvt_lock);
+ if (globals.call_list) {
+ switch_channel_t *channel = switch_core_session_get_channel(globals.call_list->session);
+ switch_channel_queue_dtmf(channel, dtmf);
+ }
+ switch_mutex_unlock(globals.pvt_lock);
+ }
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tp,*tech_pvt = NULL;
- char *callid = argv[0];
- uint8_t one_call = 0;
-
- switch_mutex_lock(globals.pvt_lock);
- if (switch_strlen_zero(callid)) {
- if (globals.call_list) {
- if (globals.call_list->next) {
- tech_pvt = globals.call_list->next;
- } else {
- tech_pvt = globals.call_list;
- one_call = 1;
- }
- }
- } else if (!strcasecmp(callid, "none")) {
- for (tp = globals.call_list; tp; tp = tp->next) {
- switch_clear_flag_locked(tp, TFLAG_MASTER);
- }
- stream->write_function(stream, "OK\n");
- goto done;
- } else {
- tech_pvt = switch_core_hash_find(globals.call_hash, callid);
- }
+ private_t *tp, *tech_pvt = NULL;
+ char *callid = argv[0];
+ uint8_t one_call = 0;
+
+ switch_mutex_lock(globals.pvt_lock);
+ if (switch_strlen_zero(callid)) {
+ if (globals.call_list) {
+ if (globals.call_list->next) {
+ tech_pvt = globals.call_list->next;
+ } else {
+ tech_pvt = globals.call_list;
+ one_call = 1;
+ }
+ }
+ } else if (!strcasecmp(callid, "none")) {
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ switch_clear_flag_locked(tp, TFLAG_MASTER);
+ }
+ stream->write_function(stream, "OK\n");
+ goto done;
+ } else {
+ tech_pvt = switch_core_hash_find(globals.call_hash, callid);
+ }
if (tech_pvt) {
- if (tech_pvt == globals.call_list && !tech_pvt->next) {
- one_call = 1;
- }
-
- if (!one_call) {
- remove_pvt(tech_pvt);
- }
- add_pvt(tech_pvt, PA_MASTER);
- stream->write_function(stream, "OK\n");
+ if (tech_pvt == globals.call_list && !tech_pvt->next) {
+ one_call = 1;
+ }
+
+ if (!one_call) {
+ remove_pvt(tech_pvt);
+ }
+ add_pvt(tech_pvt, PA_MASTER);
+ stream->write_function(stream, "OK\n");
} else {
stream->write_function(stream, "NO SUCH CALL\n");
}
- done:
- switch_mutex_unlock(globals.pvt_lock);
+ done:
+ switch_mutex_unlock(globals.pvt_lock);
return SWITCH_STATUS_SUCCESS;
@@ -1456,23 +1387,23 @@
static switch_status_t hangup_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tech_pvt;
- char *callid = argv[0];
-
- switch_mutex_lock(globals.pvt_lock);
- if (switch_strlen_zero(callid)) {
- tech_pvt = globals.call_list;
- } else {
- tech_pvt = switch_core_hash_find(globals.call_hash, callid);
- }
+ private_t *tech_pvt;
+ char *callid = argv[0];
+
+ switch_mutex_lock(globals.pvt_lock);
+ if (switch_strlen_zero(callid)) {
+ tech_pvt = globals.call_list;
+ } else {
+ tech_pvt = switch_core_hash_find(globals.call_hash, callid);
+ }
if (tech_pvt) {
- switch_set_flag_locked(tech_pvt, TFLAG_HUP);
+ switch_channel_hangup(switch_core_session_get_channel(tech_pvt->session), SWITCH_CAUSE_NORMAL_CLEARING);
stream->write_function(stream, "OK\n");
} else {
stream->write_function(stream, "NO SUCH CALL\n");
}
- switch_mutex_unlock(globals.pvt_lock);
+ switch_mutex_unlock(globals.pvt_lock);
return SWITCH_STATUS_SUCCESS;
@@ -1480,43 +1411,43 @@
static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tp;
- int x = 0;
- char *callid = argv[0];
-
- switch_mutex_lock(globals.pvt_lock);
-
- if (!switch_strlen_zero(callid)) {
- if ((tp = switch_core_hash_find(globals.call_hash, callid))) {
- if (switch_test_flag(tp, TFLAG_ANSWER)) {
- stream->write_function(stream, "CALL ALREADY ANSWERED\n");
- } else {
- switch_channel_t *channel = switch_core_session_get_channel(tp->session);
- switch_set_flag_locked(tp, TFLAG_ANSWER);
- switch_channel_answer(channel);
- add_pvt(tp, PA_MASTER);
- }
- } else {
- stream->write_function(stream, "NO SUCH CALL\n");
- }
-
- goto done;
- }
-
- for (tp = globals.call_list; tp; tp = tp->next) {
- if (!switch_test_flag(tp, TFLAG_ANSWER)) {
- switch_channel_t *channel = switch_core_session_get_channel(tp->session);
- switch_set_flag_locked(tp, TFLAG_ANSWER);
- switch_channel_answer(channel);
- add_pvt(tp, PA_MASTER);
- x++;
- break;
- }
- }
- done:
- switch_mutex_unlock(globals.pvt_lock);
+ private_t *tp;
+ int x = 0;
+ char *callid = argv[0];
+
+ switch_mutex_lock(globals.pvt_lock);
+
+ if (!switch_strlen_zero(callid)) {
+ if ((tp = switch_core_hash_find(globals.call_hash, callid))) {
+ if (switch_test_flag(tp, TFLAG_ANSWER)) {
+ stream->write_function(stream, "CALL ALREADY ANSWERED\n");
+ } else {
+ switch_channel_t *channel = switch_core_session_get_channel(tp->session);
+ switch_set_flag_locked(tp, TFLAG_ANSWER);
+ switch_channel_answer(channel);
+ add_pvt(tp, PA_MASTER);
+ }
+ } else {
+ stream->write_function(stream, "NO SUCH CALL\n");
+ }
- stream->write_function(stream, "Answered %d channels.\n", x);
+ goto done;
+ }
+
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ if (!switch_test_flag(tp, TFLAG_ANSWER)) {
+ switch_channel_t *channel = switch_core_session_get_channel(tp->session);
+ switch_set_flag_locked(tp, TFLAG_ANSWER);
+ switch_channel_answer(channel);
+ add_pvt(tp, PA_MASTER);
+ x++;
+ break;
+ }
+ }
+ done:
+ switch_mutex_unlock(globals.pvt_lock);
+
+ stream->write_function(stream, "Answered %d channels.\n", x);
return SWITCH_STATUS_SUCCESS;
@@ -1525,113 +1456,110 @@
static switch_status_t do_flags(char **argv, int argc, switch_stream_handle_t *stream)
{
- char *action = argv[0];
- char *flag_str = argv[1];
- GFLAGS flags = GFLAG_NONE;
- char *p;
- int x = 0;
-
- if (argc < 2) {
- goto desc;
- }
-
- for (x = 1; x < argc; x++) {
- flag_str = argv[x];
- for(p = flag_str; *p; p++) {
- *p = (char)tolower(*p);
- }
-
- if (strstr(flag_str, "ear")) {
- flags |= GFLAG_EAR;
- }
- if (strstr(flag_str, "mouth")) {
- flags |= GFLAG_MOUTH;
- }
- }
-
- if (!strcasecmp(action, "on")) {
- if (flags & GFLAG_EAR) {
- switch_set_flag((&globals), GFLAG_EAR);
- }
- if (flags & GFLAG_MOUTH) {
- switch_set_flag((&globals), GFLAG_MOUTH);
- }
- } else if (!strcasecmp(action, "off")) {
- if (flags & GFLAG_EAR) {
- switch_clear_flag((&globals), GFLAG_EAR);
- }
- if (flags & GFLAG_MOUTH) {
- switch_clear_flag((&globals), GFLAG_MOUTH);
- }
- } else {
- goto bad;
- }
-
- desc:
- x = 0;
- stream->write_function(stream, "FLAGS: ");
- if (switch_test_flag((&globals), GFLAG_EAR)) {
- stream->write_function(stream, "ear");
- x++;
- }
- if (switch_test_flag((&globals), GFLAG_MOUTH)) {
- stream->write_function(stream, "%smouth", x ? "|" : "");
- x++;
- }
- if (!x) {
- stream->write_function(stream, "none");
- }
-
- goto done;
-
- bad:
- stream->write_function(stream, "Usage: flags [on|off] <flags>\n");
- done:
- return SWITCH_STATUS_SUCCESS;
+ char *action = argv[0];
+ char *flag_str = argv[1];
+ GFLAGS flags = GFLAG_NONE;
+ char *p;
+ int x = 0;
+
+ if (argc < 2) {
+ goto desc;
+ }
+
+ for (x = 1; x < argc; x++) {
+ flag_str = argv[x];
+ for (p = flag_str; *p; p++) {
+ *p = (char) tolower(*p);
+ }
+
+ if (strstr(flag_str, "ear")) {
+ flags |= GFLAG_EAR;
+ }
+ if (strstr(flag_str, "mouth")) {
+ flags |= GFLAG_MOUTH;
+ }
+ }
+
+ if (!strcasecmp(action, "on")) {
+ if (flags & GFLAG_EAR) {
+ switch_set_flag((&globals), GFLAG_EAR);
+ }
+ if (flags & GFLAG_MOUTH) {
+ switch_set_flag((&globals), GFLAG_MOUTH);
+ }
+ } else if (!strcasecmp(action, "off")) {
+ if (flags & GFLAG_EAR) {
+ switch_clear_flag((&globals), GFLAG_EAR);
+ }
+ if (flags & GFLAG_MOUTH) {
+ switch_clear_flag((&globals), GFLAG_MOUTH);
+ }
+ } else {
+ goto bad;
+ }
+
+ desc:
+ x = 0;
+ stream->write_function(stream, "FLAGS: ");
+ if (switch_test_flag((&globals), GFLAG_EAR)) {
+ stream->write_function(stream, "ear");
+ x++;
+ }
+ if (switch_test_flag((&globals), GFLAG_MOUTH)) {
+ stream->write_function(stream, "%smouth", x ? "|" : "");
+ x++;
+ }
+ if (!x) {
+ stream->write_function(stream, "none");
+ }
+
+ goto done;
+
+ bad:
+ stream->write_function(stream, "Usage: flags [on|off] <flags>\n");
+ done:
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t list_calls(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tp;
- int x = 0;
- char *cid_name = "n/a";
- char *cid_num = "n/a";
-
- switch_mutex_lock(globals.pvt_lock);
- for (tp = globals.call_list; tp; tp = tp->next) {
+ private_t *tp;
+ int x = 0;
+ char *cid_name = "n/a";
+ char *cid_num = "n/a";
+
+ switch_mutex_lock(globals.pvt_lock);
+ for (tp = globals.call_list; tp; tp = tp->next) {
switch_channel_t *channel;
- switch_caller_profile_t *profile;
- x++;
- channel = switch_core_session_get_channel(tp->session);
-
- if ((profile = switch_channel_get_caller_profile(channel))) {
- if (profile->originatee_caller_profile) {
- cid_name = "Outbound Call";
- cid_num = profile->originatee_caller_profile->destination_number;
- } else {
- cid_name = profile->caller_id_name;
- cid_num = profile->caller_id_number;
- }
- }
-
- stream->write_function(stream, "%s %s [%s (%s)] %s\n", tp->call_id, switch_channel_get_name(channel),
- cid_name,
- cid_num,
- switch_test_flag(tp, TFLAG_MASTER) ? "active" : "hold"
- );
- }
- switch_mutex_unlock(globals.pvt_lock);
+ switch_caller_profile_t *profile;
+ x++;
+ channel = switch_core_session_get_channel(tp->session);
+
+ if ((profile = switch_channel_get_caller_profile(channel))) {
+ if (profile->originatee_caller_profile) {
+ cid_name = "Outbound Call";
+ cid_num = profile->originatee_caller_profile->destination_number;
+ } else {
+ cid_name = profile->caller_id_name;
+ cid_num = profile->caller_id_number;
+ }
+ }
+
+ stream->write_function(stream, "%s %s [%s (%s)] %s\n", tp->call_id, switch_channel_get_name(channel),
+ cid_name, cid_num, switch_test_flag(tp, TFLAG_MASTER) ? "active" : "hold");
+ }
+ switch_mutex_unlock(globals.pvt_lock);
- stream->write_function(stream, "\n%d call%s\n", x, x == 1 ? "" : "s");
+ stream->write_function(stream, "\n%d call%s\n", x, x == 1 ? "" : "s");
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t *stream)
{
switch_core_session_t *session;
switch_status_t status = SWITCH_STATUS_SUCCESS;
- char *dest = NULL;
+ char *dest = NULL;
if (!argv[0]) {
stream->write_function(stream, "FAIL:Usage: call <dest>\n");
@@ -1639,12 +1567,12 @@
}
dest = argv[0];
- if ((session = switch_core_session_request(&channel_endpoint_interface, NULL)) != 0) {
+ if ((session = switch_core_session_request(channel_endpoint_interface, NULL)) != 0) {
private_t *tech_pvt;
switch_channel_t *channel;
- char *dialplan = globals.dialplan;
- char *cid_name = globals.cid_name;
- char *cid_num = globals.cid_num;
+ char *dialplan = globals.dialplan;
+ char *cid_name = globals.cid_name;
+ char *cid_num = globals.cid_num;
switch_core_session_add_stream(session, NULL);
if ((tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t))) != 0) {
@@ -1653,7 +1581,7 @@
channel = switch_core_session_get_channel(session);
switch_core_session_set_private(session, tech_pvt);
tech_pvt->session = session;
- globals.flags = GFLAG_EAR | GFLAG_MOUTH;
+ globals.flags = GFLAG_EAR | GFLAG_MOUTH;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
switch_core_session_destroy(&session);
@@ -1661,31 +1589,29 @@
}
if (!switch_strlen_zero(argv[1])) {
- dialplan = argv[1];
- }
+ dialplan = argv[1];
+ }
- if (!switch_strlen_zero(argv[2])) {
- cid_num = argv[2];
- }
-
- if (!switch_strlen_zero(argv[3])) {
- cid_name = argv[3];
- }
-
- if (!switch_strlen_zero(argv[4])) {
- tech_pvt->sample_rate = atoi(argv[4]);
- }
-
- if (!switch_strlen_zero(argv[4])) {
- tech_pvt->codec_ms = atoi(argv[5]);
- }
+ if (!switch_strlen_zero(argv[2])) {
+ cid_num = argv[2];
+ }
+
+ if (!switch_strlen_zero(argv[3])) {
+ cid_name = argv[3];
+ }
+
+ if (!switch_strlen_zero(argv[4])) {
+ tech_pvt->sample_rate = atoi(argv[4]);
+ }
+
+ if (!switch_strlen_zero(argv[4])) {
+ tech_pvt->codec_ms = atoi(argv[5]);
+ }
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
NULL,
- dialplan,
- cid_name,
- cid_num,
- NULL, NULL, NULL, NULL, (char *)modname, NULL, dest)) != 0) {
+ dialplan, cid_name, cid_num, NULL, NULL, NULL, NULL, (char *) modname, NULL,
+ dest)) != 0) {
char name[128];
snprintf(name, sizeof(name), "PortAudio/%s",
tech_pvt->caller_profile->destination_number ? tech_pvt->caller_profile->destination_number : modname);
@@ -1695,14 +1621,19 @@
}
tech_pvt->session = session;
if ((status = engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms)) == SWITCH_STATUS_SUCCESS) {
- switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
- switch_channel_mark_answered(channel);
+ switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
+ switch_channel_mark_answered(channel);
switch_channel_set_state(channel, CS_INIT);
- switch_core_session_thread_launch(tech_pvt->session);
- add_pvt(tech_pvt, PA_MASTER);
- stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+ if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+ switch_core_session_destroy(&session);
+ stream->write_function(stream, "FAIL:Thread Error!\n");
+ } else {
+ add_pvt(tech_pvt, PA_MASTER);
+ stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+ }
} else {
- switch_core_session_destroy(&session);
+ switch_core_session_destroy(&session);
stream->write_function(stream, "FAIL:Device Error!\n");
}
}
@@ -1710,74 +1641,131 @@
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t padep(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+static switch_status_t set_volume(char **argv, int argc, switch_stream_handle_t *stream)
{
- stream->write_function(stream, "This command no longer exists (try 'pa help')\n");
- return SWITCH_STATUS_SUCCESS;
+ PxVolume volume;
+ switch_mutex_lock(globals.device_lock);
+ if (!switch_strlen_zero(argv[1])) {
+ volume = (PxVolume) atof(argv[1]);
+ Px_SetMasterVolume( globals.mixer, volume );
+ }
+ switch_mutex_unlock(globals.device_lock);
+ return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t pa_cmd(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(pa_cmd)
{
- char *argv[1024] = {0};
- int argc = 0;
- char *mycmd = NULL, *devname = NULL;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- pa_command_t func = NULL;
- int lead = 1, devval = 0;
- const char *usage_string = "USAGE:\n"
- "--------------------------------------------------------------------------------\n"
- "pa help\n"
- "pa dump\n"
- "pa call <dest> [<dialplan> <cid_name> <cid_num> <rate>]\n"
- "pa answer [<call_id>]\n"
- "pa hangup [<call_id>]\n"
- "pa list\n"
- "pa switch [<call_id>|none]\n"
- "pa dtmf <digit string>\n"
- "pa flags [on|off] [ear] [mouth]\n"
+ char *argv[1024] = { 0 };
+ int argc = 0;
+ char *mycmd = NULL, *devname = NULL;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ pa_command_t func = NULL;
+ int lead = 1, devval = 0;
+ char *wcmd = NULL, *action = NULL;
+ char cmd_buf[1024] = "";
+ char *http = NULL;
+
+ const char *usage_string = "USAGE:\n"
+ "--------------------------------------------------------------------------------\n"
+ "pa help\n"
+ "pa dump\n"
+ "pa call <dest> [<dialplan> <cid_name> <cid_num> <rate>]\n"
+ "pa answer [<call_id>]\n"
+ "pa hangup [<call_id>]\n"
+ "pa list\n"
+ "pa switch [<call_id>|none]\n"
+ "pa dtmf <digit string>\n"
+ "pa flags [on|off] [ear] [mouth]\n"
"pa devlist\n"
"pa indev [#<num>|<partial name>\n"
"pa outdev [#<num>|<partial name>\n"
"pa ringdev [#<num>|<partial name>\n"
- "--------------------------------------------------------------------------------\n";
+ "pa setvolume <volume between 0.0 and 1.0>\n"
+ "--------------------------------------------------------------------------------\n";
+
+ if (stream->event) {
+ http = switch_event_get_header(stream->event, "http-host");
+ }
+
+
+ if (http) {
+#if 0
+ switch_event_header_t *hp;
+ stream->write_function(stream, "<pre>");
+ for (hp = stream->event->headers; hp; hp = hp->next) {
+ stream->write_function(stream, "[%s]=[%s]\n", hp->name, hp->value);
+ }
+ stream->write_function(stream, "</pre>");
+#endif
+
+ wcmd = switch_str_nil(switch_event_get_header(stream->event, "wcmd"));
+ action = switch_event_get_header(stream->event, "action");
- if (switch_strlen_zero(cmd)) {
- stream->write_function(stream, "%s", usage_string);
- goto done;
- }
-
- if (!(mycmd = strdup(cmd))) {
- status = SWITCH_STATUS_MEMERR;
- goto done;
- }
-
- if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
- stream->write_function(stream, "%s", usage_string);
- goto done;
- }
-
- if (!strcasecmp(argv[0], "call")) {
- func = place_call;
- } else if (!strcasecmp(argv[0], "help")) {
- stream->write_function(stream, "%s", usage_string);
- goto done;
- } else if (!strcasecmp(argv[0], "devlist")) {
+ if (action) {
+ if (strlen(action) == 1) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "dtmf %s", action);
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "mute")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "flags off mouth");
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "unmute")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "flags on mouth");
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "switch")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "switch %s", wcmd);
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "call")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "call %s", wcmd);
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "hangup") || !strcmp(action, "list") || !strcmp(action, "answer")) {
+ cmd = action;
+ }
+ }
+
+ if (switch_strlen_zero(cmd)) {
+ goto done;
+ }
+
+ } else {
+
+ if (switch_strlen_zero(cmd)) {
+ stream->write_function(stream, "%s", usage_string);
+ goto done;
+ }
+ }
+
+ if (!(mycmd = strdup(cmd))) {
+ status = SWITCH_STATUS_MEMERR;
+ goto done;
+ }
+
+ if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
+ stream->write_function(stream, "%s", usage_string);
+ goto done;
+ }
+
+ if (!strcasecmp(argv[0], "call")) {
+ func = place_call;
+ } else if (!strcasecmp(argv[0], "help")) {
+ stream->write_function(stream, "%s", usage_string);
+ goto done;
+ } else if (!strcasecmp(argv[0], "devlist")) {
func = devlist;
- } else if (!strcasecmp(argv[0], "dump")) {
- dump_info();
- goto done;
- } else if (!strcasecmp(argv[0], "list")) {
- func = list_calls;
- } else if (!strcasecmp(argv[0], "flags")) {
- func = do_flags;
- } else if (!strcasecmp(argv[0], "hangup")) {
- func = hangup_call;
- } else if (!strcasecmp(argv[0], "answer")) {
- func = answer_call;
- } else if (!strcasecmp(argv[0], "switch")) {
- func = switch_call;
- } else if (!strcasecmp(argv[0], "dtmf")) {
- func = dtmf_call;
+ } else if (!strcasecmp(argv[0], "dump")) {
+ dump_info();
+ goto done;
+ } else if (!strcasecmp(argv[0], "list")) {
+ func = list_calls;
+ } else if (!strcasecmp(argv[0], "flags")) {
+ func = do_flags;
+ } else if (!strcasecmp(argv[0], "hangup")) {
+ func = hangup_call;
+ } else if (!strcasecmp(argv[0], "answer")) {
+ func = answer_call;
+ } else if (!strcasecmp(argv[0], "switch")) {
+ func = switch_call;
+ } else if (!strcasecmp(argv[0], "dtmf")) {
+ func = dtmf_call;
} else if (argv[1] && !strcmp(argv[0], "indev")) {
if (*argv[1] == '#') {
devval = get_dev_by_number(atoi(argv[1] + 1), 1);
@@ -1795,7 +1783,7 @@
devval = get_dev_by_name(argv[1], 0);
}
devname = "outdev";
- if (devval > 0) {
+ if (devval > 0) {
globals.outdev = devval;
}
} else if (argv[1] && !strcmp(argv[0], "ringdev")) {
@@ -1807,12 +1795,20 @@
devname = "ringdev";
if (devval > 0) {
globals.ringdev = devval;
+ }
+ } else if (!strcasecmp(argv[0], "setvolume")) {
+ func = set_volume;
+ }
+
+ if (func) {
+ if (http) {
+ stream->write_function(stream, "<pre>");
}
- }
-
- if (func) {
- status = func(&argv[lead], argc - lead, stream);
- } else {
+ status = func(&argv[lead], argc - lead, stream);
+ if (http) {
+ stream->write_function(stream, "\n\n</pre>");
+ }
+ } else {
if (devname) {
if (devval > 0) {
stream->write_function(stream, "%s set to %d\n", devname, devval);
@@ -1822,13 +1818,52 @@
} else {
stream->write_function(stream, "Unknown Command [%s]\n", argv[0]);
}
- }
+ }
+
+ done:
- done:
+ if (http) {
- switch_safe_free(mycmd);
+ stream->write_function(stream,
+ "<br><br><table align=center><tr><td><center><form method=post>\n"
+ "<input type=text name=wcmd size=40><br><br>\n"
+
+ "<input name=action type=submit value=\"call\"> "
+ "<input name=action type=submit value=\"hangup\"> "
+ "<input name=action type=submit value=\"list\"> "
+ "<input name=action type=submit value=\"switch\"> "
+ "<input name=action type=submit value=\"mute\"> "
+ "<input name=action type=submit value=\"unmute\"> "
+ "<input name=action type=submit value=\"answer\"> <br><br>"
+ "<table border=1>\n"
+ "<tr><td><input name=action type=submit value=\"1\"></td>"
+ "<td><input name=action type=submit value=\"2\"></td>"
+ "<td><input name=action type=submit value=\"3\"></td>\n"
+ "<td><input name=action type=submit value=\"A\"></td></tr>\n"
+
+ "<tr><td><input name=action type=submit value=\"4\"></td>"
+ "<td><input name=action type=submit value=\"5\"></td>"
+ "<td><input name=action type=submit value=\"6\"></td>\n"
+ "<td><input name=action type=submit value=\"B\"></td></tr>\n"
+
+ "<tr><td><input name=action type=submit value=\"7\"></td>"
+ "<td><input name=action type=submit value=\"8\"></td>"
+ "<td><input name=action type=submit value=\"9\"></td>\n"
+ "<td><input name=action type=submit value=\"C\"></td></tr>\n"
+
+ "<tr><td><input name=action type=submit value=\"*\"></td>"
+ "<td><input name=action type=submit value=\"0\"></td>"
+ "<td><input name=action type=submit value=\"#\"></td>\n"
+ "<td><input name=action type=submit value=\"D\"></td></tr>\n"
+ "</table>"
+
+ "</form><br></center></td></tr></table>\n"
+ );
+ }
- return status;
+ switch_safe_free(mycmd);
+
+ return status;
}
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c Fri Aug 24 13:50:56 2007
@@ -81,24 +81,25 @@
# define PaUtil_WriteMemoryBarrier()
#else
-#if defined(__APPLE__) //|| defined(__FreeBSD__)
+#if defined(__APPLE__) //|| defined(__FreeBSD__)
# include <libkern/OSAtomic.h>
- /* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
- full memory barriers, so the three types of barriers are the same. */
+ /* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
+ full memory barriers, so the three types of barriers are the same. */
# define PaUtil_FullMemoryBarrier() OSMemoryBarrier()
# define PaUtil_ReadMemoryBarrier() OSMemoryBarrier()
# define PaUtil_WriteMemoryBarrier() OSMemoryBarrier()
#elif defined(__GNUC__)
- /* GCC understands volatile asm and "memory" to mean it
- * should not reorder memory read/writes */
+
+ /* GCC understands volatile asm and "memory" to mean it
+ * should not reorder memory read/writes */
# if defined( __PPC__ )
-# define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory")
-# define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory")
-# define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory")
+# define PaUtil_FullMemoryBarrier() __asm__ volatile("sync":::"memory")
+# define PaUtil_ReadMemoryBarrier() __asm__ volatile("sync":::"memory")
+# define PaUtil_WriteMemoryBarrier() __asm__ volatile("sync":::"memory")
# elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ ) || defined(__x86_64__)
-# define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory")
-# define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory")
-# define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory")
+# define PaUtil_FullMemoryBarrier() __asm__ volatile("mfence":::"memory")
+# define PaUtil_ReadMemoryBarrier() __asm__ volatile("lfence":::"memory")
+# define PaUtil_WriteMemoryBarrier() __asm__ volatile("sfence":::"memory")
# else
# define PaUtil_FullMemoryBarrier()
# define PaUtil_ReadMemoryBarrier()
@@ -122,37 +123,39 @@
* Initialize FIFO.
* numBytes must be power of 2, returns -1 if not.
*/
-long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr )
+long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr)
{
- if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
- rbuf->bufferSize = numBytes;
- rbuf->buffer = (char *)dataPtr;
- PaUtil_FlushRingBuffer( rbuf );
- rbuf->bigMask = (numBytes*2)-1;
- rbuf->smallMask = (numBytes)-1;
- return 0;
+ if (((numBytes - 1) & numBytes) != 0)
+ return -1; /* Not Power of two. */
+ rbuf->bufferSize = numBytes;
+ rbuf->buffer = (char *) dataPtr;
+ PaUtil_FlushRingBuffer(rbuf);
+ rbuf->bigMask = (numBytes * 2) - 1;
+ rbuf->smallMask = (numBytes) - 1;
+ return 0;
}
/***************************************************************************
** Return number of bytes available for reading. */
-long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf )
+long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf)
{
- PaUtil_ReadMemoryBarrier();
- return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
+ PaUtil_ReadMemoryBarrier();
+ return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask);
}
+
/***************************************************************************
** Return number of bytes available for writing. */
-long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf )
+long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf)
{
- /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
- return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
+ /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
+ return (rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
}
/***************************************************************************
** Clear buffer. Should only be called when buffer is NOT being read. */
-void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
+void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf)
{
- rbuf->writeIndex = rbuf->readIndex = 0;
+ rbuf->writeIndex = rbuf->readIndex = 0;
}
/***************************************************************************
@@ -161,42 +164,38 @@
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or numBytes, whichever is smaller.
*/
-long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 )
-{
- long index;
- long available = PaUtil_GetRingBufferWriteAvailable( rbuf );
- if( numBytes > available ) numBytes = available;
- /* Check to see if write is not contiguous. */
- index = rbuf->writeIndex & rbuf->smallMask;
- if( (index + numBytes) > rbuf->bufferSize )
- {
- /* Write data in two blocks that wrap the buffer. */
- long firstHalf = rbuf->bufferSize - index;
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = firstHalf;
- *dataPtr2 = &rbuf->buffer[0];
- *sizePtr2 = numBytes - firstHalf;
- }
- else
- {
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = numBytes;
- *dataPtr2 = NULL;
- *sizePtr2 = 0;
- }
- return numBytes;
+long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2)
+{
+ long index;
+ long available = PaUtil_GetRingBufferWriteAvailable(rbuf);
+ if (numBytes > available)
+ numBytes = available;
+ /* Check to see if write is not contiguous. */
+ index = rbuf->writeIndex & rbuf->smallMask;
+ if ((index + numBytes) > rbuf->bufferSize) {
+ /* Write data in two blocks that wrap the buffer. */
+ long firstHalf = rbuf->bufferSize - index;
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = numBytes - firstHalf;
+ } else {
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = numBytes;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return numBytes;
}
/***************************************************************************
*/
-long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes )
+long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes)
{
- /* we need to ensure that previous writes are seen before we update the write index */
- PaUtil_WriteMemoryBarrier();
- return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
+ /* we need to ensure that previous writes are seen before we update the write index */
+ PaUtil_WriteMemoryBarrier();
+ return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
}
/***************************************************************************
@@ -205,81 +204,72 @@
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or numBytes, whichever is smaller.
*/
-long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 )
-{
- long index;
- long available = PaUtil_GetRingBufferReadAvailable( rbuf );
- if( numBytes > available ) numBytes = available;
- /* Check to see if read is not contiguous. */
- index = rbuf->readIndex & rbuf->smallMask;
- if( (index + numBytes) > rbuf->bufferSize )
- {
- /* Write data in two blocks that wrap the buffer. */
- long firstHalf = rbuf->bufferSize - index;
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = firstHalf;
- *dataPtr2 = &rbuf->buffer[0];
- *sizePtr2 = numBytes - firstHalf;
- }
- else
- {
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = numBytes;
- *dataPtr2 = NULL;
- *sizePtr2 = 0;
- }
- return numBytes;
+long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2)
+{
+ long index;
+ long available = PaUtil_GetRingBufferReadAvailable(rbuf);
+ if (numBytes > available)
+ numBytes = available;
+ /* Check to see if read is not contiguous. */
+ index = rbuf->readIndex & rbuf->smallMask;
+ if ((index + numBytes) > rbuf->bufferSize) {
+ /* Write data in two blocks that wrap the buffer. */
+ long firstHalf = rbuf->bufferSize - index;
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = numBytes - firstHalf;
+ } else {
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = numBytes;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return numBytes;
}
+
/***************************************************************************
*/
-long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes )
+long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes)
{
- /* we need to ensure that previous writes are always seen before updating the index. */
- PaUtil_WriteMemoryBarrier();
- return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
+ /* we need to ensure that previous writes are always seen before updating the index. */
+ PaUtil_WriteMemoryBarrier();
+ return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
}
/***************************************************************************
** Return bytes written. */
-long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes )
+long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes)
{
- long size1, size2, numWritten;
- void *data1, *data2;
- numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
- if( size2 > 0 )
- {
-
- memcpy( data1, data, size1 );
- data = ((char *)data) + size1;
- memcpy( data2, data, size2 );
- }
- else
- {
- memcpy( data1, data, size1 );
- }
- PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten );
- return numWritten;
+ long size1, size2, numWritten;
+ void *data1, *data2;
+ numWritten = PaUtil_GetRingBufferWriteRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
+ if (size2 > 0) {
+
+ memcpy(data1, data, size1);
+ data = ((char *) data) + size1;
+ memcpy(data2, data, size2);
+ } else {
+ memcpy(data1, data, size1);
+ }
+ PaUtil_AdvanceRingBufferWriteIndex(rbuf, numWritten);
+ return numWritten;
}
/***************************************************************************
** Return bytes read. */
-long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes )
+long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes)
{
- long size1, size2, numRead;
- void *data1, *data2;
- numRead = PaUtil_GetRingBufferReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
- if( size2 > 0 )
- {
- memcpy( data, data1, size1 );
- data = ((char *)data) + size1;
- memcpy( data, data2, size2 );
- }
- else
- {
- memcpy( data, data1, size1 );
- }
- PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead );
- return numRead;
+ long size1, size2, numRead;
+ void *data1, *data2;
+ numRead = PaUtil_GetRingBufferReadRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
+ if (size2 > 0) {
+ memcpy(data, data1, size1);
+ data = ((char *) data) + size1;
+ memcpy(data, data2, size2);
+ } else {
+ memcpy(data, data1, size1);
+ }
+ PaUtil_AdvanceRingBufferReadIndex(rbuf, numRead);
+ return numRead;
}
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h Fri Aug 24 13:50:56 2007
@@ -51,19 +51,17 @@
*/
#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef struct PaUtilRingBuffer
-{
- long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
- long writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */
- long readIndex; /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */
- long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */
- long smallMask; /* Used for fitting indices to buffer. */
- char *buffer;
-}PaUtilRingBuffer;
+extern "C" {
+#endif /* __cplusplus */
+
+ typedef struct PaUtilRingBuffer {
+ long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
+ long writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */
+ long readIndex; /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */
+ long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */
+ long smallMask; /* Used for fitting indices to buffer. */
+ char *buffer;
+ } PaUtilRingBuffer;
/** Initialize Ring Buffer.
@@ -76,13 +74,13 @@
@return -1 if numBytes is not a power of 2, otherwise 0.
*/
-long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr );
+ long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr);
/** Clear buffer. Should only be called when buffer is NOT being read.
@param rbuf The ring buffer.
*/
-void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf );
+ void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf);
/** Retrieve the number of bytes available in the ring buffer for writing.
@@ -90,7 +88,7 @@
@return The number of bytes available for writing.
*/
-long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf );
+ long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf);
/** Retrieve the number of bytes available in the ring buffer for reading.
@@ -98,7 +96,7 @@
@return The number of bytes available for reading.
*/
-long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf );
+ long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf);
/** Write data to the ring buffer.
@@ -110,7 +108,7 @@
@return The number of bytes written.
*/
-long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes );
+ long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes);
/** Read data from the ring buffer.
@@ -122,7 +120,7 @@
@return The number of bytes read.
*/
-long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes );
+ long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes);
/** Get address of region(s) to which we can write data.
@@ -144,9 +142,7 @@
@return The room available to be written or numBytes, whichever is smaller.
*/
-long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 );
+ long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2);
/** Advance the write index to the next location to be written.
@@ -156,7 +152,7 @@
@return The new position.
*/
-long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes );
+ long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes);
/** Get address of region(s) from which we can write data.
@@ -178,9 +174,7 @@
@return The number of bytes available for reading.
*/
-long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 );
+ long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2);
/** Advance the read index to the next location to be read.
@@ -190,9 +184,9 @@
@return The new position.
*/
-long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes );
+ long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes);
#ifdef __cplusplus
}
-#endif /* __cplusplus */
-#endif /* PA_RINGBUFFER_H */
+#endif /* __cplusplus */
+#endif /* PA_RINGBUFFER_H */
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c Fri Aug 24 13:50:56 2007
@@ -40,6 +40,7 @@
* license above.
*/
+#include <switch.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
@@ -49,176 +50,181 @@
#include <string.h>
#include <time.h>
-/************************************************************************/
-/******** Constants *****************************************************/
-/************************************************************************/
-
-#define FRAMES_PER_BUFFER (256)
/************************************************************************/
/******** Prototypes ****************************************************/
/************************************************************************/
-static int blockingIOCallback( const void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void *userData );
-static PaError PABLIO_InitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame );
-static PaError PABLIO_TermFIFO( PaUtilRingBuffer *rbuf );
+static int blockingIOCallback(const void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
+static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame);
+static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf);
/************************************************************************/
/******** Functions *****************************************************/
/************************************************************************/
/* Called from PortAudio.
- * Read and write data only if there is room in FIFOs.
+ * Read and write data
*/
-static int blockingIOCallback( const void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void *userData )
+static int blockingIOCallback(const void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
- PABLIO_Stream *data = (PABLIO_Stream*)userData;
- long numBytes = data->bytesPerFrame * framesPerBuffer;
-
- /* This may get called with NULL inputBuffer during initial setup. */
- if( inputBuffer != NULL )
- {
- PaUtil_WriteRingBuffer( &data->inFIFO, inputBuffer, numBytes );
- }
- if( outputBuffer != NULL )
- {
- int i;
- int numRead = PaUtil_ReadRingBuffer( &data->outFIFO, outputBuffer, numBytes );
- /* Zero out remainder of buffer if we run out of data. */
- for( i=numRead; i<numBytes; i++ )
- {
- ((char *)outputBuffer)[i] = 0;
- }
- }
+ PABLIO_Stream *data = (PABLIO_Stream *) userData;
+ long numBytes = data->bytesPerFrame * framesPerBuffer;
+
+ /* This may get called with NULL inputBuffer during initial setup. */
+ if (inputBuffer != NULL) {
+ if (PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes) != numBytes) {
+ PaUtil_FlushRingBuffer(&data->inFIFO);
+ PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes);
+ }
+ }
+ if (outputBuffer != NULL) {
+ int i;
+ int numRead = PaUtil_ReadRingBuffer(&data->outFIFO, outputBuffer, numBytes);
+ /* Zero out remainder of buffer if we run out of data. */
+ for (i = numRead; i < numBytes; i++) {
+ ((char *) outputBuffer)[i] = 0;
+ }
+ }
- return 0;
+ return 0;
}
/* Allocate buffer. */
-static PaError PABLIO_InitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame )
+static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame)
{
- long numBytes = numFrames * bytesPerFrame;
- char *buffer = (char *) malloc( numBytes );
- if( buffer == NULL ) return paInsufficientMemory;
- memset( buffer, 0, numBytes );
- return (PaError) PaUtil_InitializeRingBuffer( rbuf, numBytes, buffer );
+ long numBytes = numFrames * bytesPerFrame;
+ char *buffer = (char *) malloc(numBytes);
+ if (buffer == NULL)
+ return paInsufficientMemory;
+ memset(buffer, 0, numBytes);
+ return (PaError) PaUtil_InitializeRingBuffer(rbuf, numBytes, buffer);
}
/* Free buffer. */
-static PaError PABLIO_TermFIFO( PaUtilRingBuffer *rbuf )
+static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf)
{
- if( rbuf->buffer ) free( rbuf->buffer );
- rbuf->buffer = NULL;
- return paNoError;
+ if (rbuf->buffer)
+ free(rbuf->buffer);
+ rbuf->buffer = NULL;
+ return paNoError;
}
/************************************************************
* Write data to ring buffer.
* Will not return until all the data has been written.
*/
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer)
{
- long bytesWritten;
- char *p = (char *) data;
- long numBytes = aStream->bytesPerFrame * numFrames;
- while( numBytes > 0)
- {
- bytesWritten = PaUtil_WriteRingBuffer( &aStream->outFIFO, p, numBytes );
- numBytes -= bytesWritten;
- p += bytesWritten;
- if( numBytes > 0) Pa_Sleep(10);
- }
- return numFrames;
+ long bytesWritten;
+ char *p = (char *) data;
+ long numBytes = aStream->bytesPerFrame * numFrames;
+
+ while (numBytes > 0) {
+ bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFO, p, numBytes);
+ numBytes -= bytesWritten;
+ p += bytesWritten;
+ if (numBytes > 0) {
+ if (switch_core_timer_check(timer) == SWITCH_STATUS_SUCCESS) {
+ PaUtil_FlushRingBuffer(&aStream->outFIFO);
+ return 0;
+ }
+ switch_yield(1000);
+ }
+ }
+ return numFrames;
}
/************************************************************
* Read data from ring buffer.
* Will not return until all the data has been read.
*/
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer)
{
- long bytesRead;
- char *p = (char *) data;
- long numBytes = aStream->bytesPerFrame * numFrames;
-
- while( numBytes > 0)
- {
- bytesRead = PaUtil_ReadRingBuffer( &aStream->inFIFO, p, numBytes );
- numBytes -= bytesRead;
- p += bytesRead;
- if( numBytes > 0) Pa_Sleep(10);
- }
- return numFrames;
+ long bytesRead;
+ char *p = (char *) data;
+ long numBytes = aStream->bytesPerFrame * numFrames;
+
+ while (numBytes > 0) {
+ bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFO, p, numBytes);
+ numBytes -= bytesRead;
+ if (numBytes > 0) {
+ if (switch_core_timer_check(timer) == SWITCH_STATUS_SUCCESS) {
+ PaUtil_FlushRingBuffer(&aStream->inFIFO);
+ return 0;
+ }
+ switch_yield(1000);
+ }
+ }
+ return numFrames;
}
/************************************************************
* Return the number of frames that could be written to the stream without
* having to wait.
*/
-long GetAudioStreamWriteable( PABLIO_Stream *aStream )
+long GetAudioStreamWriteable(PABLIO_Stream * aStream)
{
- int bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- return bytesEmpty / aStream->bytesPerFrame;
+ int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ return bytesEmpty / aStream->bytesPerFrame;
}
/************************************************************
* Return the number of frames that are available to be read from the
* stream without having to wait.
*/
-long GetAudioStreamReadable( PABLIO_Stream *aStream )
+long GetAudioStreamReadable(PABLIO_Stream * aStream)
{
- int bytesFull = PaUtil_GetRingBufferReadAvailable( &aStream->inFIFO );
- return bytesFull / aStream->bytesPerFrame;
+ int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFO);
+ return bytesFull / aStream->bytesPerFrame;
}
-/************************************************************/
-static unsigned long RoundUpToNextPowerOf2( unsigned long n )
+/***********************************************************/
+static unsigned long RoundUpToNextPowerOf2(unsigned long n)
{
- long numBits = 0;
- if( ((n-1) & n) == 0) return n; /* Already Power of two. */
- while( n > 0 )
- {
- n= n>>1;
- numBits++;
- }
- return (1<<numBits);
+ long numBits = 0;
+ if (((n - 1) & n) == 0)
+ return n;
+ while (n > 0) {
+ n = n >> 1;
+ numBits++;
+ }
+ return (1 << numBits);
}
+
+
/************************************************************
* Opens a PortAudio stream with default characteristics.
* Allocates PABLIO_Stream structure.
*
*/
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr,
- const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters,
- double sampleRate,
- PaStreamFlags streamFlags)
+PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
+ const PaStreamParameters *inputParameters,
+ const PaStreamParameters *outputParameters,
+ double sampleRate,
+ PaStreamFlags streamFlags,
+ long samples_per_frame)
{
- long bytesPerSample;
- PaError err;
- PABLIO_Stream *aStream;
- long minNumBuffers;
- long numFrames;
- long numBytes;
+ long bytesPerSample = 2;
+ PaError err;
+ PABLIO_Stream *aStream;
+ long numFrames;
+ //long numBytes;
int channels = 1;
- /* Allocate PABLIO_Stream structure for caller. */
- aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );
- if( aStream == NULL ) return paInsufficientMemory;
- memset( aStream, 0, sizeof(PABLIO_Stream) );
-
- /* Initialize PortAudio */
- err = Pa_Initialize();
- if( err != paNoError ) goto error;
+ /* Allocate PABLIO_Stream structure for caller. */
+ aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream));
+ if (aStream == NULL)
+ return paInsufficientMemory;
+ memset(aStream, 0, sizeof(PABLIO_Stream));
+
+ /* Initialize PortAudio */
+ err = Pa_Initialize();
+ if (err != paNoError)
+ goto error;
if (inputParameters) {
channels = inputParameters->channelCount;
@@ -226,81 +232,74 @@
channels = outputParameters->channelCount;
}
- numFrames = 4 * FRAMES_PER_BUFFER;
- numFrames = RoundUpToNextPowerOf2( numFrames );
-
- bytesPerSample = 2;
- aStream->samplesPerFrame = channels;
- aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
+ numFrames = RoundUpToNextPowerOf2(samples_per_frame * 5);
+ aStream->bytesPerFrame = bytesPerSample;
- /* Initialize Ring Buffers */
+ /* Initialize Ring Buffers */
if (inputParameters) {
- err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->bytesPerFrame );
- if( err != paNoError ) goto error;
+ err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
+ if (err != paNoError)
+ goto error;
}
if (outputParameters) {
- err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame );
- if( err != paNoError ) goto error;
+ err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
+ if (err != paNoError)
+ goto error;
}
/* Make Write FIFO appear full initially. */
- numBytes = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- PaUtil_AdvanceRingBufferWriteIndex( &aStream->outFIFO, numBytes );
-
+ //numBytes = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ //PaUtil_AdvanceRingBufferWriteIndex(&aStream->outFIFO, numBytes);
+
- /* Open a PortAudio stream that we will use to communicate with the underlying
- * audio drivers. */
- err = Pa_OpenStream(
- &aStream->stream,
- inputParameters,
- outputParameters,
- sampleRate,
- FRAMES_PER_BUFFER,
- streamFlags,
- blockingIOCallback,
- aStream );
- if( err != paNoError ) goto error;
-
- err = Pa_StartStream( aStream->stream );
- if( err != paNoError ) goto error;
- *rwblPtr = aStream;
- return paNoError;
-
-error:
- CloseAudioStream( aStream );
- *rwblPtr = NULL;
- return err;
+ /* Open a PortAudio stream that we will use to communicate with the underlying
+ * audio drivers. */
+ err = Pa_OpenStream(&aStream->stream, inputParameters, outputParameters, sampleRate, samples_per_frame, streamFlags, blockingIOCallback, aStream);
+
+ if (err != paNoError)
+ goto error;
+
+ err = Pa_StartStream(aStream->stream);
+ if (err != paNoError)
+ goto error;
+ *rwblPtr = aStream;
+ return paNoError;
+
+ error:
+ CloseAudioStream(aStream);
+ *rwblPtr = NULL;
+ return err;
}
/************************************************************/
-PaError CloseAudioStream( PABLIO_Stream *aStream )
+PaError CloseAudioStream(PABLIO_Stream * aStream)
{
- PaError err;
- int bytesEmpty;
- int byteSize = aStream->outFIFO.bufferSize;
-
- /* If we are writing data, make sure we play everything written. */
- if( byteSize > 0 )
- {
- bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- while( bytesEmpty < byteSize )
- {
- Pa_Sleep( 10 );
- bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- }
- }
-
- err = Pa_StopStream( aStream->stream );
- if( err != paNoError ) goto error;
- err = Pa_CloseStream( aStream->stream );
- if( err != paNoError ) goto error;
- Pa_Terminate();
-
-error:
- PABLIO_TermFIFO( &aStream->inFIFO );
- PABLIO_TermFIFO( &aStream->outFIFO );
- free( aStream );
- return err;
+ PaError err;
+ int bytesEmpty;
+ int byteSize = aStream->outFIFO.bufferSize;
+
+ /* If we are writing data, make sure we play everything written. */
+ if (byteSize > 0) {
+ bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ while (bytesEmpty < byteSize) {
+ Pa_Sleep(10);
+ bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ }
+ }
+
+ err = Pa_StopStream(aStream->stream);
+ if (err != paNoError)
+ goto error;
+ err = Pa_CloseStream(aStream->stream);
+ if (err != paNoError)
+ goto error;
+ Pa_Terminate();
+
+ error:
+ PABLIO_TermFIFO(&aStream->inFIFO);
+ PABLIO_TermFIFO(&aStream->outFIFO);
+ free(aStream);
+ return err;
}
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h Fri Aug 24 13:50:56 2007
@@ -2,9 +2,8 @@
#define _PABLIO_H
#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+extern "C" {
+#endif /* __cplusplus */
/*
* $Id: pablio.h 1083 2006-08-23 07:30:49Z rossb $
@@ -57,15 +56,12 @@
#include <string.h>
-typedef struct
-{
- PaUtilRingBuffer inFIFO;
- PaUtilRingBuffer outFIFO;
- PaStream *stream;
- int bytesPerFrame;
- int samplesPerFrame;
-}
-PABLIO_Stream;
+ typedef struct {
+ PaUtilRingBuffer inFIFO;
+ PaUtilRingBuffer outFIFO;
+ PaStream *stream;
+ int bytesPerFrame;
+ } PABLIO_Stream;
/* Values for flags for OpenAudioStream(). */
#define PABLIO_READ (1<<0)
@@ -78,25 +74,25 @@
* Write data to ring buffer.
* Will not return until all the data has been written.
*/
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer);
/************************************************************
* Read data from ring buffer.
* Will not return until all the data has been read.
*/
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer);
/************************************************************
* Return the number of frames that could be written to the stream without
* having to wait.
*/
-long GetAudioStreamWriteable( PABLIO_Stream *aStream );
+ long GetAudioStreamWriteable(PABLIO_Stream * aStream);
/************************************************************
* Return the number of frames that are available to be read from the
* stream without having to wait.
*/
-long GetAudioStreamReadable( PABLIO_Stream *aStream );
+ long GetAudioStreamReadable(PABLIO_Stream * aStream);
/************************************************************
* Opens a PortAudio stream with default characteristics.
@@ -106,15 +102,13 @@
* PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
* and either PABLIO_MONO or PABLIO_STEREO
*/
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr,
- const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters,
- double sampleRate,
- PaStreamCallbackFlags statusFlags);
+ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
+ const PaStreamParameters * inputParameters,
+ const PaStreamParameters * outputParameters, double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_frame);
-PaError CloseAudioStream( PABLIO_Stream *aStream );
+ PaError CloseAudioStream(PABLIO_Stream * aStream);
#ifdef __cplusplus
}
-#endif /* __cplusplus */
-#endif /* _PABLIO_H */
+#endif /* __cplusplus */
+#endif /* _PABLIO_H */
More information about the Freeswitch-branches
mailing list