Freeswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- 12151 discussions
[commit] r5662 - freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio
by Freeswitch SVN 24 Aug '07
by Freeswitch SVN 24 Aug '07
24 Aug '07
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 */
1
0
23 Aug '07
Author: silik0n
Date: Thu Aug 23 14:34:50 2007
New Revision: 5661
Modified:
freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
Log:
fix and ooops
Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Thu Aug 23 14:34:50 2007
@@ -1269,13 +1269,7 @@
if (argc > 1) {
- tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- if (!switch_strlen_zero(tmp)) {
- phrase_data = tmp;
- } else {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
- }
+ phrase_data = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
}
if (argc > 2) {
1
0
22 Aug '07
Author: achaloyan
Date: Wed Aug 22 15:15:11 2007
New Revision: 5660
Modified:
freeswitch/trunk/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
Log:
add common for asr and tts FLAG_HAS_MESSAGE to indicate there is a mrcp message to process; fix processing of some mrcp responses and events.
Modified: freeswitch/trunk/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/trunk/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/trunk/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Wed Aug 22 15:15:11 2007
@@ -62,14 +62,9 @@
#include "mrcp_recognizer.h"
#include "mrcp_synthesizer.h"
#include "mrcp_generic_header.h"
-#include "mrcp_resource_set.h"
#include <switch.h>
-#define OPENMRCP_WAIT_TIMEOUT 5000
-#define MY_BUF_LEN 1024 * 128
-#define MY_BLOCK_SIZE MY_BUF_LEN
-
SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openmrcp_shutdown);
SWITCH_MODULE_DEFINITION(mod_openmrcp, mod_openmrcp_load,
@@ -95,12 +90,9 @@
} openmrcp_session_t;
typedef enum {
- FLAG_HAS_TEXT = (1 << 0),
- FLAG_BARGE = (1 << 1),
- FLAG_READY = (1 << 2),
- FLAG_SPEAK_COMPLETE = (1 << 3),
- FLAG_FEED_STARTED = (1 << 4),
- FLAG_TERMINATING = (1 << 5)
+ FLAG_HAS_MESSAGE = (1 << 0),
+ FLAG_FEED_STARTED = (1 << 1),
+ FLAG_TERMINATING = (1 << 2)
} mrcp_flag_t;
typedef struct {
@@ -220,38 +212,19 @@
return MRCP_STATUS_FAILURE;
}
- if (mrcp_message->start_line.message_type != MRCP_MESSAGE_TYPE_EVENT) {
+ if (mrcp_message->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE && mrcp_message->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ignoring mrcp response\n");
return MRCP_STATUS_SUCCESS;
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mrcp msg body: %s\n", mrcp_message->body);
-
- if (mrcp_message->channel_id.resource_id == MRCP_RESOURCE_RECOGNIZER) {
- if (mrcp_message->start_line.method_id == RECOGNIZER_RECOGNITION_COMPLETE) {
- openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_HAS_TEXT\n");
- switch_set_flag_locked(openmrcp_session, FLAG_HAS_TEXT);
- }
- else if (mrcp_message->start_line.method_id == RECOGNIZER_START_OF_INPUT) {
- openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_BARGE\n");
- switch_set_flag_locked(openmrcp_session, FLAG_BARGE);
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
- }
- }
- else if(mrcp_message->channel_id.resource_id == MRCP_RESOURCE_SYNTHESIZER) {
- if (mrcp_message->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setting FLAG_SPEAK_COMPLETE\n");
- switch_set_flag_locked(openmrcp_session, FLAG_SPEAK_COMPLETE);
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
- }
+ if (switch_test_flag(openmrcp_session, FLAG_HAS_MESSAGE)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "already has message\n");
+ return MRCP_STATUS_SUCCESS;
}
-
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_HAS_MESSAGE\n");
+ openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
+ switch_set_flag_locked(openmrcp_session, FLAG_HAS_MESSAGE);
return MRCP_STATUS_SUCCESS;
}
@@ -473,8 +446,8 @@
{
openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
- switch_status_t rv = (switch_test_flag(asr_session, FLAG_HAS_TEXT) || switch_test_flag(asr_session, FLAG_BARGE)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
-
+ switch_status_t rv = (switch_test_flag(asr_session, FLAG_HAS_MESSAGE)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+
return rv;
}
@@ -483,50 +456,61 @@
{
openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
switch_status_t ret = SWITCH_STATUS_SUCCESS;
+ mrcp_message_t *message;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_get_results called\n");
- if (switch_test_flag(asr_session, FLAG_BARGE)) {
- switch_clear_flag_locked(asr_session, FLAG_BARGE);
- ret = SWITCH_STATUS_BREAK;
- }
-
- if (switch_test_flag(asr_session, FLAG_HAS_TEXT)) {
- /*!
- we have to extract the XML but stripping off the <?xml version="1.0"?>
- header. the body looks like:
-
- Completion-Cause:001 no-match
- Content-Type: application/nlsml+xml
- Content-Length: 260
-
- <?xml version="1.0"?>
- <result xmlns="http://www.ietf.org/xml/ns/mrcpv2" xmlns:ex="http://www.example.com/example" score="100" grammar="session:request1@form-level.store">
- <interpretation> <input mode="speech">open a</input>
- </interpretation>
- </result>
- */
-
- if(asr_session->mrcp_message_last_rcvd && asr_session->mrcp_message_last_rcvd->body) {
- char *marker = "?>"; // FIXME -- lame and brittle way of doing this. use regex or better.
- char *position = strstr(asr_session->mrcp_message_last_rcvd->body, marker);
- if (!position) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad result received from mrcp server: %s", asr_session->mrcp_message_last_rcvd->body);
- ret = SWITCH_STATUS_FALSE;
+ message = asr_session->mrcp_message_last_rcvd;
+ asr_session->mrcp_message_last_rcvd = NULL;
+ // since we are returning our result here, future calls to check_results
+ // should return False
+ switch_clear_flag_locked(asr_session, FLAG_HAS_MESSAGE);
+
+ if (message->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE) {
+ if (message->start_line.status_code != MRCP_STATUS_CODE_SUCCESS &&
+ message->start_line.status_code != MRCP_STATUS_CODE_SUCCESS_WITH_IGNORE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "error code received [%d]\n", message->start_line.status_code);
+ ret = SWITCH_STATUS_FALSE;
+ }
+ }
+ else if (message->start_line.message_type == MRCP_MESSAGE_TYPE_EVENT) {
+ if (message->start_line.method_id == RECOGNIZER_RECOGNITION_COMPLETE) {
+ /*!
+ we have to extract the XML but stripping off the <?xml version="1.0"?>
+ header. the body looks like:
+
+ Completion-Cause:001 no-match
+ Content-Type: application/nlsml+xml
+ Content-Length: 260
+
+ <?xml version="1.0"?>
+ <result xmlns="http://www.ietf.org/xml/ns/mrcpv2" xmlns:ex="http://www.example.com/example" score="100" grammar="session:request1@form-level.store">
+ <interpretation> <input mode="speech">open a</input>
+ </interpretation>
+ </result>
+ */
+
+ if(message->body) {
+ char *marker = "?>"; // FIXME -- lame and brittle way of doing this. use regex or better.
+ char *position = strstr(message->body, marker);
+ if (!position) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad result received from mrcp server: %s", message->body);
+ ret = SWITCH_STATUS_FALSE;
+ }
+ else {
+ position += strlen(marker);
+ *xmlstr = strdup(position);
+ }
}
else {
- position += strlen(marker);
- *xmlstr = strdup(position);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No result received from mrcp server\n");
+ ret = SWITCH_STATUS_FALSE;
}
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No result received from mrcp server\n");
- ret = SWITCH_STATUS_FALSE;
- }
- // since we are returning our result here, future calls to check_results
- // should return False
- switch_clear_flag_locked(asr_session, FLAG_HAS_TEXT);
- ret = SWITCH_STATUS_SUCCESS;
+ ret = SWITCH_STATUS_SUCCESS;
+ }
+ else if (message->start_line.method_id == RECOGNIZER_START_OF_INPUT) {
+ ret = SWITCH_STATUS_BREAK;
+ }
}
return ret;
}
@@ -658,10 +642,25 @@
media_frame_t media_frame;
audio_source_t *audio_source;
- if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
- /* tell fs we are done */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
- return SWITCH_STATUS_BREAK;
+ if (switch_test_flag(tts_session, FLAG_HAS_MESSAGE)) {
+ mrcp_message_t *message = tts_session->mrcp_message_last_rcvd;
+ tts_session->mrcp_message_last_rcvd = NULL;
+ switch_clear_flag_locked(tts_session, FLAG_HAS_MESSAGE);
+
+ if (message->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE) {
+ if (message->start_line.status_code != MRCP_STATUS_CODE_SUCCESS &&
+ message->start_line.status_code != MRCP_STATUS_CODE_SUCCESS_WITH_IGNORE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "error code received [%d]\n", message->start_line.status_code);
+ return SWITCH_STATUS_BREAK;
+ }
+ }
+ else if (message->start_line.message_type == MRCP_MESSAGE_TYPE_EVENT) {
+ if (message->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE) {
+ /* tell fs we are done */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
+ return SWITCH_STATUS_BREAK;
+ }
+ }
}
audio_source = mrcp_client_audio_source_get(tts_session->audio_channel);
1
0
Author: greenlizard
Date: Wed Aug 22 10:23:28 2007
New Revision: 5659
Added:
freeswitch/trunk/scripts/py_modules/
freeswitch/trunk/scripts/py_modules/__init__.py
freeswitch/trunk/scripts/py_modules/speechtools.py
freeswitch/trunk/scripts/recipewizard.py
Log:
speech recognition demo in python
Added: freeswitch/trunk/scripts/py_modules/__init__.py
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/py_modules/__init__.py Wed Aug 22 10:23:28 2007
@@ -0,0 +1 @@
+# empty
Added: freeswitch/trunk/scripts/py_modules/speechtools.py
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/py_modules/speechtools.py Wed Aug 22 10:23:28 2007
@@ -0,0 +1,198 @@
+from freeswitch import *
+from xml.dom import minidom
+
+VOICE_ENGINE = "cepstral"
+VOICE = "William"
+
+"""
+A few classes that make it easier to write speech applications
+using Python. It is roughly modelled after the equivalent that
+is written in JavaScript.
+
+Status: should work, but not yet complete. some pending items
+are mentioned in comments
+"""
+
+class Grammar:
+ def __init__(self, name, path, obj_path,
+ min_score=1, confirm_score=400, halt=False):
+ """
+ @param name - name of grammar to reference it later
+ @param path - path to xml grammar file
+ @param obj_path - xml path to find interpretation from root
+ in result xml, eg, 'interpretation'
+ @param min_score - score threshold to accept result
+ @param confirm_score - if score below this threshold, ask user
+ if they are sure this is correct
+ @param halt - not sure what was used for in js, currently unused
+ """
+ self.name=name
+ self.path=path
+ self.obj_path=obj_path
+ self.min_score=min_score
+ self.confirm_score=confirm_score
+ self.halt=halt
+
+
+class SpeechDetect:
+
+ def __init__(self, session, module_name, ip_addr):
+ self.session=session
+ self.module_name=module_name
+ self.ip_addr=ip_addr
+ self.grammars = {}
+
+ def addGrammar(self, grammar):
+ self.grammars[grammar.name]=grammar
+
+ def setGrammar(self, name):
+ self.grammar = self.grammars[name]
+
+ def detectSpeech(self):
+ # TODO: we might not always want to call detect_speech
+ # with this cmd, see js version for other options
+ # also see detect_speech_function() in mod_dptools.c
+ cmd = "%s %s %s %s" % (self.module_name,
+ self.grammar.name,
+ self.grammar.path,
+ self.ip_addr)
+ console_log("debug", "calling detect_speech with: %s\n" % cmd)
+ self.session.execute("detect_speech", cmd)
+ console_log("debug", "finished calling detect_speech\n")
+
+class SpeechObtainer:
+
+ def __init__(self, speech_detect, required_phrases, wait_time, max_tries):
+ """
+ @param speech_detect - the speech detect object, which holds a
+ reference to underlying session and can
+ be re-used by many SpeechObtainers
+ @param required_phrases - the number of required phrases from the
+ grammar. for example if its prompting for
+ the toppings on a sandwhich and min toppings
+ is 3, use 3. normally will be 1.
+ @param wait_time - the time, in millisconds, to wait for
+ input during each loop iteration
+ @param max_tries - this number multiplied by wait time gives the
+ 'total wait time' before we give up and return
+ partial or no result
+ """
+ self.speech_detect=speech_detect
+ self.required_phrases=required_phrases
+ self.wait_time=wait_time
+ self.max_tries=max_tries
+
+ self.detected_phrases = []
+
+ def setGrammar(self, grammar):
+ """
+ @param grammar - instance of grammar class
+ """
+ self.grammar=grammar
+ self.speech_detect.addGrammar(grammar)
+ self.speech_detect.setGrammar(self.grammar.name)
+
+ def detectSpeech(self):
+ self.speech_detect.detectSpeech()
+
+ def run(self):
+ """
+ start speech detection with the current grammar,
+ and listen for results from asr engine. once a result
+ has been returned, return it to caller
+ """
+
+ def dtmf_handler(input, itype, funcargs):
+ console_log("INFO","\n\nDTMF itype: %s\n" % itype)
+ if itype == 1: # TODO!! use names for comparison instead of number
+ return self.handle_event(input, funcargs)
+ elif itype== 0:
+ console_log("INFO","\n\nDTMF input: %s\n" % input)
+ else:
+ console_log("INFO","\n\nUnknown input type: %s\n" % itype)
+ return None
+
+
+ num_tries = 0
+
+ session = self.speech_detect.session
+
+ console_log("debug", "setting dtmf callback\n")
+ session.setDTMFCallback(dtmf_handler, "")
+ console_log("debug", "calling getDigits\n")
+
+ console_log("debug", "starting run() while loop\n")
+ while (session.ready() and
+ num_tries < self.max_tries and
+ len(self.detected_phrases) < self.required_phrases):
+ console_log("debug", "top of run() while loop\n")
+ session.collectDigits(self.wait_time)
+ num_tries += 1
+
+ console_log("debug", "while loop finished\n")
+ return self.detected_phrases
+
+ def handle_event(self, event, funcargs):
+ """
+ when the dtmf handler receives an event, it calls back
+ this method. event is a dictionary with subdictionaries ..
+
+ Example 1
+ =========
+
+ {'body': None, 'headers': {'Speech-Type': 'begin-speaking'}}
+
+ Example 2
+ =========
+ {'body': '<result xmlns='http://www.ietf.org/xml/ns/mrcpv2'
+ xmlns:ex='http://www.example.com/example' score='100'
+ grammar='session:request1@form-level.store'><interpretation>
+ <input mode='speech'>waffles</input></interpretation></result>',
+ 'headers': {'Speech-Type': 'detected-speech'}}
+
+ This dictionary is constructed in run_dtmf_callback() in
+ freeswitch_python.cpp
+
+ """
+
+ # what kind of event?
+ headers = event['headers']
+ speech_type = headers['Speech-Type']
+ if speech_type == "begin-speaking":
+ # not sure what to do with this, try returning "stop"
+ # so that it might stop playing a sound file once
+ # speech has been detected
+ return "stop"
+ elif speech_type == "detected-speech":
+ # extract the detected phrase. from result
+ # BUG: this assumes only ONE interpretation in the xml
+ # result. rest will get igored
+ # NOTE: have to wrap everything with str() (at least
+ # calls to console_log because otherwise it chokes on
+ # unicode strings.
+ # TODO: check the score
+ body = event['body']
+ dom = minidom.parseString(body)
+ phrase = dom.getElementsByTagName(self.grammar.obj_path)[0]
+ phrase_text = self.getText(phrase)
+ if phrase_text:
+ self.detected_phrases.append(str(phrase_text))
+ # do we want to return stop? what should we return?
+ return "stop"
+ else:
+ raise Exception("Unknown speech event: %s" % speech_type)
+
+
+ def getText(self, elt):
+
+ """ given an element, get its text. if there is more than
+ one text node child, just append all the text together.
+ """
+
+ result = ""
+ children = elt.childNodes
+ for child in children:
+ if child.nodeType == child.TEXT_NODE:
+ result += str(child.nodeValue)
+ return result
+
Added: freeswitch/trunk/scripts/recipewizard.py
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/recipewizard.py Wed Aug 22 10:23:28 2007
@@ -0,0 +1,87 @@
+from freeswitch import *
+from py_modules.speechtools import Grammar, SpeechDetect
+from py_modules.speechtools import SpeechObtainer
+
+import time, os
+
+VOICE_ENGINE = "cepstral"
+VOICE = "William"
+GRAMMAR_ROOT = "/usr/src/freeswitch_trunk/scripts"
+
+"""
+Example speech recognition application in python.
+
+How to make this work:
+
+* Get mod_openmrcp working along with an MRCP asr server
+* Add /usr/src/freeswitch/scripts or equivalent to your PYTHONPATH
+* Restart freeswitch
+* Create $GRAMMAR_ROOT/mainmenu.xml from contents in mainmenu() comments
+
+"""
+
+class RecipeWizard:
+
+ def __init__(self, session):
+ self.session=session
+ self.session.set_tts_parms(VOICE_ENGINE, VOICE)
+ self.main()
+
+ def main(self):
+
+ console_log("debug", "recipe wizard main()\n")
+ self.speechdetect = SpeechDetect(self.session, "openmrcp", "127.0.0.1");
+ self.speechobtainer = SpeechObtainer(speech_detect=self.speechdetect,
+ required_phrases=1,
+ wait_time=5000,
+ max_tries=3)
+ gfile = os.path.join(GRAMMAR_ROOT, "mainmenu.xml")
+ self.grammar = Grammar("mainmenu", gfile,"input",80,90)
+ self.speechobtainer.setGrammar(self.grammar);
+ console_log("debug", "calling speechobtainer.run()\n")
+ self.speechobtainer.detectSpeech()
+ self.session.speak("Hello. Welcome to the recipe wizard. Drinks or food?")
+ result = self.speechobtainer.run()
+ console_log("debug", "speechobtainer.run() result: %s\n" % result)
+ if result:
+ self.session.speak("Received result. Result is: %s" % result[0])
+ else:
+ self.session.speak("Sorry, I did not hear you")
+
+ console_log("debug", "speechobtainer.run() finished\n")
+
+def mainmenu():
+ """
+ <!DOCTYPE grammar PUBLIC "-//W3C//DTD GRAMMAR 1.0//EN"
+ "http://www.w3.org/TR/speech-grammar/grammar.dtd">
+
+ <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/06/grammar
+ http://www.w3.org/TR/speech-grammar/grammar.xsd"
+ version="1.0" mode="voice" root="root">
+
+
+ <rule id="root" scope="public">
+
+ <rule id="main">
+ <one-of>
+ <item weight="10">drinks</item>
+ <item weight="2">food</item>
+ </one-of>
+ </rule>
+
+ </rule>
+
+ </grammar>
+
+ """
+ pass
+
+def handler(uuid):
+ session = PySession(uuid)
+ session.answer()
+ rw = RecipeWizard(session)
+ session.hangup("1")
+
+
1
0
22 Aug '07
Author: mikej
Date: Wed Aug 22 09:16:37 2007
New Revision: 5658
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
Log:
map 404 correct per rfc 4497
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c Wed Aug 22 09:16:37 2007
@@ -1369,6 +1369,7 @@
case 603:
return SWITCH_CAUSE_CALL_REJECTED;
case 404:
+ return SWITCH_CAUSE_UNALLOCATED;
case 485:
case 604:
return SWITCH_CAUSE_NO_ROUTE_DESTINATION;
1
0
Author: mikej
Date: Tue Aug 21 23:10:08 2007
New Revision: 5657
Modified:
freeswitch/trunk/src/switch_core_session.c
Log:
pass new caller profile vars across the bridge.
Modified: freeswitch/trunk/src/switch_core_session.c
==============================================================================
--- freeswitch/trunk/src/switch_core_session.c (original)
+++ freeswitch/trunk/src/switch_core_session.c Tue Aug 21 23:10:08 2007
@@ -218,6 +218,11 @@
caller_profile->rdnis,
caller_profile->source, caller_profile->context, caller_profile->destination_number);
outgoing_profile->flags = caller_profile->flags;
+ outgoing_profile->caller_ton = caller_profile->caller_ton;
+ outgoing_profile->caller_numplan = caller_profile->caller_numplan;
+ outgoing_profile->destination_number_ton = caller_profile->destination_number_ton;
+ outgoing_profile->destination_number_numplan = caller_profile->destination_number_numplan;
+
}
}
if (!outgoing_profile) {
1
0
Author: mikej
Date: Tue Aug 21 22:55:19 2007
New Revision: 5656
Modified:
freeswitch/trunk/src/switch_ivr_originate.c
Log:
pass new caller profile vars across the bridge.
Modified: freeswitch/trunk/src/switch_ivr_originate.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_originate.c (original)
+++ freeswitch/trunk/src/switch_ivr_originate.c Tue Aug 21 22:55:19 2007
@@ -489,6 +489,10 @@
caller_caller_profile->rdnis,
caller_caller_profile->source, caller_caller_profile->context, chan_data);
new_profile->flags = caller_caller_profile->flags;
+ new_profile->caller_ton = caller_caller_profile->caller_ton;
+ new_profile->caller_numplan = caller_caller_profile->caller_numplan;
+ new_profile->destination_number_ton = caller_caller_profile->destination_number_ton;
+ new_profile->destination_number_numplan = caller_caller_profile->destination_number_numplan;
pool = NULL;
} else {
if (!cid_name_override) {
@@ -515,6 +519,10 @@
caller_profile_override->aniii,
caller_profile_override->rdnis,
caller_profile_override->source, caller_profile_override->context, chan_data);
+ new_profile->caller_ton = caller_profile_override->caller_ton;
+ new_profile->caller_numplan = caller_profile_override->caller_numplan;
+ new_profile->destination_number_ton = caller_profile_override->destination_number_ton;
+ new_profile->destination_number_numplan = caller_profile_override->destination_number_numplan;
} else {
new_profile = switch_caller_profile_new(pool,
NULL,
1
0
22 Aug '07
Author: mikej
Date: Tue Aug 21 20:22:22 2007
New Revision: 5655
Modified:
freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
Log:
add utility app for profile vars
Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Tue Aug 21 20:22:22 2007
@@ -346,6 +346,88 @@
}
}
+
+SWITCH_STANDARD_APP(set_profile_var_function)
+{
+ switch_channel_t *channel;
+ switch_caller_profile_t *caller_profile;
+ char *name, *val = NULL;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ caller_profile = switch_channel_get_caller_profile(channel);
+
+ if (switch_strlen_zero(data)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No variable name specified.\n");
+ } else {
+ name = switch_core_session_strdup(session, data);
+ val = strchr(name, '=');
+
+ if (val) {
+ *val++ = '\0';
+ if (switch_strlen_zero(val)) {
+ val = NULL;
+ }
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SET_PROFILE_VAR [%s]=[%s]\n", name, val ? val : "UNDEF");
+
+ if (!strcasecmp(name, "dialplan")) {
+ caller_profile->dialplan = val;
+ }
+ if (!strcasecmp(name, "username")) {
+ caller_profile->username = val;
+ }
+ if (!strcasecmp(name, "caller_id_name")) {
+ caller_profile->caller_id_name = val;
+ }
+ if (!strcasecmp(name, "caller_id_number")) {
+ caller_profile->caller_id_number = val;
+ }
+ if (!strcasecmp(name, "caller_ton")) {
+ caller_profile->caller_ton = (uint8_t)atoi(val);
+ }
+ if (!strcasecmp(name, "caller_numplan")) {
+ caller_profile->caller_numplan = (uint8_t)atoi(val);
+ }
+ if (!strcasecmp(name, "destination_number_ton")) {
+ caller_profile->destination_number_ton = (uint8_t)atoi(val);
+ }
+ if (!strcasecmp(name, "destination_number_numplan")) {
+ caller_profile->destination_number_numplan = (uint8_t)atoi(val);
+ }
+ if (!strcasecmp(name, "ani")) {
+ caller_profile->ani = val;
+ }
+ if (!strcasecmp(name, "aniii")) {
+ caller_profile->aniii = val;
+ }
+ if (!strcasecmp(name, "network_addr")) {
+ caller_profile->network_addr = val;
+ }
+ if (!strcasecmp(name, "rdnis")) {
+ caller_profile->rdnis = val;
+ }
+ if (!strcasecmp(name, "destination_number")) {
+ caller_profile->destination_number = val;
+ }
+ if (!strcasecmp(name, "uuid")) {
+ caller_profile->uuid = val;
+ }
+ if (!strcasecmp(name, "source")) {
+ caller_profile->source = val;
+ }
+ if (!strcasecmp(name, "context")) {
+ caller_profile->context = val;
+ }
+ if (!strcasecmp(name, "chan_name")) {
+ caller_profile->chan_name = val;
+ }
+ }
+}
+
+
SWITCH_STANDARD_APP(export_function)
{
switch_channel_t *channel;
@@ -1141,6 +1223,7 @@
#define SCHED_HANGUP_DESCR "Schedule a hangup in the future"
#define UNSET_LONG_DESC "Unset a channel varaible for the channel calling the application."
#define SET_LONG_DESC "Set a channel varaible for the channel calling the application."
+#define SET_PROFILE_VAR_LONG_DESC "Set a caller profile varaible for the channel calling the application."
#define EXPORT_LONG_DESC "Set and export a channel varaible for the channel calling the application."
#define LOG_LONG_DESC "Logs a channel varaible for the channel calling the application."
#define TRANSFER_LONG_DESC "Immediatly transfer the calling channel to a new extension"
@@ -1171,6 +1254,7 @@
SWITCH_ADD_APP(app_interface, "event", "Fire an event", "Fire an event", event_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "export", "Export a channel varaible across a bridge", EXPORT_LONG_DESC, export_function, "<varname>=<value>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "set", "Set a channel varaible", SET_LONG_DESC, set_function, "<varname>=<value>", SAF_SUPPORT_NOMEDIA);
+ SWITCH_ADD_APP(app_interface, "set_profile_var", "Set a caller profile varaible", SET_PROFILE_VAR_LONG_DESC, set_profile_var_function, "<varname>=<value>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "unset", "Unset a channel varaible", UNSET_LONG_DESC, unset_function, "<varname>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);
1
0
22 Aug '07
Author: mikej
Date: Tue Aug 21 20:21:09 2007
New Revision: 5654
Modified:
freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
Log:
fix windows build
Modified: freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
==============================================================================
--- freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c (original)
+++ freeswitch/trunk/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c Tue Aug 21 20:21:09 2007
@@ -72,7 +72,7 @@
xml_binding_t *binding = (xml_binding_t *) user_data;
char *file_url;
struct curl_slist *slist = NULL;
- long httpRes;
+ long httpRes = 0;
if (!binding) {
return NULL;
1
0
21 Aug '07
Author: anthm
Date: Tue Aug 21 15:00:06 2007
New Revision: 5653
Modified:
freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
Log:
let session.sayPhrase method take a blank language string
Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Tue Aug 21 15:00:06 2007
@@ -1242,6 +1242,7 @@
char *phrase_name = NULL;
char *phrase_data = NULL;
char *phrase_lang = NULL;
+ char *tmp = NULL;
//char *input_callback = NULL;
void *bp = NULL;
int len = 0;
@@ -1268,11 +1269,20 @@
if (argc > 1) {
- phrase_data = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+ tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+ if (!switch_strlen_zero(tmp)) {
+ phrase_data = tmp;
+ } else {
+ *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+ return JS_TRUE;
+ }
}
if (argc > 2) {
- phrase_lang = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
+ tmp = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
+ if (!switch_strlen_zero(tmp)) {
+ phrase_lang = tmp;
+ }
}
if (argc > 3) {
1
0