[Freeswitch-branches] [commit] r5662 - freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio

Freeswitch SVN cseket at freeswitch.org
Fri Aug 24 13:50:57 EDT 2007


Author: cseket
Date: Fri Aug 24 13:50:56 2007
New Revision: 5662

Modified:
   freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/   (props changed)
   freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile
   freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c
   freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c
   freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h
   freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c
   freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h

Log:
merge from trunk and try to fix MODENDP-20

Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile	(original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile	Fri Aug 24 13:50:56 2007
@@ -1,22 +1,29 @@
-CFLAGS += -I.
-LDFLAGS += -lportaudio -L$(PREFIX) 
-MYOBJS = pablio.o pa_ringbuffer.o
+BASE=../../../..
 
-all:	depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
+PA_DIR=$(BASE)/libs/portaudio
 
-depends:
-	MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install portaudio --prefix=$(PREFIX) --with-pic
-%.o:  %.c
-	$(CC) -fPIC $(CFLAGS) -c -o $@ $<
+PALA=$(PA_DIR)/lib/libportaudio.la
+LOCAL_CFLAGS=-I. -I$(PA_DIR)/include -D__EXTENSION__=1
 
-$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c $(MYOBJS)
-	$(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o 
-	$(CC) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(MODNAME).o $(MYOBJS) $(LDFLAGS)
+LOCAL_INSERT_LDFLAGS=if test $$osarch = "Darwin" ; then echo "-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon" ; fi ;
 
+LOCAL_LIBADD=$(PALA)
+LOCAL_OBJS=pablio.o pa_ringbuffer.o
+LOCAL_SOURCES=pablio.c pa_ringbuffer.c
 
+PX_DIR=$(BASE)/libs/portmixer
+PXA=$(PX_DIR)/libportmixer.a
+LOCAL_CFLAGS+=-I$(PX_DIR)/include
+LOCAL_LIBADD+=$(PXA)
 
-clean:
-	rm -fr *.$(DYNAMIC_LIB_EXTEN) *.o *~
+include $(BASE)/build/modmake.rules
 
-install:
-	cp -f $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(PREFIX)/mod
+$(PALA): $(PA_DIR) $(PA_DIR)/.update
+	cd $(PA_DIR) && $(MAKE)
+	$(TOUCH_TARGET)
+
+$(PXA): $(PX_DIR) $(PX_DIR)/.update
+	cd $(PX_DIR) && $(MAKE)
+	$(TOUCH_TARGET)
+
+$(LOCAL_OBJS): $(LOCAL_SOURCES)

Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c	(original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c	Fri Aug 24 13:50:56 2007
@@ -6,7 +6,7 @@
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
+ * the License. You may obtain a copy of the License `
  * http://www.mozilla.org/MPL/
  *
  * Software distributed under the License is distributed on an "AS IS" basis,
@@ -29,32 +29,34 @@
  * mod_portaudio.c -- PortAudio Endpoint Module
  *
  */
-#include <switch.h>
+#include "switch.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 #include "pablio.h"
 #include <string.h>
+#include <portmixer.h>
 
 #define MY_EVENT_RINGING "portaudio::ringing"
 
-static const char modname[] = "mod_portaudio";
+SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown);
+SWITCH_MODULE_DEFINITION(mod_portaudio, mod_portaudio_load, mod_portaudio_shutdown, NULL);
 
 static switch_memory_pool_t *module_pool = NULL;
-//static int running = 1;
+static switch_endpoint_interface_t *channel_endpoint_interface;
 
 #define SAMPLE_TYPE  paInt16
-//#define SAMPLE_TYPE  paFloat32
-typedef short SAMPLE;
+typedef int16_t SAMPLE;
 
-typedef switch_status_t (*pa_command_t)(char **argv, int argc, switch_stream_handle_t *stream);
+typedef switch_status_t (*pa_command_t) (char **argv, int argc, switch_stream_handle_t *stream);
 
 typedef enum {
-    GFLAG_NONE = 0,
-    GFLAG_EAR = (1 << 0),
-    GFLAG_MOUTH = (1 << 1),
-    GFLAG_RING = (1 << 2)
+	GFLAG_NONE = 0,
+	GFLAG_EAR = (1 << 0),
+	GFLAG_MOUTH = (1 << 1),
+	GFLAG_RING = (1 << 2)
 } GFLAGS;
 
 typedef enum {
@@ -75,17 +77,16 @@
 	switch_core_session_t *session;
 	switch_caller_profile_t *caller_profile;
 	char call_id[50];
-    int sample_rate;
-    int codec_ms;
+	int sample_rate;
+	int codec_ms;
 	switch_mutex_t *flag_mutex;
-    char *hold_file;
-    switch_file_handle_t fh;
-    switch_file_handle_t *hfh;
+	char *hold_file;
+	switch_file_handle_t fh;
+	switch_file_handle_t *hfh;
 	switch_frame_t hold_frame;
-    unsigned char holdbuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
+	unsigned char holdbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
 	switch_codec_t write_codec;
-    switch_timer_t timer;
-    struct private_object *next;
+	struct private_object *next;
 };
 
 typedef struct private_object private_t;
@@ -96,9 +97,9 @@
 	char *cid_name;
 	char *cid_num;
 	char *dialplan;
-    char *ring_file;
-    char *hold_file;
-    char *timer_name;
+	char *ring_file;
+	char *hold_file;
+	char *timer_name;
 	int ringdev;
 	int indev;
 	int outdev;
@@ -114,12 +115,14 @@
 	switch_codec_t read_codec;
 	switch_codec_t write_codec;
 	switch_frame_t read_frame;
-    switch_frame_t cng_frame;
-	unsigned char databuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
-	unsigned char cngbuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
-    private_t *call_list;
-    int ring_interval;
-    GFLAGS flags;
+	switch_frame_t cng_frame;
+	unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+	unsigned char cngbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+	private_t *call_list;
+	int ring_interval;
+	GFLAGS flags;
+	switch_timer_t timer;
+	PxMixer *mixer;
 } globals;
 
 
@@ -128,126 +131,125 @@
 
 
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_name, globals.cid_name)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_num, globals.cid_num)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ring_file, globals.ring_file)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_hold_file, globals.hold_file)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_timer_name, globals.timer_name)
-
+	SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_name, globals.cid_name)
+	SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_num, globals.cid_num)
+	SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ring_file, globals.ring_file)
+	SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_hold_file, globals.hold_file)
+	SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_timer_name, globals.timer_name)
 #define is_master(t) switch_test_flag(t, TFLAG_MASTER)
-static void add_pvt(private_t *tech_pvt, int master);
-static void remove_pvt(private_t *tech_pvt);
-static switch_status_t channel_on_init(switch_core_session_t *session);
-static switch_status_t channel_on_hangup(switch_core_session_t *session);
-static switch_status_t channel_on_ring(switch_core_session_t *session);
-static switch_status_t channel_on_loopback(switch_core_session_t *session);
-static switch_status_t channel_on_transmit(switch_core_session_t *session);
-static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
-													switch_caller_profile_t *outbound_profile,
-													switch_core_session_t **new_session, switch_memory_pool_t **pool);
-static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
-                                          switch_io_flag_t flags, int stream_id);
-static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
-                                           switch_io_flag_t flags, int stream_id);
-static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
-static switch_status_t engage_device(int samplerate, int codec_ms);
-static switch_status_t engage_ring_device(int sample_rate, int channels);
-static void deactivate_ring_device(void);
-static int dump_info(void);
-static switch_status_t load_config(void);
-static int get_dev_by_name(char *name, int in);
-static int get_dev_by_number(int number, int in);
-static switch_status_t pa_cmd(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
-static switch_status_t padep(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
-
+	 static void add_pvt(private_t * tech_pvt, int master);
+	 static void remove_pvt(private_t * tech_pvt);
+	 static switch_status_t channel_on_init(switch_core_session_t *session);
+	 static switch_status_t channel_on_hangup(switch_core_session_t *session);
+	 static switch_status_t channel_on_ring(switch_core_session_t *session);
+	 static switch_status_t channel_on_loopback(switch_core_session_t *session);
+	 static switch_status_t channel_on_transmit(switch_core_session_t *session);
+	 static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
+														 switch_caller_profile_t *outbound_profile,
+														 switch_core_session_t **new_session, switch_memory_pool_t **pool);
+	 static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id);
+	 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id);
+	 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
+	 static switch_status_t engage_device(int samplerate, int codec_ms);
+	 static switch_status_t engage_ring_device(int sample_rate, int channels);
+	 static void deactivate_ring_device(void);
+	 static int dump_info(void);
+	 static switch_status_t load_config(void);
+	 static int get_dev_by_name(char *name, int in);
+	 static int get_dev_by_number(int number, int in);
+	 static switch_status_t pa_cmd(const char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
 
 /* 
    State methods they get called when the state changes to the specific state 
    returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
    so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
 */
-static switch_status_t channel_on_init(switch_core_session_t *session)
+	 static switch_status_t channel_on_init(switch_core_session_t *session)
 {
 	switch_channel_t *channel;
 	private_t *tech_pvt = NULL;
 	switch_time_t last;
 	int waitsec = globals.ring_interval * 1000000;
-    switch_file_handle_t fh = {0};
-    char *val, *ring_file = NULL, *hold_file = NULL;
-    int16_t abuf[2048];
+	switch_file_handle_t fh = { 0 };
+	char *val, *ring_file = NULL, *hold_file = NULL;
+	int16_t abuf[2048];
 
-    tech_pvt = switch_core_session_get_private(session);
+	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
 
-    
+
 	last = switch_time_now() - waitsec;
 
 
-    if ((val = switch_channel_get_variable(channel, "pa_hold_file"))) {
-        hold_file = val;
-    } else {
-        hold_file = globals.hold_file;
-    }
-
-    if (hold_file) {
-        tech_pvt->hold_file = switch_core_session_strdup(session, hold_file);
-    }
+
+	if ((val = switch_channel_get_variable(channel, "pa_hold_file"))) {
+		hold_file = val;
+	} else {
+		hold_file = globals.hold_file;
+	}
+
+	if (hold_file) {
+		tech_pvt->hold_file = switch_core_session_strdup(session, hold_file);
+	}
 
 	if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
 
-        
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n", switch_channel_get_name(channel),
-                          switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER));
-        
-
-
-        if (engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms) != SWITCH_STATUS_SUCCESS) {
-            switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
-            return SWITCH_STATUS_FALSE;
-        }
-
-        if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
-            add_pvt(tech_pvt, PA_SLAVE);
-
-            ring_file = globals.ring_file;
-            if ((val = switch_channel_get_variable(channel, "pa_ring_file"))) {
-                ring_file = val;
-            }
-
-            if (switch_test_flag((&globals), GFLAG_RING)) {
-                ring_file = NULL;
-            }
-            switch_set_flag_locked((&globals), GFLAG_RING);
-            if (ring_file) {
-                if (switch_core_file_open(&fh,
-                                          ring_file,
-                                          SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
-                                          NULL) == SWITCH_STATUS_SUCCESS) {
-            
-                    if (engage_ring_device(fh.samplerate, fh.channels) != SWITCH_STATUS_SUCCESS) {
-                        switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
-                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ring Error!\n");
-                        switch_core_file_close(&fh);
-                        return SWITCH_STATUS_GENERR;
-                    }
-                } else {
-                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open %s, disabling ring file!\n", ring_file);
-                    ring_file = NULL;
-                }
-            }
-        }
+
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n",
+						  switch_channel_get_name(channel), switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER));
+
+
+
+		if (engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms) != SWITCH_STATUS_SUCCESS) {
+			switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+			return SWITCH_STATUS_FALSE;
+		}
+
+		if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
+			add_pvt(tech_pvt, PA_SLAVE);
+
+			ring_file = globals.ring_file;
+			if ((val = switch_channel_get_variable(channel, "pa_ring_file"))) {
+				ring_file = val;
+			}
+
+			if (switch_test_flag((&globals), GFLAG_RING)) {
+				ring_file = NULL;
+			}
+			switch_set_flag_locked((&globals), GFLAG_RING);
+			if (ring_file) {
+				if (switch_core_file_open(&fh,
+										  ring_file,
+										  globals.read_codec.implementation->number_of_channels,
+										  globals.read_codec.implementation->samples_per_second,
+										  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
+
+					if (engage_ring_device(fh.samplerate, fh.channels) != SWITCH_STATUS_SUCCESS) {
+						switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ring Error!\n");
+						switch_core_file_close(&fh);
+						return SWITCH_STATUS_GENERR;
+					}
+				} else {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open %s, disabling ring file!\n", ring_file);
+					ring_file = NULL;
+				}
+			}
+		}
 
 		switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
 		switch_channel_mark_ring_ready(channel);
-		
+
 		while (switch_channel_get_state(channel) == CS_INIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
+			switch_size_t olen = globals.timer.samples;
+				
 			if (switch_time_now() - last >= waitsec) {
 				char buf[512];
 				switch_event_t *event;
-                
+
 				snprintf(buf, sizeof(buf), "BRRRRING! BRRRRING! call %s\n", tech_pvt->call_id);
 
 				if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) {
@@ -256,49 +258,46 @@
 					switch_channel_event_set_data(channel, event);
 					switch_event_fire(&event);
 				}
-
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", buf);
 				last = switch_time_now();
-                if (ring_file) {
-                    unsigned int pos = 0;
-                    switch_core_file_seek(&fh, &pos, 0, SEEK_SET);				 
-                    for (;;) {
-                        switch_size_t olen = 1024;
-                        switch_core_file_read(&fh, abuf, &olen);
-                        if (olen == 0) {
-                            break;
-                        }
-                        WriteAudioStream(globals.ring_stream, abuf, (long)olen);
-                    }
-                }
-            }
-
-            switch_yield(globals.read_codec.implementation->microseconds_per_frame);
-
-        }
-        switch_clear_flag_locked((&globals), GFLAG_RING);
-    }
-
-    if (ring_file) {
-        deactivate_ring_device();
-        switch_core_file_close(&fh);
-        switch_core_codec_destroy(&tech_pvt->write_codec);
-		switch_core_timer_destroy(&tech_pvt->timer);
-    }
+			}
+			
+			if (ring_file) {
+				if (switch_core_timer_next(&globals.timer) != SWITCH_STATUS_SUCCESS) {
+					switch_core_file_close(&fh);
+					break;
+				}
+				switch_core_file_read(&fh, abuf, &olen);
+				if (olen == 0) {
+					unsigned int pos = 0;
+					switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
+				}
+				if (globals.ring_stream) {
+					WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.timer);
+				}
+			}
+		}
+		switch_clear_flag_locked((&globals), GFLAG_RING);
+	}
+
+	if (ring_file) {
+		deactivate_ring_device();
+		switch_core_file_close(&fh);
+	}
 
 	if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
-        if (!switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
-            switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER);
-            return SWITCH_STATUS_SUCCESS;
-        }
+		if (!switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
+			switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER);
+			return SWITCH_STATUS_SUCCESS;
+		}
 	}
 
-    switch_set_flag_locked(tech_pvt, TFLAG_IO);
-
-    /* Move Channel's State Machine to RING */
-    switch_channel_set_state(channel, CS_RING);
-	
-    return SWITCH_STATUS_SUCCESS;
+	switch_set_flag_locked(tech_pvt, TFLAG_IO);
+
+	/* Move Channel's State Machine to RING */
+	switch_channel_set_state(channel, CS_RING);
+
+	return SWITCH_STATUS_SUCCESS;
 
 }
 
@@ -344,6 +343,11 @@
 		globals.audio_stream = NULL;
 	}
 	switch_mutex_unlock(globals.device_lock);
+	if (globals.mixer) {
+		Px_CloseMixer(globals.mixer);
+		globals.mixer = NULL;
+	}
+
 }
 
 
@@ -359,72 +363,72 @@
 
 
 
-static void add_pvt(private_t *tech_pvt, int master) 
+static void add_pvt(private_t * tech_pvt, int master)
 {
-    private_t *tp;
-    uint8_t in_list = 0;
+	private_t *tp;
+	uint8_t in_list = 0;
+
+	switch_mutex_lock(globals.pvt_lock);
+
+	if (switch_strlen_zero(tech_pvt->call_id)) {
+		snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id);
+		switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
+		switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec);
+		switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec);
+	}
+
+	for (tp = globals.call_list; tp; tp = tp->next) {
+		if (tp == tech_pvt) {
+			in_list = 1;
+		}
+		if (master) {
+			switch_clear_flag_locked(tp, TFLAG_MASTER);
+		}
+	}
 
-    switch_mutex_lock(globals.pvt_lock);
 
-    if (switch_strlen_zero(tech_pvt->call_id)) {
-        snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id);
-        switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
-        switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec);
-        switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec);
-    }
-
-    for (tp = globals.call_list; tp; tp = tp->next) {
-        if (tp == tech_pvt) {
-            in_list = 1;
-        }
-        if (master) {
-            switch_clear_flag_locked(tp, TFLAG_MASTER);
-        }
-    }
-
-
-    if (master) {
-        if (!in_list) {
-            tech_pvt->next = globals.call_list;
-            globals.call_list = tech_pvt;
-        }
-        switch_set_flag_locked(tech_pvt, TFLAG_MASTER);
-
-    } else if (!in_list) {
-        for (tp = globals.call_list; tp && tp->next; tp = tp->next);
-        if (tp) {
-            tp->next = tech_pvt;
-        } else {
-            globals.call_list = tech_pvt;
-        }
-    }
+	if (master) {
+		if (!in_list) {
+			tech_pvt->next = globals.call_list;
+			globals.call_list = tech_pvt;
+		}
+		switch_set_flag_locked(tech_pvt, TFLAG_MASTER);
+
+	} else if (!in_list) {
+		for (tp = globals.call_list; tp && tp->next; tp = tp->next);
+		if (tp) {
+			tp->next = tech_pvt;
+		} else {
+			globals.call_list = tech_pvt;
+		}
+	}
 
 	switch_mutex_unlock(globals.pvt_lock);
 }
 
-static void remove_pvt(private_t *tech_pvt) 
+static void remove_pvt(private_t * tech_pvt)
 {
-    private_t *tp, *last = NULL;
+	private_t *tp, *last = NULL;
 
 	switch_mutex_lock(globals.pvt_lock);
-    for (tp = globals.call_list; tp; tp = tp->next) {
-        switch_clear_flag_locked(tp, TFLAG_MASTER);
-        if (tp == tech_pvt) {
-            if (last) {
-                last->next = tp->next;
-            } else {
-                globals.call_list = tp->next;
-            }
-        }
-        last = tp;
-    }
-
-    if (globals.call_list) {
-        switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
-    } else {
-        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No more channels, deactivating audio\n");
-        deactivate_audio_device();
-    }
+	for (tp = globals.call_list; tp; tp = tp->next) {
+		switch_clear_flag_locked(tp, TFLAG_MASTER);
+		if (tp == tech_pvt) {
+			if (last) {
+				last->next = tp->next;
+			} else {
+				globals.call_list = tp->next;
+			}
+		}
+		last = tp;
+	}
+
+	if (globals.call_list) {
+		switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No more channels, deactivating audio\n");
+		deactivate_audio_device();
+	}
 
 	switch_mutex_unlock(globals.pvt_lock);
 }
@@ -440,17 +444,17 @@
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
-    remove_pvt(tech_pvt);
+	remove_pvt(tech_pvt);
 
 	switch_clear_flag_locked(tech_pvt, TFLAG_IO);
 	switch_set_flag_locked(tech_pvt, TFLAG_HUP);
 
 	switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
 
-    if (tech_pvt->hfh) {
-        tech_pvt->hfh = NULL;
-        switch_core_file_close(&tech_pvt->fh);
-    }
+	if (tech_pvt->hfh) {
+		tech_pvt->hfh = NULL;
+		switch_core_file_close(&tech_pvt->fh);
+	}
 
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
 
@@ -468,14 +472,14 @@
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
-    switch (sig) {
-    case SWITCH_SIG_KILL:
-        switch_set_flag_locked(tech_pvt, TFLAG_HUP);
-        switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-        break;
-    default:
-        break;
-    }
+	switch (sig) {
+	case SWITCH_SIG_KILL:
+		switch_set_flag_locked(tech_pvt, TFLAG_HUP);
+		switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+		break;
+	default:
+		break;
+	}
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
 
 
@@ -538,8 +542,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
-                                          switch_io_flag_t flags, int stream_id)
+static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id)
 {
 	switch_channel_t *channel = NULL;
 	private_t *tech_pvt = NULL;
@@ -553,109 +556,90 @@
 	assert(tech_pvt != NULL);
 
 	if (!globals.audio_stream) {
-        return SWITCH_STATUS_FALSE;
-    }
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+		goto cng;
+	}
 
-    if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
-        return SWITCH_STATUS_FALSE;
-    }
-    
-    if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
-        goto cng;
-    }
-
-    if (!is_master(tech_pvt)) {
-        if (tech_pvt->hold_file) {
-            if (!tech_pvt->hfh) {
-                int codec_ms = tech_pvt->codec_ms ? tech_pvt->codec_ms : globals.codec_ms;
-                int sample_rate = tech_pvt->sample_rate ? tech_pvt->sample_rate : globals.sample_rate;
-
-                if (switch_core_codec_init(&tech_pvt->write_codec,
-                                           "L16",
-                                           NULL,
-                                           sample_rate,
-                                           codec_ms,
-                                           1,
-                                           SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
-                                           NULL,
-                                           switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
-                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
-                    switch_core_codec_destroy(&globals.read_codec);
-                    tech_pvt->hold_file = NULL;
-                    goto cng;
-                }
-
-                if (switch_core_file_open(&tech_pvt->fh,
-                                          tech_pvt->hold_file,
-                                          SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
-                                          switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
-                    switch_core_codec_destroy(&tech_pvt->write_codec);
-                    tech_pvt->hold_file = NULL;
-                    goto cng;
-                }
-
-                if (switch_core_timer_init(&tech_pvt->timer,
-                                           globals.timer_name,
-                                           codec_ms,
-                                           globals.read_codec.implementation->samples_per_frame,
-                                           switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
-                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
-                    switch_core_file_close(&tech_pvt->fh);
-                    switch_core_codec_destroy(&tech_pvt->write_codec);
-                    goto cng;
-                }
-                
-                tech_pvt->hfh = &tech_pvt->fh;
-                tech_pvt->hold_frame.data = tech_pvt->holdbuf;
-                tech_pvt->hold_frame.buflen = sizeof(tech_pvt->holdbuf);
-                tech_pvt->hold_frame.rate = sample_rate;
-                tech_pvt->hold_frame.codec = &tech_pvt->write_codec;
-            }
-            
-            goto hold;
-        }
-    cng:
-        switch_yield(globals.read_codec.implementation->microseconds_per_frame);
-        *frame = &globals.cng_frame;
+	if (!is_master(tech_pvt)) {
+		if (tech_pvt->hold_file) {
+			if (!tech_pvt->hfh) {
+				int sample_rate = tech_pvt->sample_rate ? tech_pvt->sample_rate : globals.sample_rate;
+				if (switch_core_file_open(&tech_pvt->fh,
+										  tech_pvt->hold_file,
+										  globals.read_codec.implementation->number_of_channels,
+										  globals.read_codec.implementation->samples_per_second,
+										  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
+										  switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
+					tech_pvt->hold_file = NULL;
+					goto cng;
+				}
+
+				tech_pvt->hfh = &tech_pvt->fh;
+				tech_pvt->hold_frame.data = tech_pvt->holdbuf;
+				tech_pvt->hold_frame.buflen = sizeof(tech_pvt->holdbuf);
+				tech_pvt->hold_frame.rate = sample_rate;
+				tech_pvt->hold_frame.codec = &globals.write_codec;
+			}
+
+			goto hold;
+		}
+	  cng:
+		switch_yield(globals.read_codec.implementation->microseconds_per_frame);
+		*frame = &globals.cng_frame;
 		return SWITCH_STATUS_SUCCESS;
 
-    hold:
+	  hold:
 
-        {
-            switch_size_t olen = globals.read_codec.implementation->samples_per_frame;
-			if (switch_core_timer_next(&tech_pvt->timer) != SWITCH_STATUS_SUCCESS) {
-                switch_core_file_close(&tech_pvt->fh);
-                switch_core_codec_destroy(&tech_pvt->write_codec);
-                goto cng;
+		{
+			switch_size_t olen = globals.read_codec.implementation->samples_per_frame;
+			if (switch_core_timer_next(&globals.timer) != SWITCH_STATUS_SUCCESS) {
+				switch_core_file_close(&tech_pvt->fh);
+				goto cng;
+			}
+			switch_core_file_read(tech_pvt->hfh, tech_pvt->hold_frame.data, &olen);
+
+			if (olen == 0) {
+				unsigned int pos = 0;
+				switch_core_file_seek(tech_pvt->hfh, &pos, 0, SEEK_SET);
+				goto cng;
 			}
-            switch_core_file_read(tech_pvt->hfh, tech_pvt->hold_frame.data, &olen);
-            
-            if (olen == 0) {
-                unsigned int pos = 0;
-                switch_core_file_seek(tech_pvt->hfh, &pos, 0, SEEK_SET);				 
-                goto cng;
-            }
-            
-            
-            tech_pvt->hold_frame.datalen = (uint32_t)(olen * sizeof(int16_t));
-            tech_pvt->hold_frame.samples = (uint32_t)olen;
-            *frame = &tech_pvt->hold_frame;
-            
-        }
 
-		return SWITCH_STATUS_SUCCESS;        
-    }
+
+			tech_pvt->hold_frame.datalen = (uint32_t) (olen * sizeof(int16_t));
+			tech_pvt->hold_frame.samples = (uint32_t) olen;
+			tech_pvt->hold_frame.timestamp = globals.timer.samplecount;
+			*frame = &tech_pvt->hold_frame;
+
+		}
+
+		return SWITCH_STATUS_SUCCESS;
+	}
 
 	switch_mutex_lock(globals.device_lock);
 
-    if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_frame)) != 0) {
+	if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, 
+								   globals.read_codec.implementation->samples_per_frame, 
+								   &globals.timer)) == 0) {
+		switch_mutex_unlock(globals.device_lock);
+		goto cng;
+	} else {
 		globals.read_frame.datalen = samples * 2;
 		globals.read_frame.samples = samples;
+
+		switch_core_timer_check(&globals.timer);
+		globals.read_frame.timestamp = globals.timer.samplecount;
 		*frame = &globals.read_frame;
 
-        if (!switch_test_flag((&globals), GFLAG_MOUTH)) {
-            memset(globals.read_frame.data, 255, globals.read_frame.datalen);
-        }
+		if (!switch_test_flag((&globals), GFLAG_MOUTH)) {
+			memset(globals.read_frame.data, 255, globals.read_frame.datalen);
+		}
 
 		status = SWITCH_STATUS_SUCCESS;
 	}
@@ -664,8 +648,7 @@
 	return status;
 }
 
-static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
-                                           switch_io_flag_t flags, int stream_id)
+static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id)
 {
 	switch_channel_t *channel = NULL;
 	private_t *tech_pvt = NULL;
@@ -677,21 +660,22 @@
 	assert(tech_pvt != NULL);
 
 	if (!globals.audio_stream) {
-        return SWITCH_STATUS_FALSE;
-    }
+		return SWITCH_STATUS_FALSE;
+	}
 
-    if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
-        return SWITCH_STATUS_FALSE;
-    }
-
-    if (!is_master(tech_pvt) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
-		return SWITCH_STATUS_SUCCESS;        
-    }
+	if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (!is_master(tech_pvt) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
+		return SWITCH_STATUS_SUCCESS;
+	}
 
 	if (globals.audio_stream) {
-        if (switch_test_flag((&globals), GFLAG_EAR)) {
-            WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)));
-        }
+		if (switch_test_flag((&globals), GFLAG_EAR)) {
+			WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)),
+							 &globals.timer);
+		}
 		status = SWITCH_STATUS_SUCCESS;
 	}
 
@@ -717,16 +701,19 @@
 {
 	switch_channel_t *channel;
 	private_t *tech_pvt;
-			
+
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
-			
+
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
 
 	switch (msg->message_id) {
-	case SWITCH_MESSAGE_INDICATE_PROGRESS: 
+	case SWITCH_MESSAGE_INDICATE_ANSWER:
+		channel_answer_channel(session);
+		break;
+	case SWITCH_MESSAGE_INDICATE_PROGRESS:
 		{
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage Early Media\n");
 			switch_set_flag_locked(tech_pvt, TFLAG_IO);
@@ -737,55 +724,7 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_api_interface_t send_dtmf_interface = {
-    /*.interface_name */ "padtmf",
-    /*.desc */ "DEPRICATED (see 'pa')",
-    /*.function */ padep,
-    /*.syntax */ "DEPRICATED (see 'pa')",
-    /*.next */ NULL
-};
-
-static switch_api_interface_t answer_call_interface = {
-    /*.interface_name */ "paoffhook",
-    /*.desc */ "DEPRICATED (see 'pa')",
-    /*.function */ padep,
-    /*.syntax */ "DEPRICATED (see 'pa')",
-    /*.next */ &send_dtmf_interface
-};
-
-static switch_api_interface_t channel_info_interface = {
-    /*.interface_name */ "painfo",
-    /*.desc */ "DEPRICATED (see 'pa')",
-    /*.function */ padep,
-    /*.syntax */ "DEPRICATED (see 'pa')",
-    /*.next */ &answer_call_interface
-};
-
-static switch_api_interface_t channel_hup_interface = {
-    /*.interface_name */ "pahup",
-    /*.desc */ "DEPRICATED (see 'pa')",
-    /*.function */ padep,
-    /*.syntax */ "DEPRICATED (see 'pa')",
-    /*.next */ &channel_info_interface
-};
-
-static switch_api_interface_t channel_call_interface = {
-    /*.interface_name */ "pacall",
-    /*.desc */ "DEPRICATED (see 'pa')",
-    /*.function */ padep,
-    /*.syntax */ "DEPRICATED (see 'pa')",
-    /*.next */ &channel_hup_interface
-};
-
-static switch_api_interface_t channel_api_interface = {
-	/*.interface_name */ "pa",
-	/*.desc */ "PortAudio",
-	/*.function */ pa_cmd,
-	/*.syntax */ "<command> [<args>]",
-	/*.next */ &channel_call_interface
-};
-
-static const switch_state_handler_table_t channel_event_handlers = {
+static switch_state_handler_table_t channel_event_handlers = {
 	/*.on_init */ channel_on_init,
 	/*.on_ring */ channel_on_ring,
 	/*.on_execute */ channel_on_execute,
@@ -794,56 +733,38 @@
 	/*.on_transmit */ channel_on_transmit
 };
 
-static const switch_io_routines_t channel_io_routines = {
+static switch_io_routines_t channel_io_routines = {
 	/*.outgoing_channel */ channel_outgoing_channel,
-	/*.answer_channel */ channel_answer_channel,
 	/*.read_frame */ channel_read_frame,
 	/*.write_frame */ channel_write_frame,
 	/*.kill_channel */ channel_kill_channel,
 	/*.waitfor_read */ channel_waitfor_read,
 	/*.waitfor_write */ channel_waitfor_write,
 	/*.send_dtmf */ channel_send_dtmf,
-	/*.receive_message*/ channel_receive_message
-};
-
-static const switch_endpoint_interface_t channel_endpoint_interface = {
-	/*.interface_name */ "portaudio",
-	/*.io_routines */ &channel_io_routines,
-	/*.event_handlers */ &channel_event_handlers,
-	/*.private */ NULL,
-	/*.next */ NULL
-};
-
-static const switch_loadable_module_interface_t channel_module_interface = {
-	/*.module_name */ modname,
-	/*.endpoint_interface */ &channel_endpoint_interface,
-	/*.timer_interface */ NULL,
-	/*.dialplan_interface */ NULL,
-	/*.codec_interface */ NULL,
-	/*.application_interface */ NULL,
-	/*.api_interface */ &channel_api_interface
+	/*.receive_message */ channel_receive_message
 };
 
 /* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
    that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
 */
-static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile,
+static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
+													switch_caller_profile_t *outbound_profile,
 													switch_core_session_t **new_session, switch_memory_pool_t **pool)
 {
 
-	if ((*new_session = switch_core_session_request(&channel_endpoint_interface, pool)) != 0) {
+	if ((*new_session = switch_core_session_request(channel_endpoint_interface, pool)) != 0) {
 		private_t *tech_pvt;
 		switch_channel_t *channel;
 		switch_caller_profile_t *caller_profile;
 
 		switch_core_session_add_stream(*new_session, NULL);
 		if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
-			memset(tech_pvt, 0, sizeof(*tech_pvt));            
+			memset(tech_pvt, 0, sizeof(*tech_pvt));
 			switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
 			channel = switch_core_session_get_channel(*new_session);
 			switch_core_session_set_private(*new_session, tech_pvt);
 			tech_pvt->session = *new_session;
-            globals.flags = GFLAG_EAR | GFLAG_MOUTH;
+			globals.flags = GFLAG_EAR | GFLAG_MOUTH;
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 			switch_core_session_destroy(new_session);
@@ -852,9 +773,9 @@
 
 		if (outbound_profile) {
 			char name[128];
-            char *id = !switch_strlen_zero(outbound_profile->caller_id_number) ? outbound_profile->caller_id_number : "na";
+			char *id = !switch_strlen_zero(outbound_profile->caller_id_number) ? outbound_profile->caller_id_number : "na";
 			snprintf(name, sizeof(name), "PortAudio/%s", id);
-					 
+
 			switch_channel_set_name(channel, name);
 
 			caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
@@ -877,30 +798,28 @@
 }
 
 
-SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
+SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
 {
+	switch_status_t status;
+	switch_api_interface_t *api_interface;
 
-    switch_status_t status;
-
-	if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
-		return SWITCH_STATUS_TERM;
-	}
+	module_pool = pool;
 
 	Pa_Initialize();
 
 	if (dump_info()) {
-        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
 		return SWITCH_STATUS_TERM;
-    }
+	}
 
 	if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
-        return status;
-    }
+		return status;
+	}
 
 
-    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Input Device: %d, Output Device: %d, Ring Device: %d Sample Rate: %d MS: %d\n", 
-                      globals.indev, globals.outdev, globals.ringdev, globals.sample_rate, globals.codec_ms);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+					  "Input Device: %d, Output Device: %d, Ring Device: %d Sample Rate: %d MS: %d\n", globals.indev,
+					  globals.outdev, globals.ringdev, globals.sample_rate, globals.codec_ms);
 
 
 	switch_core_hash_init(&globals.call_hash, module_pool);
@@ -920,10 +839,16 @@
 	globals.cng_frame.data = globals.cngbuf;
 	globals.cng_frame.buflen = sizeof(globals.cngbuf);
 	globals.cng_frame.datalen = sizeof(globals.cngbuf);
-    switch_set_flag((&globals.cng_frame), SFF_CNG);
+	switch_set_flag((&globals.cng_frame), SFF_CNG);
 
 	/* connect my internal structure to the blank pointer passed to me */
-	*module_interface = &channel_module_interface;
+	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
+	channel_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
+	channel_endpoint_interface->interface_name = "portaudio";
+	channel_endpoint_interface->io_routines = &channel_io_routines;
+	channel_endpoint_interface->state_handler = &channel_event_handlers;
+
+	SWITCH_ADD_API(api_interface, "pa", "PortAudio", pa_cmd, "<command> [<args>]");
 
 	/* indicate that the module should continue to be loaded */
 	return SWITCH_STATUS_SUCCESS;
@@ -934,7 +859,7 @@
 {
 	char *cf = "portaudio.conf";
 	switch_xml_t cfg, xml, settings, param;
-    switch_status_t status = SWITCH_STATUS_SUCCESS;
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
 
 	if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
@@ -942,7 +867,7 @@
 	}
 
 	memset(&globals, 0, sizeof(globals));
-    globals.indev = globals.outdev = globals.ringdev = -1;
+	globals.indev = globals.outdev = globals.ringdev = -1;
 
 	if ((settings = switch_xml_child(cfg, "settings"))) {
 		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
@@ -952,7 +877,7 @@
 			if (!strcmp(var, "debug")) {
 				globals.debug = atoi(val);
 			} else if (!strcmp(var, "ring-interval")) {
-                globals.ring_interval = atoi(val);
+				globals.ring_interval = atoi(val);
 			} else if (!strcmp(var, "ring-file")) {
 				set_global_ring_file(val);
 			} else if (!strcmp(var, "hold-file")) {
@@ -987,7 +912,7 @@
 				} else {
 					globals.ringdev = get_dev_by_name(val, 0);
 				}
-            }
+			}
 		}
 	}
 
@@ -1006,44 +931,44 @@
 	if (!globals.ring_interval) {
 		globals.ring_interval = 5;
 	}
-    
-    if (!globals.timer_name) {
-        set_global_timer_name("soft");
-    }
-
-    if (globals.indev < 0) {
-        globals.indev = get_dev_by_name(NULL, 1);
-        if (globals.indev > -1) {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device!\n");
-        } else {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
-            status = SWITCH_STATUS_GENERR;            
-        }
-    }
-
-    if (globals.outdev < 0) {
-        globals.outdev = get_dev_by_name(NULL, 0);
-        if (globals.outdev > -1) {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device!\n");
-        } else {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
-            status = SWITCH_STATUS_GENERR;            
-        }
-    }
-
-    if (globals.ringdev < 0) {
-        if (globals.outdev > -1) {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ring device configured using output device!\n");
-            globals.ringdev = globals.outdev;
-        } 
-    }
+
+	if (!globals.timer_name) {
+		set_global_timer_name("soft");
+	}
+
+	if (globals.indev < 0) {
+		globals.indev = get_dev_by_name(NULL, 1);
+		if (globals.indev > -1) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device!\n");
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+			status = SWITCH_STATUS_GENERR;
+		}
+	}
+
+	if (globals.outdev < 0) {
+		globals.outdev = get_dev_by_name(NULL, 0);
+		if (globals.outdev > -1) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device!\n");
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+			status = SWITCH_STATUS_GENERR;
+		}
+	}
+
+	if (globals.ringdev < 0) {
+		if (globals.outdev > -1) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ring device configured using output device!\n");
+			globals.ringdev = globals.outdev;
+		}
+	}
 
 	switch_xml_free(xml);
 
 	return status;
 }
 
-SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown)
 {
 	if (globals.read_codec.implementation) {
 		switch_core_codec_destroy(&globals.read_codec);
@@ -1053,6 +978,7 @@
 		switch_core_codec_destroy(&globals.write_codec);
 	}
 
+	switch_core_timer_destroy(&globals.timer);
 	Pa_Terminate();
 
 	return SWITCH_STATUS_SUCCESS;
@@ -1061,18 +987,18 @@
 
 static int get_dev_by_number(int number, int in)
 {
-    int numDevices = Pa_GetDeviceCount();
+	int numDevices = Pa_GetDeviceCount();
 	const PaDeviceInfo *pdi;
 
-    if (number > -1 && number < numDevices && (pdi = Pa_GetDeviceInfo(number))) {
-        if (in && pdi->maxInputChannels) {
-            return number;
-        } else if (!in && pdi->maxOutputChannels) {
-            return number;
-        }
-    }
-    
-    return -1;
+	if (number > -1 && number < numDevices && (pdi = Pa_GetDeviceInfo(number))) {
+		if (in && pdi->maxInputChannels) {
+			return number;
+		} else if (!in && pdi->maxOutputChannels) {
+			return number;
+		}
+	}
+
+	return -1;
 }
 
 static int get_dev_by_name(char *name, int in)
@@ -1088,15 +1014,15 @@
 	}
 
 	for (i = 0; i < numDevices; i++) {
-        int match = 0;
+		int match = 0;
 		pdi = Pa_GetDeviceInfo(i);
-        
+
 		if (switch_strlen_zero(name)) {
-            match = 1;
-        } else if (strstr(pdi->name, name)) {
-            match = 1;
-        }
-        
+			match = 1;
+		} else if (strstr(pdi->name, name)) {
+			match = 1;
+		}
+
 		if (match) {
 			if (in && pdi->maxInputChannels) {
 				return i;
@@ -1106,248 +1032,253 @@
 		}
 	}
 
-    if (switch_strlen_zero(name)) {
-        return -1;
-    }
+	if (switch_strlen_zero(name)) {
+		return -1;
+	}
 
 	return get_dev_by_name(NULL, in);
 }
 
 
 /*******************************************************************/
-static void PrintSupportedStandardSampleRates(const PaStreamParameters *inputParameters,
-                                              const PaStreamParameters *outputParameters)
+static void PrintSupportedStandardSampleRates(const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters)
 {
-    int i, printCount, cr = 7;
-    PaError err;
-    static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
-                                            44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1};
-
-    printCount = cr;
-    for(i=0; standardSampleRates[i] > 0; i++) {
-        err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
-        if (err == paFormatIsSupported) {
-            if (printCount == cr) {
-                printCount = 0;
-                switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "\n\t%0.2f", standardSampleRates[i]);
-            } else {
-                switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  ", %0.2f", standardSampleRates[i]);
-            }
-            printCount++;
-        }
-    }
-    if (!printCount) {
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  " None\n");
-    } else {
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "\n");
-    }
+	int i, printCount, cr = 7;
+	PaError err;
+	static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
+		44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1
+	};
+
+	printCount = cr;
+	for (i = 0; standardSampleRates[i] > 0; i++) {
+		err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
+		if (err == paFormatIsSupported) {
+			if (printCount == cr) {
+				printCount = 0;
+				switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n\t%0.2f", standardSampleRates[i]);
+			} else {
+				switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, ", %0.2f", standardSampleRates[i]);
+			}
+			printCount++;
+		}
+	}
+	if (!printCount) {
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, " None\n");
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n");
+	}
 }
+
 /*******************************************************************/
 
 static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *stream)
 {
-	int     i, numDevices;
-    const   PaDeviceInfo *deviceInfo;
-            
-    numDevices = Pa_GetDeviceCount();
-    if (numDevices < 0) {
+	int i, numDevices;
+	const PaDeviceInfo *deviceInfo;
+
+	numDevices = Pa_GetDeviceCount();
+	if (numDevices < 0) {
 		return SWITCH_STATUS_SUCCESS;
-    }
-	for(i=0; i<numDevices; i++) {
-        deviceInfo = Pa_GetDeviceInfo(i);
-        stream->write_function(stream, "%d;%s;%d;%d\n", i, deviceInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
+	}
+	for (i = 0; i < numDevices; i++) {
+		deviceInfo = Pa_GetDeviceInfo(i);
+		stream->write_function(stream, "%d;%s;%d;%d\n", i, deviceInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
 	}
 
-    return SWITCH_STATUS_SUCCESS;
+	return SWITCH_STATUS_SUCCESS;
 }
 
 static int dump_info(void)
 {
-    int     i, numDevices, defaultDisplayed;
-    const   PaDeviceInfo *deviceInfo;
-    PaStreamParameters inputParameters, outputParameters;
-    PaError err;
-    const char *line = "--------------------------------------------------------------------------------\n";
-    
+	int i, numDevices, defaultDisplayed;
+	const PaDeviceInfo *deviceInfo;
+	PaStreamParameters inputParameters, outputParameters;
+	PaError err;
+	const char *line = "--------------------------------------------------------------------------------\n";
+
 
 
-    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "PortAudio version number = %d\nPortAudio version text = '%s'\n",
-                      Pa_GetVersion(), Pa_GetVersionText());
+	switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+					  "PortAudio version number = %d\nPortAudio version text = '%s'\n", Pa_GetVersion(), Pa_GetVersionText());
 	if (globals.audio_stream) {
-		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "ERROR: Cannot use this command this while a call is in progress\n");
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
 		return 0;
 	}
-            
-    numDevices = Pa_GetDeviceCount();
-    if (numDevices < 0) {
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
-        err = numDevices;
-        goto error;
-    }
-    
-    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "Number of devices = %d\n", numDevices);
-    for(i=0; i<numDevices; i++) {
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
-        deviceInfo = Pa_GetDeviceInfo(i);
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "Device #%d ", i);
-                
-        /* Mark global and API specific default devices */
-        defaultDisplayed = 0;
-        if (i == Pa_GetDefaultInputDevice()) {
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "**Default Input");
-            defaultDisplayed = 1;
-            
-        } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
-            
-            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "**Default %s Input", hostInfo->name);
-            defaultDisplayed = 1;
-        }
-        
-        if (i == Pa_GetDefaultOutputDevice()) {
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "**Default Output");
-            defaultDisplayed = 1;
-
-        } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
-
-            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "**Default %s Output", hostInfo->name);
-            defaultDisplayed = 1;
-        }
-
-        if (defaultDisplayed) {
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "** | ");
-        }
-        /* print device info fields */
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "Name: %s\n", deviceInfo->name);
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "Host: %s | ",  Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "inputs: %d | ", deviceInfo->maxInputChannels );
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "outputs: %d | ", deviceInfo->maxOutputChannels );
-
-        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,  "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
-
-        /* poll for standard sample rates */
-        inputParameters.device = i;
-        inputParameters.channelCount = deviceInfo->maxInputChannels;
-        inputParameters.sampleFormat = paInt16;
-        inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
-        inputParameters.hostApiSpecificStreamInfo = NULL;
-        
-        outputParameters.device = i;
-        outputParameters.channelCount = deviceInfo->maxOutputChannels;
-        outputParameters.sampleFormat = paInt16;
-        outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
-        outputParameters.hostApiSpecificStreamInfo = NULL;
-
-        if (inputParameters.channelCount > 0) {
-
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:",
-                              inputParameters.channelCount);
-            PrintSupportedStandardSampleRates(&inputParameters, NULL);
-        }
-
-        if (outputParameters.channelCount > 0) {
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:",
-                              outputParameters.channelCount);
-            PrintSupportedStandardSampleRates(NULL, &outputParameters);
-        }
-
-        if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
-
-            switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "full-duplex 16 bit %d channel input, %d channel output rates:",
-                              inputParameters.channelCount, outputParameters.channelCount);
-            PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
-        }
-    }
-
-    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
-    
-    return 0;
-
- error:
-    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,  "An error occured while using the portaudio stream\n");
-    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,  "Error number: %d\n", err);
-    switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,  "Error message: %s\n", Pa_GetErrorText(err));
-    return err;
+
+	numDevices = Pa_GetDeviceCount();
+	if (numDevices < 0) {
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
+		err = numDevices;
+		goto error;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices);
+	for (i = 0; i < numDevices; i++) {
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+		deviceInfo = Pa_GetDeviceInfo(i);
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Device #%d ", i);
+
+		/* Mark global and API specific default devices */
+		defaultDisplayed = 0;
+		if (i == Pa_GetDefaultInputDevice()) {
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Input");
+			defaultDisplayed = 1;
+
+		} else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
+
+			const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name);
+			defaultDisplayed = 1;
+		}
+
+		if (i == Pa_GetDefaultOutputDevice()) {
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Output");
+			defaultDisplayed = 1;
+
+		} else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
+
+			const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name);
+			defaultDisplayed = 1;
+		}
+
+		if (defaultDisplayed) {
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "** | ");
+		}
+		/* print device info fields */
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name);
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels);
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels);
+
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
+
+		/* poll for standard sample rates */
+		inputParameters.device = i;
+		inputParameters.channelCount = deviceInfo->maxInputChannels;
+		inputParameters.sampleFormat = paInt16;
+		inputParameters.suggestedLatency = 0;	/* ignored by Pa_IsFormatSupported() */
+		inputParameters.hostApiSpecificStreamInfo = NULL;
+
+		outputParameters.device = i;
+		outputParameters.channelCount = deviceInfo->maxOutputChannels;
+		outputParameters.sampleFormat = paInt16;
+		outputParameters.suggestedLatency = 0;	/* ignored by Pa_IsFormatSupported() */
+		outputParameters.hostApiSpecificStreamInfo = NULL;
+
+		if (inputParameters.channelCount > 0) {
+
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:", inputParameters.channelCount);
+			PrintSupportedStandardSampleRates(&inputParameters, NULL);
+		}
+
+		if (outputParameters.channelCount > 0) {
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:", outputParameters.channelCount);
+			PrintSupportedStandardSampleRates(NULL, &outputParameters);
+		}
+
+		if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
+
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+							  "full-duplex 16 bit %d channel input, %d channel output rates:", inputParameters.channelCount,
+							  outputParameters.channelCount);
+			PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
+		}
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+
+	return 0;
+
+  error:
+	switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "An error occured while using the portaudio stream\n");
+	switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error number: %d\n", err);
+	switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error message: %s\n", Pa_GetErrorText(err));
+	return err;
 }
 
 
 
 static switch_status_t engage_device(int sample_rate, int codec_ms)
 {
-    PaStreamParameters inputParameters, outputParameters;
+	PaStreamParameters inputParameters, outputParameters;
 	PaError err;
 
-    if (!globals.audio_stream) {
-        if (!sample_rate) {
-            sample_rate = globals.sample_rate;
-        }
-        if (!codec_ms) {
-            codec_ms = globals.codec_ms;
-        }
-
-        if (switch_core_codec_init(&globals.read_codec,
-                                   "L16",
-                                   NULL,
-                                   sample_rate,
-                                   codec_ms,
-                                   1,
-                                   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
-                                   NULL, 
-                                   NULL) != SWITCH_STATUS_SUCCESS) {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
-            return SWITCH_STATUS_FALSE;
-        } else {
-            if (switch_core_codec_init(&globals.write_codec,
-                                       "L16",
-                                       NULL,
-                                       sample_rate,
-                                       codec_ms,
-                                       1,
-                                       SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
-                                       NULL,
-                                       NULL) != SWITCH_STATUS_SUCCESS) {
-                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
-                switch_core_codec_destroy(&globals.read_codec);
-                return SWITCH_STATUS_FALSE;
-            }
-        }
-
-        globals.read_frame.rate = sample_rate;
-        globals.read_frame.codec = &globals.read_codec;
-
-
-
-        switch_mutex_lock(globals.device_lock);
-        /* LOCKED ***************************************************************************************************/
-        inputParameters.device = globals.indev;
-        inputParameters.channelCount = 1;
-        inputParameters.sampleFormat = SAMPLE_TYPE;
-        inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
-        inputParameters.hostApiSpecificStreamInfo = NULL;
-
-        outputParameters.device = globals.outdev;
-        outputParameters.channelCount = 1;
-        outputParameters.sampleFormat =  SAMPLE_TYPE;
-        outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
-        outputParameters.hostApiSpecificStreamInfo = NULL;
-        err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff);
-        /* UNLOCKED **************************************************************************************************/
-        switch_mutex_unlock(globals.device_lock);
-
-
-        if (err != paNoError) {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device!\n");
-            switch_core_codec_destroy(&globals.read_codec);
-            switch_core_codec_destroy(&globals.write_codec);
-
-            return SWITCH_STATUS_FALSE;
-        }
-    }
+	if (!globals.audio_stream) {
+		if (!sample_rate) {
+			sample_rate = globals.sample_rate;
+		}
+		if (!codec_ms) {
+			codec_ms = globals.codec_ms;
+		}
+
+		if (switch_core_codec_init(&globals.read_codec,
+								   "L16",
+								   NULL, sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+								   NULL) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+			return SWITCH_STATUS_FALSE;
+		} else {
+			if (switch_core_codec_init(&globals.write_codec,
+									   "L16",
+									   NULL,
+									   sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+									   NULL) != SWITCH_STATUS_SUCCESS) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+				switch_core_codec_destroy(&globals.read_codec);
+				return SWITCH_STATUS_FALSE;
+			}
+		}
+
+		if (switch_core_timer_init(&globals.timer,
+								   globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_frame,
+								   module_pool) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
+			switch_core_codec_destroy(&globals.read_codec);
+			switch_core_codec_destroy(&globals.write_codec);
+			return SWITCH_STATUS_FALSE;
+		}
+
 
 
+		globals.read_frame.rate = sample_rate;
+		globals.read_frame.codec = &globals.read_codec;
 
-    return SWITCH_STATUS_SUCCESS;
+
+
+		switch_mutex_lock(globals.device_lock);
+		/* LOCKED ************************************************************************************************** */
+		inputParameters.device = globals.indev;
+		inputParameters.channelCount = 1;
+		inputParameters.sampleFormat = SAMPLE_TYPE;
+		inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
+		inputParameters.hostApiSpecificStreamInfo = NULL;
+
+		outputParameters.device = globals.outdev;
+		outputParameters.channelCount = 1;
+		outputParameters.sampleFormat = SAMPLE_TYPE;
+		outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+		outputParameters.hostApiSpecificStreamInfo = NULL;
+		err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, 
+							  globals.read_codec.implementation->samples_per_frame);
+		/* UNLOCKED ************************************************************************************************* */
+		switch_mutex_unlock(globals.device_lock);
+
+		globals.mixer = Px_OpenMixer(&globals.audio_stream, 0);
+
+
+		if (err != paNoError) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device!\n");
+			switch_core_codec_destroy(&globals.read_codec);
+			switch_core_codec_destroy(&globals.write_codec);
+
+			return SWITCH_STATUS_FALSE;
+		}
+	}
+
+
+
+	return SWITCH_STATUS_SUCCESS;
 
 
 }
@@ -1355,35 +1286,35 @@
 
 static switch_status_t engage_ring_device(int sample_rate, int channels)
 {
-	//int codec_ms = 20;
-    PaStreamParameters outputParameters;
+	PaStreamParameters outputParameters;
 	PaError err;
 
-    if (!globals.ring_stream) {
-        if (!sample_rate) {
-            sample_rate = globals.sample_rate;
-        }
-
-        switch_mutex_lock(globals.device_lock);
-        /* LOCKED ***************************************************************************************************/
-        outputParameters.device = globals.ringdev;
-        outputParameters.channelCount = channels;
-        outputParameters.sampleFormat =  SAMPLE_TYPE;
-        outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
-        outputParameters.hostApiSpecificStreamInfo = NULL;
-        err = OpenAudioStream(&globals.ring_stream, NULL, &outputParameters, sample_rate, paClipOff);
-        /* UNLOCKED **************************************************************************************************/
-        switch_mutex_unlock(globals.device_lock);
-
-
-        if (err != paNoError) {
-            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device!\n");
-            return SWITCH_STATUS_FALSE;
-        }
-    }
+	if (!globals.ring_stream) {
+		if (!sample_rate) {
+			sample_rate = globals.sample_rate;
+		}
+
+		switch_mutex_lock(globals.device_lock);
+		/* LOCKED ************************************************************************************************** */
+		outputParameters.device = globals.ringdev;
+		outputParameters.channelCount = channels;
+		outputParameters.sampleFormat = SAMPLE_TYPE;
+		outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+		outputParameters.hostApiSpecificStreamInfo = NULL;
+		err = OpenAudioStream(&globals.ring_stream, NULL, &outputParameters, sample_rate, paClipOff,
+							  globals.read_codec.implementation->samples_per_frame);
+		/* UNLOCKED ************************************************************************************************* */
+		switch_mutex_unlock(globals.device_lock);
+
+
+		if (err != paNoError) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device!\n");
+			return SWITCH_STATUS_FALSE;
+		}
+	}
 
-    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Engage ring device! rate: %d channels %d\n", sample_rate, channels);
-    return SWITCH_STATUS_SUCCESS;
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Engage ring device! rate: %d channels %d\n", sample_rate, channels);
+	return SWITCH_STATUS_SUCCESS;
 }
 
 
@@ -1391,64 +1322,64 @@
 
 static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream)
 {
-    char *dtmf = argv[0];
+	char *dtmf = argv[0];
 
-    if (switch_strlen_zero(dtmf)) {
-        stream->write_function(stream, "No DTMF Supplied!\n");
-    } else {
-        switch_mutex_lock(globals.pvt_lock);
-        if (globals.call_list) {
-            switch_channel_t *channel = switch_core_session_get_channel(globals.call_list->session);
-            switch_channel_queue_dtmf(channel, dtmf);
-        }
-        switch_mutex_unlock(globals.pvt_lock);
-    }
+	if (switch_strlen_zero(dtmf)) {
+		stream->write_function(stream, "No DTMF Supplied!\n");
+	} else {
+		switch_mutex_lock(globals.pvt_lock);
+		if (globals.call_list) {
+			switch_channel_t *channel = switch_core_session_get_channel(globals.call_list->session);
+			switch_channel_queue_dtmf(channel, dtmf);
+		}
+		switch_mutex_unlock(globals.pvt_lock);
+	}
 
-    return SWITCH_STATUS_SUCCESS;
+	return SWITCH_STATUS_SUCCESS;
 }
 
 static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t *stream)
 {
-    private_t *tp,*tech_pvt = NULL;
-    char *callid = argv[0];
-    uint8_t one_call = 0;
-
-    switch_mutex_lock(globals.pvt_lock);
-    if (switch_strlen_zero(callid)) {
-        if (globals.call_list) {
-            if (globals.call_list->next) {
-                tech_pvt = globals.call_list->next;
-            } else {
-                tech_pvt = globals.call_list;
-                one_call = 1;
-            }
-        }
-    } else if (!strcasecmp(callid, "none")) {
-        for (tp = globals.call_list; tp; tp = tp->next) {
-            switch_clear_flag_locked(tp, TFLAG_MASTER);
-        }
-        stream->write_function(stream, "OK\n");
-        goto done;
-    } else {
-        tech_pvt = switch_core_hash_find(globals.call_hash, callid);
-    }
+	private_t *tp, *tech_pvt = NULL;
+	char *callid = argv[0];
+	uint8_t one_call = 0;
+
+	switch_mutex_lock(globals.pvt_lock);
+	if (switch_strlen_zero(callid)) {
+		if (globals.call_list) {
+			if (globals.call_list->next) {
+				tech_pvt = globals.call_list->next;
+			} else {
+				tech_pvt = globals.call_list;
+				one_call = 1;
+			}
+		}
+	} else if (!strcasecmp(callid, "none")) {
+		for (tp = globals.call_list; tp; tp = tp->next) {
+			switch_clear_flag_locked(tp, TFLAG_MASTER);
+		}
+		stream->write_function(stream, "OK\n");
+		goto done;
+	} else {
+		tech_pvt = switch_core_hash_find(globals.call_hash, callid);
+	}
 
 	if (tech_pvt) {
-        if (tech_pvt == globals.call_list && !tech_pvt->next) {
-            one_call = 1;
-        }
-
-        if (!one_call) {
-            remove_pvt(tech_pvt);
-        }
-        add_pvt(tech_pvt, PA_MASTER);
-        stream->write_function(stream, "OK\n");
+		if (tech_pvt == globals.call_list && !tech_pvt->next) {
+			one_call = 1;
+		}
+
+		if (!one_call) {
+			remove_pvt(tech_pvt);
+		}
+		add_pvt(tech_pvt, PA_MASTER);
+		stream->write_function(stream, "OK\n");
 	} else {
 		stream->write_function(stream, "NO SUCH CALL\n");
 	}
 
- done:
-    switch_mutex_unlock(globals.pvt_lock);
+  done:
+	switch_mutex_unlock(globals.pvt_lock);
 
 	return SWITCH_STATUS_SUCCESS;
 
@@ -1456,23 +1387,23 @@
 
 static switch_status_t hangup_call(char **argv, int argc, switch_stream_handle_t *stream)
 {
-    private_t *tech_pvt;
-    char *callid = argv[0];
-    
-    switch_mutex_lock(globals.pvt_lock);
-    if (switch_strlen_zero(callid)) {
-        tech_pvt = globals.call_list;
-    } else {
-        tech_pvt = switch_core_hash_find(globals.call_hash, callid);
-    }
+	private_t *tech_pvt;
+	char *callid = argv[0];
+
+	switch_mutex_lock(globals.pvt_lock);
+	if (switch_strlen_zero(callid)) {
+		tech_pvt = globals.call_list;
+	} else {
+		tech_pvt = switch_core_hash_find(globals.call_hash, callid);
+	}
 
 	if (tech_pvt) {
-        switch_set_flag_locked(tech_pvt, TFLAG_HUP);
+		switch_channel_hangup(switch_core_session_get_channel(tech_pvt->session), SWITCH_CAUSE_NORMAL_CLEARING);
 		stream->write_function(stream, "OK\n");
 	} else {
 		stream->write_function(stream, "NO SUCH CALL\n");
 	}
-    switch_mutex_unlock(globals.pvt_lock);
+	switch_mutex_unlock(globals.pvt_lock);
 
 	return SWITCH_STATUS_SUCCESS;
 
@@ -1480,43 +1411,43 @@
 
 static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t *stream)
 {
-    private_t *tp;
-    int x = 0;
-    char *callid = argv[0];
-    
-    switch_mutex_lock(globals.pvt_lock);
-
-    if (!switch_strlen_zero(callid)) {
-        if ((tp = switch_core_hash_find(globals.call_hash, callid))) {
-            if (switch_test_flag(tp, TFLAG_ANSWER)) {
-                stream->write_function(stream, "CALL ALREADY ANSWERED\n");
-            } else {
-                switch_channel_t *channel = switch_core_session_get_channel(tp->session);
-                switch_set_flag_locked(tp, TFLAG_ANSWER);
-                switch_channel_answer(channel);
-                add_pvt(tp, PA_MASTER);
-            }
-        } else {
-            stream->write_function(stream, "NO SUCH CALL\n");
-        }
-
-        goto done;
-    }
-
-    for (tp = globals.call_list; tp; tp = tp->next) {
-        if (!switch_test_flag(tp, TFLAG_ANSWER)) {
-            switch_channel_t *channel = switch_core_session_get_channel(tp->session);
-            switch_set_flag_locked(tp, TFLAG_ANSWER);
-            switch_channel_answer(channel);
-            add_pvt(tp, PA_MASTER);
-            x++;
-            break;
-        }
-	} 
- done:
-    switch_mutex_unlock(globals.pvt_lock);
+	private_t *tp;
+	int x = 0;
+	char *callid = argv[0];
+
+	switch_mutex_lock(globals.pvt_lock);
+
+	if (!switch_strlen_zero(callid)) {
+		if ((tp = switch_core_hash_find(globals.call_hash, callid))) {
+			if (switch_test_flag(tp, TFLAG_ANSWER)) {
+				stream->write_function(stream, "CALL ALREADY ANSWERED\n");
+			} else {
+				switch_channel_t *channel = switch_core_session_get_channel(tp->session);
+				switch_set_flag_locked(tp, TFLAG_ANSWER);
+				switch_channel_answer(channel);
+				add_pvt(tp, PA_MASTER);
+			}
+		} else {
+			stream->write_function(stream, "NO SUCH CALL\n");
+		}
 
-    stream->write_function(stream, "Answered %d channels.\n", x);    
+		goto done;
+	}
+
+	for (tp = globals.call_list; tp; tp = tp->next) {
+		if (!switch_test_flag(tp, TFLAG_ANSWER)) {
+			switch_channel_t *channel = switch_core_session_get_channel(tp->session);
+			switch_set_flag_locked(tp, TFLAG_ANSWER);
+			switch_channel_answer(channel);
+			add_pvt(tp, PA_MASTER);
+			x++;
+			break;
+		}
+	}
+  done:
+	switch_mutex_unlock(globals.pvt_lock);
+
+	stream->write_function(stream, "Answered %d channels.\n", x);
 
 
 	return SWITCH_STATUS_SUCCESS;
@@ -1525,113 +1456,110 @@
 
 static switch_status_t do_flags(char **argv, int argc, switch_stream_handle_t *stream)
 {
-    char *action = argv[0];
-    char *flag_str = argv[1];
-    GFLAGS flags = GFLAG_NONE;
-    char *p;
-    int x = 0;
-
-    if (argc < 2) {
-        goto desc;
-    }
-
-    for (x = 1; x < argc; x++) {
-        flag_str = argv[x];
-        for(p = flag_str; *p; p++) {
-            *p = (char)tolower(*p);
-        }
-    
-        if (strstr(flag_str, "ear")) {
-            flags |= GFLAG_EAR;
-        } 
-        if (strstr(flag_str, "mouth")) {
-            flags |= GFLAG_MOUTH;
-        }
-    }
-
-    if (!strcasecmp(action, "on")) {
-        if (flags & GFLAG_EAR) {
-            switch_set_flag((&globals), GFLAG_EAR);
-        }
-        if (flags & GFLAG_MOUTH) {
-            switch_set_flag((&globals), GFLAG_MOUTH);
-        }
-    } else if (!strcasecmp(action, "off")) {
-        if (flags & GFLAG_EAR) {
-            switch_clear_flag((&globals), GFLAG_EAR);
-        }
-        if (flags & GFLAG_MOUTH) {
-            switch_clear_flag((&globals), GFLAG_MOUTH);
-        }
-    } else {
-        goto bad;
-    }
-
- desc:
-    x = 0;
-    stream->write_function(stream, "FLAGS: ");
-    if (switch_test_flag((&globals), GFLAG_EAR)) {
-        stream->write_function(stream, "ear");
-        x++;
-    }
-    if (switch_test_flag((&globals), GFLAG_MOUTH)) {
-        stream->write_function(stream, "%smouth", x ? "|" : "");
-        x++;
-    }
-    if (!x) {
-        stream->write_function(stream, "none");
-    }
-
-    goto done;
-
- bad:
-    stream->write_function(stream, "Usage: flags [on|off] <flags>\n");    
- done:
-    return SWITCH_STATUS_SUCCESS;
+	char *action = argv[0];
+	char *flag_str = argv[1];
+	GFLAGS flags = GFLAG_NONE;
+	char *p;
+	int x = 0;
+
+	if (argc < 2) {
+		goto desc;
+	}
+
+	for (x = 1; x < argc; x++) {
+		flag_str = argv[x];
+		for (p = flag_str; *p; p++) {
+			*p = (char) tolower(*p);
+		}
+
+		if (strstr(flag_str, "ear")) {
+			flags |= GFLAG_EAR;
+		}
+		if (strstr(flag_str, "mouth")) {
+			flags |= GFLAG_MOUTH;
+		}
+	}
+
+	if (!strcasecmp(action, "on")) {
+		if (flags & GFLAG_EAR) {
+			switch_set_flag((&globals), GFLAG_EAR);
+		}
+		if (flags & GFLAG_MOUTH) {
+			switch_set_flag((&globals), GFLAG_MOUTH);
+		}
+	} else if (!strcasecmp(action, "off")) {
+		if (flags & GFLAG_EAR) {
+			switch_clear_flag((&globals), GFLAG_EAR);
+		}
+		if (flags & GFLAG_MOUTH) {
+			switch_clear_flag((&globals), GFLAG_MOUTH);
+		}
+	} else {
+		goto bad;
+	}
+
+  desc:
+	x = 0;
+	stream->write_function(stream, "FLAGS: ");
+	if (switch_test_flag((&globals), GFLAG_EAR)) {
+		stream->write_function(stream, "ear");
+		x++;
+	}
+	if (switch_test_flag((&globals), GFLAG_MOUTH)) {
+		stream->write_function(stream, "%smouth", x ? "|" : "");
+		x++;
+	}
+	if (!x) {
+		stream->write_function(stream, "none");
+	}
+
+	goto done;
+
+  bad:
+	stream->write_function(stream, "Usage: flags [on|off] <flags>\n");
+  done:
+	return SWITCH_STATUS_SUCCESS;
 }
 
 static switch_status_t list_calls(char **argv, int argc, switch_stream_handle_t *stream)
 {
-    private_t *tp;
-    int x = 0;
-    char *cid_name = "n/a";
-    char *cid_num = "n/a";
-    
-    switch_mutex_lock(globals.pvt_lock);
-    for (tp = globals.call_list; tp; tp = tp->next) {
+	private_t *tp;
+	int x = 0;
+	char *cid_name = "n/a";
+	char *cid_num = "n/a";
+
+	switch_mutex_lock(globals.pvt_lock);
+	for (tp = globals.call_list; tp; tp = tp->next) {
 		switch_channel_t *channel;
-        switch_caller_profile_t *profile;
-        x++;
-        channel = switch_core_session_get_channel(tp->session);        
-        
-        if ((profile = switch_channel_get_caller_profile(channel))) {
-            if (profile->originatee_caller_profile) {
-                cid_name = "Outbound Call";
-                cid_num = profile->originatee_caller_profile->destination_number;
-            } else {
-                cid_name = profile->caller_id_name;
-                cid_num = profile->caller_id_number;
-            }
-        }
-
-        stream->write_function(stream, "%s %s [%s (%s)] %s\n", tp->call_id, switch_channel_get_name(channel),
-                               cid_name,
-                               cid_num,
-                               switch_test_flag(tp, TFLAG_MASTER) ? "active" : "hold"
-                               );
-    }
-    switch_mutex_unlock(globals.pvt_lock);
+		switch_caller_profile_t *profile;
+		x++;
+		channel = switch_core_session_get_channel(tp->session);
+
+		if ((profile = switch_channel_get_caller_profile(channel))) {
+			if (profile->originatee_caller_profile) {
+				cid_name = "Outbound Call";
+				cid_num = profile->originatee_caller_profile->destination_number;
+			} else {
+				cid_name = profile->caller_id_name;
+				cid_num = profile->caller_id_number;
+			}
+		}
+
+		stream->write_function(stream, "%s %s [%s (%s)] %s\n", tp->call_id, switch_channel_get_name(channel),
+							   cid_name, cid_num, switch_test_flag(tp, TFLAG_MASTER) ? "active" : "hold");
+	}
+	switch_mutex_unlock(globals.pvt_lock);
 
-    stream->write_function(stream, "\n%d call%s\n", x, x == 1 ? "" : "s");
+	stream->write_function(stream, "\n%d call%s\n", x, x == 1 ? "" : "s");
 
-    return SWITCH_STATUS_SUCCESS;
+	return SWITCH_STATUS_SUCCESS;
 }
 
 static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t *stream)
 {
 	switch_core_session_t *session;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
-    char *dest = NULL;
+	char *dest = NULL;
 
 	if (!argv[0]) {
 		stream->write_function(stream, "FAIL:Usage: call <dest>\n");
@@ -1639,12 +1567,12 @@
 	}
 	dest = argv[0];
 
-	if ((session = switch_core_session_request(&channel_endpoint_interface, NULL)) != 0) {
+	if ((session = switch_core_session_request(channel_endpoint_interface, NULL)) != 0) {
 		private_t *tech_pvt;
 		switch_channel_t *channel;
-        char *dialplan = globals.dialplan;
-        char *cid_name = globals.cid_name;
-        char *cid_num = globals.cid_num;        
+		char *dialplan = globals.dialplan;
+		char *cid_name = globals.cid_name;
+		char *cid_num = globals.cid_num;
 
 		switch_core_session_add_stream(session, NULL);
 		if ((tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t))) != 0) {
@@ -1653,7 +1581,7 @@
 			channel = switch_core_session_get_channel(session);
 			switch_core_session_set_private(session, tech_pvt);
 			tech_pvt->session = session;
-            globals.flags = GFLAG_EAR | GFLAG_MOUTH;
+			globals.flags = GFLAG_EAR | GFLAG_MOUTH;
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 			switch_core_session_destroy(&session);
@@ -1661,31 +1589,29 @@
 		}
 
 		if (!switch_strlen_zero(argv[1])) {
-            dialplan = argv[1];
-        }
+			dialplan = argv[1];
+		}
 
-        if (!switch_strlen_zero(argv[2])) {
-            cid_num = argv[2];
-        }
-
-        if (!switch_strlen_zero(argv[3])) {
-            cid_name = argv[3];
-        }
-
-        if (!switch_strlen_zero(argv[4])) {
-            tech_pvt->sample_rate = atoi(argv[4]);
-        }
-
-        if (!switch_strlen_zero(argv[4])) {
-            tech_pvt->codec_ms = atoi(argv[5]);
-        }
+		if (!switch_strlen_zero(argv[2])) {
+			cid_num = argv[2];
+		}
+
+		if (!switch_strlen_zero(argv[3])) {
+			cid_name = argv[3];
+		}
+
+		if (!switch_strlen_zero(argv[4])) {
+			tech_pvt->sample_rate = atoi(argv[4]);
+		}
+
+		if (!switch_strlen_zero(argv[4])) {
+			tech_pvt->codec_ms = atoi(argv[5]);
+		}
 
 		if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
 																  NULL,
-																  dialplan,
-                                                                  cid_name,
-																  cid_num,
-                                                                  NULL, NULL, NULL, NULL, (char *)modname, NULL, dest)) != 0) {
+																  dialplan, cid_name, cid_num, NULL, NULL, NULL, NULL, (char *) modname, NULL,
+																  dest)) != 0) {
 			char name[128];
 			snprintf(name, sizeof(name), "PortAudio/%s",
 					 tech_pvt->caller_profile->destination_number ? tech_pvt->caller_profile->destination_number : modname);
@@ -1695,14 +1621,19 @@
 		}
 		tech_pvt->session = session;
 		if ((status = engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms)) == SWITCH_STATUS_SUCCESS) {
-            switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
-            switch_channel_mark_answered(channel);
+			switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
+			switch_channel_mark_answered(channel);
 			switch_channel_set_state(channel, CS_INIT);
-			switch_core_session_thread_launch(tech_pvt->session);
-            add_pvt(tech_pvt, PA_MASTER);
-			stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+			if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+				switch_core_session_destroy(&session);
+				stream->write_function(stream, "FAIL:Thread Error!\n");
+			} else {
+				add_pvt(tech_pvt, PA_MASTER);
+				stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+			}
 		} else {
-            switch_core_session_destroy(&session);
+			switch_core_session_destroy(&session);
 			stream->write_function(stream, "FAIL:Device Error!\n");
 		}
 	}
@@ -1710,74 +1641,131 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t padep(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+static switch_status_t set_volume(char **argv, int argc, switch_stream_handle_t *stream)
 {
-    stream->write_function(stream, "This command no longer exists (try 'pa help')\n");
-    return SWITCH_STATUS_SUCCESS;
+	PxVolume volume;
+	switch_mutex_lock(globals.device_lock);
+	if (!switch_strlen_zero(argv[1])) {
+		volume = (PxVolume) atof(argv[1]);
+		Px_SetMasterVolume( globals.mixer, volume );
+	}
+	switch_mutex_unlock(globals.device_lock);
+	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t pa_cmd(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(pa_cmd)
 {
-    char *argv[1024] = {0};
-    int argc = 0;
-    char *mycmd = NULL, *devname = NULL;
-    switch_status_t status = SWITCH_STATUS_SUCCESS;
-    pa_command_t func = NULL;
-    int lead = 1, devval = 0;
-    const char *usage_string = "USAGE:\n"
-        "--------------------------------------------------------------------------------\n"
-        "pa help\n"
-        "pa dump\n"
-        "pa call <dest> [<dialplan> <cid_name> <cid_num> <rate>]\n"
-        "pa answer [<call_id>]\n"
-        "pa hangup [<call_id>]\n"
-        "pa list\n"
-        "pa switch [<call_id>|none]\n"
-        "pa dtmf <digit string>\n"
-        "pa flags [on|off] [ear] [mouth]\n"
+	char *argv[1024] = { 0 };
+	int argc = 0;
+	char *mycmd = NULL, *devname = NULL;
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	pa_command_t func = NULL;
+	int lead = 1, devval = 0;
+	char *wcmd = NULL, *action = NULL;
+	char cmd_buf[1024] = "";
+	char *http = NULL;
+
+	const char *usage_string = "USAGE:\n"
+		"--------------------------------------------------------------------------------\n"
+		"pa help\n"
+		"pa dump\n"
+		"pa call <dest> [<dialplan> <cid_name> <cid_num> <rate>]\n"
+		"pa answer [<call_id>]\n"
+		"pa hangup [<call_id>]\n"
+		"pa list\n"
+		"pa switch [<call_id>|none]\n"
+		"pa dtmf <digit string>\n"
+		"pa flags [on|off] [ear] [mouth]\n"
 		"pa devlist\n"
 		"pa indev [#<num>|<partial name>\n"
 		"pa outdev [#<num>|<partial name>\n"
 		"pa ringdev [#<num>|<partial name>\n"
-        "--------------------------------------------------------------------------------\n";
+		"pa setvolume <volume between 0.0 and 1.0>\n"
+		"--------------------------------------------------------------------------------\n";
+
+	if (stream->event) {
+		http = switch_event_get_header(stream->event, "http-host");
+	}
+
+
+	if (http) {
+#if 0
+		switch_event_header_t *hp;
+		stream->write_function(stream, "<pre>");
+		for (hp = stream->event->headers; hp; hp = hp->next) {
+			stream->write_function(stream, "[%s]=[%s]\n", hp->name, hp->value);
+		}
+		stream->write_function(stream, "</pre>");
+#endif
+
+		wcmd = switch_str_nil(switch_event_get_header(stream->event, "wcmd"));
+		action = switch_event_get_header(stream->event, "action");
 
-    if (switch_strlen_zero(cmd)) {
-        stream->write_function(stream, "%s", usage_string);
-        goto done;
-    }
-
-    if (!(mycmd = strdup(cmd))) {
-        status = SWITCH_STATUS_MEMERR;
-        goto done;
-    }
-    
-    if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
-        stream->write_function(stream, "%s", usage_string);
-        goto done;
-    }
-    
-    if (!strcasecmp(argv[0], "call")) {
-        func = place_call;
-    } else if (!strcasecmp(argv[0], "help")) {
-        stream->write_function(stream, "%s", usage_string);
-        goto done;
-    } else if (!strcasecmp(argv[0], "devlist")) {
+		if (action) {
+			if (strlen(action) == 1) {
+				snprintf(cmd_buf, sizeof(cmd_buf), "dtmf %s", action);
+				cmd = cmd_buf;
+			} else if (!strcmp(action, "mute")) {
+				snprintf(cmd_buf, sizeof(cmd_buf), "flags off mouth");
+				cmd = cmd_buf;
+			} else if (!strcmp(action, "unmute")) {
+				snprintf(cmd_buf, sizeof(cmd_buf), "flags on mouth");
+				cmd = cmd_buf;
+			} else if (!strcmp(action, "switch")) {
+				snprintf(cmd_buf, sizeof(cmd_buf), "switch %s", wcmd);
+				cmd = cmd_buf;
+			} else if (!strcmp(action, "call")) {
+				snprintf(cmd_buf, sizeof(cmd_buf), "call %s", wcmd);
+				cmd = cmd_buf;
+			} else if (!strcmp(action, "hangup") || !strcmp(action, "list") || !strcmp(action, "answer")) {
+				cmd = action;
+			}
+		}
+
+		if (switch_strlen_zero(cmd)) {
+			goto done;
+		}
+
+	} else {
+
+		if (switch_strlen_zero(cmd)) {
+			stream->write_function(stream, "%s", usage_string);
+			goto done;
+		}
+	}
+
+	if (!(mycmd = strdup(cmd))) {
+		status = SWITCH_STATUS_MEMERR;
+		goto done;
+	}
+
+	if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
+		stream->write_function(stream, "%s", usage_string);
+		goto done;
+	}
+
+	if (!strcasecmp(argv[0], "call")) {
+		func = place_call;
+	} else if (!strcasecmp(argv[0], "help")) {
+		stream->write_function(stream, "%s", usage_string);
+		goto done;
+	} else if (!strcasecmp(argv[0], "devlist")) {
 		func = devlist;
-    } else if (!strcasecmp(argv[0], "dump")) {
-        dump_info();
-        goto done;
-    } else if (!strcasecmp(argv[0], "list")) {
-        func = list_calls;
-    } else if (!strcasecmp(argv[0], "flags")) {
-        func = do_flags;
-    } else if (!strcasecmp(argv[0], "hangup")) {
-        func = hangup_call;
-    } else if (!strcasecmp(argv[0], "answer")) {
-        func = answer_call;
-    } else if (!strcasecmp(argv[0], "switch")) {
-        func = switch_call;
-    } else if (!strcasecmp(argv[0], "dtmf")) {
-        func = dtmf_call;
+	} else if (!strcasecmp(argv[0], "dump")) {
+		dump_info();
+		goto done;
+	} else if (!strcasecmp(argv[0], "list")) {
+		func = list_calls;
+	} else if (!strcasecmp(argv[0], "flags")) {
+		func = do_flags;
+	} else if (!strcasecmp(argv[0], "hangup")) {
+		func = hangup_call;
+	} else if (!strcasecmp(argv[0], "answer")) {
+		func = answer_call;
+	} else if (!strcasecmp(argv[0], "switch")) {
+		func = switch_call;
+	} else if (!strcasecmp(argv[0], "dtmf")) {
+		func = dtmf_call;
 	} else if (argv[1] && !strcmp(argv[0], "indev")) {
 		if (*argv[1] == '#') {
 			devval = get_dev_by_number(atoi(argv[1] + 1), 1);
@@ -1795,7 +1783,7 @@
 			devval = get_dev_by_name(argv[1], 0);
 		}
 		devname = "outdev";
-		if (devval > 0)  {
+		if (devval > 0) {
 			globals.outdev = devval;
 		}
 	} else if (argv[1] && !strcmp(argv[0], "ringdev")) {
@@ -1807,12 +1795,20 @@
 		devname = "ringdev";
 		if (devval > 0) {
 			globals.ringdev = devval;
+	 	}
+	} else if (!strcasecmp(argv[0], "setvolume")) {
+		func = set_volume;
+	}
+
+	if (func) {
+		if (http) {
+			stream->write_function(stream, "<pre>");
 		}
-    }
-    
-    if (func) {
-        status = func(&argv[lead], argc - lead, stream);
-    } else {
+		status = func(&argv[lead], argc - lead, stream);
+		if (http) {
+			stream->write_function(stream, "\n\n</pre>");
+		}
+	} else {
 		if (devname) {
 			if (devval > 0) {
 				stream->write_function(stream, "%s set to %d\n", devname, devval);
@@ -1822,13 +1818,52 @@
 		} else {
 			stream->write_function(stream, "Unknown Command [%s]\n", argv[0]);
 		}
-    }
+	}
+
+  done:
 
- done:
+	if (http) {
 
-    switch_safe_free(mycmd);
+		stream->write_function(stream,
+							   "<br><br><table align=center><tr><td><center><form method=post>\n"
+							   "<input type=text name=wcmd size=40><br><br>\n"
+
+							   "<input name=action type=submit value=\"call\"> "
+							   "<input name=action type=submit value=\"hangup\"> "
+							   "<input name=action type=submit value=\"list\"> "
+							   "<input name=action type=submit value=\"switch\"> "
+							   "<input name=action type=submit value=\"mute\"> "
+							   "<input name=action type=submit value=\"unmute\"> "
+							   "<input name=action type=submit value=\"answer\"> <br><br>"
+							   "<table border=1>\n"
+							   "<tr><td><input name=action type=submit value=\"1\"></td>"
+							   "<td><input name=action type=submit value=\"2\"></td>"
+							   "<td><input name=action type=submit value=\"3\"></td>\n"
+							   "<td><input name=action type=submit value=\"A\"></td></tr>\n"
+
+							   "<tr><td><input name=action type=submit value=\"4\"></td>"
+							   "<td><input name=action type=submit value=\"5\"></td>"
+							   "<td><input name=action type=submit value=\"6\"></td>\n"
+							   "<td><input name=action type=submit value=\"B\"></td></tr>\n"
+
+							   "<tr><td><input name=action type=submit value=\"7\"></td>"
+							   "<td><input name=action type=submit value=\"8\"></td>"
+							   "<td><input name=action type=submit value=\"9\"></td>\n"
+							   "<td><input name=action type=submit value=\"C\"></td></tr>\n"
+
+							   "<tr><td><input name=action type=submit value=\"*\"></td>"
+							   "<td><input name=action type=submit value=\"0\"></td>"
+							   "<td><input name=action type=submit value=\"#\"></td>\n"
+							   "<td><input name=action type=submit value=\"D\"></td></tr>\n"
+							   "</table>"
+							   
+							   "</form><br></center></td></tr></table>\n"
+							   );
+	}
 
-    return status;
+	switch_safe_free(mycmd);
+
+	return status;
 }
 
 

Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c	(original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c	Fri Aug 24 13:50:56 2007
@@ -81,24 +81,25 @@
 #   define PaUtil_WriteMemoryBarrier()
 #else
 
-#if defined(__APPLE__) //|| defined(__FreeBSD__)
+#if defined(__APPLE__)			//|| defined(__FreeBSD__)
 #   include <libkern/OSAtomic.h>
-    /* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
-       full memory barriers, so the three types of barriers are the same. */
+	/* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
+	   full memory barriers, so the three types of barriers are the same. */
 #   define PaUtil_FullMemoryBarrier()  OSMemoryBarrier()
 #   define PaUtil_ReadMemoryBarrier()  OSMemoryBarrier()
 #   define PaUtil_WriteMemoryBarrier() OSMemoryBarrier()
 #elif defined(__GNUC__)
-    /* GCC understands volatile asm and "memory" to mean it
-     * should not reorder memory read/writes */
+
+	/* GCC understands volatile asm and "memory" to mean it
+	 * should not reorder memory read/writes */
 #   if defined( __PPC__ )
-#      define PaUtil_FullMemoryBarrier()  asm volatile("sync":::"memory")
-#      define PaUtil_ReadMemoryBarrier()  asm volatile("sync":::"memory")
-#      define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory")
+#      define PaUtil_FullMemoryBarrier()  __asm__ volatile("sync":::"memory")
+#      define PaUtil_ReadMemoryBarrier()  __asm__ volatile("sync":::"memory")
+#      define PaUtil_WriteMemoryBarrier() __asm__ volatile("sync":::"memory")
 #   elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ ) || defined(__x86_64__)
-#      define PaUtil_FullMemoryBarrier()  asm volatile("mfence":::"memory")
-#      define PaUtil_ReadMemoryBarrier()  asm volatile("lfence":::"memory")
-#      define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory")
+#      define PaUtil_FullMemoryBarrier()  __asm__ volatile("mfence":::"memory")
+#      define PaUtil_ReadMemoryBarrier()  __asm__ volatile("lfence":::"memory")
+#      define PaUtil_WriteMemoryBarrier() __asm__ volatile("sfence":::"memory")
 #   else
 #      define PaUtil_FullMemoryBarrier()
 #      define PaUtil_ReadMemoryBarrier()
@@ -122,37 +123,39 @@
  * Initialize FIFO.
  * numBytes must be power of 2, returns -1 if not.
  */
-long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr )
+long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr)
 {
-    if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
-    rbuf->bufferSize = numBytes;
-    rbuf->buffer = (char *)dataPtr;
-    PaUtil_FlushRingBuffer( rbuf );
-    rbuf->bigMask = (numBytes*2)-1;
-    rbuf->smallMask = (numBytes)-1;
-    return 0;
+	if (((numBytes - 1) & numBytes) != 0)
+		return -1;				/* Not Power of two. */
+	rbuf->bufferSize = numBytes;
+	rbuf->buffer = (char *) dataPtr;
+	PaUtil_FlushRingBuffer(rbuf);
+	rbuf->bigMask = (numBytes * 2) - 1;
+	rbuf->smallMask = (numBytes) - 1;
+	return 0;
 }
 
 /***************************************************************************
 ** Return number of bytes available for reading. */
-long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf )
+long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf)
 {
-    PaUtil_ReadMemoryBarrier();
-    return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
+	PaUtil_ReadMemoryBarrier();
+	return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask);
 }
+
 /***************************************************************************
 ** Return number of bytes available for writing. */
-long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf )
+long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf)
 {
-    /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
-    return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
+	/* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
+	return (rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
 }
 
 /***************************************************************************
 ** Clear buffer. Should only be called when buffer is NOT being read. */
-void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
+void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf)
 {
-    rbuf->writeIndex = rbuf->readIndex = 0;
+	rbuf->writeIndex = rbuf->readIndex = 0;
 }
 
 /***************************************************************************
@@ -161,42 +164,38 @@
 ** If non-contiguous, size2 will be the size of second region.
 ** Returns room available to be written or numBytes, whichever is smaller.
 */
-long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes,
-                                       void **dataPtr1, long *sizePtr1,
-                                       void **dataPtr2, long *sizePtr2 )
-{
-    long   index;
-    long   available = PaUtil_GetRingBufferWriteAvailable( rbuf );
-    if( numBytes > available ) numBytes = available;
-    /* Check to see if write is not contiguous. */
-    index = rbuf->writeIndex & rbuf->smallMask;
-    if( (index + numBytes) > rbuf->bufferSize )
-    {
-        /* Write data in two blocks that wrap the buffer. */
-        long   firstHalf = rbuf->bufferSize - index;
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = firstHalf;
-        *dataPtr2 = &rbuf->buffer[0];
-        *sizePtr2 = numBytes - firstHalf;
-    }
-    else
-    {
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = numBytes;
-        *dataPtr2 = NULL;
-        *sizePtr2 = 0;
-    }
-    return numBytes;
+long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2)
+{
+	long index;
+	long available = PaUtil_GetRingBufferWriteAvailable(rbuf);
+	if (numBytes > available)
+		numBytes = available;
+	/* Check to see if write is not contiguous. */
+	index = rbuf->writeIndex & rbuf->smallMask;
+	if ((index + numBytes) > rbuf->bufferSize) {
+		/* Write data in two blocks that wrap the buffer. */
+		long firstHalf = rbuf->bufferSize - index;
+		*dataPtr1 = &rbuf->buffer[index];
+		*sizePtr1 = firstHalf;
+		*dataPtr2 = &rbuf->buffer[0];
+		*sizePtr2 = numBytes - firstHalf;
+	} else {
+		*dataPtr1 = &rbuf->buffer[index];
+		*sizePtr1 = numBytes;
+		*dataPtr2 = NULL;
+		*sizePtr2 = 0;
+	}
+	return numBytes;
 }
 
 
 /***************************************************************************
 */
-long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes )
+long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes)
 {
-    /* we need to ensure that previous writes are seen before we update the write index */
-    PaUtil_WriteMemoryBarrier();
-    return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
+	/* we need to ensure that previous writes are seen before we update the write index */
+	PaUtil_WriteMemoryBarrier();
+	return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
 }
 
 /***************************************************************************
@@ -205,81 +204,72 @@
 ** If non-contiguous, size2 will be the size of second region.
 ** Returns room available to be written or numBytes, whichever is smaller.
 */
-long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes,
-                                void **dataPtr1, long *sizePtr1,
-                                void **dataPtr2, long *sizePtr2 )
-{
-    long   index;
-    long   available = PaUtil_GetRingBufferReadAvailable( rbuf );
-    if( numBytes > available ) numBytes = available;
-    /* Check to see if read is not contiguous. */
-    index = rbuf->readIndex & rbuf->smallMask;
-    if( (index + numBytes) > rbuf->bufferSize )
-    {
-        /* Write data in two blocks that wrap the buffer. */
-        long firstHalf = rbuf->bufferSize - index;
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = firstHalf;
-        *dataPtr2 = &rbuf->buffer[0];
-        *sizePtr2 = numBytes - firstHalf;
-    }
-    else
-    {
-        *dataPtr1 = &rbuf->buffer[index];
-        *sizePtr1 = numBytes;
-        *dataPtr2 = NULL;
-        *sizePtr2 = 0;
-    }
-    return numBytes;
+long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2)
+{
+	long index;
+	long available = PaUtil_GetRingBufferReadAvailable(rbuf);
+	if (numBytes > available)
+		numBytes = available;
+	/* Check to see if read is not contiguous. */
+	index = rbuf->readIndex & rbuf->smallMask;
+	if ((index + numBytes) > rbuf->bufferSize) {
+		/* Write data in two blocks that wrap the buffer. */
+		long firstHalf = rbuf->bufferSize - index;
+		*dataPtr1 = &rbuf->buffer[index];
+		*sizePtr1 = firstHalf;
+		*dataPtr2 = &rbuf->buffer[0];
+		*sizePtr2 = numBytes - firstHalf;
+	} else {
+		*dataPtr1 = &rbuf->buffer[index];
+		*sizePtr1 = numBytes;
+		*dataPtr2 = NULL;
+		*sizePtr2 = 0;
+	}
+	return numBytes;
 }
+
 /***************************************************************************
 */
-long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes )
+long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes)
 {
-    /* we need to ensure that previous writes are always seen before updating the index. */
-    PaUtil_WriteMemoryBarrier();
-    return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
+	/* we need to ensure that previous writes are always seen before updating the index. */
+	PaUtil_WriteMemoryBarrier();
+	return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
 }
 
 /***************************************************************************
 ** Return bytes written. */
-long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes )
+long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes)
 {
-    long size1, size2, numWritten;
-    void *data1, *data2;
-    numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
-    if( size2 > 0 )
-    {
-
-        memcpy( data1, data, size1 );
-        data = ((char *)data) + size1;
-        memcpy( data2, data, size2 );
-    }
-    else
-    {
-        memcpy( data1, data, size1 );
-    }
-    PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten );
-    return numWritten;
+	long size1, size2, numWritten;
+	void *data1, *data2;
+	numWritten = PaUtil_GetRingBufferWriteRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
+	if (size2 > 0) {
+
+		memcpy(data1, data, size1);
+		data = ((char *) data) + size1;
+		memcpy(data2, data, size2);
+	} else {
+		memcpy(data1, data, size1);
+	}
+	PaUtil_AdvanceRingBufferWriteIndex(rbuf, numWritten);
+	return numWritten;
 }
 
 /***************************************************************************
 ** Return bytes read. */
-long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes )
+long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes)
 {
-    long size1, size2, numRead;
-    void *data1, *data2;
-    numRead = PaUtil_GetRingBufferReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
-    if( size2 > 0 )
-    {
-        memcpy( data, data1, size1 );
-        data = ((char *)data) + size1;
-        memcpy( data, data2, size2 );
-    }
-    else
-    {
-        memcpy( data, data1, size1 );
-    }
-    PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead );
-    return numRead;
+	long size1, size2, numRead;
+	void *data1, *data2;
+	numRead = PaUtil_GetRingBufferReadRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
+	if (size2 > 0) {
+		memcpy(data, data1, size1);
+		data = ((char *) data) + size1;
+		memcpy(data, data2, size2);
+	} else {
+		memcpy(data, data1, size1);
+	}
+	PaUtil_AdvanceRingBufferReadIndex(rbuf, numRead);
+	return numRead;
 }

Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h	(original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h	Fri Aug 24 13:50:56 2007
@@ -51,19 +51,17 @@
 */
 
 #ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef struct PaUtilRingBuffer
-{
-    long   bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
-    long   writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */
-    long   readIndex;  /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */
-    long   bigMask;    /* Used for wrapping indices with extra bit to distinguish full/empty. */
-    long   smallMask;  /* Used for fitting indices to buffer. */
-    char  *buffer;
-}PaUtilRingBuffer;
+extern "C" {
+#endif							/* __cplusplus */
+
+	typedef struct PaUtilRingBuffer {
+		long bufferSize;		/* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
+		long writeIndex;		/* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */
+		long readIndex;			/* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */
+		long bigMask;			/* Used for wrapping indices with extra bit to distinguish full/empty. */
+		long smallMask;			/* Used for fitting indices to buffer. */
+		char *buffer;
+	} PaUtilRingBuffer;
 
 /** Initialize Ring Buffer.
 
@@ -76,13 +74,13 @@
 
  @return -1 if numBytes is not a power of 2, otherwise 0.
 */
-long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr );
+	long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr);
 
 /** Clear buffer. Should only be called when buffer is NOT being read.
 
  @param rbuf The ring buffer.
 */
-void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf );
+	void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf);
 
 /** Retrieve the number of bytes available in the ring buffer for writing.
 
@@ -90,7 +88,7 @@
 
  @return The number of bytes available for writing.
 */
-long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf );
+	long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf);
 
 /** Retrieve the number of bytes available in the ring buffer for reading.
 
@@ -98,7 +96,7 @@
 
  @return The number of bytes available for reading.
 */
-long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf );
+	long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf);
 
 /** Write data to the ring buffer.
 
@@ -110,7 +108,7 @@
 
  @return The number of bytes written.
 */
-long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes );
+	long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes);
 
 /** Read data from the ring buffer.
 
@@ -122,7 +120,7 @@
 
  @return The number of bytes read.
 */
-long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes );
+	long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes);
 
 /** Get address of region(s) to which we can write data.
 
@@ -144,9 +142,7 @@
 
  @return The room available to be written or numBytes, whichever is smaller.
 */
-long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes,
-                                       void **dataPtr1, long *sizePtr1,
-                                       void **dataPtr2, long *sizePtr2 );
+	long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2);
 
 /** Advance the write index to the next location to be written.
 
@@ -156,7 +152,7 @@
 
  @return The new position.
 */
-long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes );
+	long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes);
 
 /** Get address of region(s) from which we can write data.
 
@@ -178,9 +174,7 @@
 
  @return The number of bytes available for reading.
 */
-long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes,
-                                      void **dataPtr1, long *sizePtr1,
-                                      void **dataPtr2, long *sizePtr2 );
+	long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2);
 
 /** Advance the read index to the next location to be read.
 
@@ -190,9 +184,9 @@
 
  @return The new position.
 */
-long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes );
+	long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes);
 
 #ifdef __cplusplus
 }
-#endif /* __cplusplus */
-#endif /* PA_RINGBUFFER_H */
+#endif							/* __cplusplus */
+#endif							/* PA_RINGBUFFER_H */

Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c	(original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c	Fri Aug 24 13:50:56 2007
@@ -40,6 +40,7 @@
  * license above.
  */
 
+#include <switch.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
@@ -49,176 +50,181 @@
 #include <string.h>
 #include <time.h>
 
-/************************************************************************/
-/******** Constants *****************************************************/
-/************************************************************************/
-
-#define FRAMES_PER_BUFFER    (256)
 
 /************************************************************************/
 /******** Prototypes ****************************************************/
 /************************************************************************/
 
-static int blockingIOCallback( const void *inputBuffer, void *outputBuffer,
-                               unsigned long framesPerBuffer,
-							   const PaStreamCallbackTimeInfo* timeInfo,
-							   PaStreamCallbackFlags statusFlags,
-							   void *userData );
-static PaError PABLIO_InitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame );
-static PaError PABLIO_TermFIFO( PaUtilRingBuffer *rbuf );
+static int blockingIOCallback(const void *inputBuffer, void *outputBuffer,
+							  unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
+static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame);
+static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf);
 
 /************************************************************************/
 /******** Functions *****************************************************/
 /************************************************************************/
 
 /* Called from PortAudio.
- * Read and write data only if there is room in FIFOs.
+ * Read and write data 
  */
-static int blockingIOCallback( const void *inputBuffer, void *outputBuffer,
-                               unsigned long framesPerBuffer,
-                               const PaStreamCallbackTimeInfo* timeInfo,
-							   PaStreamCallbackFlags statusFlags,
-							   void *userData )
+static int blockingIOCallback(const void *inputBuffer, void *outputBuffer,
+							  unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
 {
-    PABLIO_Stream *data = (PABLIO_Stream*)userData;
-    long numBytes = data->bytesPerFrame * framesPerBuffer;
-
-    /* This may get called with NULL inputBuffer during initial setup. */
-    if( inputBuffer != NULL )
-    {
-        PaUtil_WriteRingBuffer( &data->inFIFO, inputBuffer, numBytes );
-    }
-    if( outputBuffer != NULL )
-    {
-        int i;
-        int numRead = PaUtil_ReadRingBuffer( &data->outFIFO, outputBuffer, numBytes );
-        /* Zero out remainder of buffer if we run out of data. */
-        for( i=numRead; i<numBytes; i++ )
-        {
-            ((char *)outputBuffer)[i] = 0;
-        }
-    }
+	PABLIO_Stream *data = (PABLIO_Stream *) userData;
+	long numBytes = data->bytesPerFrame * framesPerBuffer;
+	
+	/* This may get called with NULL inputBuffer during initial setup. */
+	if (inputBuffer != NULL) {
+		if (PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes) != numBytes) {
+			PaUtil_FlushRingBuffer(&data->inFIFO);
+			PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes);
+		}
+	}
+	if (outputBuffer != NULL) {
+		int i;
+		int numRead = PaUtil_ReadRingBuffer(&data->outFIFO, outputBuffer, numBytes);
+		/* Zero out remainder of buffer if we run out of data. */
+		for (i = numRead; i < numBytes; i++) {
+			((char *) outputBuffer)[i] = 0;
+		}
+	}
 
-    return 0;
+	return 0;
 }
 
 /* Allocate buffer. */
-static PaError PABLIO_InitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame )
+static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame)
 {
-    long numBytes = numFrames * bytesPerFrame;
-    char *buffer = (char *) malloc( numBytes );
-    if( buffer == NULL ) return paInsufficientMemory;
-    memset( buffer, 0, numBytes );
-    return (PaError) PaUtil_InitializeRingBuffer( rbuf, numBytes, buffer );
+	long numBytes = numFrames * bytesPerFrame;
+	char *buffer = (char *) malloc(numBytes);
+	if (buffer == NULL)
+		return paInsufficientMemory;
+	memset(buffer, 0, numBytes);
+	return (PaError) PaUtil_InitializeRingBuffer(rbuf, numBytes, buffer);
 }
 
 /* Free buffer. */
-static PaError PABLIO_TermFIFO( PaUtilRingBuffer *rbuf )
+static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf)
 {
-    if( rbuf->buffer ) free( rbuf->buffer );
-    rbuf->buffer = NULL;
-    return paNoError;
+	if (rbuf->buffer)
+		free(rbuf->buffer);
+	rbuf->buffer = NULL;
+	return paNoError;
 }
 
 /************************************************************
  * Write data to ring buffer.
  * Will not return until all the data has been written.
  */
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer)
 {
-    long bytesWritten;
-    char *p = (char *) data;
-    long numBytes = aStream->bytesPerFrame * numFrames;
-    while( numBytes > 0)
-    {
-        bytesWritten = PaUtil_WriteRingBuffer( &aStream->outFIFO, p, numBytes );
-        numBytes -= bytesWritten;
-        p += bytesWritten;
-        if( numBytes > 0) Pa_Sleep(10);
-    }
-    return numFrames;
+	long bytesWritten;
+	char *p = (char *) data;
+	long numBytes = aStream->bytesPerFrame * numFrames;
+
+	while (numBytes > 0) {
+		bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFO, p, numBytes);
+		numBytes -= bytesWritten;
+		p += bytesWritten;
+		if (numBytes > 0) {
+			if (switch_core_timer_check(timer) == SWITCH_STATUS_SUCCESS) {
+				PaUtil_FlushRingBuffer(&aStream->outFIFO);
+				return 0;
+			}
+			switch_yield(1000);
+		}
+	}
+	return numFrames;
 }
 
 /************************************************************
  * Read data from ring buffer.
  * Will not return until all the data has been read.
  */
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer)
 {
-    long bytesRead;
-    char *p = (char *) data;
-    long numBytes = aStream->bytesPerFrame * numFrames;
-
-    while( numBytes > 0)
-    {
-        bytesRead = PaUtil_ReadRingBuffer( &aStream->inFIFO, p, numBytes );
-        numBytes -= bytesRead;
-        p += bytesRead;
-        if( numBytes > 0) Pa_Sleep(10);
-    }
-    return numFrames;
+	long bytesRead;
+	char *p = (char *) data;
+	long numBytes = aStream->bytesPerFrame * numFrames;
+	
+	while (numBytes > 0) {
+		bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFO, p, numBytes);
+		numBytes -= bytesRead;
+		if (numBytes > 0) {
+			if (switch_core_timer_check(timer) == SWITCH_STATUS_SUCCESS) {
+				PaUtil_FlushRingBuffer(&aStream->inFIFO);
+				return 0;
+			}
+			switch_yield(1000);
+		}
+	}
+	return numFrames;
 }
 
 /************************************************************
  * Return the number of frames that could be written to the stream without
  * having to wait.
  */
-long GetAudioStreamWriteable( PABLIO_Stream *aStream )
+long GetAudioStreamWriteable(PABLIO_Stream * aStream)
 {
-    int bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
-    return bytesEmpty / aStream->bytesPerFrame;
+	int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+	return bytesEmpty / aStream->bytesPerFrame;
 }
 
 /************************************************************
  * Return the number of frames that are available to be read from the
  * stream without having to wait.
  */
-long GetAudioStreamReadable( PABLIO_Stream *aStream )
+long GetAudioStreamReadable(PABLIO_Stream * aStream)
 {
-    int bytesFull = PaUtil_GetRingBufferReadAvailable( &aStream->inFIFO );
-    return bytesFull / aStream->bytesPerFrame;
+	int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFO);
+	return bytesFull / aStream->bytesPerFrame;
 }
 
-/************************************************************/
-static unsigned long RoundUpToNextPowerOf2( unsigned long n )
+/***********************************************************/
+static unsigned long RoundUpToNextPowerOf2(unsigned long n)
 {
-    long numBits = 0;
-    if( ((n-1) & n) == 0) return n; /* Already Power of two. */
-    while( n > 0 )
-    {
-        n= n>>1;
-        numBits++;
-    }
-    return (1<<numBits);
+	long numBits = 0;
+	if (((n - 1) & n) == 0)
+		return n;				
+	while (n > 0) {
+		n = n >> 1;
+		numBits++;
+	}
+	return (1 << numBits);
 }
 
+
+
 /************************************************************
  * Opens a PortAudio stream with default characteristics.
  * Allocates PABLIO_Stream structure.
  *
  */
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr, 
-						 const PaStreamParameters *inputParameters,
-						 const PaStreamParameters *outputParameters,
-						 double sampleRate,
-						 PaStreamFlags streamFlags)
+PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
+						const PaStreamParameters *inputParameters,
+						const PaStreamParameters *outputParameters,
+						double sampleRate,
+						PaStreamFlags streamFlags,
+						long samples_per_frame)
 {
-    long   bytesPerSample;
-    PaError err;
-    PABLIO_Stream *aStream;
-    long   minNumBuffers;
-    long   numFrames;
-	long numBytes;
+	long bytesPerSample = 2;
+	PaError err;
+	PABLIO_Stream *aStream;
+	long numFrames;
+	//long numBytes;
 	int channels = 1;
 
-    /* Allocate PABLIO_Stream structure for caller. */
-    aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );
-    if( aStream == NULL ) return paInsufficientMemory;
-    memset( aStream, 0, sizeof(PABLIO_Stream) );
-
-    /* Initialize PortAudio  */
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
+	/* Allocate PABLIO_Stream structure for caller. */
+	aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream));
+	if (aStream == NULL)
+		return paInsufficientMemory;
+	memset(aStream, 0, sizeof(PABLIO_Stream));
+
+	/* Initialize PortAudio  */
+	err = Pa_Initialize();
+	if (err != paNoError)
+		goto error;
 
 	if (inputParameters) {
 		channels = inputParameters->channelCount;
@@ -226,81 +232,74 @@
 		channels = outputParameters->channelCount;
 	}
 
-    numFrames = 4 * FRAMES_PER_BUFFER;
-    numFrames = RoundUpToNextPowerOf2( numFrames );
-
-	bytesPerSample = 2;
-	aStream->samplesPerFrame = channels;
-    aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
+	numFrames = RoundUpToNextPowerOf2(samples_per_frame * 5);
+	aStream->bytesPerFrame = bytesPerSample;
 
-    /* Initialize Ring Buffers */
+	/* Initialize Ring Buffers */
 
 	if (inputParameters) {
-		err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->bytesPerFrame );
-		if( err != paNoError ) goto error;
+		err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
+		if (err != paNoError)
+			goto error;
 	}
 
 	if (outputParameters) {
-		err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame );
-		if( err != paNoError ) goto error;
+		err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
+		if (err != paNoError)
+			goto error;
 	}
 
 	/* Make Write FIFO appear full initially. */
-	numBytes = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
-	PaUtil_AdvanceRingBufferWriteIndex( &aStream->outFIFO, numBytes );
-	
+	//numBytes = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+	//PaUtil_AdvanceRingBufferWriteIndex(&aStream->outFIFO, numBytes);
+
 
-    /* Open a PortAudio stream that we will use to communicate with the underlying
-     * audio drivers. */
-    err = Pa_OpenStream(
-              &aStream->stream,
-			  inputParameters,
-              outputParameters,
-			  sampleRate,
-              FRAMES_PER_BUFFER,
-			  streamFlags,
-              blockingIOCallback,
-              aStream );
-    if( err != paNoError ) goto error;
-
-    err = Pa_StartStream( aStream->stream );
-    if( err != paNoError ) goto error;
-    *rwblPtr = aStream;
-    return paNoError;
-
-error:
-    CloseAudioStream( aStream );
-    *rwblPtr = NULL;
-    return err;
+	/* Open a PortAudio stream that we will use to communicate with the underlying
+	 * audio drivers. */
+	err = Pa_OpenStream(&aStream->stream, inputParameters, outputParameters, sampleRate, samples_per_frame, streamFlags, blockingIOCallback, aStream);
+
+	if (err != paNoError)
+		goto error;
+
+	err = Pa_StartStream(aStream->stream);
+	if (err != paNoError)
+		goto error;
+	*rwblPtr = aStream;
+	return paNoError;
+
+  error:
+	CloseAudioStream(aStream);
+	*rwblPtr = NULL;
+	return err;
 }
 
 /************************************************************/
-PaError CloseAudioStream( PABLIO_Stream *aStream )
+PaError CloseAudioStream(PABLIO_Stream * aStream)
 {
-    PaError err;
-    int bytesEmpty;
-    int byteSize = aStream->outFIFO.bufferSize;
-
-    /* If we are writing data, make sure we play everything written. */
-    if( byteSize > 0 )
-    {
-        bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
-        while( bytesEmpty < byteSize )
-        {
-            Pa_Sleep( 10 );
-            bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
-        }
-    }
-
-    err = Pa_StopStream( aStream->stream );
-    if( err != paNoError ) goto error;
-    err = Pa_CloseStream( aStream->stream );
-    if( err != paNoError ) goto error;
-    Pa_Terminate();
-
-error:
-    PABLIO_TermFIFO( &aStream->inFIFO );
-    PABLIO_TermFIFO( &aStream->outFIFO );
-    free( aStream );
-    return err;
+	PaError err;
+	int bytesEmpty;
+	int byteSize = aStream->outFIFO.bufferSize;
+
+	/* If we are writing data, make sure we play everything written. */
+	if (byteSize > 0) {
+		bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+		while (bytesEmpty < byteSize) {
+			Pa_Sleep(10);
+			bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+		}
+	}
+
+	err = Pa_StopStream(aStream->stream);
+	if (err != paNoError)
+		goto error;
+	err = Pa_CloseStream(aStream->stream);
+	if (err != paNoError)
+		goto error;
+	Pa_Terminate();
+
+  error:
+	PABLIO_TermFIFO(&aStream->inFIFO);
+	PABLIO_TermFIFO(&aStream->outFIFO);
+	free(aStream);
+	return err;
 }

Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h	(original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h	Fri Aug 24 13:50:56 2007
@@ -2,9 +2,8 @@
 #define _PABLIO_H
 
 #ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+extern "C" {
+#endif							/* __cplusplus */
 
 /*
  * $Id: pablio.h 1083 2006-08-23 07:30:49Z rossb $
@@ -57,15 +56,12 @@
 
 #include <string.h>
 
-typedef struct
-{
-    PaUtilRingBuffer   inFIFO;
-    PaUtilRingBuffer   outFIFO;
-    PaStream *stream;
-    int          bytesPerFrame;
-    int          samplesPerFrame;
-}
-PABLIO_Stream;
+	typedef struct {
+		PaUtilRingBuffer inFIFO;
+		PaUtilRingBuffer outFIFO;
+		PaStream *stream;
+		int bytesPerFrame;
+	} PABLIO_Stream;
 
 /* Values for flags for OpenAudioStream(). */
 #define PABLIO_READ     (1<<0)
@@ -78,25 +74,25 @@
  * Write data to ring buffer.
  * Will not return until all the data has been written.
  */
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+	long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer);
 
 /************************************************************
  * Read data from ring buffer.
  * Will not return until all the data has been read.
  */
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+	long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer);
 
 /************************************************************
  * Return the number of frames that could be written to the stream without
  * having to wait.
  */
-long GetAudioStreamWriteable( PABLIO_Stream *aStream );
+	long GetAudioStreamWriteable(PABLIO_Stream * aStream);
 
 /************************************************************
  * Return the number of frames that are available to be read from the
  * stream without having to wait.
  */
-long GetAudioStreamReadable( PABLIO_Stream *aStream );
+	long GetAudioStreamReadable(PABLIO_Stream * aStream);
 
 /************************************************************
  * Opens a PortAudio stream with default characteristics.
@@ -106,15 +102,13 @@
  *    PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
  *    and either PABLIO_MONO or PABLIO_STEREO
  */
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr, 
-						 const PaStreamParameters *inputParameters,
-						 const PaStreamParameters *outputParameters,
-						 double sampleRate,
-						 PaStreamCallbackFlags statusFlags);
+	PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
+							const PaStreamParameters * inputParameters,
+							const PaStreamParameters * outputParameters, double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_frame);
 
-PaError CloseAudioStream( PABLIO_Stream *aStream );
+	PaError CloseAudioStream(PABLIO_Stream * aStream);
 
 #ifdef __cplusplus
 }
-#endif /* __cplusplus */
-#endif /* _PABLIO_H */
+#endif							/* __cplusplus */
+#endif							/* _PABLIO_H */



More information about the Freeswitch-branches mailing list