From 7d88add653fb874d3c0f13496564926d24869530 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 28 Aug 2024 15:07:02 +0300 Subject: [PATCH 1/3] [mod_dahdi_codec] Remove from tree --- .gitignore | 1 - build/modules.conf.in | 1 - build/modules.conf.most | 1 - configure.ac | 1 - debian/bootstrap.sh | 2 - debian/control-modules | 4 - src/mod/codecs/mod_dahdi_codec/Makefile.am | 8 - .../codecs/mod_dahdi_codec/mod_dahdi_codec.c | 583 ------------------ 8 files changed, 601 deletions(-) delete mode 100644 src/mod/codecs/mod_dahdi_codec/Makefile.am delete mode 100644 src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c diff --git a/.gitignore b/.gitignore index 6a47caf4ae..2d0effae96 100644 --- a/.gitignore +++ b/.gitignore @@ -151,7 +151,6 @@ Release/ /src/mod/applications/mod_test/test/Makefile.in /src/mod/codecs/mod_com_g729/Makefile /src/mod/codecs/mod_com_g729/Makefile.in -/src/mod/codecs/mod_dahdi_codec/Makefile /src/mod/dialplans/mod_dialplan_directory/Makefile /src/mod/formats/mod_shell_stream/Makefile /src/mod/languages/mod_lua/mod_lua_wrap.cpp.orig diff --git a/build/modules.conf.in b/build/modules.conf.in index 9a4c419f64..34266964dc 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -64,7 +64,6 @@ codecs/mod_b64 #codecs/mod_clearmode #codecs/mod_codec2 #codecs/mod_com_g729 -#codecs/mod_dahdi_codec codecs/mod_g723_1 codecs/mod_g729 codecs/mod_h26x diff --git a/build/modules.conf.most b/build/modules.conf.most index 0cc812dba4..c25126f5c8 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -62,7 +62,6 @@ codecs/mod_b64 codecs/mod_bv codecs/mod_codec2 #codecs/mod_com_g729 -codecs/mod_dahdi_codec codecs/mod_g723_1 codecs/mod_g729 codecs/mod_h26x diff --git a/configure.ac b/configure.ac index 8866ba7a1b..139ff97358 100755 --- a/configure.ac +++ b/configure.ac @@ -2159,7 +2159,6 @@ AC_CONFIG_FILES([Makefile src/mod/codecs/mod_clearmode/Makefile src/mod/codecs/mod_codec2/Makefile src/mod/codecs/mod_com_g729/Makefile - src/mod/codecs/mod_dahdi_codec/Makefile src/mod/codecs/mod_g723_1/Makefile src/mod/codecs/mod_g729/Makefile src/mod/codecs/mod_h26x/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 4a87f02570..37cc2fe0c3 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -710,7 +710,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-b64 (= \${binary:Version}), freeswitch-mod-bv (= \${binary:Version}), freeswitch-mod-codec2 (= \${binary:Version}), - freeswitch-mod-dahdi-codec (= \${binary:Version}), freeswitch-mod-g723-1 (= \${binary:Version}), freeswitch-mod-g729 (= \${binary:Version}), freeswitch-mod-h26x (= \${binary:Version}), @@ -737,7 +736,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-b64-dbg (= \${binary:Version}), freeswitch-mod-bv-dbg (= \${binary:Version}), freeswitch-mod-codec2-dbg (= \${binary:Version}), - freeswitch-mod-dahdi-codec-dbg (= \${binary:Version}), freeswitch-mod-g723-1-dbg (= \${binary:Version}), freeswitch-mod-g729-dbg (= \${binary:Version}), freeswitch-mod-h26x-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 8e59f8f3ae..afcf1e23e9 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -311,10 +311,6 @@ Module: codecs/mod_com_g729 Description: mod_com_g729 Adds mod_com_g729. -Module: codecs/mod_dahdi_codec -Description: mod_dahdi_codec - Adds mod_dahdi_codec. - Module: codecs/mod_g723_1 Description: mod_g723_1 Adds mod_g723_1. diff --git a/src/mod/codecs/mod_dahdi_codec/Makefile.am b/src/mod/codecs/mod_dahdi_codec/Makefile.am deleted file mode 100644 index d4e3287746..0000000000 --- a/src/mod/codecs/mod_dahdi_codec/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_dahdi_codec - -mod_LTLIBRARIES = mod_dahdi_codec.la -mod_dahdi_codec_la_SOURCES = mod_dahdi_codec.c -mod_dahdi_codec_la_CFLAGS = $(AM_CFLAGS) -mod_dahdi_codec_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_dahdi_codec_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c b/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c deleted file mode 100644 index 6e7f15428c..0000000000 --- a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * 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 - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / DAHDI codec module - * - * The Initial Developer of the Original Code is - * Moises Silva - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Moises Silva - * - * mod_dahdi_codec -- DAHDI Codecs (G729A 8.0kbit, G723.1 5.3kbit) - * - * Thanks to Voiceway for sponsoring this module and Neocenter for providing the DAHDI hardware to test - * - */ - -#include -#include -#include -#include /* __u32 */ -#include -#include -#include -#include - -/* - * some rules to keep in mind for G729 (the frame size may be different for G723) - * we cannot write more than SFRAME_SIZE (320) - sizeof(struct rtp_packet) which - * seems to be 266 bytes - * if we write less than 160 bytes (1 ulaw frame which is 20 bytes of G729 bytes, a read will block forever) - * TODO: do buffering ourselves to provide just the fixed amount of samples that the card expects - * */ -#define DAHDI_G729_INPUT_FRAME_SIZE 160 -#define DAHDI_G729_OUTPUT_FRAME_SIZE 20 - -/*#define DEBUG_DAHDI_CODEC 1*/ - -#define CODEC_G729_IANA_CODE 18 -#define CODEC_G723_IANA_CODE 4 - -switch_mutex_t *transcoder_counter_mutex; -static uint32_t total_encoders = 0; -static uint32_t total_encoders_usage = 0; -static uint32_t total_decoders = 0; -static uint32_t total_decoders_usage = 0; - -/* - Zaptel/DAHDI definitions to not require the headers installed - Zaptel and DAHDI are binary compatible (at least in the transcoder interface) - */ - -#define DAHDI_TC_CODE 'T' -#define DAHDI_TC_ALLOCATE _IOW(DAHDI_TC_CODE, 1, struct dahdi_transcoder_formats) -#define DAHDI_TC_GETINFO _IOWR(DAHDI_TC_CODE, 2, struct dahdi_transcoder_info) - -#define DAHDI_FORMAT_G723_1 (1 << 0) -#define DAHDI_FORMAT_ULAW (1 << 2) -#define DAHDI_FORMAT_SLINEAR (1 << 6) -#define DAHDI_FORMAT_G729A (1 << 8) - -struct dahdi_transcoder_formats { - __u32 srcfmt; - __u32 dstfmt; -}; - -struct dahdi_transcoder_info { - __u32 tcnum; - char name[80]; - __u32 numchannels; - __u32 dstfmts; - __u32 srcfmts; -}; - -static const char transcoding_device_dahdi[] = "/dev/dahdi/transcode"; -static const char transcoder_name_dahdi[] = "DAHDI"; -static const char transcoding_device_zap[] = "/dev/zap/transcode"; -static const char transcoder_name_zap[] = "Zap"; -static const char *transcoding_device = NULL; -static const char *transcoder_name = NULL; - -SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load); -SWITCH_MODULE_DEFINITION(mod_dahdi_codec, mod_dahdi_codec_load, NULL, NULL); - -struct dahdi_context { - int32_t encoding_fd; - int32_t decoding_fd; - uint8_t codec_r; -}; - -static int32_t switch_dahdi_get_transcoder(struct dahdi_transcoder_formats *fmts) -{ - int32_t fdflags; - int32_t fd = open(transcoding_device, O_RDWR); - if (fd < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno)); - return -1; - } - if (ioctl(fd, DAHDI_TC_ALLOCATE, fmts)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to attach to transcoder: %s.\n", strerror(errno)); - close(fd); - return -1; - } - fdflags = fcntl(fd, F_GETFL); - if (fdflags > -1) { - fdflags |= O_NONBLOCK; - if (fcntl(fd, F_SETFL, fdflags)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not set non-block mode in %s transcoder FD: %s\n", - transcoder_name, strerror(errno)); - /* should we abort? this may cause channels to hangup when overruning the device - * see jira dahdi codec issue MODCODEC-8 (Hung Calls and Codec DAHDI G.729A 8.0k decoder error!) - * */ - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not get flags from %s transcoder FD: %s\n", transcoder_name, strerror(errno)); - } - - if (fmts->srcfmt & DAHDI_FORMAT_ULAW) { - switch_mutex_lock(transcoder_counter_mutex); - total_encoders_usage++; - switch_mutex_unlock(transcoder_counter_mutex); - } else { - switch_mutex_lock(transcoder_counter_mutex); - total_decoders_usage++; - switch_mutex_unlock(transcoder_counter_mutex); - } - - return fd; -} - -static switch_status_t init_encoder(switch_codec_t *codec) -{ - struct dahdi_transcoder_formats fmts; - struct dahdi_context *context = codec->private_info; - - fmts.srcfmt = DAHDI_FORMAT_ULAW; - fmts.dstfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE) - ? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1; - context->encoding_fd = switch_dahdi_get_transcoder(&fmts); - if (context->encoding_fd < 0) { -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "encoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt); -#endif - return SWITCH_STATUS_FALSE; - } -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt); -#endif - - - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t init_decoder(switch_codec_t *codec) -{ - struct dahdi_transcoder_formats fmts; - struct dahdi_context *context = codec->private_info; - - fmts.dstfmt = DAHDI_FORMAT_ULAW; - fmts.srcfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE) - ? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1; - context->decoding_fd = switch_dahdi_get_transcoder(&fmts); - if (context->decoding_fd < 0) { -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt); -#endif - return SWITCH_STATUS_FALSE; - } -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt); -#endif - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_dahdi_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - uint32_t encoding, decoding; - struct dahdi_context *context = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI init called.\n"); - - encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); - decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - - if (!(encoding || decoding)) { -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No encoding or decoding requested for DAHDI transcoder?.\n"); -#endif - return SWITCH_STATUS_FALSE; - } - - if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) { -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate memory for dahdi codec context.\n"); -#endif - return SWITCH_STATUS_FALSE; - } - - codec->private_info = context; - context->encoding_fd = -1; - context->decoding_fd = -1; - - /* ulaw requires 8 times more storage than g729 and 12 times more than G723, right? - * this can be used to calculate the target buffer when encoding and decoding - * */ - context->codec_r = (codec->implementation->ianacode == CODEC_G729_IANA_CODE) - ? 8 : 12; - - - return SWITCH_STATUS_SUCCESS; -} - -static int wait_for_transcoder(int fd) -{ - /* let's wait a bit for the transcoder, if in 20msthe driver does not notify us that its ready to give us something - then just bail out with 0 bytes encoded/decoded as result, I'd expect the card to hold that buffer and return it later */ - int res = 0; - struct pollfd readpoll; - memset(&readpoll, 0, sizeof(readpoll)); - readpoll.fd = fd; - readpoll.events = POLLIN; - /* my testing shows that it does not take more than 1ms to encode a 160 bytes frame ulaw to g729, - I dont think there is much difference decoding and for g723, waiting 10ms seems more than reasonable */ - res = poll(&readpoll, 1, 10); - return res; -} - -static switch_status_t switch_dahdi_encode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *decoded_data, - uint32_t decoded_data_len, - uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, - unsigned int *flag) -{ - int32_t res; - short *dbuf_linear; - unsigned char ebuf_ulaw[decoded_data_len / 2]; - uint32_t i; - struct dahdi_context *context = NULL; - switch_status_t status; - -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI encode called to encode %d bytes.\n", decoded_data_len); -#endif - context = codec->private_info; - - if (context->encoding_fd == -1) { - if ((status = init_encoder(codec)) != SWITCH_STATUS_SUCCESS) { - return status; - } - } - - dbuf_linear = decoded_data; - for (i = 0; i < decoded_data_len / sizeof(short); i++) { - ebuf_ulaw[i] = linear_to_ulaw(dbuf_linear[i]); - } -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing %d bytes of decoded ulaw data.\n", i); -#endif - res = write(context->encoding_fd, ebuf_ulaw, i); - if (-1 == res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to %s encoder device.\n", transcoder_name); - return SWITCH_STATUS_FALSE; - } - if (i != res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s encoder device, but only wrote %d bytes.\n", i, - transcoder_name, res); - return SWITCH_STATUS_FALSE; - } - res = wait_for_transcoder(context->encoding_fd); - if (-1 == res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to poll on %s encoder device: %s.\n", transcoder_name, strerror(errno)); - return SWITCH_STATUS_FALSE; - } - if (0 == res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s encoder device.\n", transcoder_name); - *encoded_data_len = 0; - return SWITCH_STATUS_SUCCESS; - } -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read %d bytes of encoded data.\n", *encoded_data_len); -#endif - res = read(context->encoding_fd, encoded_data, *encoded_data_len); - if (-1 == res) { - if (EAGAIN == errno || EWOULDBLOCK == errno) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s encoder device (%s).\n", transcoder_name, strerror(errno)); - *encoded_data_len = 0; - return SWITCH_STATUS_SUCCESS; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from %s encoder device: %s.\n", transcoder_name, strerror(errno)); - return SWITCH_STATUS_FALSE; - } - *encoded_data_len = res; -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read %d bytes of encoded data.\n", res); -#endif - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_dahdi_decode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *encoded_data, - uint32_t encoded_data_len, - uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, - unsigned int *flag) -{ - int32_t res; - short *dbuf_linear; - // we only can decode up to half ulaw bytes of whatever their destiny linear buffer is - unsigned char dbuf_ulaw[*decoded_data_len / 2]; - unsigned char *ebuf_g729; - uint32_t i; - struct dahdi_context *context; - switch_status_t status; - -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode called to decode %d bytes.\n", encoded_data_len); -#endif - - context = codec->private_info; - dbuf_linear = decoded_data; - ebuf_g729 = encoded_data; - - if (context->decoding_fd == -1) { - if ((status = init_decoder(codec)) != SWITCH_STATUS_SUCCESS) { - return status; - } - } - - if (*flag & SWITCH_CODEC_FLAG_SILENCE) { - memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet); - *decoded_data_len = codec->implementation->decoded_bytes_per_packet; -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode in silence returned %d bytes.\n", *decoded_data_len); -#endif - return SWITCH_STATUS_SUCCESS; - } -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing %d bytes to decode.\n", encoded_data_len); -#endif - res = write(context->decoding_fd, ebuf_g729, encoded_data_len); - if (-1 == res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to %s decoder device: %s.\n", transcoder_name, strerror(errno)); - return SWITCH_STATUS_FALSE; - } - if (encoded_data_len != res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s decoder device, but only wrote %d bytes.\n", - encoded_data_len, transcoder_name, res); - return SWITCH_STATUS_FALSE; - } -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read from device %d bytes of decoded ulaw data.\n", sizeof(dbuf_ulaw)); -#endif - res = wait_for_transcoder(context->decoding_fd); - if (-1 == res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to poll on %s decoder device: %s.\n", transcoder_name, strerror(errno)); - return SWITCH_STATUS_FALSE; - } - if (0 == res) { - memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet); - *decoded_data_len = codec->implementation->decoded_bytes_per_packet; -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device, returning silence frame of %d bytes.\n", transcoder_name, - *decoded_data_len); -#endif - return SWITCH_STATUS_SUCCESS; - } - res = read(context->decoding_fd, dbuf_ulaw, sizeof(dbuf_ulaw)); - if (-1 == res) { - if (EAGAIN == errno || EWOULDBLOCK == errno) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device (%s).\n", transcoder_name, strerror(errno)); - *decoded_data_len = 0; - return SWITCH_STATUS_SUCCESS; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from %s decoder device: %s.\n", transcoder_name, strerror(errno)); - return SWITCH_STATUS_FALSE; - } - for (i = 0; i < res; i++) { - dbuf_linear[i] = ulaw_to_linear(dbuf_ulaw[i]); - } - *decoded_data_len = i * 2; -#ifdef DEBUG_DAHDI_CODEC - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode returned %d bytes.\n", *decoded_data_len); -#endif - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_dahdi_destroy(switch_codec_t *codec) -{ - /* memory pool takes care of the private_info memory */ - struct dahdi_context *context = codec->private_info; - if (context->encoding_fd >= 0) { - switch_mutex_lock(transcoder_counter_mutex); - total_encoders_usage--; - switch_mutex_unlock(transcoder_counter_mutex); - close(context->encoding_fd); - } - if (context->decoding_fd >= 0) { - switch_mutex_lock(transcoder_counter_mutex); - total_decoders_usage--; - switch_mutex_unlock(transcoder_counter_mutex); - close(context->decoding_fd); - } - codec->private_info = NULL; - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(dahdi_transcode_usage) -{ - if (!total_encoders && !total_decoders) { - stream->write_function(stream, "No DAHDI transcoding hardware found.\n"); - return SWITCH_STATUS_SUCCESS; - } - switch_mutex_lock(transcoder_counter_mutex); - stream->write_function(stream, "Using %d encoders of a total of %d available.\n", total_encoders_usage, total_encoders); - stream->write_function(stream, "Using %d decoders of a total of %d available.\n", total_decoders_usage, total_decoders); - switch_mutex_unlock(transcoder_counter_mutex); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load) -{ - switch_api_interface_t *api_interface; - switch_codec_interface_t *codec_interface; - struct stat statbuf; - struct dahdi_transcoder_info info = { 0 }; - int32_t fd; - int mpf = 20000; /* Algorithmic delay of 15ms with 5ms of look-ahead delay */ - int spf = 160; - int bpfd = 320; - int bpfc = 20; - int fpnp = 20; - - total_encoders = 0; - total_encoders_usage = 0; - total_decoders = 0; - total_decoders_usage = 0; - - /* Let's check if DAHDI or Zaptel device should be used */ - if (!stat(transcoding_device_dahdi, &statbuf)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DAHDI transcoding device found.\n"); - transcoding_device = transcoding_device_dahdi; - transcoder_name = transcoder_name_dahdi; - } else if (!stat(transcoding_device_zap, &statbuf)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Zap transcoding device found.\n"); - transcoding_device = transcoding_device_zap; - transcoder_name = transcoder_name_zap; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No DAHDI or Zap transcoder device was found in /dev/.\n"); - return SWITCH_STATUS_FALSE; - } - - fd = open(transcoding_device, O_RDWR); - if (fd < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno)); - return SWITCH_STATUS_FALSE; - } - - for (info.tcnum = 0; !ioctl(fd, DAHDI_TC_GETINFO, &info); info.tcnum++) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found dahdi transcoder name: %s\n", info.name); - if ((info.srcfmts & DAHDI_FORMAT_ULAW) && (info.dstfmts & (DAHDI_FORMAT_G729A | DAHDI_FORMAT_G723_1))) { - total_encoders += info.numchannels; - continue; - } - if ((info.dstfmts & DAHDI_FORMAT_ULAW) && (info.srcfmts & (DAHDI_FORMAT_G729A | DAHDI_FORMAT_G723_1))) { - total_decoders += info.numchannels; - continue; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Not using transcoder %s, we just support ULAW and G723.1/G729A", info.name); - } - close(fd); - - if (!total_encoders && !total_decoders) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No DAHDI transcoders found.\n"); - return SWITCH_STATUS_FALSE; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Found %d ULAW to G729A/G723.1 encoders.\n", total_encoders); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Found %d G729A/G723.1 to ULAW decoders.\n", total_decoders); - - switch_mutex_init(&transcoder_counter_mutex, SWITCH_MUTEX_UNNESTED, pool); - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_CODEC(codec_interface, "DAHDI G.729A 8.0k"); /* 8.0kbit */ - - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 18, /* the IANA code number */ - "G729", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 8000, /* samples transferred per second */ - 8000, /* actual samples transferred per second */ - 8000, /* bits transferred per second */ - mpf, /* number of microseconds per frame */ - spf, /* number of samples per frame */ - bpfd, /* number of bytes per frame decompressed */ - bpfc, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - fpnp, /* number of frames per network packet */ - switch_dahdi_init, /* function to initialize a codec handle using this implementation */ - switch_dahdi_encode, /* function to encode raw data into encoded data */ - switch_dahdi_decode, /* function to decode encoded data into raw data */ - switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */ - - mpf = 30000; - spf = 240; - bpfd = 480; - bpfc = 30; - fpnp = 30; - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 18, /* the IANA code number */ - "G729", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 8000, /* samples transferred per second */ - 8000, /* actual samples transferred per second */ - 8000, /* bits transferred per second */ - mpf, /* number of microseconds per frame */ - spf, /* number of samples per frame */ - bpfd, /* number of bytes per frame decompressed */ - bpfc, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - fpnp, /* number of frames per network packet */ - switch_dahdi_init, /* function to initialize a codec handle using this implementation */ - switch_dahdi_encode, /* function to encode raw data into encoded data */ - switch_dahdi_decode, /* function to decode encoded data into raw data */ - switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */ - - SWITCH_ADD_CODEC(codec_interface, "DAHDI G.723.1 5.3k"); /* 5.3kbit */ - mpf = 30000; /* Algorithmic delay of 37.5ms with 7.5ms of look-ahead delay */ - spf = 240; - bpfd = 480; - bpfc = 20; - fpnp = 10; - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 4, /* the IANA code number */ - "G723", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 8000, /* samples transferred per second */ - 8000, /* actual samples transferred per second */ - 8000, /* bits transferred per second */ - mpf, /* number of microseconds per frame */ - spf, /* number of samples per frame */ - bpfd, /* number of bytes per frame decompressed */ - bpfc, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - fpnp, /* number of frames per network packet */ - switch_dahdi_init, /* function to initialize a codec handle using this implementation */ - switch_dahdi_encode, /* function to encode raw data into encoded data */ - switch_dahdi_decode, /* function to decode encoded data into raw data */ - switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */ - - SWITCH_ADD_API(api_interface, "dahdi_transcode", "DAHDI Transcode", dahdi_transcode_usage, NULL); - switch_console_set_complete("add dahdi_transcode"); - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ From 49e63f6fffc6962ecfe762c57aae0c1e5bcc5096 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 28 Aug 2024 20:35:10 +0300 Subject: [PATCH 2/3] [mod_portaudio, mod_portaudio_stream] Remove from tree --- Freeswitch.2017.sln | 29 - LICENSE | 9 - build/modules.conf.in | 2 - build/modules.conf.most | 2 - conf/curl/autoload_configs/portaudio.conf.xml | 33 - .../autoload_configs/modules.conf.xml | 1 - .../autoload_configs/portaudio.conf.xml | 33 - .../vanilla/autoload_configs/modules.conf.xml | 1 - .../autoload_configs/portaudio.conf.xml | 221 -- conf/vanilla/dialplan/default.xml | 10 - configure.ac | 6 - debian/bootstrap.sh | 4 - debian/control-modules | 10 - debian/copyright | 9 - freeswitch.spec | 32 +- libs/.gitignore | 2 - libs/win32/portaudio/portaudio.2017.vcxproj | 859 ----- src/mod/.gitignore | 6 - src/mod/endpoints/mod_portaudio/Makefile.am | 19 - .../conf/autoload_configs/portaudio.conf.xml | 221 -- .../mod_portaudio/mod_PortAudio.2017.vcxproj | 195 - .../endpoints/mod_portaudio/mod_portaudio.c | 3312 ----------------- .../endpoints/mod_portaudio/pa_ringbuffer.c | 275 -- .../endpoints/mod_portaudio/pa_ringbuffer.h | 192 - src/mod/endpoints/mod_portaudio/pablio.c | 442 --- src/mod/endpoints/mod_portaudio/pablio.h | 132 - .../formats/mod_portaudio_stream/Makefile.am | 20 - .../mod_portaudio_stream.c | 615 --- w32/Setup/Setup.2017.wixproj | 8 - w32/Setup/inno_setup/fscomm.iss | 1 - w32/download_portaudio.props | 40 - 31 files changed, 2 insertions(+), 6739 deletions(-) delete mode 100644 conf/curl/autoload_configs/portaudio.conf.xml delete mode 100644 conf/insideout/autoload_configs/portaudio.conf.xml delete mode 100644 conf/vanilla/autoload_configs/portaudio.conf.xml delete mode 100644 libs/win32/portaudio/portaudio.2017.vcxproj delete mode 100644 src/mod/endpoints/mod_portaudio/Makefile.am delete mode 100644 src/mod/endpoints/mod_portaudio/conf/autoload_configs/portaudio.conf.xml delete mode 100644 src/mod/endpoints/mod_portaudio/mod_PortAudio.2017.vcxproj delete mode 100644 src/mod/endpoints/mod_portaudio/mod_portaudio.c delete mode 100644 src/mod/endpoints/mod_portaudio/pa_ringbuffer.c delete mode 100644 src/mod/endpoints/mod_portaudio/pa_ringbuffer.h delete mode 100644 src/mod/endpoints/mod_portaudio/pablio.c delete mode 100644 src/mod/endpoints/mod_portaudio/pablio.h delete mode 100644 src/mod/formats/mod_portaudio_stream/Makefile.am delete mode 100644 src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c delete mode 100644 w32/download_portaudio.props diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index f75602a56f..230732acfb 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -79,7 +79,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "autoload_configs", "autoloa conf\vanilla\autoload_configs\logfile.conf.xml = conf\vanilla\autoload_configs\logfile.conf.xml conf\vanilla\autoload_configs\modules.conf.xml = conf\vanilla\autoload_configs\modules.conf.xml conf\vanilla\autoload_configs\openmrcp.conf.xml = conf\vanilla\autoload_configs\openmrcp.conf.xml - conf\vanilla\autoload_configs\portaudio.conf.xml = conf\vanilla\autoload_configs\portaudio.conf.xml conf\vanilla\autoload_configs\rss.conf.xml = conf\vanilla\autoload_configs\rss.conf.xml conf\vanilla\autoload_configs\sofia.conf.xml = conf\vanilla\autoload_configs\sofia.conf.xml conf\vanilla\autoload_configs\switch.conf.xml = conf\vanilla\autoload_configs\switch.conf.xml @@ -173,8 +172,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_g729", "src\mod\codecs\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_sndfile", "src\mod\formats\mod_sndfile\mod_sndfile.2017.vcxproj", "{AFAC0568-7548-42D5-9F6A-8D3400A1E4F6}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_PortAudio", "src\mod\endpoints\mod_portaudio\mod_PortAudio.2017.vcxproj", "{5FD31A25-5D83-4794-8BEE-904DAD84CE71}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "docs", "docs\docs.2017.vcxproj", "{1A1FF289-4FD6-4285-A422-D31DD67A4723}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_dialplan_xml", "src\mod\dialplans\mod_dialplan_xml\mod_dialplan_xml.2017.vcxproj", "{07113B25-D3AF-4E04-BA77-4CD1171F022C}" @@ -234,8 +231,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_curl", "src\mod\xml EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_en", "src\mod\say\mod_say_en\mod_say_en.2017.vcxproj", "{988CACF7-3FCB-4992-BE69-77872AE67DC8}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portaudio", "libs\win32\portaudio\portaudio.2017.vcxproj", "{0A18A071-125E-442F-AFF7-A3F68ABECF99}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_cdr", "src\mod\xml_int\mod_xml_cdr\mod_xml_cdr.2017.vcxproj", "{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_amr", "src\mod\codecs\mod_amr\mod_amr.2017.vcxproj", "{8DEB383C-4091-4F42-A56F-C9E46D552D79}" @@ -604,17 +599,6 @@ Global {AFAC0568-7548-42D5-9F6A-8D3400A1E4F6}.Release|Win32.Build.0 = Release|Win32 {AFAC0568-7548-42D5-9F6A-8D3400A1E4F6}.Release|x64.ActiveCfg = Release|x64 {AFAC0568-7548-42D5-9F6A-8D3400A1E4F6}.Release|x64.Build.0 = Release|x64 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.All|Win32.ActiveCfg = Release|x64 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.All|x64.ActiveCfg = Release|x64 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.All|x64.Build.0 = Release|x64 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Debug|Win32.ActiveCfg = Debug|Win32 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Debug|Win32.Build.0 = Debug|Win32 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Debug|x64.ActiveCfg = Debug|x64 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Debug|x64.Build.0 = Debug|x64 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Release|Win32.ActiveCfg = Release|Win32 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Release|Win32.Build.0 = Release|Win32 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Release|x64.ActiveCfg = Release|x64 - {5FD31A25-5D83-4794-8BEE-904DAD84CE71}.Release|x64.Build.0 = Release|x64 {1A1FF289-4FD6-4285-A422-D31DD67A4723}.All|Win32.ActiveCfg = Release|Win32 {1A1FF289-4FD6-4285-A422-D31DD67A4723}.All|x64.ActiveCfg = Release|Win32 {1A1FF289-4FD6-4285-A422-D31DD67A4723}.Debug|Win32.ActiveCfg = Debug|Win32 @@ -910,17 +894,6 @@ Global {988CACF7-3FCB-4992-BE69-77872AE67DC8}.Release|Win32.Build.0 = Release|Win32 {988CACF7-3FCB-4992-BE69-77872AE67DC8}.Release|x64.ActiveCfg = Release|x64 {988CACF7-3FCB-4992-BE69-77872AE67DC8}.Release|x64.Build.0 = Release|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|Win32.ActiveCfg = Release DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64.ActiveCfg = Release DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64.Build.0 = Release DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug DirectSound|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug DirectSound|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release DirectSound|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release DirectSound|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release DirectSound|x64 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|Win32.ActiveCfg = Release|x64 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.ActiveCfg = Release|x64 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.Build.0 = Release|x64 @@ -2521,7 +2494,6 @@ Global {3DAF028C-AB5B-4183-A01B-DCC43F5A87F0} = {D4A12E4C-DBDA-4614-BA26-3425AE9F60F5} {1D95CD95-0DE2-48C3-AC23-D5C7D1C9C0F0} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {AFAC0568-7548-42D5-9F6A-8D3400A1E4F6} = {A5A27244-AD24-46E5-B01B-840CD296C91D} - {5FD31A25-5D83-4794-8BEE-904DAD84CE71} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} {1A1FF289-4FD6-4285-A422-D31DD67A4723} = {CBD81696-EFB4-4D2F-8451-1B8DAA86155A} {07113B25-D3AF-4E04-BA77-4CD1171F022C} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4} {EC3E5C7F-EE09-47E2-80FE-546363D14A98} = {B8F5B47B-8568-46EB-B320-64C17D2A98BC} @@ -2550,7 +2522,6 @@ Global {71A967D5-0E99-4CEF-A587-98836EE6F2EF} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78} {AB91A099-7690-4ECF-8994-E458F4EA1ED4} = {F69A4A6B-9360-4EBB-A280-22AA3C455AC5} {988CACF7-3FCB-4992-BE69-77872AE67DC8} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} - {0A18A071-125E-442F-AFF7-A3F68ABECF99} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836} = {F69A4A6B-9360-4EBB-A280-22AA3C455AC5} {8DEB383C-4091-4F42-A56F-C9E46D552D79} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {2C3C2423-234B-4772-8899-D3B137E5CA35} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} diff --git a/LICENSE b/LICENSE index d106a66b4f..c5d335d312 100644 --- a/LICENSE +++ b/LICENSE @@ -1533,15 +1533,6 @@ Files: src/mod/endpoints/mod_skinny/*.p[lm] Copyright: 2010, Mathieu Parent License: Perl -Files: src/mod/endpoints/mod_portaudio/* -Copyright: 1999-2000 Ross Bencina and Phil Burk - 2005-2014, Anthony Minessale II -License: MIT/X11 (BSD like) - -Files: src/mod/endpoints/mod_portaudio/mod_portaudio.c -Copyright: 2005-2014, Anthony Minessale II -License: MPL-1.1 - Files: src/mod/endpoints/mod_sofia/sip-dig.c Copyright: 2006 Nokia Corporation License: LGPL-2.1+ diff --git a/build/modules.conf.in b/build/modules.conf.in index 34266964dc..76f192308c 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -85,7 +85,6 @@ dialplans/mod_dialplan_xml #endpoints/mod_khomp endpoints/mod_loopback #endpoints/mod_opal -#endpoints/mod_portaudio endpoints/mod_rtc #endpoints/mod_rtmp endpoints/mod_skinny @@ -111,7 +110,6 @@ event_handlers/mod_event_socket formats/mod_local_stream formats/mod_native_file formats/mod_png -#formats/mod_portaudio_stream #formats/mod_shell_stream #formats/mod_shout formats/mod_sndfile diff --git a/build/modules.conf.most b/build/modules.conf.most index c25126f5c8..943ff71336 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -83,7 +83,6 @@ directories/mod_ldap #endpoints/mod_khomp endpoints/mod_loopback #endpoints/mod_opal -endpoints/mod_portaudio endpoints/mod_rtc endpoints/mod_rtmp endpoints/mod_skinny @@ -107,7 +106,6 @@ formats/mod_imagick formats/mod_local_stream formats/mod_native_file formats/mod_png -formats/mod_portaudio_stream formats/mod_shell_stream formats/mod_shout formats/mod_sndfile diff --git a/conf/curl/autoload_configs/portaudio.conf.xml b/conf/curl/autoload_configs/portaudio.conf.xml deleted file mode 100644 index 129576acbf..0000000000 --- a/conf/curl/autoload_configs/portaudio.conf.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/insideout/autoload_configs/modules.conf.xml b/conf/insideout/autoload_configs/modules.conf.xml index e54dbfe04f..0e1f60f77d 100755 --- a/conf/insideout/autoload_configs/modules.conf.xml +++ b/conf/insideout/autoload_configs/modules.conf.xml @@ -29,7 +29,6 @@ - diff --git a/conf/insideout/autoload_configs/portaudio.conf.xml b/conf/insideout/autoload_configs/portaudio.conf.xml deleted file mode 100644 index 129576acbf..0000000000 --- a/conf/insideout/autoload_configs/portaudio.conf.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 2bc4376215..20f7fe1c1f 100755 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -36,7 +36,6 @@ - diff --git a/conf/vanilla/autoload_configs/portaudio.conf.xml b/conf/vanilla/autoload_configs/portaudio.conf.xml deleted file mode 100644 index a715571c6f..0000000000 --- a/conf/vanilla/autoload_configs/portaudio.conf.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/vanilla/dialplan/default.xml b/conf/vanilla/dialplan/default.xml index c3edafc1c8..fb999d54ac 100644 --- a/conf/vanilla/dialplan/default.xml +++ b/conf/vanilla/dialplan/default.xml @@ -340,16 +340,6 @@ - - - - - - - diff --git a/configure.ac b/configure.ac index 139ff97358..e56bc72e9d 100755 --- a/configure.ac +++ b/configure.ac @@ -1261,7 +1261,6 @@ case $host in path_push_unique PKG_CONFIG_PATH /usr/local/opt/curl/lib/pkgconfig path_push_unique PKG_CONFIG_PATH /usr/local/opt/sqlite/lib/pkgconfig/ path_push_unique PKG_CONFIG_PATH /usr/local/opt/ldns/lib/pkgconfig/ - path_push_unique PKG_CONFIG_PATH /usr/local/opt/portaudio/lib/pkgconfig/ path_push_unique PKG_CONFIG_PATH /usr/local/opt/ffmpeg/lib/pkgconfig/ ;; esac @@ -1328,9 +1327,6 @@ PKG_CHECK_MODULES([SPEEX], [speex >= 1.2rc1 speexdsp >= 1.2rc1]) PKG_CHECK_MODULES([YAML], [yaml-0.1 >= 0.1.4],[ AM_CONDITIONAL([HAVE_YAML],[true])],[ AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_YAML],[false])]) -PKG_CHECK_MODULES([PORTAUDIO], [portaudio-2.0 >= 19],[ - AM_CONDITIONAL([HAVE_PORTAUDIO],[true])],[ - AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_PORTAUDIO],[false])]) PKG_CHECK_MODULES([LDNS], [libldns-fs >= 1.6.6],[ AM_CONDITIONAL([HAVE_LDNS],[true])],[ PKG_CHECK_MODULES([LDNS], [libldns >= 1.6.6],[ @@ -2182,7 +2178,6 @@ AC_CONFIG_FILES([Makefile src/mod/endpoints/mod_khomp/Makefile src/mod/endpoints/mod_loopback/Makefile src/mod/endpoints/mod_opal/Makefile - src/mod/endpoints/mod_portaudio/Makefile src/mod/endpoints/mod_reference/Makefile src/mod/endpoints/mod_rtmp/Makefile src/mod/endpoints/mod_skinny/Makefile @@ -2217,7 +2212,6 @@ AC_CONFIG_FILES([Makefile src/mod/formats/mod_sndfile/Makefile src/mod/formats/mod_tone_stream/Makefile src/mod/formats/mod_vlc/Makefile - src/mod/formats/mod_portaudio_stream/Makefile src/mod/languages/mod_java/Makefile src/mod/languages/mod_lua/Makefile src/mod/languages/mod_managed/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 37cc2fe0c3..d3a00c7071 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -658,7 +658,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-dialplan-directory (= \${binary:Version}), freeswitch-mod-dialplan-xml (= \${binary:Version}), freeswitch-mod-loopback (= \${binary:Version}), - freeswitch-mod-portaudio (= \${binary:Version}), freeswitch-mod-rtc (= \${binary:Version}), freeswitch-mod-rtmp (= \${binary:Version}), freeswitch-mod-skinny (= \${binary:Version}), @@ -674,7 +673,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-snmp (= \${binary:Version}), freeswitch-mod-local-stream (= \${binary:Version}), freeswitch-mod-native-file (= \${binary:Version}), - freeswitch-mod-portaudio-stream (= \${binary:Version}), freeswitch-mod-shell-stream (= \${binary:Version}), freeswitch-mod-sndfile (= \${binary:Version}), freeswitch-mod-tone-stream (= \${binary:Version}), @@ -892,7 +890,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-dialplan-directory-dbg (= \${binary:Version}), freeswitch-mod-dialplan-xml-dbg (= \${binary:Version}), freeswitch-mod-loopback-dbg (= \${binary:Version}), - freeswitch-mod-portaudio-dbg (= \${binary:Version}), freeswitch-mod-rtc-dbg (= \${binary:Version}), freeswitch-mod-rtmp-dbg (= \${binary:Version}), freeswitch-mod-skinny-dbg (= \${binary:Version}), @@ -908,7 +905,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-snmp-dbg (= \${binary:Version}), freeswitch-mod-local-stream-dbg (= \${binary:Version}), freeswitch-mod-native-file-dbg (= \${binary:Version}), - freeswitch-mod-portaudio-stream-dbg (= \${binary:Version}), freeswitch-mod-shell-stream-dbg (= \${binary:Version}), freeswitch-mod-sndfile-dbg (= \${binary:Version}), freeswitch-mod-tone-stream-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index afcf1e23e9..b11dc10005 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -427,11 +427,6 @@ Description: mod_opal Adds mod_opal. Build-Depends: libopal-dev -Module: endpoints/mod_portaudio -Description: mod_portaudio - Adds mod_portaudio. -Build-Depends: portaudio19-dev - Module: endpoints/mod_reference Description: mod_reference Adds mod_reference. @@ -554,11 +549,6 @@ Module: formats/mod_png Description: Adds mod_png Adds mod_png. -Module: formats/mod_portaudio_stream -Description: mod_portaudio_stream - Adds mod_portaudio_stream. -Build-Depends: portaudio19-dev - Module: formats/mod_shell_stream Description: mod_shell_stream Adds mod_shell_stream. diff --git a/debian/copyright b/debian/copyright index 18b2f92ddc..0165760810 100755 --- a/debian/copyright +++ b/debian/copyright @@ -1533,15 +1533,6 @@ Files: src/mod/endpoints/mod_skinny/*.p[lm] Copyright: 2010, Mathieu Parent License: Perl -Files: src/mod/endpoints/mod_portaudio/* -Copyright: 1999-2000 Ross Bencina and Phil Burk - 2005-2014, Anthony Minessale II -License: MIT/X11 (BSD like) - -Files: src/mod/endpoints/mod_portaudio/mod_portaudio.c -Copyright: 2005-2014, Anthony Minessale II -License: MPL-1.1 - Files: src/mod/endpoints/mod_sofia/sip-dig.c Copyright: 2006 Nokia Corporation License: LGPL-2.1+ diff --git a/freeswitch.spec b/freeswitch.spec index aa897fd9a9..773b8784c7 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -827,17 +827,6 @@ PostgreSQL native support for FreeSWITCH. #%description endpoint-khomp #Khomp hardware endpoint support for FreeSWITCH open source telephony platform. -%package endpoint-portaudio -Summary: PortAudio endpoint support for FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} -Requires: alsa-lib -BuildRequires: alsa-lib-devel -BuildRequires: portaudio-devel - -%description endpoint-portaudio -PortAudio endpoint support for FreeSWITCH open source telephony platform. - %package endpoint-rtmp Summary: RTPM Endpoint support for FreeSWITCH open source telephony platform Group: System/Libraries @@ -1001,15 +990,6 @@ transcoding is necessary. The default FreeSWITCH sound files are in wav format. Generally, these require transcoding when being played to callers. However, if a native format sound file is available then FreeSWITCH can use it. -%package format-portaudio-stream -Summary: PortAudio Media Steam support for the FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} -BuildRequires: portaudio-devel - -%description format-portaudio-stream -Portaudio Streaming interface Audio for FreeSWITCH - %package format-shell-stream Summary: Implements Media Steaming from arbitrary shell commands for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1288,7 +1268,6 @@ Requires: freeswitch-codec-siren Requires: freeswitch-database-pgsql Requires: freeswitch-format-local-stream Requires: freeswitch-format-native-file -Requires: freeswitch-format-portaudio-stream Requires: freeswitch-format-tone-stream Requires: freeswitch-lang-en @@ -1403,7 +1382,7 @@ DIRECTORIES_MODULES="" # ###################################################################################################################### ENDPOINTS_MODULES=" \ - endpoints/mod_loopback endpoints/mod_portaudio endpoints/mod_rtmp \ + endpoints/mod_loopback endpoints/mod_rtmp \ endpoints/mod_skinny endpoints/mod_verto endpoints/mod_rtc endpoints/mod_sofia" ## DISABLED MODULES DUE TO BUILD ISSUES endpoints/mod_h323 endpoints/mod_khomp @@ -1424,7 +1403,7 @@ EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv # File and Audio Format Handlers # ###################################################################################################################### -FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_opusfile formats/mod_portaudio_stream \ +FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_opusfile \ formats/mod_shell_stream formats/mod_shout formats/mod_sndfile formats/mod_tone_stream" ###################################################################################################################### @@ -1845,7 +1824,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/oreka.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/osp.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/pocketsphinx.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/portaudio.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/post_load_modules.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/pre_load_modules.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/presence_map.conf.xml @@ -2146,9 +2124,6 @@ fi #%files endpoint-khomp #%{MODINSTDIR}/mod_khomp.so* -%files endpoint-portaudio -%{MODINSTDIR}/mod_portaudio.so* - %files endpoint-rtmp %{MODINSTDIR}/mod_rtmp.so* @@ -2213,9 +2188,6 @@ fi %files format-opusfile %{MODINSTDIR}/mod_opusfile.so* -%files format-portaudio-stream -%{MODINSTDIR}/mod_portaudio_stream.so* - %files format-shell-stream %{MODINSTDIR}/mod_shell_stream.so* diff --git a/libs/.gitignore b/libs/.gitignore index 77e312f88b..d4d419affc 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -592,8 +592,6 @@ srtp/build/compile /sqlite-*/ /sqlite/ /ldns/ -/portaudio/ -portaudio.*.log apr/configure libyuv/Makefile libyuv/convert diff --git a/libs/win32/portaudio/portaudio.2017.vcxproj b/libs/win32/portaudio/portaudio.2017.vcxproj deleted file mode 100644 index 05445a6ee9..0000000000 --- a/libs/win32/portaudio/portaudio.2017.vcxproj +++ /dev/null @@ -1,859 +0,0 @@ - - - - - Debug DirectSound - Win32 - - - Debug DirectSound - x64 - - - Debug - Win32 - - - Debug - x64 - - - Release DirectSound - Win32 - - - Release DirectSound - x64 - - - Release - Win32 - - - Release - x64 - - - - portaudio - {0A18A071-125E-442F-AFF7-A3F68ABECF99} - portaudio - - - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - StaticLibrary - false - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - - - Disabled - Default - ..\..\portaudio\src\common;..\..\portaudio\include;.\;..\..\portaudio\src\os\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_DS;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\portaudio\src\common;..\..\portaudio\include;.\;..\..\portaudio\src\os\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_DS;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - - - Disabled - ..\..\portaudio\src\common;..\..\portaudio\include;.\;..\..\portaudio\src\os\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_DS;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - X64 - - - Disabled - ..\..\portaudio\src\common;..\..\portaudio\include;.\;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_DS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - - - Disabled - ..\..\portaudio\src\common;..\..\portaudio\include;.\;..\..\portaudio\src\os\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_USE_DS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - X64 - - - Disabled - ..\..\portaudio\src\common;..\..\portaudio\include;.\;..\..\portaudio\src\os\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_USE_DS;PAWIN_USE_WDMKS_DEVICE_INFO;PAWIN_WDMKS_NO_KSGUID_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - - - MaxSpeed - Default - ..\..\portaudio\src\common;..\..\portaudio\include;.\;..\..\portaudio\src\os\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_USE_DS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - X64 - - - MaxSpeed - Default - ..\..\portaudio\src\common;..\..\portaudio\include;.\;..\..\portaudio\src\os\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_USE_DS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Level3 - true - 4996;4312;4267;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - ..\..\portaudio\src\hostapi\asio\ASIOSDK\host;..\..\portaudio\src\hostapi\asio\ASIOSDK\host\pc;..\..\portaudio\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - \ No newline at end of file diff --git a/src/mod/.gitignore b/src/mod/.gitignore index 7284fb6176..47f1a92e0b 100644 --- a/src/mod/.gitignore +++ b/src/mod/.gitignore @@ -33,9 +33,6 @@ /codecs/mod_vp8/Makefile /dialplans/mod_dialplan_asterisk/Makefile /dialplans/mod_dialplan_xml/Makefile -/endpoints/mod_portaudio/Makefile -/endpoints/mod_portaudio/Makefile.in -/endpoints/mod_portaudio/mod_portaudio.log /endpoints/mod_skinny/Makefile /endpoints/mod_skinny/Makefile.in /endpoints/mod_skinny/mod_skinny.log @@ -45,9 +42,6 @@ /event_handlers/mod_erlang_event/Makefile /event_handlers/mod_event_socket/Makefile /formats/mod_native_file/Makefile -/formats/mod_portaudio_stream/Makefile -/formats/mod_portaudio_stream/Makefile.in -/formats/mod_portaudio_stream/mod_portaudio_stream.log /formats/mod_tone_stream/Makefile /languages/mod_java/Makefile /languages/mod_java/classes/ diff --git a/src/mod/endpoints/mod_portaudio/Makefile.am b/src/mod/endpoints/mod_portaudio/Makefile.am deleted file mode 100644 index 06ba6f6c92..0000000000 --- a/src/mod/endpoints/mod_portaudio/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_portaudio - -if HAVE_PORTAUDIO -mod_LTLIBRARIES = mod_portaudio.la -mod_portaudio_la_SOURCES = mod_portaudio.c pablio.c pa_ringbuffer.c -mod_portaudio_la_CFLAGS = $(AM_CFLAGS) -mod_portaudio_la_CPPFLAGS = -I. $(PORTAUDIO_CFLAGS) $(AM_CPPFLAGS) -mod_portaudio_la_LIBADD = $(PORTAUDIO_LIBS) $(switch_builddir)/libfreeswitch.la -mod_portaudio_la_LDFLAGS = -avoid-version -module -no-undefined -shared -if ISMAC -mod_portaudio_la_LDFLAGS += -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon -endif -else -install: error -all: error -error: - $(error You must install portaudio19-dev to build $(MODNAME)) -endif diff --git a/src/mod/endpoints/mod_portaudio/conf/autoload_configs/portaudio.conf.xml b/src/mod/endpoints/mod_portaudio/conf/autoload_configs/portaudio.conf.xml deleted file mode 100644 index b11725a2dc..0000000000 --- a/src/mod/endpoints/mod_portaudio/conf/autoload_configs/portaudio.conf.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/endpoints/mod_portaudio/mod_PortAudio.2017.vcxproj b/src/mod/endpoints/mod_portaudio/mod_PortAudio.2017.vcxproj deleted file mode 100644 index 42d6ceeb55..0000000000 --- a/src/mod/endpoints/mod_portaudio/mod_PortAudio.2017.vcxproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mod_PortAudio - {5FD31A25-5D83-4794-8BEE-904DAD84CE71} - mod_PortAudio - Win32Proj - - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - NativeMinimumRules.ruleset - false - - - NativeMinimumRules.ruleset - false - - - NativeMinimumRules.ruleset - false - - - NativeMinimumRules.ruleset - false - - - - %(RootDir)%(Directory)..\..\..\..\libs\portaudio\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;ALLOW_SMP_DANGERS;%(PreprocessorDefinitions) - - - 4100;4101;%(DisableSpecificWarnings) - false - - - /NODEFAULTLIB:LIMBCTD %(AdditionalOptions) - ksuser.lib;%(AdditionalDependencies) - $(ProjectDir)..\..\..\..\libs\portaudio\winvc\Lib;%(AdditionalLibraryDirectories) - false - - - - - - - X64 - - - %(RootDir)%(Directory)..\..\..\..\libs\portaudio\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;ALLOW_SMP_DANGERS;%(PreprocessorDefinitions) - - - 4100;4101;%(DisableSpecificWarnings) - false - - - /NODEFAULTLIB:LIMBCTD %(AdditionalOptions) - ksuser.lib;%(AdditionalDependencies) - $(ProjectDir)..\..\..\..\libs\portaudio\winvc\Lib;%(AdditionalLibraryDirectories) - false - - - MachineX64 - - - - - %(RootDir)%(Directory)..\..\..\..\libs\portaudio\include;%(AdditionalIncludeDirectories) - ALLOW_SMP_DANGERS;%(PreprocessorDefinitions) - - - 4100;4101;%(DisableSpecificWarnings) - false - - - ksuser.lib;%(AdditionalDependencies) - $(ProjectDir)..\..\..\..\libs\portaudio\winvc\Lib;%(AdditionalLibraryDirectories) - false - - - - - - - X64 - - - %(RootDir)%(Directory)..\..\..\..\libs\portaudio\include;%(AdditionalIncludeDirectories) - ALLOW_SMP_DANGERS;%(PreprocessorDefinitions) - - - 4100;4101;%(DisableSpecificWarnings) - false - - - ksuser.lib;%(AdditionalDependencies) - $(ProjectDir)..\..\..\..\libs\portaudio\winvc\Lib;%(AdditionalLibraryDirectories) - false - - - MachineX64 - - - - - 6011;4100;4101;%(DisableSpecificWarnings) - 6011;4100;4101;%(DisableSpecificWarnings) - 6011;4100;4101;%(DisableSpecificWarnings) - 6011;4100;4101;%(DisableSpecificWarnings) - - - - - - - - - - - {f6c55d93-b927-4483-bb69-15aef3dd2dff} - false - - - {0a18a071-125e-442f-aff7-a3f68abecf99} - - - {202d7a4e-760d-4d0e-afa1-d7459ced30ff} - false - - - - - - \ No newline at end of file diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c deleted file mode 100644 index acd578e2e2..0000000000 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ /dev/null @@ -1,3312 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * 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 ` - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Moises Silva (Multiple endpoints work sponsored by Comrex Corporation) - * Raymond Chandler - * - * - * mod_portaudio.c -- PortAudio Endpoint Module - * - */ - -#include "switch.h" - -#include -#include -#include -#include -#include "pablio.h" - -#define MY_EVENT_RINGING "portaudio::ringing" -#define MY_EVENT_MAKE_CALL "portaudio::makecall" -#define MY_EVENT_CALL_HELD "portaudio::callheld" -#define MY_EVENT_CALL_RESUMED "portaudio::callresumed" -#define MY_EVENT_ERROR_AUDIO_DEV "portaudio::audio_dev_error" -#define SWITCH_PA_CALL_ID_VARIABLE "pa_call_id" - -#define MIN_STREAM_SAMPLE_RATE 8000 -#define STREAM_SAMPLES_PER_PACKET(stream) ((stream->codec_ms * stream->sample_rate) / 1000) - -SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown); -//SWITCH_MODULE_RUNTIME_FUNCTION(mod_portaudio_runtime); -SWITCH_MODULE_DEFINITION(mod_portaudio, mod_portaudio_load, mod_portaudio_shutdown, NULL); - -static switch_memory_pool_t *module_pool = NULL; -switch_endpoint_interface_t *portaudio_endpoint_interface; - -#define SAMPLE_TYPE paInt16 -typedef int16_t SAMPLE; - -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) -} GFLAGS; - -typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_DTMF = (1 << 3), - TFLAG_VOICE = (1 << 4), - TFLAG_HANGUP = (1 << 5), - TFLAG_LINEAR = (1 << 6), - TFLAG_ANSWER = (1 << 7), - TFLAG_HUP = (1 << 8), - TFLAG_MASTER = (1 << 9), - TFLAG_AUTO_ANSWER = (1 << 10) -} TFLAGS; - -struct audio_stream { - int indev; - int outdev; - PABLIO_Stream *stream; - switch_timer_t write_timer; - struct audio_stream *next; -}; -typedef struct audio_stream audio_stream_t; - -/* Audio stream that can be shared across endpoints */ -typedef struct _shared_audio_stream_t { - /*! Friendly name for this stream */ - char name[255]; - /*! Sampling rate */ - int sample_rate; - /*! Buffer packetization (and therefore timing) */ - int codec_ms; - /*! The PA input device */ - int indev; - /*! Input channels being used */ - uint8_t inchan_used[MAX_IO_CHANNELS]; - /*! The PA output device */ - int outdev; - /*! Output channels being used */ - uint8_t outchan_used[MAX_IO_CHANNELS]; - /*! How many channels to create (for both indev and outdev) */ - int channels; - /*! The io stream helper to buffer audio */ - PABLIO_Stream *stream; - /* It can be shared after all :-) */ - switch_mutex_t *mutex; -} shared_audio_stream_t; - -typedef struct private_object private_t; -/* Endpoint that can be called via portaudio/endpoint/ */ -typedef struct _audio_endpoint { - /*! Friendly name for this endpoint */ - char name[255]; - - /*! Input stream for this endpoint */ - shared_audio_stream_t *in_stream; - - /*! Output stream for this endpoint */ - shared_audio_stream_t *out_stream; - - /*! Channel index within the input stream where we get the audio for this endpoint */ - int inchan; - - /*! Channel index within the output stream where we get the audio for this endpoint */ - int outchan; - - /*! Associated private information if involved in a call */ - private_t *master; - - /*! For timed read and writes */ - switch_timer_t read_timer; - switch_timer_t write_timer; - - /* We need our own read frame */ - switch_frame_t read_frame; - unsigned char read_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - - /* Needed codecs for the core to read/write in the proper format */ - switch_codec_t read_codec; - switch_codec_t write_codec; - - /*! Let's be safe */ - switch_mutex_t *mutex; -} audio_endpoint_t; - -struct private_object { - unsigned int flags; - switch_core_session_t *session; - switch_caller_profile_t *caller_profile; - char call_id[50]; - int sample_rate; - int codec_ms; - switch_mutex_t *flag_mutex; - char *hold_file; - switch_file_handle_t fh; - switch_file_handle_t *hfh; - switch_frame_t hold_frame; - unsigned char holdbuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - audio_endpoint_t *audio_endpoint; - struct private_object *next; -}; - - -static struct { - int debug; - int port; - char *cid_name; - char *cid_num; - char *dialplan; - char *context; - char *ring_file; - char *hold_file; - char *timer_name; - int ringdev; - int indev; - int outdev; - int call_id; - int unload_device_fail; - switch_hash_t *call_hash; - switch_mutex_t *device_lock; - switch_mutex_t *pvt_lock; - switch_mutex_t *streams_lock; - switch_mutex_t *flag_mutex; - switch_mutex_t *pa_mutex; - int sample_rate; - int codec_ms; - audio_stream_t *main_stream; - audio_stream_t *ring_stream; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_frame_t read_frame; - switch_frame_t cng_frame; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - unsigned char cngbuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - private_t *call_list; - audio_stream_t *stream_list; - /*! Streams that can be used by multiple endpoints at the same time */ - switch_hash_t *sh_streams; - /*! Endpoints configured */ - switch_hash_t *endpoints; - int ring_interval; - GFLAGS flags; - switch_timer_t read_timer; - switch_timer_t readfile_timer; - switch_timer_t hold_timer; - int dual_streams; - time_t deactivate_timer; - int live_stream_switch; - int no_auto_resume_call; - int no_ring_during_call; - int codecs_inited; - int stream_in_use; //only really used by playdev - int destroying_streams; -} globals; - - -#define PA_MASTER 1 -#define PA_SLAVE 0 - - -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context); -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_destroy(switch_core_session_t *session); -static switch_status_t channel_on_routing(switch_core_session_t *session); -static switch_status_t channel_on_exchange_media(switch_core_session_t *session); -static switch_status_t channel_on_soft_execute(switch_core_session_t *session); -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause); -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, 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 create_codecs(int restart); -static void create_hold_event(private_t *tech_pvt, int unhold); -static audio_stream_t * find_audio_stream(int indev, int outdev, int already_locked); -static audio_stream_t * get_audio_stream(int indev, int outdev); -static audio_stream_t * create_audio_stream(int indev, int outdev); -PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters); -static switch_status_t switch_audio_stream(); -static void add_stream(audio_stream_t *stream, int already_locked); -static void remove_stream(audio_stream_t *stream, int already_locked); -static switch_status_t destroy_audio_stream(int indev, int outdev); -static switch_status_t destroy_actual_stream(audio_stream_t *stream); -static void destroy_audio_streams(); -static switch_status_t validate_main_audio_stream(); -static switch_status_t validate_ring_audio_stream(); - -static int dump_info(int verbose); -static switch_status_t load_config(void); -static int get_dev_by_name(char *name, int in); -static int get_dev_by_number(char *numstr, int in); -SWITCH_STANDARD_API(pa_cmd); - -/* - 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) -{ - switch_channel_t *channel; - - if (session) { - if ((channel = switch_core_session_get_channel(session))) { - switch_channel_set_flag(channel, CF_AUDIO); - } - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_routing(switch_core_session_t *session) -{ - - switch_channel_t *channel = switch_core_session_get_channel(session); - private_t *tech_pvt = switch_core_session_get_private(session); - switch_time_t last; - int waitsec = globals.ring_interval * 1000000; - switch_file_handle_t fh = { 0 }; - const char *val, *ring_file = NULL, *hold_file = NULL; - int16_t abuf[2048]; - - switch_assert(tech_pvt != NULL); - - last = switch_micro_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 (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - if (!tech_pvt->audio_endpoint && validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) { - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_STATUS_FALSE; - } - - if (!tech_pvt->audio_endpoint && - switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && - !switch_test_flag(tech_pvt, TFLAG_AUTO_ANSWER)) { - - 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->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - - if (validate_ring_audio_stream() != SWITCH_STATUS_SUCCESS) { - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Ring Error!\n"); - switch_core_file_close(&fh); - return SWITCH_STATUS_GENERR; - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot open %s, disabling ring file!\n", ring_file); - ring_file = NULL; - } - } - } - - if (tech_pvt->audio_endpoint || switch_test_flag(tech_pvt, TFLAG_AUTO_ANSWER)) { - switch_mutex_lock(globals.pvt_lock); - add_pvt(tech_pvt, PA_MASTER); - if (switch_test_flag(tech_pvt, TFLAG_AUTO_ANSWER)) { - switch_channel_mark_answered(channel); - switch_set_flag(tech_pvt, TFLAG_ANSWER); - } - switch_mutex_unlock(globals.pvt_lock); - switch_yield(1000000); - } else { - switch_channel_mark_ring_ready(channel); - } - - while (switch_channel_get_state(channel) == CS_ROUTING && - !switch_channel_test_flag(channel, CF_ANSWERED) && - !switch_test_flag(tech_pvt, TFLAG_ANSWER)) { - switch_size_t olen = globals.readfile_timer.samples; - - if (switch_micro_time_now() - last >= waitsec) { - char buf[512]; - switch_event_t *event; - - switch_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) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_info", buf); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id); /* left behind for backwards compatability */ - switch_channel_set_variable(channel, SWITCH_PA_CALL_ID_VARIABLE, tech_pvt->call_id); - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s\n", buf); - last = switch_micro_time_now(); - } - - if (ring_file) { - if (switch_core_timer_next(&globals.readfile_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 && (! switch_test_flag(globals.call_list, TFLAG_MASTER) || - ( !globals.no_ring_during_call && globals.main_stream != globals.ring_stream)) ) { //if there is a ring stream and not an active call or if there is an active call and we are allowed to ring during it AND the ring stream is not the main stream - WriteAudioStream(globals.ring_stream->stream, abuf, (long) olen, 0, &globals.ring_stream->write_timer); - } - } else { - switch_yield(10000); - } - } - switch_clear_flag_locked((&globals), GFLAG_RING); - } - - if (ring_file) { - switch_core_file_close(&fh); - } - - if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - if (!switch_test_flag(tech_pvt, TFLAG_ANSWER) && - !switch_channel_test_flag(channel, CF_ANSWERED)) { - switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER); - return SWITCH_STATUS_SUCCESS; - } - switch_set_flag(tech_pvt, TFLAG_ANSWER); - } - - switch_set_flag_locked(tech_pvt, TFLAG_IO); - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", - switch_channel_get_name(switch_core_session_get_channel(session))); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_execute(switch_core_session_t *session) -{ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", - switch_channel_get_name(switch_core_session_get_channel(session))); - return SWITCH_STATUS_SUCCESS; -} - -static audio_stream_t* find_audio_stream(int indev, int outdev, int already_locked) -{ - audio_stream_t *cur_stream; - - if (! globals.stream_list) { - return NULL; - } - - if (! already_locked) { - switch_mutex_lock(globals.streams_lock); - } - cur_stream = globals.stream_list; - - while (cur_stream != NULL) { - if (cur_stream->outdev == outdev) { - if (indev == -1 || cur_stream->indev == indev) { - if (! already_locked) { - switch_mutex_unlock(globals.streams_lock); - } - return cur_stream; - } - } - cur_stream = cur_stream->next; - } - if (! already_locked) { - switch_mutex_unlock(globals.streams_lock); - } - return NULL; -} - -static void destroy_audio_streams() -{ - int close_wait = 4; - globals.destroying_streams = 1; - - while (globals.stream_in_use && close_wait--) { - switch_yield(250000); - } - while (globals.stream_list != NULL) { - destroy_audio_stream(globals.stream_list->indev, globals.stream_list->outdev); - } - globals.destroying_streams = 0; -} - -static switch_status_t validate_main_audio_stream() -{ - if (globals.read_timer.timer_interface) { - switch_core_timer_sync(&globals.read_timer); - } - - if (globals.main_stream) { - if (globals.main_stream->write_timer.timer_interface) { - switch_core_timer_sync(&(globals.main_stream->write_timer)); - } - - return SWITCH_STATUS_SUCCESS; - } - - globals.main_stream = get_audio_stream(globals.indev, globals.outdev); - - if (globals.main_stream) { - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_FALSE; -} - -static switch_status_t validate_ring_audio_stream() -{ - if (globals.ringdev == -1) { - return SWITCH_STATUS_SUCCESS; - } - if (globals.ring_stream) { - if (globals.ring_stream->write_timer.timer_interface) { - switch_core_timer_sync(&(globals.ring_stream->write_timer)); - } - return SWITCH_STATUS_SUCCESS; - } - globals.ring_stream = get_audio_stream(-1, globals.ringdev); - if (globals.ring_stream) { - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_FALSE; -} - -static switch_status_t destroy_actual_stream(audio_stream_t *stream) -{ - if (stream == NULL) { - return SWITCH_STATUS_FALSE; - } - - if (globals.main_stream == stream) { - globals.main_stream = NULL; - } - - if (globals.ring_stream == stream) { - globals.ring_stream = NULL; - } - - CloseAudioStream(stream->stream); - stream->stream = NULL; - - if (stream->write_timer.timer_interface) { - switch_core_timer_destroy(&stream->write_timer); - } - - switch_safe_free(stream); - return SWITCH_STATUS_SUCCESS; -} -static switch_status_t destroy_audio_stream(int indev, int outdev) -{ - audio_stream_t *stream; - - switch_mutex_lock(globals.streams_lock); - stream = find_audio_stream(indev, outdev,1); - if (stream == NULL) { - switch_mutex_unlock(globals.streams_lock); - return SWITCH_STATUS_FALSE; - } - - remove_stream(stream, 1); - switch_mutex_unlock(globals.streams_lock); - - destroy_actual_stream(stream); - return SWITCH_STATUS_SUCCESS; -} - - -static void destroy_codecs(void) -{ - - if (switch_core_codec_ready(&globals.read_codec)) { - switch_core_codec_destroy(&globals.read_codec); - } - - if (switch_core_codec_ready(&globals.write_codec)) { - switch_core_codec_destroy(&globals.write_codec); - } - - if (globals.read_timer.timer_interface) { - switch_core_timer_destroy(&globals.read_timer); - } - - if (globals.readfile_timer.timer_interface) { - switch_core_timer_destroy(&globals.readfile_timer); - } - - if (globals.hold_timer.timer_interface) { - switch_core_timer_destroy(&globals.hold_timer); - } - - globals.codecs_inited = 0; -} - -static void create_hold_event(private_t *tech_pvt, int unhold) -{ - switch_event_t *event; - char * event_id; - - if (unhold) { - event_id = MY_EVENT_CALL_RESUMED; - } else { - event_id = MY_EVENT_CALL_HELD; - } - - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, event_id) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(switch_core_session_get_channel(tech_pvt->session), event); - switch_event_fire(&event); - } -} - -static void add_stream(audio_stream_t * stream, int already_locked) -{ - audio_stream_t *last; - - if (! already_locked) { - switch_mutex_lock(globals.streams_lock); - } - for (last = globals.stream_list; last && last->next; last = last->next); - if (last == NULL) { - globals.stream_list = stream; - } else { - last->next = stream; - } - if (! already_locked) { - switch_mutex_unlock(globals.streams_lock); - } -} -static void remove_stream(audio_stream_t * stream, int already_locked) -{ - audio_stream_t *previous; - if (! already_locked) { - switch_mutex_lock(globals.streams_lock); - } - if (globals.stream_list == stream) { - globals.stream_list = stream->next; - } else { - for (previous = globals.stream_list; previous && previous->next && previous->next != stream; previous = previous->next) { - ; - } - if (previous) { - previous->next = stream->next; - } - } - if (! already_locked) { - switch_mutex_unlock(globals.streams_lock); - } -} - -static void add_pvt(private_t *tech_pvt, int master) -{ - private_t *tp; - uint8_t in_list = 0; - - switch_mutex_lock(globals.pvt_lock); - - if (*tech_pvt->call_id == '\0') { - switch_mutex_lock(globals.pa_mutex); - switch_snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id); - switch_channel_set_variable(switch_core_session_get_channel(tech_pvt->session), SWITCH_PA_CALL_ID_VARIABLE, tech_pvt->call_id); - switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt); - if (!tech_pvt->audio_endpoint) { - switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec); - switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec); - } - switch_mutex_unlock(globals.pa_mutex); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Added call %s\n", tech_pvt->call_id); - } - - for (tp = globals.call_list; tp; tp = tp->next) { - if (tp == tech_pvt) { - in_list = 1; - } - if (master && switch_test_flag(tp, TFLAG_MASTER) ) { - switch_clear_flag_locked(tp, TFLAG_MASTER); - create_hold_event(tp, 0); - } - } - - - 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) -{ - private_t *tp, *last = NULL; - int was_master = 0; - - switch_mutex_lock(globals.pvt_lock); - for (tp = globals.call_list; tp; tp = tp->next) { - - if (tp == tech_pvt) { - if (switch_test_flag(tp, TFLAG_MASTER)) { - switch_clear_flag_locked(tp, TFLAG_MASTER); - was_master = 1; - } - if (last) { - last->next = tp->next; - } else { - globals.call_list = tp->next; - } - } - last = tp; - } - - if (globals.call_list) { - if (was_master && ! globals.no_auto_resume_call) { - switch_set_flag_locked(globals.call_list, TFLAG_MASTER); - create_hold_event(globals.call_list, 1); - } - } else { - globals.deactivate_timer = switch_epoch_time_now(NULL) + 2; - destroy_audio_streams(); - } - - switch_mutex_unlock(globals.pvt_lock); -} - -static void tech_close_file(private_t *tech_pvt) -{ - if (tech_pvt->hfh) { - tech_pvt->hfh = NULL; - switch_core_file_close(&tech_pvt->fh); - } -} - -static switch_status_t channel_on_destroy(switch_core_session_t *session) -{ - //private_t *tech_pvt = switch_core_session_get_private(session); - //switch_assert(tech_pvt != NULL); - return SWITCH_STATUS_SUCCESS; -} - -static int release_stream_channel(shared_audio_stream_t *stream, int index, int input); -static switch_status_t channel_on_hangup(switch_core_session_t *session) -{ - private_t *tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - if (tech_pvt->audio_endpoint) { - audio_endpoint_t *endpoint = tech_pvt->audio_endpoint; - - tech_pvt->audio_endpoint = NULL; - - switch_mutex_lock(endpoint->mutex); - - release_stream_channel(endpoint->in_stream, endpoint->inchan, 1); - release_stream_channel(endpoint->out_stream, endpoint->outchan, 0); - switch_core_timer_destroy(&endpoint->read_timer); - switch_core_timer_destroy(&endpoint->write_timer); - switch_core_codec_destroy(&endpoint->read_codec); - switch_core_codec_destroy(&endpoint->write_codec); - endpoint->master = NULL; - - switch_mutex_unlock(endpoint->mutex); - } - - switch_mutex_lock(globals.pa_mutex); - switch_core_hash_delete(globals.call_hash, tech_pvt->call_id); - switch_mutex_unlock(globals.pa_mutex); - - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - switch_set_flag_locked(tech_pvt, TFLAG_HUP); - - remove_pvt(tech_pvt); - - tech_close_file(tech_pvt); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", - switch_channel_get_name(switch_core_session_get_channel(session))); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - private_t *tech_pvt = switch_core_session_get_private(session); - switch_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_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL KILL\n", switch_channel_get_name(channel)); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_soft_execute(switch_core_session_t *session) -{ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CHANNEL TRANSMIT\n"); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_exchange_media(switch_core_session_t *session) -{ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CHANNEL LOOPBACK\n"); - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) -{ - private_t *tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "DTMF ON CALL %s [%c]\n", tech_pvt->call_id, dtmf->digit); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_endpoint_read(audio_endpoint_t *endpoint, switch_frame_t **frame) -{ - int samples = 0; - - if (!endpoint->in_stream) { - switch_core_timer_next(&endpoint->read_timer); - *frame = &globals.cng_frame; - return SWITCH_STATUS_SUCCESS; - } - - endpoint->read_frame.data = endpoint->read_buf; - endpoint->read_frame.buflen = sizeof(endpoint->read_buf); - endpoint->read_frame.source = __FILE__; - samples = ReadAudioStream(endpoint->in_stream->stream, - endpoint->read_frame.data, STREAM_SAMPLES_PER_PACKET(endpoint->in_stream), - endpoint->inchan, &endpoint->read_timer); - - if (!samples) { - switch_core_timer_next(&endpoint->read_timer); - *frame = &globals.cng_frame; - return SWITCH_STATUS_SUCCESS; - } - - endpoint->read_frame.datalen = (samples * sizeof(int16_t)); - endpoint->read_frame.samples = samples; - endpoint->read_frame.codec = &endpoint->read_codec; - *frame = &endpoint->read_frame; - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) -{ - private_t *tech_pvt = switch_core_session_get_private(session); - int samples = 0; - switch_status_t status = SWITCH_STATUS_FALSE; - switch_assert(tech_pvt != NULL); - - if (tech_pvt->audio_endpoint) { - return channel_endpoint_read(tech_pvt->audio_endpoint, frame); - } - - if (!globals.main_stream) { - goto normal_return; - } - - if (switch_test_flag(tech_pvt, TFLAG_HUP)) { - goto normal_return; - } - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - goto cng_wait; - } - - if (!is_master(tech_pvt)) { - if (tech_pvt->hold_file) { - switch_size_t olen = globals.read_codec.implementation->samples_per_packet; - - if (!tech_pvt->hfh) { - int 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->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - tech_pvt->hold_file = NULL; - goto cng_wait; - } - - 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; - } - - if (switch_core_timer_next(&globals.hold_timer) != SWITCH_STATUS_SUCCESS) { - switch_core_file_close(&tech_pvt->fh); - goto cng_nowait; - } - 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_nowait; - } - - tech_pvt->hold_frame.datalen = (uint32_t) (olen * sizeof(int16_t)); - tech_pvt->hold_frame.samples = (uint32_t) olen; - *frame = &tech_pvt->hold_frame; - - status = SWITCH_STATUS_SUCCESS; - goto normal_return; - } - - goto cng_wait; - } - - if (tech_pvt->hfh) { - tech_close_file(tech_pvt); - } - - switch_mutex_lock(globals.device_lock); - samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, 0, &globals.read_timer); - switch_mutex_unlock(globals.device_lock); - - if (samples) { - globals.read_frame.datalen = samples * 2; - globals.read_frame.samples = samples; - - *frame = &globals.read_frame; - - if (!switch_test_flag((&globals), GFLAG_MOUTH)) { - memset(globals.read_frame.data, 255, globals.read_frame.datalen); - } - status = SWITCH_STATUS_SUCCESS; - } else { - goto cng_nowait; - } - -normal_return: - return status; - - cng_nowait: - *frame = &globals.cng_frame; - return SWITCH_STATUS_SUCCESS; - - cng_wait: - switch_core_timer_next(&globals.hold_timer); - *frame = &globals.cng_frame; - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t channel_endpoint_write(audio_endpoint_t *endpoint, switch_frame_t *frame) -{ - if (!endpoint->out_stream) { - switch_core_timer_next(&endpoint->write_timer); - return SWITCH_STATUS_SUCCESS; - } - if (!endpoint->master) { - return SWITCH_STATUS_SUCCESS; - } - if (switch_test_flag(endpoint->master, TFLAG_HUP)) { - return SWITCH_STATUS_FALSE; - } - if (!switch_test_flag(endpoint->master, TFLAG_IO)) { - return SWITCH_STATUS_SUCCESS; - } - WriteAudioStream(endpoint->out_stream->stream, (short *)frame->data, - (int)(frame->datalen / sizeof(SAMPLE)), - endpoint->outchan, &(endpoint->write_timer)); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) -{ - switch_status_t status = SWITCH_STATUS_FALSE; - private_t *tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - if (tech_pvt->audio_endpoint) { - return channel_endpoint_write(tech_pvt->audio_endpoint, frame); - } - - if (!globals.main_stream) { - 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 (globals.main_stream) { - if (switch_test_flag((&globals), GFLAG_EAR)) { - WriteAudioStream(globals.main_stream->stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), 0, &(globals.main_stream->write_timer)); - } - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -static switch_status_t channel_answer_channel(switch_core_session_t *session) -{ - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - private_t *tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_ANSWER: - channel_answer_channel(session); - break; - case SWITCH_MESSAGE_INDICATE_PROGRESS: - { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engage Early Media\n"); - switch_set_flag_locked(tech_pvt, TFLAG_IO); - } - default: - break; - } - return SWITCH_STATUS_SUCCESS; -} - -switch_state_handler_table_t portaudio_event_handlers = { - /*.on_init */ channel_on_init, - /*.on_routing */ channel_on_routing, - /*.on_execute */ channel_on_execute, - /*.on_hangup */ channel_on_hangup, - /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ channel_on_destroy -}; - -switch_io_routines_t portaudio_io_routines = { - /*.outgoing_channel */ channel_outgoing_channel, - /*.read_frame */ channel_read_frame, - /*.write_frame */ channel_write_frame, - /*.kill_channel */ channel_kill_channel, - /*.send_dtmf */ channel_send_dtmf, - /*.receive_message */ channel_receive_message -}; - -static int create_shared_audio_stream(shared_audio_stream_t *stream); -static int destroy_shared_audio_stream(shared_audio_stream_t *stream); -static int take_stream_channel(shared_audio_stream_t *stream, int index, int input) -{ - int rc = 0; - if (!stream) { - return rc; - } - - switch_mutex_lock(stream->mutex); - - if (!stream->stream && create_shared_audio_stream(stream)) { - rc = -1; - goto done; - } - - if (input) { - if (stream->inchan_used[index]) { - rc = -1; - goto done; - } - stream->inchan_used[index] = 1; - } else { - if (!input && stream->outchan_used[index]) { - rc = -1; - goto done; - } - stream->outchan_used[index] = 1; - } - -done: - switch_mutex_unlock(stream->mutex); - return rc; -} - -static int release_stream_channel(shared_audio_stream_t *stream, int index, int input) -{ - int i = 0; - int destroy_stream = 1; - int rc = 0; - - if (!stream) { - return rc; - } - - switch_mutex_lock(stream->mutex); - - if (input) { - stream->inchan_used[index] = 0; - } else { - stream->outchan_used[index] = 0; - } - - for (i = 0; i < stream->channels; i++) { - if (stream->inchan_used[i] || stream->outchan_used[i]) { - destroy_stream = 0; - } - } - if (destroy_stream) { - destroy_shared_audio_stream(stream); - } - - switch_mutex_unlock(stream->mutex); - return rc; -} - -/* 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_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause) -{ - char name[128]; - const char *id = NULL; - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - switch_caller_profile_t *caller_profile = NULL; - switch_call_cause_t retcause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - int codec_ms = -1; - int samples_per_packet = -1; - int sample_rate = 0; - audio_endpoint_t *endpoint = NULL; - char *endpoint_name = NULL; - const char *endpoint_answer = NULL; - - if (!outbound_profile) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n"); - return retcause; - } - - if (!(*new_session = switch_core_session_request_uuid(portaudio_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid")))) { - return retcause; - } - - 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)); - 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; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); - switch_core_session_destroy(new_session); - return retcause; - } - - if (outbound_profile->destination_number && !strncasecmp(outbound_profile->destination_number, "endpoint", sizeof("endpoint")-1)) { - endpoint = NULL; - endpoint_name = switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number); - endpoint_name = strchr(endpoint_name, '/'); - if (!endpoint_name) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "No portaudio endpoint specified\n"); - goto error; - } - endpoint_name++; - endpoint = switch_core_hash_find(globals.endpoints, endpoint_name); - if (!endpoint) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Invalid portaudio endpoint %s\n", endpoint_name); - goto error; - } - - switch_mutex_lock(endpoint->mutex); - - if (endpoint->master) { - /* someone already has this endpoint */ - retcause = SWITCH_CAUSE_USER_BUSY; - goto error; - } - - codec_ms = endpoint->in_stream ? endpoint->in_stream->codec_ms : endpoint->out_stream->codec_ms; - samples_per_packet = endpoint->in_stream ? - STREAM_SAMPLES_PER_PACKET(endpoint->in_stream) : STREAM_SAMPLES_PER_PACKET(endpoint->out_stream); - sample_rate = endpoint->in_stream ? endpoint->in_stream->sample_rate : endpoint->out_stream->sample_rate; - - if (switch_core_timer_init(&endpoint->read_timer, - globals.timer_name, codec_ms, - samples_per_packet, module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to setup read timer for endpoint '%s'!\n", endpoint->name); - goto error; - } - - /* The write timer must be setup regardless */ - if (switch_core_timer_init(&endpoint->write_timer, - globals.timer_name, codec_ms, - samples_per_packet, module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to setup read timer for endpoint '%s'!\n", endpoint->name); - goto error; - } - - if (switch_core_codec_init(&endpoint->read_codec, - "L16", NULL, 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"); - goto error; - } - - if (switch_core_codec_init(&endpoint->write_codec, - "L16", NULL, 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"); - goto error; - } - switch_core_session_set_read_codec(tech_pvt->session, &endpoint->read_codec); - switch_core_session_set_write_codec(tech_pvt->session, &endpoint->write_codec); - - /* try to acquire the stream */ - if (take_stream_channel(endpoint->in_stream, endpoint->inchan, 1)) { - retcause = SWITCH_CAUSE_USER_BUSY; - goto error; - } - if (take_stream_channel(endpoint->out_stream, endpoint->outchan, 0)) { - release_stream_channel(endpoint->in_stream, endpoint->inchan, 1); - retcause = SWITCH_CAUSE_USER_BUSY; - goto error; - } - switch_snprintf(name, sizeof(name), "portaudio/endpoint-%s", endpoint_name); - if (var_event && (endpoint_answer = (switch_event_get_header(var_event, "endpoint_answer")))) { - if (switch_true(endpoint_answer)) { - switch_set_flag(tech_pvt, TFLAG_AUTO_ANSWER); - } - } else { - switch_set_flag(tech_pvt, TFLAG_AUTO_ANSWER); - } - endpoint->master = tech_pvt; - tech_pvt->audio_endpoint = endpoint; - switch_mutex_unlock(endpoint->mutex); - } else { - id = !zstr(outbound_profile->caller_id_number) ? outbound_profile->caller_id_number : "na"; - switch_snprintf(name, sizeof(name), "portaudio/%s", id); - if (outbound_profile->destination_number && !strcasecmp(outbound_profile->destination_number, "auto_answer")) { - switch_set_flag(tech_pvt, TFLAG_AUTO_ANSWER); - } - } - switch_channel_set_name(channel, name); - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - switch_channel_set_caller_profile(channel, caller_profile); - tech_pvt->caller_profile = caller_profile; - - switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); - switch_channel_set_state(channel, CS_INIT); - switch_channel_set_flag(channel, CF_AUDIO); - return SWITCH_CAUSE_SUCCESS; - -error: - if (endpoint) { - if (!endpoint->master) { - if (endpoint->read_timer.interval) { - switch_core_timer_destroy(&endpoint->read_timer); - } - if (endpoint->write_timer.interval) { - switch_core_timer_destroy(&endpoint->write_timer); - } - if (endpoint->read_codec.codec_interface) { - switch_core_codec_destroy(&endpoint->read_codec); - } - if (endpoint->write_codec.codec_interface) { - switch_core_codec_destroy(&endpoint->write_codec); - } - } - switch_mutex_unlock(endpoint->mutex); - } - - switch_core_session_destroy(new_session); - - return retcause; -} - - -SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) -{ - switch_status_t status; - switch_api_interface_t *api_interface; - - module_pool = pool; - - if (paNoError != Pa_Initialize()) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot initialize port audio!\n"); - return SWITCH_STATUS_TERM; - } - - memset(&globals, 0, sizeof(globals)); - - switch_core_hash_init(&globals.call_hash); - switch_core_hash_init(&globals.sh_streams); - switch_core_hash_init(&globals.endpoints); - switch_mutex_init(&globals.device_lock, SWITCH_MUTEX_NESTED, module_pool); - switch_mutex_init(&globals.pvt_lock, SWITCH_MUTEX_NESTED, module_pool); - switch_mutex_init(&globals.streams_lock, SWITCH_MUTEX_NESTED, module_pool); - switch_mutex_init(&globals.flag_mutex, SWITCH_MUTEX_NESTED, module_pool); - switch_mutex_init(&globals.pa_mutex, SWITCH_MUTEX_NESTED, module_pool); - globals.codecs_inited = 0; - globals.read_frame.data = globals.databuf; - globals.read_frame.buflen = sizeof(globals.databuf); - globals.cng_frame.data = globals.cngbuf; - globals.cng_frame.buflen = sizeof(globals.cngbuf); - switch_set_flag((&globals.cng_frame), SFF_CNG); - globals.flags = GFLAG_EAR | GFLAG_MOUTH; - /* dual streams makes portaudio on solaris choke */ -#if defined(sun) || defined(__sun) - globals.dual_streams = 0; -#endif - - if ((status = load_config()) != SWITCH_STATUS_SUCCESS) { - return status; - } - - if (dump_info(0)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n"); - return SWITCH_STATUS_TERM; - } - - 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); - - - if (switch_event_reserve_subclass(MY_EVENT_RINGING) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_GENERR; - } - - if (switch_event_reserve_subclass(MY_EVENT_MAKE_CALL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_GENERR; - } - if (switch_event_reserve_subclass(MY_EVENT_CALL_HELD) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_GENERR; - } - if (switch_event_reserve_subclass(MY_EVENT_CALL_RESUMED) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_GENERR; - } - - if (switch_event_reserve_subclass(MY_EVENT_ERROR_AUDIO_DEV) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); - return SWITCH_STATUS_GENERR; - } - - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - portaudio_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - portaudio_endpoint_interface->interface_name = "portaudio"; - portaudio_endpoint_interface->io_routines = &portaudio_io_routines; - portaudio_endpoint_interface->state_handler = &portaudio_event_handlers; - - SWITCH_ADD_API(api_interface, "pa", "PortAudio", pa_cmd, " []"); - switch_console_set_complete("add pa help"); - switch_console_set_complete("add pa dump"); - switch_console_set_complete("add pa call"); - switch_console_set_complete("add pa answer"); - switch_console_set_complete("add pa hangup"); - switch_console_set_complete("add pa list"); - switch_console_set_complete("add pa switch"); - switch_console_set_complete("add pa dtmf"); - switch_console_set_complete("add pa flags"); - switch_console_set_complete("add pa devlist"); - switch_console_set_complete("add pa indev"); - switch_console_set_complete("add pa outdev"); - switch_console_set_complete("add pa preparestream"); - switch_console_set_complete("add pa switchstream"); - switch_console_set_complete("add pa closestreams"); - switch_console_set_complete("add pa ringdev"); - switch_console_set_complete("add pa ringfile"); - switch_console_set_complete("add pa play"); - switch_console_set_complete("add pa playdev"); - switch_console_set_complete("add pa looptest"); - switch_console_set_complete("add pa shstreams"); - switch_console_set_complete("add pa endpoints"); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -static int check_device(char *devstr, int check_input) -{ - int devval; - if (devstr[0] == '#') { - devval = get_dev_by_number(devstr + 1, check_input); - } else { - devval = get_dev_by_name(devstr, check_input); - } - return devval; -} - -static switch_status_t load_streams(switch_xml_t streams) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_xml_t param, mystream; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading streams ...\n"); - for (mystream = switch_xml_child(streams, "stream"); mystream; mystream = mystream->next) { - shared_audio_stream_t *stream = NULL; - int devval = -1; - char *stream_name = (char *) switch_xml_attr_soft(mystream, "name"); - - if (!stream_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing stream name attribute, skipping ...\n"); - continue; - } - - /* check if that stream name is not already used */ - stream = switch_core_hash_find(globals.sh_streams, stream_name); - if (stream) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "A stream with name '%s' already exists\n", stream_name); - continue; - } - - stream = switch_core_alloc(module_pool, sizeof(*stream)); - if (!stream) { - continue; - } - switch_mutex_init(&stream->mutex, SWITCH_MUTEX_NESTED, module_pool); - stream->indev = -1; - stream->outdev = -1; - stream->sample_rate = globals.sample_rate; - stream->codec_ms = globals.codec_ms; - stream->channels = 1; - switch_snprintf(stream->name, sizeof(stream->name), "%s", stream_name); - for (param = switch_xml_child(mystream, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parsing stream '%s' parameter %s = %s\n", stream_name, var, val); - if (!strcmp(var, "indev")) { - devval = check_device(val, 1); - if (devval < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Invalid indev specified for stream '%s'\n", stream_name); - stream->indev = -1; - continue; - } - stream->indev = devval; - } else if (!strcmp(var, "outdev")) { - devval = check_device(val, 0); - if (devval < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Invalid outdev specified for stream '%s'\n", stream_name); - stream->outdev = -1; - continue; - } - stream->outdev = devval; - } else if (!strcmp(var, "sample-rate")) { - stream->sample_rate = atoi(val); - if (stream->sample_rate < MIN_STREAM_SAMPLE_RATE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Invalid sample rate specified for stream '%s', forcing to 8000\n", stream_name); - stream->sample_rate = MIN_STREAM_SAMPLE_RATE; - } - } else if (!strcmp(var, "codec-ms")) { - int tmp = atoi(val); - if (switch_check_interval(stream->sample_rate, tmp)) { - stream->codec_ms = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "codec-ms must be multiple of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL); - } - } else if (!strcmp(var, "channels")) { - stream->channels = atoi(val); - if (stream->channels < 1 || stream->channels > MAX_IO_CHANNELS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Invalid number of channels specified for stream '%s', forcing to 1\n", stream_name); - stream->channels = 1; - } - } - } - if (stream->indev < 0 && stream->outdev < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "You need at least one device for stream '%s'\n", stream_name); - continue; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Created stream '%s', sample-rate = %d, codec-ms = %d\n", stream->name, stream->sample_rate, stream->codec_ms); - switch_core_hash_insert(globals.sh_streams, stream->name, stream); - } - return status; -} - -static int check_stream_compat(shared_audio_stream_t *in_stream, shared_audio_stream_t *out_stream) -{ - if (!in_stream || !out_stream) { - /* nothing to be compatible with */ - return 0; - } - if (in_stream->sample_rate != out_stream->sample_rate) { - return -1; - } - if (in_stream->codec_ms != out_stream->codec_ms) { - return -1; - } - return 0; -} - -static shared_audio_stream_t *check_stream(char *streamstr, int check_input, int *chanindex) -{ - shared_audio_stream_t *stream = NULL; - int cnum = 0; - char stream_name[255]; - char *chan = NULL; - - *chanindex = -1; - - switch_snprintf(stream_name, sizeof(stream_name), "%s", streamstr); - - chan = strchr(stream_name, ':'); - if (!chan) { - return NULL; - } - *chan = 0; - chan++; - cnum = atoi(chan); - - stream = switch_core_hash_find(globals.sh_streams, stream_name); - if (!stream) { - return NULL; - } - - if (cnum < 0 || cnum > stream->channels) { - return NULL; - } - - if (check_input && stream->indev < 0) { - return NULL; - } - - if (!check_input && stream->outdev < 0) { - return NULL; - } - - *chanindex = cnum; - - return stream; -} - -static switch_status_t load_endpoints(switch_xml_t endpoints) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_xml_t param, myendpoint; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading endpoints ...\n"); - for (myendpoint = switch_xml_child(endpoints, "endpoint"); myendpoint; myendpoint = myendpoint->next) { - audio_endpoint_t *endpoint = NULL; - shared_audio_stream_t *stream = NULL; - char *endpoint_name = (char *) switch_xml_attr_soft(myendpoint, "name"); - - if (!endpoint_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing endpoint name attribute, skipping ...\n"); - continue; - } - - /* check if that endpoint name is not already used */ - endpoint = switch_core_hash_find(globals.endpoints, endpoint_name); - if (endpoint) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An endpoint with name '%s' already exists\n", endpoint_name); - continue; - } - - endpoint = switch_core_alloc(module_pool, sizeof(*endpoint)); - if (!endpoint) { - continue; - } - switch_mutex_init(&endpoint->mutex, SWITCH_MUTEX_NESTED, module_pool); - endpoint->inchan = -1; - endpoint->outchan = -1; - switch_snprintf(endpoint->name, sizeof(endpoint->name), "%s", endpoint_name); - for (param = switch_xml_child(myendpoint, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parsing endpoint '%s' parameter %s = %s\n", endpoint_name, var, val); - if (!strcmp(var, "instream")) { - stream = check_stream(val, 1, &endpoint->inchan) ; - if (!stream) { - endpoint->in_stream = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Invalid instream specified for endpoint '%s'\n", endpoint_name); - continue; - } - endpoint->in_stream = stream; - } else if (!strcmp(var, "outstream")) { - stream = check_stream(val, 0, &endpoint->outchan); - if (!stream) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Invalid outstream specified for endpoint '%s'\n", endpoint_name); - endpoint->out_stream = NULL; - continue; - } - endpoint->out_stream = stream; - } - } - if (!endpoint->in_stream && !endpoint->out_stream) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "You need at least one stream for endpoint '%s'\n", endpoint_name); - continue; - } - if (check_stream_compat(endpoint->in_stream, endpoint->out_stream)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Incompatible input and output streams for endpoint '%s'\n", endpoint_name); - continue; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Created endpoint '%s', instream = %s, outstream = %s\n", endpoint->name, - endpoint->in_stream ? endpoint->in_stream->name : "(none)", - endpoint->out_stream ? endpoint->out_stream->name : "(none)"); - switch_core_hash_insert(globals.endpoints, endpoint->name, endpoint); - } - return status; -} - -static switch_status_t load_config(void) -{ - char *cf = "portaudio.conf"; - switch_xml_t cfg, xml, settings, streams, endpoints, param; - 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); - return SWITCH_STATUS_TERM; - } - destroy_audio_streams(); - destroy_codecs(); - globals.dual_streams = 0; - globals.live_stream_switch = 0; - globals.no_auto_resume_call = 0; - globals.no_ring_during_call = 0; - globals.indev = globals.outdev = globals.ringdev = -1; - globals.sample_rate = 8000; - globals.unload_device_fail = 0; - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcmp(var, "debug")) { - globals.debug = atoi(val); - } else if (!strcmp(var, "ring-interval")) { - globals.ring_interval = atoi(val); - } else if (!strcmp(var, "no-auto-resume-call")) { - if (switch_true(val)) { - globals.no_auto_resume_call = 1; - } else { - globals.no_auto_resume_call = 0; - } - } else if (!strcmp(var, "no-ring-during-call")) { - if (switch_true(val)) { - globals.no_ring_during_call = 1; - } else { - globals.no_ring_during_call = 0; - } - } else if (!strcmp(var, "live-stream-switch")) { - if (switch_true(val)) { - globals.live_stream_switch = 1; - } else { - globals.live_stream_switch = 0; - } - } else if (!strcmp(var, "ring-file")) { - set_global_ring_file(val); - } else if (!strcmp(var, "hold-file")) { - set_global_hold_file(val); - } else if (!strcmp(var, "dual-streams")) { - if (switch_true(val)) { - globals.dual_streams = 1; - } else { - globals.dual_streams = 0; - } - } else if (!strcmp(var, "timer-name")) { - set_global_timer_name(val); - } else if (!strcmp(var, "sample-rate")) { - globals.sample_rate = atoi(val); - } else if (!strcmp(var, "codec-ms")) { - int tmp = atoi(val); - if (switch_check_interval(globals.sample_rate, tmp)) { - globals.codec_ms = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "codec-ms must be multiple of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL); - } - } else if (!strcmp(var, "dialplan")) { - set_global_dialplan(val); - } else if (!strcmp(var, "context")) { - set_global_context(val); - } else if (!strcmp(var, "cid-name")) { - set_global_cid_name(val); - } else if (!strcmp(var, "cid-num")) { - set_global_cid_num(val); - } else if (!strcmp(var, "indev")) { - if (*val == '#') { - globals.indev = get_dev_by_number(val + 1, 1); - } else { - globals.indev = get_dev_by_name(val, 1); - } - } else if (!strcmp(var, "outdev")) { - if (*val == '#') { - globals.outdev = get_dev_by_number(val + 1, 0); - } else { - globals.outdev = get_dev_by_name(val, 0); - } - } else if (!strcmp(var, "ringdev")) { - if (*val == '#') { - globals.ringdev = get_dev_by_number(val + 1, 0); - } else { - globals.ringdev = get_dev_by_name(val, 0); - } - } else if (!strcasecmp(var, "unload-on-device-fail")) { - globals.unload_device_fail = switch_true(val); - } - } - } - - if (!globals.dialplan) { - set_global_dialplan("XML"); - } - - if (!globals.context) { - set_global_context("default"); - } - - if (!globals.sample_rate) { - globals.sample_rate = 8000; - } - - if (!globals.codec_ms) { - globals.codec_ms = 20; - } - - globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2; - - 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); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "global indev [%d]\n", globals.indev); - 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"); - if (globals.unload_device_fail) { - status = SWITCH_STATUS_GENERR; - } - } - } - - if (globals.outdev < 0) { - globals.outdev = get_dev_by_name(NULL, 0); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "global outdev [%d]\n", globals.outdev); - 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 output device\n"); - if (globals.unload_device_fail) { - status = SWITCH_STATUS_GENERR; - } - } - } - - if (globals.ringdev < 0) { - if (globals.outdev > -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid or no ring device configured, using output device as ring device\n"); - globals.ringdev = globals.outdev; - } - } - - /* streams and endpoints must be last, some initialization depend on globals defaults */ - if ((streams = switch_xml_child(cfg, "streams"))) { - load_streams(streams); - } - - if ((endpoints = switch_xml_child(cfg, "endpoints"))) { - load_endpoints(endpoints); - } - - - switch_xml_free(xml); - - return status; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown) -{ - - destroy_audio_streams(); - destroy_codecs(); - - Pa_Terminate(); - switch_core_hash_destroy(&globals.call_hash); - switch_core_hash_destroy(&globals.sh_streams); - switch_core_hash_destroy(&globals.endpoints); - - switch_event_free_subclass(MY_EVENT_RINGING); - switch_event_free_subclass(MY_EVENT_MAKE_CALL); - switch_event_free_subclass(MY_EVENT_ERROR_AUDIO_DEV); - switch_event_free_subclass(MY_EVENT_CALL_HELD); - switch_event_free_subclass(MY_EVENT_CALL_RESUMED); - - - switch_safe_free(globals.dialplan); - switch_safe_free(globals.context); - switch_safe_free(globals.cid_name); - switch_safe_free(globals.cid_num); - switch_safe_free(globals.ring_file); - switch_safe_free(globals.hold_file); - switch_safe_free(globals.timer_name); - - return SWITCH_STATUS_SUCCESS; -} - -static int get_dev_by_number(char *numstr, int in) -{ - int numDevices = Pa_GetDeviceCount(); - const PaDeviceInfo *pdi; - char *end_ptr; - int number; - - number = (int) strtol(numstr, &end_ptr, 10); - - if (end_ptr == numstr || number < 0) { - 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) -{ - int i; - int numDevices; - const PaDeviceInfo *pdi; - numDevices = Pa_GetDeviceCount(); - - if (numDevices < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices); - return -2; - } - - for (i = 0; i < numDevices; i++) { - int match = 0; - pdi = Pa_GetDeviceInfo(i); - - if (zstr(name)) { - match = 1; - } else if (pdi && pdi->name && strstr(pdi->name, name)) { - match = 1; - } - - if (match) { - if (in && pdi->maxInputChannels) { - return i; - } else if (!in && pdi->maxOutputChannels) { - return i; - } - } - } - - return -1; -} - - -/*******************************************************************/ -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"); - } -} - -/*******************************************************************/ -static switch_status_t play_dev(switch_stream_handle_t *stream, int outdev, char * file, const char * max_seconds, const char * no_close) -{ - switch_file_handle_t fh = { 0 }; - int samples = 0; - int seconds = 5; - audio_stream_t * audio_stream; - int created_stream = 0; - int wrote = 0; - switch_size_t olen; - int16_t abuf[2048]; - - - if (!strcasecmp(file, "ringtest")) { - file = globals.ring_file; - } - if (outdev == -1) { - stream->write_function(stream, "Invalid output audio device\n"); - return SWITCH_STATUS_FALSE; - } - audio_stream = get_audio_stream(-1, outdev); - - fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; - - if (switch_core_file_open(&fh, file, - globals.read_codec.implementation->number_of_channels, - globals.read_codec.implementation->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "Cannot play requested file %s\n", file); - return SWITCH_STATUS_FALSE; - } - - olen = globals.read_codec.implementation->samples_per_packet; - - if (max_seconds) { - int i = atoi(max_seconds); - if (i >= 0) { - seconds = i; - } - } - - if (globals.call_list) { - switch_mutex_lock(globals.pvt_lock); - if (!globals.main_stream) { - switch_mutex_unlock(globals.pvt_lock); - return SWITCH_STATUS_FALSE; - } - - if ( switch_test_flag(globals.call_list, TFLAG_MASTER) && globals.main_stream->outdev == outdev) { /*so we are the active stream so we need to dupe it basically */ - audio_stream = create_audio_stream(-1,outdev); - created_stream=1; - } - switch_mutex_unlock(globals.pvt_lock); - } - - if (! audio_stream) { - stream->write_function(stream, "Failed to engage audio device\n"); - return SWITCH_STATUS_FALSE; - } - - - - samples = globals.read_codec.implementation->actual_samples_per_second * seconds; - globals.stream_in_use=1; - while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) { - if (globals.destroying_streams || ! audio_stream->stream) { - break; - } - - WriteAudioStream(audio_stream->stream, abuf, (long) olen, 0, &(audio_stream->write_timer)); - wrote += (int) olen; - if (samples) { - samples -= (int) olen; - if (samples <= 0) { - break; - } - } - olen = globals.read_codec.implementation->samples_per_packet; - } - globals.stream_in_use = 0; - - switch_core_file_close(&fh); - if (! globals.call_list && ( ! no_close || strcasecmp(no_close, "no_close"))) { - destroy_audio_streams(); - } - - seconds = wrote / globals.read_codec.implementation->actual_samples_per_second; - stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz", - file, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second); - if (created_stream) { /*still need this as not added to the global pool */ - destroy_actual_stream(audio_stream); - } - return SWITCH_STATUS_SUCCESS; -} -static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *stream) -{ - int i, numDevices, prev; - const PaDeviceInfo *deviceInfo; - const PaHostApiInfo *hostApiInfo; - - numDevices = Pa_GetDeviceCount(); - - if (numDevices < 0) { - return SWITCH_STATUS_SUCCESS; - } - - if (argv[0] && !strcasecmp(argv[0], "xml")) { - stream->write_function(stream, "\n\t\n"); - - for (i = 0; i < numDevices; i++) { - deviceInfo = Pa_GetDeviceInfo(i); - hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi); - stream->write_function(stream, "\t\t\n", i, deviceInfo->name, - hostApiInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels); - } - - stream->write_function(stream, "\t\n\t\n" - "\t\t\n" - "\t\t\n" - "\t\t\n" "\t\n\n", globals.ringdev, globals.indev, globals.outdev); - } else { - - for (i = 0; i < numDevices; i++) { - deviceInfo = Pa_GetDeviceInfo(i); - hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi); - - stream->write_function(stream, "%d;%s(%s);%d;%d;", i, deviceInfo->name, hostApiInfo->name, deviceInfo->maxInputChannels, - deviceInfo->maxOutputChannels); - - prev = 0; - if (globals.ringdev == i) { - stream->write_function(stream, "r"); - prev = 1; - } - - if (globals.indev == i) { - if (prev) { - stream->write_function(stream, ","); - } - stream->write_function(stream, "i"); - prev = 1; - } - - if (globals.outdev == i) { - if (prev) { - stream->write_function(stream, ","); - } - stream->write_function(stream, "o"); - } - - stream->write_function(stream, "\n"); - - } - } - - return SWITCH_STATUS_SUCCESS; -} - -static int dump_info(int verbose) -{ - int i, numDevices, defaultDisplayed; - const PaDeviceInfo *deviceInfo; - PaStreamParameters inputParameters, outputParameters; - PaError err; - const char *line = "--------------------------------------------------------------------------------\n"; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, - "PortAudio version number = %d\nPortAudio version text = '%s'\n", Pa_GetVersion(), Pa_GetVersionText()); - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - return 0; - } - - if (verbose < 0) { - destroy_audio_streams(); - destroy_codecs(); - Pa_Terminate(); - Pa_Initialize(); - load_config(); - verbose = 0; - } - - numDevices = Pa_GetDeviceCount(); - if (numDevices < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices); - err = numDevices; - goto error; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices); - - if (!verbose) { - return 0; - } - - for (i = 0; i < numDevices; i++) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s", line); - deviceInfo = Pa_GetDeviceInfo(i); - switch_log_printf(SWITCH_CHANNEL_LOG, 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, 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, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name); - defaultDisplayed = 1; - } - - if (i == Pa_GetDefaultOutputDevice()) { - switch_log_printf(SWITCH_CHANNEL_LOG, 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, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name); - defaultDisplayed = 1; - } - - if (defaultDisplayed) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "** | "); - } - /* print device info fields */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Default input latency: %.3f | ", deviceInfo->defaultLowInputLatency); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Default output latency: %.3f\n", deviceInfo->defaultLowOutputLatency); - - /* poll for standard sample rates */ - inputParameters.device = i; - inputParameters.channelCount = deviceInfo->maxInputChannels; - inputParameters.sampleFormat = paInt16; - inputParameters.suggestedLatency = deviceInfo->defaultLowInputLatency; /* ignored by Pa_IsFormatSupported() */ - inputParameters.hostApiSpecificStreamInfo = NULL; - - outputParameters.device = i; - outputParameters.channelCount = deviceInfo->maxOutputChannels; - outputParameters.sampleFormat = paInt16; - outputParameters.suggestedLatency = deviceInfo->defaultLowOutputLatency; /* ignored by Pa_IsFormatSupported() */ - outputParameters.hostApiSpecificStreamInfo = NULL; - - if (inputParameters.channelCount > 0) { - - switch_log_printf(SWITCH_CHANNEL_LOG, 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, 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, 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, SWITCH_LOG_INFO, "%s", line); - - return 0; - - error: - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "An error occurred 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 create_codecs(int restart) -{ - int sample_rate = globals.sample_rate; - int codec_ms = globals.codec_ms; - - if (restart) { - destroy_codecs(); - } - if (globals.codecs_inited) { - return SWITCH_STATUS_SUCCESS; - } - - if (!switch_core_codec_ready(&globals.read_codec)) { - if (switch_core_codec_init(&globals.read_codec, - "L16", - NULL, - 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; - } - } - - switch_assert(globals.read_codec.implementation); - - if (!switch_core_codec_ready(&globals.write_codec)) { - if (switch_core_codec_init(&globals.write_codec, - "L16", - NULL, - 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 (!globals.read_timer.timer_interface) { - if (switch_core_timer_init(&globals.read_timer, - globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, - 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; - } - } - if (!globals.readfile_timer.timer_interface) { - if (switch_core_timer_init(&globals.readfile_timer, - globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, - 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; - } - } - - - if (!globals.hold_timer.timer_interface) { - if (switch_core_timer_init(&globals.hold_timer, - globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, - module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup hold timer failed!\n"); - switch_core_codec_destroy(&globals.read_codec); - switch_core_codec_destroy(&globals.write_codec); - switch_core_timer_destroy(&globals.read_timer); - switch_core_timer_destroy(&globals.readfile_timer); - - return SWITCH_STATUS_FALSE; - } - } - - globals.cng_frame.rate = globals.read_frame.rate = sample_rate; - globals.cng_frame.codec = globals.read_frame.codec = &globals.read_codec; - - globals.codecs_inited=1; - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_audio_stream() -{ - audio_stream_t *stream; - if (! globals.call_list) { /* If no active calls then it will automatically switch over on next call */ - return SWITCH_STATUS_SUCCESS; - } - stream = get_audio_stream(globals.indev, globals.outdev); - if (stream == NULL) { - return SWITCH_STATUS_FALSE; - } - - globals.main_stream = stream;//TODO: need locks around here?? - - return SWITCH_STATUS_SUCCESS; -} - -PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters) -{ - if (inputParameters->device != -1) { - return OpenAudioStream(stream, inputParameters, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams); - } - return OpenAudioStream(stream, NULL, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, 0); -} - -PaError open_shared_audio_stream(shared_audio_stream_t *shstream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters) -{ - PaError err; - if (inputParameters->device != -1) { - err = OpenAudioStream(&shstream->stream, inputParameters->device != -1 ? inputParameters : NULL, - outputParameters->device != -1 ? outputParameters : NULL, shstream->sample_rate, - paClipOff, STREAM_SAMPLES_PER_PACKET(shstream), globals.dual_streams); - } else { - err = OpenAudioStream(&shstream->stream, NULL, outputParameters, shstream->sample_rate, - paClipOff, STREAM_SAMPLES_PER_PACKET(shstream), 0); - } - if (err != paNoError) { - shstream->stream = NULL; - } - return err; -} - -static int create_shared_audio_stream(shared_audio_stream_t *shstream) -{ - PaStreamParameters inputParameters, outputParameters; - PaError err; - switch_event_t *event; - - inputParameters.device = shstream->indev; - if (shstream->indev != -1) { - inputParameters.channelCount = shstream->channels; - inputParameters.sampleFormat = SAMPLE_TYPE; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = NULL; - } - outputParameters.device = shstream->outdev; - if (shstream->outdev != -1) { - outputParameters.channelCount = shstream->channels; - outputParameters.sampleFormat = SAMPLE_TYPE; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - } - - err = open_shared_audio_stream(shstream, &inputParameters, &outputParameters); - if (err != paNoError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Error opening audio device retrying (indev = %d, outdev = %d, error = %s)\n", - inputParameters.device, outputParameters.device, Pa_GetErrorText(err)); - switch_yield(1000000); - err = open_shared_audio_stream(shstream, &inputParameters, &outputParameters); - } - - if (err != paNoError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device (indev = %d, outdev = %d, error = %s)\n", - inputParameters.device, outputParameters.device, Pa_GetErrorText(err)); - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR_AUDIO_DEV) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Reason", Pa_GetErrorText(err)); - switch_event_fire(&event); - } - return -1; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created shared audio stream %s: %d channels %d\n", - shstream->name, shstream->sample_rate, shstream->channels); - return 0; -} - -static int destroy_shared_audio_stream(shared_audio_stream_t *shstream) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying shared audio stream %s\n", shstream->name); - CloseAudioStream(shstream->stream); - shstream->stream = NULL; - return 0; -} - -static audio_stream_t *create_audio_stream(int indev, int outdev) -{ - PaStreamParameters inputParameters, outputParameters; - PaError err; - switch_event_t *event; - audio_stream_t *stream; - - stream = malloc(sizeof(*stream)); - if (stream == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to alloc memory\n"); - return NULL; - } - memset(stream, 0, sizeof(*stream)); - stream->next = NULL; - stream->stream = NULL; - stream->indev = indev; - stream->outdev = outdev; - if (!stream->write_timer.timer_interface) { - if (switch_core_timer_init(&(stream->write_timer), - globals.timer_name, globals.codec_ms, globals.read_codec.implementation->samples_per_packet, - module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n"); - switch_safe_free(stream); - return NULL; - } - } - - inputParameters.device = indev; - if (indev != -1) { - inputParameters.channelCount = 1; - inputParameters.sampleFormat = SAMPLE_TYPE; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = NULL; - } - outputParameters.device = outdev; - - if (outdev != -1) { - outputParameters.channelCount = 1; - outputParameters.sampleFormat = SAMPLE_TYPE; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - } - - err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters); - if (err != paNoError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n"); - switch_yield(1000000); - err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters); - } - - if (err != paNoError) { - switch_safe_free(stream); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n"); - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR_AUDIO_DEV) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Reason", Pa_GetErrorText(err)); - switch_event_fire(&event); - } - return NULL; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created audio stream: %d channels %d\n", globals.sample_rate, outputParameters.channelCount); - return stream; -} - -audio_stream_t *get_audio_stream(int indev, int outdev) -{ - audio_stream_t *stream = NULL; - if (outdev == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error invalid output audio device\n"); - return NULL; - } - if (create_codecs(0) != SWITCH_STATUS_SUCCESS) { - return NULL; - } - - stream = find_audio_stream(indev, outdev, 0); - if (stream != NULL) { - return stream; - } - stream = create_audio_stream(indev, outdev); - if (stream) { - add_stream(stream, 0); - } - return stream; -} - -static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream) -{ - char *dtmf_str = argv[0]; - switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0) }; - - if (zstr(dtmf_str)) { - 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); - char *p = dtmf_str; - while (p && *p) { - dtmf.digit = *p; - switch_channel_queue_dtmf(channel, &dtmf); - p++; - } - } - switch_mutex_unlock(globals.pvt_lock); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t list_shared_streams(char **argv, int argc, switch_stream_handle_t *stream) -{ - switch_hash_index_t *hi; - int cnt = 0; - for (hi = switch_core_hash_first(globals.sh_streams); hi; hi = switch_core_hash_next(&hi)) { - const void *var; - void *val; - shared_audio_stream_t *s = NULL; - switch_core_hash_this(hi, &var, NULL, &val); - s = val; - stream->write_function(stream, "%s> indev: %d, outdev: %d, sample-rate: %d, codec-ms: %d, channels: %d\n", - s->name, s->indev, s->outdev, s->sample_rate, s->codec_ms, s->channels); - cnt++; - } - stream->write_function(stream, "Total streams: %d\n", cnt); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t list_endpoints(char **argv, int argc, switch_stream_handle_t *stream) -{ - switch_hash_index_t *hi; - int cnt = 0; - for (hi = switch_core_hash_first(globals.endpoints); hi; hi = switch_core_hash_next(&hi)) { - const void *var; - void *val; - audio_endpoint_t *e = NULL; - switch_core_hash_this(hi, &var, NULL, &val); - e = val; - stream->write_function(stream, "%s> instream: %s, outstream: %s\n", - e->name, e->in_stream ? e->in_stream->name : "(none)", - e->out_stream ? e->out_stream->name : "(none)"); - cnt++; - } - stream->write_function(stream, "Total endpoints: %d\n", cnt); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t close_streams(char **argv, int argc, switch_stream_handle_t *stream) -{ - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - return SWITCH_STATUS_FALSE; - } - destroy_audio_streams(); - stream->write_function(stream, "closestreams all open streams closed\n"); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t set_indev(char **argv, int argc, switch_stream_handle_t *stream) -{ - int devval; - - if (globals.call_list && ! globals.live_stream_switch) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - return SWITCH_STATUS_FALSE; - } - if (*argv[0] == '#') { - devval = get_dev_by_number(argv[0] + 1, 1); - } else { - devval = get_dev_by_name(argv[0], 1); - } - if (devval < 0) { - stream->write_function(stream, "indev not set (invalid value)\n"); - return SWITCH_STATUS_FALSE; - } - globals.indev = devval; - switch_audio_stream(); - stream->write_function(stream, "indev set to %d\n", devval); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t set_outdev(char **argv, int argc, switch_stream_handle_t *stream) -{ - int devval; - if (globals.call_list && ! globals.live_stream_switch) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - return SWITCH_STATUS_FALSE; - } - if (*argv[0] == '#') { - devval = get_dev_by_number(argv[0] + 1, 0); - } else { - devval = get_dev_by_name(argv[0], 0); - } - if (devval < 0) { - stream->write_function(stream, "outdev not set (invalid value)\n"); - return SWITCH_STATUS_FALSE; - } - - globals.outdev = devval; - switch_audio_stream(); - stream->write_function(stream, "outdev set to %d\n", devval); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t prepare_stream(char **argv, int argc, switch_stream_handle_t *stream) -{ - int devval=-2,devval2=-1; - if (! strcmp(argv[0], "#-1")) { - devval = -1; - } else if (*argv[0] == '#') { - devval = get_dev_by_number(argv[0]+1, 1); - } - if (devval == -2) { - stream->write_function(stream, "preparestream not prepared as indev has (invalid value)\n"); - return SWITCH_STATUS_FALSE; - } - if (*argv[1] == '#') { - devval2 = get_dev_by_number(argv[1]+1, 0); - } - if (devval2 == -1) { - stream->write_function(stream, "preparestream not prepared as outdev has (invalid value)\n"); - return SWITCH_STATUS_FALSE; - } - - if (! get_audio_stream(devval,devval2)) { - stream->write_function(stream, "preparestream not prepared received an invalid stream back\n"); - return SWITCH_STATUS_FALSE; - } - stream->write_function(stream, "preparestream prepared indev: %d outdev: %d\n", devval, devval2); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t switch_stream(char **argv, int argc, switch_stream_handle_t *stream) -{ - int devval =-1, devval2 = -1; - if (globals.call_list && ! globals.live_stream_switch) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - return SWITCH_STATUS_FALSE; - } - if (*argv[0] == '#') { - devval = get_dev_by_number(argv[0]+1, 1); - } - if (devval == -1) { - stream->write_function(stream, "switchstream not prepared as indev has (invalid value)\n"); - return SWITCH_STATUS_FALSE; - } - if (*argv[1] == '#') { - devval2 = get_dev_by_number(argv[1]+1, 0); - } - if (devval2 == -1) { - stream->write_function(stream, "switchstream not prepared as outdev has (invalid value)\n"); - return SWITCH_STATUS_FALSE; - } - globals.indev = devval; - globals.outdev = devval2; - if (switch_audio_stream() != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "switchstream was unable to switch\n"); - return SWITCH_STATUS_FALSE; - } - stream->write_function(stream, "switchstream switched to indev: %d outdev: %d\n", devval, devval2); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t set_ringdev(char **argv, int argc, switch_stream_handle_t *stream) -{ - int devval; - if (globals.call_list && ! globals.live_stream_switch) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - return SWITCH_STATUS_FALSE; - } - if (! strcmp(argv[0], "#-1")) { - globals.ring_stream = NULL; - globals.ringdev = -1; - stream->write_function(stream, "ringdev set to %d\n", globals.ringdev); - return SWITCH_STATUS_SUCCESS; - } else if (*argv[0] == '#') { - devval = get_dev_by_number(argv[0] + 1, 0); - } else { - devval = get_dev_by_name(argv[0], 0); - } - if (devval == -1) { - stream->write_function(stream, "ringdev not set as dev has (invalid value)\n"); - return SWITCH_STATUS_FALSE; - } - globals.ringdev = devval; - stream->write_function(stream, "ringdev set to %d\n", globals.ringdev); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t looptest(char **argv, int argc, switch_stream_handle_t *stream) -{ - int samples = 0; - int success = 0; - int i; - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - return SWITCH_STATUS_FALSE; - } - if (validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "looptest Failed to engage audio device\n"); - return SWITCH_STATUS_FALSE; - } - globals.stream_in_use = 1; - for (i = 0; i < 400; i++) { - if (globals.destroying_streams || ! globals.main_stream->stream) { - break; - } - if ((samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, 0, &globals.read_timer))) { - WriteAudioStream(globals.main_stream->stream, globals.read_frame.data, (long) samples, 0, &(globals.main_stream->write_timer)); - success = 1; - } - switch_yield(10000); - } - globals.stream_in_use = 0; - - if (!success) { - stream->write_function(stream, "Failed to read any bytes from indev\n"); - return SWITCH_STATUS_FALSE; - } - destroy_audio_streams(); - stream->write_function(stream, "looptest complete\n"); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t set_ringfile(char **argv, int argc, switch_stream_handle_t *stream) -{ - if (! argv[0]) { - stream->write_function(stream, "%s", globals.ring_file); - return SWITCH_STATUS_SUCCESS; - } - if (create_codecs(0) == SWITCH_STATUS_SUCCESS) { - switch_file_handle_t fh = { 0 }; - if (switch_core_file_open(&fh, - argv[0], - globals.read_codec.implementation->number_of_channels, - globals.read_codec.implementation->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - switch_core_file_close(&fh); - set_global_ring_file(argv[0]); - } else { - stream->write_function(stream, "ringfile Unable to open ring file %s\n", argv[0]); - return SWITCH_STATUS_FALSE; - } - } else { - stream->write_function(stream, "ringfile Failed to init codecs device\n"); - return SWITCH_STATUS_FALSE; - } - stream->write_function(stream, "ringfile set to %s", globals.ring_file); - 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 (zstr(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) { - if (switch_test_flag(tp, TFLAG_MASTER)) { - switch_clear_flag_locked(tp, TFLAG_MASTER); - create_hold_event(tp,0); - } - } - 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); - create_hold_event(tech_pvt, 1); - stream->write_function(stream, "OK\n"); - } else { - stream->write_function(stream, "NO SUCH CALL\n"); - } - - done: - switch_mutex_unlock(globals.pvt_lock); - - return SWITCH_STATUS_SUCCESS; -} - -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 (zstr(callid)) { - tech_pvt = globals.call_list; - } else { - tech_pvt = switch_core_hash_find(globals.call_hash, callid); - } - - if (tech_pvt) { - 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); - - return SWITCH_STATUS_SUCCESS; -} - -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 (!zstr(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); - if (tp != globals.call_list) { - remove_pvt(tp); - } - add_pvt(tp, PA_MASTER); - switch_channel_mark_answered(channel); - } - } 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); - add_pvt(tp, PA_MASTER); - switch_channel_mark_answered(channel); - x++; - break; - } - } - done: - switch_mutex_unlock(globals.pvt_lock); - stream->write_function(stream, "Answered %d channels.\n", x); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t do_flags(char **argv, int argc, switch_stream_handle_t *stream) -{ - char *action = argv[0]; - char *flag_str; - 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] \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; - const char *cid_name = "n/a"; - const 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); - - stream->write_function(stream, "\n%d call%s\n", x, x == 1 ? "" : "s"); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t *stream) -{ - switch_core_session_t *session; - char *dest = NULL; - - if (zstr(argv[0])) { - stream->write_function(stream, "FAIL:Usage: call \n"); - return SWITCH_STATUS_SUCCESS; - } - dest = argv[0]; - - if ((session = switch_core_session_request(portaudio_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)) != 0) { - private_t *tech_pvt; - switch_channel_t *channel; - char *dialplan = globals.dialplan; - char *context = globals.context; - char *cid_name = globals.cid_name; - char *cid_num = globals.cid_num; - char ip[25] = "0.0.0.0"; - - switch_core_session_add_stream(session, NULL); - if ((tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t))) != 0) { - memset(tech_pvt, 0, sizeof(*tech_pvt)); - switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - channel = switch_core_session_get_channel(session); - switch_core_session_set_private(session, tech_pvt); - tech_pvt->session = session; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); - switch_core_session_destroy(&session); - return SWITCH_STATUS_MEMERR; - } - - if (!zstr(argv[1])) { - dialplan = argv[1]; - } - - if (!zstr(argv[2])) { - cid_num = argv[2]; - } - - if (!zstr(argv[3])) { - cid_name = argv[3]; - } - - if (!zstr(argv[4])) { - tech_pvt->sample_rate = atoi(argv[4]); - } - - if (!zstr(argv[5])) { - tech_pvt->codec_ms = atoi(argv[5]); - } - - switch_find_local_ip(ip, sizeof(ip), NULL, AF_INET); - - if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), - NULL, dialplan, cid_name, cid_num, ip, NULL, NULL, NULL, modname, context, dest)) != 0) { - char name[128]; - switch_snprintf(name, sizeof(name), "portaudio/%s", - tech_pvt->caller_profile->destination_number ? tech_pvt->caller_profile->destination_number : modname); - switch_channel_set_name(channel, name); - - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - } - tech_pvt->session = session; - if (validate_main_audio_stream() == SWITCH_STATUS_SUCCESS) { - switch_set_flag_locked(tech_pvt, TFLAG_ANSWER); - switch_channel_mark_answered(channel); - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { - switch_event_t *event; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error spawning thread\n"); - switch_core_session_destroy(&session); - stream->write_function(stream, "FAIL:Thread Error!\n"); - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_MAKE_CALL) == SWITCH_STATUS_SUCCESS) { - char buf[512]; - switch_channel_event_set_data(channel, event); - switch_snprintf(buf, sizeof(buf), "Thread error!.\n"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "error", buf); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fail", "true"); - switch_event_fire(&event); - } - } else { - switch_event_t *event; - 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_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_MAKE_CALL) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fail", "false"); - switch_event_fire(&event); - } - } - } else { - switch_event_t *event; - switch_core_session_destroy(&session); - stream->write_function(stream, "FAIL:Device Error!\n"); - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_MAKE_CALL) == SWITCH_STATUS_SUCCESS) { - char buf[512]; - switch_channel_event_set_data(channel, event); - switch_snprintf(buf, sizeof(buf), "Device fail.\n"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "error", buf); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fail", "true"); - switch_event_fire(&event); - } - } - } - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(pa_cmd) -{ - char *argv[1024] = { 0 }; - int argc = 0; - char *mycmd = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - pa_command_t func = NULL; - int devval; - int lead = 1; - 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 rescan\n" - "pa call [ ]\n" - "pa answer []\n" - "pa hangup []\n" - "pa list\n" - "pa switch [|none]\n" - "pa dtmf \n" - "pa flags [on|off] [ear] [mouth]\n" - "pa devlist [xml]\n" - "pa indev #|\n" - "pa outdev #|\n" - "pa preparestream # #\n" - "pa switchstream # #\n" - "pa closestreams\n" - "pa ringdev #|\n" - "pa play [ringtest|] [seconds] [no_close]\n" - "pa playdev # [ringtest|] [seconds] [no_close]\n" - "pa ringfile [filename]\n" - "pa looptest\n" - "pa shstreams\n" - "pa endpoints\n" - "--------------------------------------------------------------------------------\n"; - - - if (stream->param_event) { - http = switch_event_get_header(stream->param_event, "http-host"); - } - - if (http) { - stream->write_function(stream, "Content-type: text/html\n\n"); - - wcmd = switch_str_nil(switch_event_get_header(stream->param_event, "wcmd")); - action = switch_event_get_header(stream->param_event, "action"); - - if (action) { - if (strlen(action) == 1) { - switch_snprintf(cmd_buf, sizeof(cmd_buf), "dtmf %s", action); - cmd = cmd_buf; - } else if (!strcmp(action, "mute")) { - switch_snprintf(cmd_buf, sizeof(cmd_buf), "flags off mouth"); - cmd = cmd_buf; - } else if (!strcmp(action, "unmute")) { - switch_snprintf(cmd_buf, sizeof(cmd_buf), "flags on mouth"); - cmd = cmd_buf; - } else if (!strcmp(action, "switch")) { - switch_snprintf(cmd_buf, sizeof(cmd_buf), "switch %s", wcmd); - cmd = cmd_buf; - } else if (!strcmp(action, "call")) { - switch_snprintf(cmd_buf, sizeof(cmd_buf), "call %s", wcmd); - cmd = cmd_buf; - } else if (!strcmp(action, "hangup") || !strcmp(action, "list") || !strcmp(action, "devlist") || !strcmp(action, "answer")) { - cmd = action; - } - } - - if (zstr(cmd)) { - goto done; - } - - } else { - - if (zstr(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 (!argv[0]) { - stream->write_function(stream, "Unknown Command\n"); - 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], "rescan")) { - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Looking for new devices.\n"); - dump_info(-1); - goto done; - } else if (!strcasecmp(argv[0], "dump")) { - dump_info(1); - 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], "closestreams")) { - func = close_streams; - } else if (argv[1] && !strcmp(argv[0], "indev")) { - func = set_indev; - } else if (argv[1] && !strcmp(argv[0], "outdev")) { - func = set_outdev; - } else if (argv[1] && argv[2] && !strcmp(argv[0], "preparestream")) { - func = prepare_stream; - } else if (argv[1] && argv[2] && !strcmp(argv[0], "switchstream")) { - func = switch_stream; - } else if (argv[1] && !strcmp(argv[0], "ringdev")) { - func = set_ringdev; - } else if ((argv[1] && !strcmp(argv[0], "play"))) { - if (validate_main_audio_stream() == SWITCH_STATUS_SUCCESS) { - play_dev(stream, globals.main_stream ? globals.main_stream->outdev : -1,argv[1],argv[2], argv[3]); - }else{ - stream->write_function(stream, "Failed to engage audio device\n"); - } - goto done; - } else if ((argv[1] && argv[2] && !strcmp(argv[0], "playdev"))) { - if (*argv[1] == '#') { - devval = get_dev_by_number(argv[1] + 1, 0); - } else { - devval = -1; - } - play_dev(stream, devval,argv[2],argv[3],argv[4]); - goto done; - } else if (!strcasecmp(argv[0], "looptest")) { - func = looptest; - } else if (!strcasecmp(argv[0], "ringfile")) { - func = set_ringfile; - } else if (!strcasecmp(argv[0], "shstreams")) { - func = list_shared_streams; - } else if (!strcasecmp(argv[0], "endpoints")) { - func = list_endpoints; - } else { - stream->write_function(stream, "Unknown Command or not enough args [%s]\n", argv[0]); - } - - - if (func) { - if (http) { - stream->write_function(stream, "
");
-		}
-
-		switch_mutex_lock(globals.pa_mutex);
-		func(&argv[lead], argc - lead, stream);
-		status = SWITCH_STATUS_SUCCESS; /*if func was defined we want to always return success as the command was found */
-		switch_mutex_unlock(globals.pa_mutex);
-
-		if (http) {
-			stream->write_function(stream, "\n\n
"); - } - } - - done: - if (http) { - stream->write_function(stream, - "

\n" - "

\n" - " " - " " - " " - " " - " " - " " - " " - " " - "
" - " " - " " - " " - " " - " " - " " - "

" - "\n" - "" - "" - "\n" - "\n" - "" - "" - "\n" - "\n" - "" - "" - "\n" - "\n" - "" - "" - "\n" - "\n" "
" "

\n"); - } - - switch_safe_free(mycmd); - return status; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c b/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c deleted file mode 100644 index 00e5f3a982..0000000000 --- a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * $Id: pa_ringbuffer.c 1164 2006-12-21 15:34:50Z bjornroche $ - * Portable Audio I/O Library - * Ring Buffer utility. - * - * Author: Phil Burk, http://www.softsynth.com - * modified for SMP safety on Mac OS X by Bjorn Roche - * modified for SMP safety on Linux by Leland Lucius - * also, allowed for const where possible - * Note that this is safe only for a single-thread reader and a - * single-thread writer. - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** - @file - @ingroup common_src -*/ - -#include -#include -#include -#include -#include "pa_ringbuffer.h" - -/**************** - * First, we'll define some memory barrier primitives based on the system. - * right now only OS X, FreeBSD, and Linux are supported. In addition to providing - * memory barriers, these functions should ensure that data cached in registers - * is written out to cache where it can be snooped by other CPUs. (ie, the volatile - * keyword should not be required) - * - * the primitives that must be defined are: - * - * PaUtil_FullMemoryBarrier() - * PaUtil_ReadMemoryBarrier() - * PaUtil_WriteMemoryBarrier() - * - ****************/ -#define __VIA_HACK__ -#if defined(__VIA_HACK__) -#define NO_BARRIER -#endif - -#if defined(NO_BARRIER) -# define PaUtil_FullMemoryBarrier() -# define PaUtil_ReadMemoryBarrier() -# define PaUtil_WriteMemoryBarrier() -#else - -#if defined(__APPLE__) //|| defined(__FreeBSD__) -# include - /* 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 */ -# if defined( __PPC__ ) -# 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") -# else -# define PaUtil_FullMemoryBarrier() -# define PaUtil_ReadMemoryBarrier() -# define PaUtil_WriteMemoryBarrier() -# endif -#elif defined(_MSC_VER) -# include -# pragma intrinsic(_ReadWriteBarrier) -# pragma intrinsic(_ReadBarrier) -# pragma intrinsic(_WriteBarrier) -# define PaUtil_FullMemoryBarrier() _ReadWriteBarrier() -# define PaUtil_ReadMemoryBarrier() _ReadBarrier() -# define PaUtil_WriteMemoryBarrier() _WriteBarrier() -#else -# define PaUtil_FullMemoryBarrier() -# define PaUtil_ReadMemoryBarrier() -# define PaUtil_WriteMemoryBarrier() -#endif -#endif -/*************************************************************************** - * Initialize FIFO. - * numBytes must be power of 2, returns -1 if not. - */ -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; -} - -/*************************************************************************** -** Return number of bytes available for reading. */ -long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf) -{ - PaUtil_ReadMemoryBarrier(); - return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask); -} - -/*************************************************************************** -** Return number of bytes available for writing. */ -long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * 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) -{ - rbuf->writeIndex = rbuf->readIndex = 0; -} - -/*************************************************************************** -** Get address of region(s) to which we can write data. -** If the region is contiguous, size2 will be zero. -** 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_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; -} - -/*************************************************************************** -** Get address of region(s) from which we can read data. -** If the region is contiguous, size2 will be zero. -** 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_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; -} - -/*************************************************************************** -** Return bytes written. */ -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; -} - -/*************************************************************************** -** Return bytes read. */ -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; -} diff --git a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h b/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h deleted file mode 100644 index 05e0602529..0000000000 --- a/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h +++ /dev/null @@ -1,192 +0,0 @@ -#ifndef PA_RINGBUFFER_H -#define PA_RINGBUFFER_H -/* - * $Id: pa_ringbuffer.h 1151 2006-11-29 02:11:16Z leland_lucius $ - * Portable Audio I/O Library - * Ring Buffer utility. - * - * Author: Phil Burk, http://www.softsynth.com - * modified for SMP safety on OS X by Bjorn Roche. - * also allowed for const where possible. - * Note that this is safe only for a single-thread reader - * and a single-thread writer. - * - * This program is distributed with the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup common_src -*/ - -#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; - -/** Initialize Ring Buffer. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes in the buffer and must be power of 2. - - @param dataPtr A pointer to a previously allocated area where the data - will be maintained. It must be numBytes long. - - @return -1 if numBytes is not a power of 2, otherwise 0. -*/ - 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); - -/** Retrieve the number of bytes available in the ring buffer for writing. - - @param rbuf The ring buffer. - - @return The number of bytes available for writing. -*/ - long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf); - -/** Retrieve the number of bytes available in the ring buffer for reading. - - @param rbuf The ring buffer. - - @return The number of bytes available for reading. -*/ - long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf); - -/** Write data to the ring buffer. - - @param rbuf The ring buffer. - - @param data The address of new data to write to the buffer. - - @param numBytes The number of bytes to be written. - - @return The number of bytes written. -*/ - long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes); - -/** Read data from the ring buffer. - - @param rbuf The ring buffer. - - @param data The address where the data should be stored. - - @param numBytes The number of bytes to be read. - - @return The number of bytes read. -*/ - long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes); - -/** Get address of region(s) to which we can write data. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes desired. - - @param dataPtr1 The address where the first (or only) region pointer will be - stored. - - @param sizePtr1 The address where the first (or only) region length will be - stored. - - @param dataPtr2 The address where the second region pointer will be stored if - the first region is too small to satisfy numBytes. - - @param sizePtr2 The address where the second region length will be stored if - the first region is too small to satisfy numBytes. - - @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); - -/** Advance the write index to the next location to be written. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes to advance. - - @return The new position. -*/ - long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes); - -/** Get address of region(s) from which we can write data. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes desired. - - @param dataPtr1 The address where the first (or only) region pointer will be - stored. - - @param sizePtr1 The address where the first (or only) region length will be - stored. - - @param dataPtr2 The address where the second region pointer will be stored if - the first region is too small to satisfy numBytes. - - @param sizePtr2 The address where the second region length will be stored if - the first region is too small to satisfy numBytes. - - @return The number of bytes available for reading. -*/ - 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. - - @param rbuf The ring buffer. - - @param numBytes The number of bytes to advance. - - @return The new position. -*/ - long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_RINGBUFFER_H */ diff --git a/src/mod/endpoints/mod_portaudio/pablio.c b/src/mod/endpoints/mod_portaudio/pablio.c deleted file mode 100644 index aae15eb00c..0000000000 --- a/src/mod/endpoints/mod_portaudio/pablio.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * $Id: pablio.c 1151 2006-11-29 02:11:16Z leland_lucius $ - * pablio.c - * Portable Audio Blocking Input/Output utility. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "pa_ringbuffer.h" -#include "pablio.h" - -/************************************************************************/ -/******** Prototypes ****************************************************/ -/************************************************************************/ - -static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, - void *userData); -static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, - PaStreamCallbackFlags statusFlags, void *userData); - -static int ioblockingIOCallback(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 - */ -static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData) -{ - int c = 0, i = 0, j = 0; - PABLIO_Stream *data = (PABLIO_Stream *) userData; - long numBytes = data->bytesPerFrame * framesPerBuffer; - const int16_t *inputSamples = inputBuffer; - int16_t *chanSamples = (int16_t*)data->iobuff; - - /* This may get called with NULL inputBuffer during initial setup. */ - if (inputBuffer != NULL) { - /* retrieve the data for each channel and put it in the ring buffer */ - for (c = 0; c < data->channelCount; c++) { - for (i = 0, j = c; i < (int)framesPerBuffer; j += data->channelCount, i++) { - chanSamples[i] = inputSamples[j]; - } - if (PaUtil_WriteRingBuffer(&data->inFIFOs[c], chanSamples, numBytes) != numBytes) { - PaUtil_FlushRingBuffer(&data->inFIFOs[c]); - PaUtil_WriteRingBuffer(&data->inFIFOs[c], chanSamples, numBytes); - } - } - } - - return 0; -} - -static int oblockingIOCallback(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; - int16_t *outputSamples = outputBuffer; - int16_t *chanSamples = (short *)data->iobuff; - int c = 0, i = 0, j = 0; - - if (outputBuffer != NULL) { - for (c = 0; c < data->channelCount; c++) { - int numRead = PaUtil_ReadRingBuffer(&data->outFIFOs[c], chanSamples, numBytes); - numRead = numRead / sizeof(int16_t); - for (i = 0, j = c; i < (int)framesPerBuffer; j += data->channelCount, i++) { - if (i < numRead) { - outputSamples[j] = chanSamples[i]; - } else { - outputSamples[j] = 0; - } - } - } - } - - return 0; -} - -static int ioblockingIOCallback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, - void *userData) -{ - iblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData); - oblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData); - return 0; -} - -/* Allocate buffer. */ -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); -} - -/* Free buffer. */ -static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf) -{ - 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, int chan, switch_timer_t *timer) -{ - long bytesWritten; - char *p = (char *) data; - long numBytes = aStream->bytesPerFrame * numFrames; - - switch_core_timer_next(timer); - - bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFOs[chan], p, numBytes); - numBytes -= bytesWritten; - - if (numBytes > 0) { - PaUtil_FlushRingBuffer(&aStream->outFIFOs[chan]); - return 0; - } - 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, int chan, switch_timer_t *timer) -{ - long bytesRead = 0; - char *p = (char *) data; - long avail, totalBytes = 0, neededBytes = aStream->bytesPerFrame * numFrames; - int max = 5000; - - switch_core_timer_next(timer); - - while (totalBytes < neededBytes && --max > 0) { - - avail = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[chan]); - //printf("AVAILABLE BYTES %ld pass %d\n", avail, 5000 - max); - if (avail >= neededBytes * 6) { - PaUtil_FlushRingBuffer(&aStream->inFIFOs[chan]); - } else { - - bytesRead = 0; - - if (totalBytes < neededBytes && avail >= neededBytes) { - bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFOs[chan], p, neededBytes); - totalBytes += bytesRead; - } - - if (bytesRead) { - p += bytesRead; - } else { - switch_cond_next(); - } - } - } - - return totalBytes / aStream->bytesPerFrame; -} - -/************************************************************ - * Return the number of frames that could be written to the stream without - * having to wait. - */ -long GetAudioStreamWriteable(PABLIO_Stream * aStream, int chan) -{ - int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[chan]); - 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, int chan) -{ - int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[chan]); - return bytesFull / aStream->bytesPerFrame; -} - -/***********************************************************/ -static unsigned long RoundUpToNextPowerOf2(unsigned long n) -{ - 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, long samples_per_packet, int do_dual) -{ - long bytesPerSample = 2; - PaError err; - PABLIO_Stream *aStream; - long numFrames; - //long numBytes; - int c = 0; - int channels = 1; - - if (!(inputParameters || outputParameters)) { - return -1; - } - - /* Allocate PABLIO_Stream structure for caller. */ - aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream)); - switch_assert(aStream); - memset(aStream, 0, sizeof(PABLIO_Stream)); - - if (inputParameters) { - channels = inputParameters->channelCount; - } else if (outputParameters) { - channels = outputParameters->channelCount; - } - - numFrames = RoundUpToNextPowerOf2(samples_per_packet * 5); - aStream->bytesPerFrame = bytesPerSample; - aStream->channelCount = channels; - - /* Initialize Ring Buffers */ - - if (inputParameters) { - for (c = 0; c < channels; c++) { - err = PABLIO_InitFIFO(&aStream->inFIFOs[c], numFrames, aStream->bytesPerFrame); - if (err != paNoError) { - goto error; - } - } - aStream->has_in = 1; - } - - if (outputParameters) { - for (c = 0; c < channels; c++) { - err = PABLIO_InitFIFO(&aStream->outFIFOs[c], numFrames, aStream->bytesPerFrame); - if (err != paNoError) { - goto error; - } - } - aStream->has_out = 1; - } - - /* Open a PortAudio stream that we will use to communicate with the underlying - * audio drivers. */ - - aStream->do_dual = do_dual; - - if (aStream->do_dual) { - err = Pa_OpenStream(&aStream->istream, inputParameters, NULL, sampleRate, samples_per_packet, streamFlags, iblockingIOCallback, aStream); - if (err != paNoError) { - goto error; - } - err = Pa_OpenStream(&aStream->ostream, NULL, outputParameters, sampleRate, samples_per_packet, streamFlags, oblockingIOCallback, aStream); - if (err != paNoError) { - goto error; - } - } else { - err = - Pa_OpenStream(&aStream->iostream, inputParameters, outputParameters, sampleRate, samples_per_packet, streamFlags, ioblockingIOCallback, - aStream); - } - - if (err != paNoError) { - goto error; - } - - if (aStream->do_dual) { - err = Pa_StartStream(aStream->istream); - - if (err != paNoError) { - goto error; - } - - err = Pa_StartStream(aStream->ostream); - - if (err != paNoError) { - goto error; - } - - } else { - err = Pa_StartStream(aStream->iostream); - } - - if (err != paNoError) { - goto error; - } - - *rwblPtr = aStream; - - switch_yield(500000); - - return paNoError; - - error: - - CloseAudioStream(aStream); - - *rwblPtr = NULL; - return err; -} - -/************************************************************/ -PaError CloseAudioStream(PABLIO_Stream * aStream) -{ - int bytesEmpty; - int byteSize; - int c = 0; - - - if (aStream->has_out) { - - for (c = 0; c < aStream->channelCount; c++) { - byteSize = aStream->outFIFOs[c].bufferSize; - - /* If we are writing data, make sure we play everything written. */ - if (byteSize > 0) { - bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]); - while (bytesEmpty < byteSize) { - Pa_Sleep(10); - bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]); - } - } - } - } - - if (aStream->do_dual) { - if (aStream->has_in && aStream->istream) { - if (Pa_IsStreamActive(aStream->istream)) { - Pa_StopStream(aStream->istream); - } - - Pa_CloseStream(aStream->istream); - aStream->istream = NULL; - } - - if (aStream->has_out && aStream->ostream) { - if (Pa_IsStreamActive(aStream->ostream)) { - Pa_StopStream(aStream->ostream); - } - - Pa_CloseStream(aStream->ostream); - aStream->ostream = NULL; - } - - } else { - if (aStream->iostream) { - if (Pa_IsStreamActive(aStream->iostream)) { - Pa_StopStream(aStream->iostream); - } - - Pa_CloseStream(aStream->iostream); - aStream->iostream = NULL; - } - } - - if (aStream->has_in) { - for (c = 0; c < aStream->channelCount; c++) { - PABLIO_TermFIFO(&aStream->inFIFOs[c]); - } - } - - if (aStream->has_out) { - for (c = 0; c < aStream->channelCount; c++) { - PABLIO_TermFIFO(&aStream->outFIFOs[c]); - } - } - - free(aStream); - switch_yield(500000); - - return paNoError; -} - diff --git a/src/mod/endpoints/mod_portaudio/pablio.h b/src/mod/endpoints/mod_portaudio/pablio.h deleted file mode 100644 index c40aac7a16..0000000000 --- a/src/mod/endpoints/mod_portaudio/pablio.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef PORTAUDIO_PABLIO_H -#define PORTAUDIO_PABLIO_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * $Id: pablio.h 1083 2006-08-23 07:30:49Z rossb $ - * PABLIO.h - * Portable Audio Blocking read/write utility. - * - * Author: Phil Burk, http://www.softsynth.com/portaudio/ - * - * Include file for PABLIO, the Portable Audio Blocking I/O Library. - * PABLIO is built on top of PortAudio, the Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include -#include -#include -#include "pa_ringbuffer.h" - -/*! Maximum number of channels per stream */ -#define MAX_IO_CHANNELS 2 - -/*! Maximum numer of milliseconds per packet */ -#define MAX_IO_MS 100 - -/*! Maximum sampling rate (48Khz) */ -#define MAX_SAMPLING_RATE 48000 - -/* Maximum size of a read */ -#define MAX_IO_BUFFER (((MAX_IO_MS * MAX_SAMPLING_RATE)/1000)*sizeof(int16_t)) -typedef struct { - PaStream *istream; - PaStream *ostream; - PaStream *iostream; - int bytesPerFrame; - int do_dual; - int has_in; - int has_out; - PaUtilRingBuffer inFIFOs[MAX_IO_CHANNELS]; - PaUtilRingBuffer outFIFOs[MAX_IO_CHANNELS]; - int channelCount; - char iobuff[MAX_IO_BUFFER]; -} PABLIO_Stream; - -/* Values for flags for OpenAudioStream(). */ -#define PABLIO_READ (1<<0) -#define PABLIO_WRITE (1<<1) -#define PABLIO_READ_WRITE (PABLIO_READ|PABLIO_WRITE) -#define PABLIO_MONO (1<<2) -#define PABLIO_STEREO (1<<3) - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, 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, int chan, 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, int chan); - -/************************************************************ - * Return the number of frames that are available to be read from the - * stream without having to wait. - */ -long GetAudioStreamReadable(PABLIO_Stream * aStream, int chan); - -/************************************************************ - * Opens a PortAudio stream with default characteristics. - * Allocates PABLIO_Stream structure. - * - * flags parameter can be an ORed combination of: - * 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, long samples_per_packet, int do_dual); - -PaError CloseAudioStream(PABLIO_Stream * aStream); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _PABLIO_H */ diff --git a/src/mod/formats/mod_portaudio_stream/Makefile.am b/src/mod/formats/mod_portaudio_stream/Makefile.am deleted file mode 100644 index 207a1b792f..0000000000 --- a/src/mod/formats/mod_portaudio_stream/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_portaudio_stream -MODPA_DIR=$(switch_srcdir)/src/mod/endpoints/mod_portaudio - -if HAVE_PORTAUDIO -mod_LTLIBRARIES = mod_portaudio_stream.la -mod_portaudio_stream_la_SOURCES = mod_portaudio_stream.c ../../endpoints/mod_portaudio/pablio.c ../../endpoints/mod_portaudio/pa_ringbuffer.c -mod_portaudio_stream_la_CFLAGS = $(AM_CFLAGS) -mod_portaudio_stream_la_CPPFLAGS = -I. -I$(MODPA_DIR) $(PORTAUDIO_CFLAGS) $(AM_CPPFLAGS) -mod_portaudio_stream_la_LIBADD = $(PORTAUDIO_LIBS) $(switch_builddir)/libfreeswitch.la -mod_portaudio_stream_la_LDFLAGS = -avoid-version -module -no-undefined -shared -if ISMAC -mod_portaudio_stream_la_LDFLAGS += -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon -endif -else -install: error -all: error -error: - $(error You must install portaudio19-dev to build $(MODNAME)) -endif diff --git a/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c b/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c deleted file mode 100644 index e0878a0fe7..0000000000 --- a/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * 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 - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * mod_portaudio_stream.c -- Portaudio Streaming interface Audio - * - */ -#include "switch.h" -#include -#include -#include -#include -#include "pablio.h" - -#define DEFAULT_PREBUFFER_SIZE 1024 * 64 -#define SAMPLE_TYPE paInt16 -#define PREFERRED_RATE 8000 - -SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_stream_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_stream_shutdown); -SWITCH_MODULE_DEFINITION(mod_portaudio_stream, mod_portaudio_stream_load, mod_portaudio_stream_shutdown, NULL); -static switch_memory_pool_t *module_pool = NULL; - -struct portaudio_stream_source; - -static struct { - int running; - int threads; - switch_mutex_t *mutex; - switch_hash_t *source_hash; - -} globals; - - -struct portaudio_stream_context { - struct portaudio_stream_source *source; - switch_mutex_t *audio_mutex; - switch_buffer_t *audio_buffer; - int err; - const char *func; - const char *file; - int line; - switch_file_handle_t *handle; - struct portaudio_stream_context *next; -}; - -typedef struct portaudio_stream_context portaudio_stream_context_t; - -struct portaudio_stream_source { - char *sourcename; - int sourcedev; - int rate; - int interval; - char *timer_name; - int total; - int ready; - int stopped; - uint8_t channels; - switch_size_t samples; - uint32_t prebuf; - portaudio_stream_context_t *context_list; - switch_mutex_t *mutex; - switch_memory_pool_t *pool; - switch_thread_rwlock_t *rwlock; - PABLIO_Stream *audio_stream; - switch_frame_t read_frame; - switch_timer_t timer; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_mutex_t *device_lock; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; -}; - -typedef struct portaudio_stream_source portaudio_stream_source_t; - - - -static int get_dev_by_number(char *numstr, int in) -{ - int numDevices = Pa_GetDeviceCount(); - const PaDeviceInfo *pdi; - char *end_ptr; - int number; - - number = (int) strtol(numstr, &end_ptr, 10); - - if (end_ptr == numstr || number < 0) { - 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) -{ - int i; - int numDevices; - const PaDeviceInfo *pdi; - numDevices = Pa_GetDeviceCount(); - - if (numDevices < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices); - return -2; - } - - for (i = 0; i < numDevices; i++) { - int match = 0; - pdi = Pa_GetDeviceInfo(i); - - if (zstr(name)) { - match = 1; - } else if (pdi && pdi->name && strstr(pdi->name, name)) { - match = 1; - } - - if (match) { - if (in && pdi->maxInputChannels) { - return i; - } else if (!in && pdi->maxOutputChannels) { - return i; - } - } - } - - return -1; -} - -static switch_status_t engage_device(portaudio_stream_source_t *source, int restart) -{ - PaStreamParameters inputParameters, outputParameters; - PaError err; - int sample_rate = source->rate; - int codec_ms = source->interval; - - switch_mutex_init(&source->device_lock, SWITCH_MUTEX_NESTED, module_pool); - - if (source->timer.timer_interface) { - switch_core_timer_sync(&source->timer); - } - - if (source->audio_stream) { - return SWITCH_STATUS_SUCCESS; - } - - if (!switch_core_codec_ready(&source->read_codec)) { - if (switch_core_codec_init(&source->read_codec, - "L16", - NULL, 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; - } - } - - switch_assert(source->read_codec.implementation); - - if (!switch_core_codec_ready(&source->write_codec)) { - if (switch_core_codec_init(&source->write_codec, - "L16", - NULL, 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(&source->read_codec); - return SWITCH_STATUS_FALSE; - } - } - - - if (!source->timer.timer_interface) { - if (switch_core_timer_init(&source->timer, - source->timer_name, codec_ms, source->read_codec.implementation->samples_per_packet, - module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n"); - switch_core_codec_destroy(&source->read_codec); - switch_core_codec_destroy(&source->write_codec); - return SWITCH_STATUS_FALSE; - } - } - - source->read_frame.rate = sample_rate; - source->read_frame.codec = &source->read_codec; - - switch_mutex_lock(source->device_lock); - /* LOCKED ************************************************************************************************** */ - inputParameters.device = source->sourcedev; - inputParameters.channelCount = 1; - inputParameters.sampleFormat = SAMPLE_TYPE; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = NULL; - outputParameters.device = source->sourcedev; - outputParameters.channelCount = 1; - outputParameters.sampleFormat = SAMPLE_TYPE; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - - - err = OpenAudioStream(&source->audio_stream, &inputParameters, NULL, sample_rate, paClipOff, source->read_codec.implementation->samples_per_packet, 0); - /* UNLOCKED ************************************************************************************************* */ - if (err != paNoError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n"); - switch_yield(1000000); - err = OpenAudioStream(&source->audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, - source->read_codec.implementation->samples_per_packet, 0); - } - - switch_mutex_unlock(source->device_lock); - if (err != paNoError) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n"); - switch_core_codec_destroy(&source->read_codec); - switch_core_timer_destroy(&source->timer); - return SWITCH_STATUS_FALSE; - } - - - return SWITCH_STATUS_SUCCESS; -} - -static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void *obj) -{ - portaudio_stream_source_t *source = obj; - portaudio_stream_context_t *cp; - int samples; - int bused, bytesToWrite; - - - switch_mutex_lock(globals.mutex); - globals.threads++; - switch_mutex_unlock(globals.mutex); - - if (!source->prebuf) { - source->prebuf = DEFAULT_PREBUFFER_SIZE; - } - - - - switch_mutex_lock(globals.mutex); - switch_core_hash_insert(globals.source_hash, source->sourcename, source); - switch_mutex_unlock(globals.mutex); - - - switch_thread_rwlock_create(&source->rwlock, source->pool); - - if (engage_device(source, 0) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Dev %d cant be engaged !\n", (int) source->sourcedev); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " Dev %d engaged at %d rate!\n", (int) source->sourcedev, (int) source->rate); - if (globals.running && !source->stopped) { - source->ready = 1; - - if (!source->audio_stream) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Audio Stream wops!\n"); - source->stopped = 0; - source->ready = 0; - } else { - while (globals.running && !source->stopped) { - switch_mutex_lock(source->device_lock); - samples = ReadAudioStream(source->audio_stream, source->databuf, - source->read_codec.implementation->samples_per_packet, 0, &source->timer); - switch_mutex_unlock(source->device_lock); - - - if (samples) { - bytesToWrite = source->samples; - if (samples < bytesToWrite) { - bytesToWrite = samples; - } - bytesToWrite *= source->audio_stream->bytesPerFrame; - - if (source->total) { - - switch_mutex_lock(source->mutex); - for (cp = source->context_list; cp; cp = cp->next) { - - switch_mutex_lock(cp->audio_mutex); - - bused = switch_buffer_inuse(cp->audio_buffer); - if (bused > source->samples * 768) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d] %d used %d max\n", - cp->func, cp->file, cp->line, (int) bused, (int) (source->samples * 768)); - switch_buffer_zero(cp->audio_buffer); - } else { - switch_buffer_write(cp->audio_buffer, source->databuf, bytesToWrite); - } - - switch_mutex_unlock(cp->audio_mutex); - } - switch_mutex_unlock(source->mutex); - } - - } - - } - } - - } - } - - - source->ready = 0; - - switch_mutex_lock(globals.mutex); - switch_core_hash_delete(globals.source_hash, source->sourcename); - switch_mutex_unlock(globals.mutex); - - switch_thread_rwlock_wrlock(source->rwlock); - switch_thread_rwlock_unlock(source->rwlock); - - - switch_mutex_lock(source->device_lock); - CloseAudioStream(source->audio_stream); - if (switch_core_codec_ready(&source->read_codec)) { - switch_core_codec_destroy(&source->read_codec); - switch_core_codec_destroy(&source->write_codec); - } - if (switch_core_codec_ready(&source->write_codec)) { - switch_core_codec_destroy(&source->write_codec); - } - switch_mutex_unlock(source->device_lock); - - - switch_core_destroy_memory_pool(&source->pool); - - switch_mutex_lock(globals.mutex); - globals.threads--; - switch_mutex_unlock(globals.mutex); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " thread ending succesfully !\n"); - switch_thread_exit(thread, SWITCH_STATUS_SUCCESS); - - return NULL; -} - - -static switch_status_t portaudio_stream_file_open(switch_file_handle_t *handle, const char *path) -{ - portaudio_stream_context_t *context; - portaudio_stream_source_t *source; - switch_memory_pool_t *pool; - switch_status_t status = SWITCH_STATUS_FALSE; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - uint32_t rate = PREFERRED_RATE; - char *npath; - int devNumber; - int tmp; - - handle->pre_buffer_datalen = 0; - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing! (yet)\n"); - return status; - } - - npath = switch_core_strdup(module_pool, path); - - tmp = handle->samplerate; - if (tmp == 8000 || tmp == 16000 || tmp == 32000 || tmp == 48000) { - rate = tmp; - } - - if (*path == '#') { - devNumber = get_dev_by_number(npath + 1, 1); - } else { - devNumber = get_dev_by_name(npath, 1); - } - npath = switch_mprintf("device-%d at %d", devNumber, rate); - - switch_mutex_lock(globals.mutex); - source = switch_core_hash_find(globals.source_hash, npath); - - /* dev isnt there, try to start thread */ - if (!source) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " source isnt Created, create and start thread!\n"); - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, " :S no pool\n"); - } else { - source = switch_core_alloc(pool, sizeof(*source)); - if (source != NULL) { - source->pool = pool; - source->sourcedev = devNumber; - source->sourcename = switch_core_strdup(source->pool, npath); - source->rate = rate; - source->interval = 20; - source->channels = 1; - source->timer_name = "soft"; - source->prebuf = DEFAULT_PREBUFFER_SIZE; - source->stopped = 0; - source->ready = 0; - source->samples = switch_samples_per_packet(source->rate, source->interval); - - switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool); - - switch_threadattr_create(&thd_attr, source->pool); - switch_threadattr_detach_set(thd_attr, 1); - - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool); - } - } - } - switch_mutex_unlock(globals.mutex); - switch_yield(1000000); - /* dev already engaged */ - if (source) { - - /*wait for source to be ready */ - while (source->ready == 0) { - switch_yield(100000); - } - - if (switch_thread_rwlock_tryrdlock(source->rwlock) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " error rwlock !\n"); - source = NULL; - } - } - - if (source) { - status = SWITCH_STATUS_SUCCESS; - - if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, " error allocating context!\n"); - status = SWITCH_STATUS_MEMERR; - } else { - /* everything goes fine at this point */ - handle->samples = 0; - handle->samplerate = source->rate; - handle->channels = 1; - handle->format = 0; - handle->sections = 0; - handle->seekable = 0; - handle->speed = 0; - handle->private_info = context; - handle->interval = source->interval; - - switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); - if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); - status = SWITCH_STATUS_MEMERR; - } else { - /* context created... then continue */ - context->source = source; - context->file = handle->file; - context->func = handle->func; - context->line = handle->line; - context->handle = handle; - switch_mutex_lock(source->mutex); - context->next = source->context_list; - source->context_list = context; - source->total++; - switch_mutex_unlock(source->mutex); - } - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown source %s\n", path); - status = SWITCH_STATUS_FALSE; - } - - return status; -} - - -static switch_status_t portaudio_stream_file_close(switch_file_handle_t *handle) -{ - portaudio_stream_context_t *cp, *last = NULL, *context = handle->private_info; - - - switch_mutex_lock(context->source->mutex); - for (cp = context->source->context_list; cp; cp = cp->next) { - if (cp == context) { - if (last) { - last->next = cp->next; - } else { - context->source->context_list = cp->next; - } - break; - } - last = cp; - } - context->source->total--; - switch_mutex_unlock(context->source->mutex); - switch_buffer_destroy(&context->audio_buffer); - switch_thread_rwlock_unlock(context->source->rwlock); - - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t portaudio_stream_file_read(switch_file_handle_t *handle, void *data, size_t *len) -{ - portaudio_stream_context_t *context = handle->private_info; - switch_size_t bytes = 0; - int bytesPerSample = context->source->audio_stream->bytesPerFrame; - size_t need = *len * bytesPerSample; - - if (!context->source->ready) { - *len = 0; - return SWITCH_STATUS_FALSE; - } - - switch_mutex_lock(context->audio_mutex); - if ((bytes = switch_buffer_read(context->audio_buffer, data, need))) { - *len = bytes / bytesPerSample; - } else { - if (need > 2560) { - need = 2560; - } - memset(data, 255, need); - *len = need / bytesPerSample; - } - switch_mutex_unlock(context->audio_mutex); - - - - handle->sample_count += *len; - return SWITCH_STATUS_SUCCESS; - - -} - -/* Registration */ - -static char *supported_formats[SWITCH_MAX_CODECS] = { 0 }; - -static void shutdown_event_handler(switch_event_t *event) -{ - globals.running = 0; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_stream_load) -{ - switch_file_interface_t *file_interface; - supported_formats[0] = "portaudio_stream"; - - module_pool = pool; - - Pa_Initialize(); - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); - file_interface->interface_name = modname; - file_interface->extens = supported_formats; - file_interface->file_open = portaudio_stream_file_open; - file_interface->file_close = portaudio_stream_file_close; - file_interface->file_read = portaudio_stream_file_read; - - if (switch_event_bind(modname, SWITCH_EVENT_SHUTDOWN, SWITCH_EVENT_SUBCLASS_ANY, shutdown_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind shutdown event handler!\n"); - } - - memset(&globals, 0, sizeof(globals)); - globals.running = 1; - globals.threads = 0; - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); - switch_core_hash_init(&globals.source_hash); - - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_stream_shutdown) -{ - globals.running = 0; - switch_event_unbind_callback(shutdown_event_handler); - - while (globals.threads > 0) { - switch_yield(100000); - } - - Pa_Terminate(); - - switch_core_hash_destroy(&globals.source_hash); - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index 5bd65cfa18..3540628eda 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -529,14 +529,6 @@ Binaries;Content;Satellites INSTALLFOLDER - - mod_PortAudio - {5fd31a25-5d83-4794-8bee-904dad84ce71} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - mod_rtc {3884add2-91d0-4cd6-86d3-d5fb2d4aab9e} diff --git a/w32/Setup/inno_setup/fscomm.iss b/w32/Setup/inno_setup/fscomm.iss index 56c28874eb..6e21f8caa3 100644 --- a/w32/Setup/inno_setup/fscomm.iss +++ b/w32/Setup/inno_setup/fscomm.iss @@ -66,7 +66,6 @@ Source: {#FreeSWITCH_32bit}\mod\mod_event_socket.dll; DestDir: {app}\mod; Flags: Source: {#FreeSWITCH_32bit}\mod\mod_ilbc.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_local_stream.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_loopback.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode -Source: {#FreeSWITCH_32bit}\mod\mod_PortAudio.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_siren.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_sndfile.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode Source: {#FreeSWITCH_32bit}\mod\mod_sofia.dll; DestDir: {app}\mod; Flags: 32bit ignoreversion onlyifdoesntexist; Check: not Is64BitInstallMode diff --git a/w32/download_portaudio.props b/w32/download_portaudio.props deleted file mode 100644 index 8a9b16049e..0000000000 --- a/w32/download_portaudio.props +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - true - - - - - - - - - From 4235d86aeedd4951ef61e45f5273534afc113fb9 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 28 Aug 2024 21:30:43 +0300 Subject: [PATCH 3/3] [mod_mp4, mod_mp4v, mod_mp4v2] Remove from tree --- build/modules.conf.in | 3 - build/modules.conf.most | 2 - ci.sh | 1 - configure.ac | 3 - debian/bootstrap.sh | 4 - debian/control-modules | 14 - freeswitch.spec | 13 +- src/mod/applications/mod_mp4/Makefile.am | 8 - src/mod/applications/mod_mp4/exception.hpp | 59 -- src/mod/applications/mod_mp4/mod_mp4.cpp | 550 -------------- src/mod/applications/mod_mp4/mp4_helper.cpp | 136 ---- src/mod/applications/mod_mp4/mp4_helper.hpp | 143 ---- src/mod/applications/mod_mp4v2/Makefile.am | 8 - src/mod/applications/mod_mp4v2/mod_mp4v2.c | 772 -------------------- src/mod/codecs/mod_mp4v/Makefile.am | 8 - src/mod/codecs/mod_mp4v/mod_mp4v.c | 102 --- 16 files changed, 1 insertion(+), 1825 deletions(-) delete mode 100644 src/mod/applications/mod_mp4/Makefile.am delete mode 100644 src/mod/applications/mod_mp4/exception.hpp delete mode 100644 src/mod/applications/mod_mp4/mod_mp4.cpp delete mode 100644 src/mod/applications/mod_mp4/mp4_helper.cpp delete mode 100644 src/mod/applications/mod_mp4/mp4_helper.hpp delete mode 100644 src/mod/applications/mod_mp4v2/Makefile.am delete mode 100644 src/mod/applications/mod_mp4v2/mod_mp4v2.c delete mode 100644 src/mod/codecs/mod_mp4v/Makefile.am delete mode 100644 src/mod/codecs/mod_mp4v/mod_mp4v.c diff --git a/build/modules.conf.in b/build/modules.conf.in index 76f192308c..de87399e74 100755 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -29,8 +29,6 @@ applications/mod_httapi #applications/mod_lcr #applications/mod_memcache #applications/mod_mongo -#applications/mod_mp4 -#applications/mod_mp4v2 #applications/mod_nibblebill #applications/mod_oreka #applications/mod_osp @@ -69,7 +67,6 @@ codecs/mod_g729 codecs/mod_h26x #codecs/mod_ilbc #codecs/mod_isac -#codecs/mod_mp4v codecs/mod_opus #codecs/mod_silk #codecs/mod_siren diff --git a/build/modules.conf.most b/build/modules.conf.most index 943ff71336..ad14f0bb7a 100755 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -29,7 +29,6 @@ applications/mod_http_cache applications/mod_lcr applications/mod_memcache applications/mod_mongo -applications/mod_mp4 applications/mod_nibblebill applications/mod_oreka #applications/mod_osp @@ -67,7 +66,6 @@ codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac -codecs/mod_mp4v codecs/mod_opus codecs/mod_silk codecs/mod_siren diff --git a/ci.sh b/ci.sh index d7322c4432..26947f6a70 100755 --- a/ci.sh +++ b/ci.sh @@ -93,7 +93,6 @@ configure_freeswitch() sed -i \ -e '/mod_ilbc/s/^/#/g' \ -e '/mod_isac/s/^/#/g' \ - -e '/mod_mp4/s/^/#/g' \ -e '/mod_mongo/s/^/#/g' \ -e '/mod_pocketsphinx/s/^/#/g' \ -e '/mod_siren/s/^/#/g' \ diff --git a/configure.ac b/configure.ac index e56bc72e9d..4b90871540 100755 --- a/configure.ac +++ b/configure.ac @@ -2119,8 +2119,6 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_limit/Makefile src/mod/applications/mod_memcache/Makefile src/mod/applications/mod_mongo/Makefile - src/mod/applications/mod_mp4/Makefile - src/mod/applications/mod_mp4v2/Makefile src/mod/applications/mod_nibblebill/Makefile src/mod/applications/mod_oreka/Makefile src/mod/applications/mod_osp/Makefile @@ -2160,7 +2158,6 @@ AC_CONFIG_FILES([Makefile src/mod/codecs/mod_h26x/Makefile src/mod/codecs/mod_ilbc/Makefile src/mod/codecs/mod_isac/Makefile - src/mod/codecs/mod_mp4v/Makefile src/mod/codecs/mod_opus/Makefile src/mod/codecs/mod_openh264/Makefile src/mod/codecs/mod_silk/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index d3a00c7071..d77ca48d3f 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -35,8 +35,6 @@ supported_distros="$supported_debian_distros $supported_ubuntu_distros" avoid_mods=( applications/mod_limit applications/mod_mongo - applications/mod_mp4 - applications/mod_mp4v2 applications/mod_osp applications/mod_rad_auth applications/mod_skel @@ -712,7 +710,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g729 (= \${binary:Version}), freeswitch-mod-h26x (= \${binary:Version}), freeswitch-mod-isac (= \${binary:Version}), - freeswitch-mod-mp4v (= \${binary:Version}), freeswitch-mod-opus (= \${binary:Version}), freeswitch-mod-silk (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), @@ -738,7 +735,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g729-dbg (= \${binary:Version}), freeswitch-mod-h26x-dbg (= \${binary:Version}), freeswitch-mod-isac-dbg (= \${binary:Version}), - freeswitch-mod-mp4v-dbg (= \${binary:Version}), freeswitch-mod-opus-dbg (= \${binary:Version}), freeswitch-mod-silk-dbg (= \${binary:Version}), freeswitch-mod-spandsp-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index b11dc10005..2261416c47 100755 --- a/debian/control-modules +++ b/debian/control-modules @@ -149,16 +149,6 @@ Description: MongoDB This module provides an interface to MongoDB. Build-Depends: libmongoc-dev -Module: applications/mod_mp4 -Section: contrib/comm -Description: MP4 video support - This module adds support for MP4 video playback. -Build-Depends: libmp4v2-dev - -Module: applications/mod_mp4v2 -Description: Adds mod_mp4v2 - Adds mod_mp4v2. - Module: applications/mod_nibblebill Description: Nibblebill This module allows for real-time accounting of a cash balance and @@ -333,10 +323,6 @@ Module: codecs/mod_isac Description: mod_isac Adds mod_isac. -Module: codecs/mod_mp4v -Description: mod_mp4v - Adds mod_mp4v. - Module: codecs/mod_openh264 Description: Adds mod_openh264 Adds mod_openh264. diff --git a/freeswitch.spec b/freeswitch.spec index 773b8784c7..8761ca2365 100755 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -722,14 +722,6 @@ Requires: %{name} = %{version}-%{release} %description codec-vpx iSAC Codec support for FreeSWITCH open source telephony platform -%package codec-mp4v -Summary: MP4V Video Codec support for FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description codec-mp4v -MP4V Video Codec support for FreeSWITCH open source telephony platform - %package codec-opus Summary: Opus Codec support for FreeSWITCH open source telephony platform Group: System/Libraries @@ -1351,7 +1343,7 @@ ASR_TTS_MODULES="asr_tts/mod_flite asr_tts/mod_pocketsphinx asr_tts/mod_tts_comm # ###################################################################################################################### CODECS_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_bv codecs/mod_codec2 codecs/mod_g723_1 \ - codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_mp4v codecs/mod_opus codecs/mod_silk \ + codecs/mod_g729 codecs/mod_h26x codecs/mod_ilbc codecs/mod_isac codecs/mod_opus codecs/mod_silk \ codecs/mod_siren codecs/mod_theora" # @@ -2075,9 +2067,6 @@ fi %files codec-isac %{MODINSTDIR}/mod_isac.so* -%files codec-mp4v -%{MODINSTDIR}/mod_mp4v.so* - %files codec-opus %{MODINSTDIR}/mod_opus.so* %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/opus.conf.xml diff --git a/src/mod/applications/mod_mp4/Makefile.am b/src/mod/applications/mod_mp4/Makefile.am deleted file mode 100644 index 46d3f78dfa..0000000000 --- a/src/mod/applications/mod_mp4/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4 - -mod_LTLIBRARIES = mod_mp4.la -mod_mp4_la_SOURCES = mod_mp4.cpp mp4_helper.cpp -mod_mp4_la_CFLAGS = $(AM_CFLAGS) -mod_mp4_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lmp4v2 diff --git a/src/mod/applications/mod_mp4/exception.hpp b/src/mod/applications/mod_mp4/exception.hpp deleted file mode 100644 index 75f84989a2..0000000000 --- a/src/mod/applications/mod_mp4/exception.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - -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 -http://www.mozilla.org/MPL/ - -Software distributed under the License is distributed on an "AS IS" -basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -License for the specific language governing rights and limitations -under the License. - -The Original Code is MP4 Helper Library to Freeswitch MP4 module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -*/ - -#ifndef EXCEPTION_HPP_ -#define EXCEPTION_HPP_ - -#include -#include - -class Exception: public std::exception { - public: - Exception() - { - } - - Exception(const std::string & message): message_(message) - { - } - - Exception(const std::exception & e): message_(e.what()) - { - } - - Exception(const Exception & e): message_(e.message_) - { - } - - virtual ~Exception() throw() - { - } - - const char * what() const throw() - { - return message_.c_str(); - } - - private: - std::string message_; -}; - -#endif \ No newline at end of file diff --git a/src/mod/applications/mod_mp4/mod_mp4.cpp b/src/mod/applications/mod_mp4/mod_mp4.cpp deleted file mode 100644 index 433642d816..0000000000 --- a/src/mod/applications/mod_mp4/mod_mp4.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * 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 - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Paulo Rogério Panhoto - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * mod_mp4 -- MP4 File Format support for video apps. - * - */ - -#include -#include "mp4_helper.hpp" -#include "exception.hpp" - - -#ifndef min -#define min(x, y) ((x) < (y) ? (x) : (y)) -#endif - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4_load); -SWITCH_MODULE_DEFINITION(mod_mp4, mod_mp4_load, NULL, NULL); - -#define VID_BIT (1 << 31) -#define VERSION 4201 - -#ifdef MP4_RECORD -struct file_header { - int32_t version; - char video_codec_name[32]; - char video_fmtp[128]; - uint32_t audio_rate; - uint32_t audio_ptime; - switch_time_t created; -}; - -struct record_helper { - switch_core_session_t *session; - switch_mutex_t *mutex; - int fd; - int up; -}; -#endif - -struct AVParams { - switch_core_session_t * session; - switch_channel_t * channel; - switch_timer_t * timer; - switch_frame_t * frame; - switch_mutex_t * mutex; - bool video; - switch_payload_t pt; - MP4::Context * vc; - bool done; - bool * quit; -}; - -static void *SWITCH_THREAD_FUNC record_video_thread(switch_thread_t *thread, void *obj) -{ -#ifdef MP4_RECORD - record_helper *eh = reinterpret_cast(obj); - switch_core_session_t *session = eh->session; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_status_t status; - switch_frame_t *read_frame; - int bytes; - - eh->up = 1; - while (switch_channel_ready(channel)) { - status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - - if (!SWITCH_READ_ACCEPTABLE(status)) { - break; - } - - if (switch_test_flag(read_frame, SFF_CNG)) { - continue; - } - - bytes = read_frame->packetlen | VID_BIT; - - switch_mutex_lock(eh->mutex); - - if (write(eh->fd, &bytes, sizeof(bytes)) != (int) sizeof(bytes)) { - switch_mutex_unlock(eh->mutex); - break; - } - - if (write(eh->fd, read_frame->packet, read_frame->packetlen) != (int) read_frame->packetlen) { - switch_mutex_unlock(eh->mutex); - break; - } - - switch_mutex_unlock(eh->mutex); - - switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0); - } - eh->up = 0; -#endif - return NULL; -} - -SWITCH_STANDARD_APP(record_mp4_function) -{ -#ifdef MP4_RECORD - switch_status_t status; - switch_frame_t *read_frame; - switch_channel_t *channel = switch_core_session_get_channel(session); - struct record_helper eh = { 0 }; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - int fd; - switch_mutex_t *mutex = NULL; - switch_codec_t codec, *vid_codec; - switch_codec_implementation_t read_impl = { }; - int count = 0, sanity = 30; - - switch_core_session_get_read_impl(session, &read_impl); - switch_channel_answer(channel); - - - while (switch_channel_up(channel) && !switch_channel_test_flag(channel, CF_VIDEO)) { - switch_yield(10000); - - if (count) count--; - - if (count == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s waiting for video.\n", switch_channel_get_name(channel)); - count = 100; - if (!--sanity) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s timeout waiting for video.\n", - switch_channel_get_name(channel)); - return; - } - } - } - - if (!switch_channel_ready(channel)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s not ready.\n", switch_channel_get_name(channel)); - return; - } - -/* - if ((fd = open((char *) data, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) < 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data); - return; - } -*/ - - MP4::Context ctx(reinterpret_cast(data), true); - - if (switch_core_codec_init(&codec, - "L16", - NULL, - NULL, - read_impl.samples_per_second, - read_impl.microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) - { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n"); - goto end; - } - - switch_core_session_set_read_codec(session, &codec); - - if (switch_channel_test_flag(channel, CF_VIDEO)) { - struct file_header h; - memset(&h, 0, sizeof(h)); - vid_codec = switch_core_session_get_video_read_codec(session); - - h.version = VERSION; - h.created = switch_micro_time_now(); - switch_set_string(h.video_codec_name, vid_codec->implementation->iananame); - if (vid_codec->fmtp_in) { - switch_set_string(h.video_fmtp, vid_codec->fmtp_in); - } - h.audio_rate = read_impl.samples_per_second; - h.audio_ptime = read_impl.microseconds_per_packet / 1000; - - if (write(fd, &h, sizeof(h)) != sizeof(h)) { - goto end; - } - - switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - eh.mutex = mutex; - eh.fd = fd; - eh.session = session; - switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, record_video_thread, &eh, switch_core_session_get_pool(session)); - } - - - while (switch_channel_ready(channel)) { - - status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - - if (!SWITCH_READ_ACCEPTABLE(status)) { - break; - } - - if (switch_test_flag(read_frame, SFF_CNG)) { - continue; - } - - if (mutex) { - switch_mutex_lock(mutex); - } - - if (write(fd, &read_frame->datalen, sizeof(read_frame->datalen)) != sizeof(read_frame->datalen)) { - if (mutex) { - switch_mutex_unlock(mutex); - } - break; - } - - if (write(fd, read_frame->data, read_frame->datalen) != (int) read_frame->datalen) { - if (mutex) { - switch_mutex_unlock(mutex); - } - break; - } - - if (mutex) { - switch_mutex_unlock(mutex); - } - } - - - end: - - if (eh.up) { - while (eh.up) { - switch_cond_next(); - } - } - - switch_core_session_set_read_codec(session, NULL); - switch_core_codec_destroy(&codec); -#endif -} - -static void *SWITCH_THREAD_FUNC play_video_function(switch_thread_t *thread, void *obj) -{ - AVParams * pt = reinterpret_cast(obj); - u_int next = 0, first = 0xffffffff; - uint64_t ts = 0, control = 0; - - bool ok; - bool sent = true; - pt->done = false; - switch_time_t start = switch_time_now(); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Video thread Started\n"); - while (!*pt->quit && switch_channel_ready(pt->channel)) { - if (pt->video) { - if (sent) { - switch_mutex_lock(pt->mutex); - pt->frame->packetlen = pt->frame->buflen; - ok = pt->vc->getVideoPacket(pt->frame->packet, pt->frame->packetlen, next); - switch_mutex_unlock(pt->mutex); - sent = false; - if (ok) { - switch_rtp_hdr_t *hdr = reinterpret_cast(pt->frame->packet); - if(first == 0xffffffff) first = next; - next -= first; - control = next * 90000LL / pt->vc->videoTrack().track.clock; - control -= first; - hdr->ts = htonl(control); - control = control * 1000 / 90; - if (pt->pt) - hdr->pt = pt->pt; - } else break; - } - - ts = switch_time_now() - start; - int64_t wait = control > ts ? (control - ts) : 0; - - if (wait > 0) { - switch_cond_next(); - // wait the time for the next Video frame - switch_sleep(wait); - } - - if (switch_channel_test_flag(pt->channel, CF_VIDEO)) { - switch_byte_t *data = (switch_byte_t *) pt->frame->packet; - - pt->frame->data = data + 12; - pt->frame->datalen = pt->frame->packetlen - 12; - switch_core_session_write_video_frame(pt->session, pt->frame, SWITCH_IO_FLAG_NONE, 0); - sent = true; - } - - } - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Video thread ended\n"); - pt->done = true; - return NULL; -} - -static void *SWITCH_THREAD_FUNC play_audio_function(switch_thread_t *thread, void *obj) -{ - AVParams * pt = reinterpret_cast(obj); - u_int next = 0, first = 0xffffffff; - uint64_t ts = 0, control = 0; - - bool ok; - bool sent = true; - switch_dtmf_t dtmf = {0}; - pt->done = false; - switch_frame_t * read_frame; - - while (!*pt->quit && switch_channel_ready(pt->channel)) { - // event processing. - // -- SEE switch_ivr_play_say.c:1231 && mod_dptools.c:1428 && mod_dptools.c:1919 - switch_core_session_read_frame(pt->session, &read_frame, SWITCH_IO_FLAG_SINGLE_READ, 0); - - if (switch_channel_test_flag(pt->channel, CF_BREAK)) { - switch_channel_clear_flag(pt->channel, CF_BREAK); - break; - } - - switch_ivr_parse_all_events(pt->session); - - if (switch_channel_has_dtmf(pt->channel)) { - switch_channel_dequeue_dtmf(pt->channel, &dtmf); - const char * terminators = switch_channel_get_variable(pt->channel, SWITCH_PLAYBACK_TERMINATORS_VARIABLE); - if (terminators && !strcasecmp(terminators, "none")) terminators = NULL; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Digit %c\n", dtmf.digit); - if (terminators && strchr(terminators, dtmf.digit)) { - std::string digit(&dtmf.digit, 0, 1); - switch_channel_set_variable(pt->channel, SWITCH_PLAYBACK_TERMINATOR_USED, digit.c_str()); - break; - } - } - - switch_mutex_lock(pt->mutex); - pt->frame->datalen = pt->frame->buflen; - ok = pt->vc->getAudioPacket(pt->frame->data, pt->frame->datalen, next); - switch_mutex_unlock(pt->mutex); - - if (ok) { - if (pt->frame->datalen > (int) pt->frame->buflen) - pt->frame->datalen = pt->frame->buflen; - - switch_core_session_write_frame(pt->session, pt->frame, SWITCH_IO_FLAG_NONE, 0); - switch_core_timer_next(pt->timer); - } - else break; - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pt->session), SWITCH_LOG_DEBUG, "Audio done\n"); - *pt->quit = pt->done = true; - return NULL; -} - -SWITCH_STANDARD_APP(play_mp4_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_frame_t write_frame = { 0 }, vid_frame = {0}; - switch_codec_t codec = { 0 }, vid_codec = {0}, *read_vid_codec; - unsigned char *aud_buffer; - unsigned char *vid_buffer; - switch_timer_t timer = { 0 }; - switch_codec_implementation_t read_impl = {}; - bool done = false; - - try { - MP4::Context vc((char *) data); - - switch_payload_t pt = 0; - - switch_core_session_get_read_impl(session, &read_impl); - - aud_buffer = (unsigned char *) switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); - vid_buffer = (unsigned char *) switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); - - /* - if (!vc.isOpen()) - { - char msgbuf[1024]; - sprintf(msgbuf, "PLAYBACK ERROR (%s): FILE NOT FOUND.", (char*) data); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, msgbuf); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data); - return; - } - - if(!vc.isSupported()) - { - char msgbuf[1024]; - sprintf(msgbuf, "PLAYBACK ERROR (%s): UNSUPPORTED FORMAT OR FILE NOT HINTED.", (char*) data); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, msgbuf); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, - "Error reading track info. Maybe this file is not hinted.\n"); - throw 1; - } - */ - - switch_channel_set_variable(channel, "rtp_force_video_fmtp", vc.videoTrack().fmtp.c_str()); - switch_channel_answer(channel); - - if ((read_vid_codec = switch_core_session_get_video_read_codec(session))) { - pt = read_vid_codec->agreed_pt; - } - - write_frame.codec = &codec; - write_frame.data = aud_buffer; - write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; - - vid_frame.codec = &vid_codec; - vid_frame.packet = vid_buffer; - vid_frame.data = vid_buffer + 12; - vid_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE - 12; - switch_set_flag((&vid_frame), SFF_RAW_RTP); - switch_set_flag((&vid_frame), SFF_PROXY_PACKET); - - if (switch_core_timer_init(&timer, "soft", read_impl.microseconds_per_packet / 1000, - read_impl.samples_per_packet, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Timer Activation Fail\n"); - throw 2; - } - - if (switch_core_codec_init(&codec, - vc.audioTrack().codecName, - NULL, - NULL, - vc.audioTrack().clock, - vc.audioTrack().packetLength, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - throw Exception("Audio Codec Activation Fail"); - } - - if (switch_core_codec_init(&vid_codec, - vc.videoTrack().track.codecName, - NULL, - NULL, - 0, - 0, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Activation Success\n"); - } else - { - throw Exception("Video Codec Activation Fail"); - } - switch_core_session_set_read_codec(session, &codec); - - AVParams vpt; - vpt.session = session; - vpt.channel = channel; - vpt.frame = &vid_frame; - vpt.timer = &timer; - vpt.video = true; - vpt.pt = pt; - vpt.vc = &vc; - switch_mutex_init(&vpt.mutex, SWITCH_MUTEX_DEFAULT, switch_core_session_get_pool(session)); - vpt.quit = &done; - - switch_threadattr_t * thd_attr; - switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_t *thread; - switch_thread_create(&thread, thd_attr, play_video_function, (void*)&vpt, switch_core_session_get_pool(session)); - - AVParams apt; - apt.session = session; - apt.channel = channel; - apt.frame = &write_frame; - apt.timer = &timer; - apt.video = false; - apt.vc = &vc; - apt.mutex = vpt.mutex; - apt.quit = &done; - play_audio_function(NULL, &apt); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Waiting for video thread to join.\n"); - while (!vpt.done) { - switch_cond_next(); - } - - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "FILE PLAYED"); - } catch(const std::exception & e) - { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s\n", e.what()); - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, - (std::string("PLAYBACK_FAILED - ") + e.what()).c_str()); - }catch(...) - { - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "PLAYBACK_FAILED - See FS logs for detail."); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Exception caught.\n"); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "All done.\n"); - if (timer.interval) switch_core_timer_destroy(&timer); - - switch_core_session_set_read_codec(session, NULL); - - if (switch_core_codec_ready(&codec)) switch_core_codec_destroy(&codec); - - if (switch_core_codec_ready(&vid_codec)) switch_core_codec_destroy(&vid_codec); -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4_load) -{ - switch_application_interface_t *app_interface; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - SWITCH_ADD_APP(app_interface, "play_mp4", "play an MP4 file", "play an MP4 file", play_mp4_function, "", SAF_NONE); - //SWITCH_ADD_APP(app_interface, "record_mp4", "record an MP4 file", "record an MP4 file", record_mp4_function, "", SAF_NONE); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/applications/mod_mp4/mp4_helper.cpp b/src/mod/applications/mod_mp4/mp4_helper.cpp deleted file mode 100644 index 0904cafd67..0000000000 --- a/src/mod/applications/mod_mp4/mp4_helper.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - -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 -http://www.mozilla.org/MPL/ - -Software distributed under the License is distributed on an "AS IS" -basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -License for the specific language governing rights and limitations -under the License. - -The Original Code is MP4 Helper Library to the Freeswitch MP4 Module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -Contributors: - - Seven Du -*/ - -#include -#include "mp4_helper.hpp" - -namespace MP4 -{ - - Context::Context(const char * file, bool newFile) - { - if(newFile) create(file); - else open(file); - } - - Context::~Context() - { - close(); - } - - void Context::open(const char * file) - { - fh = MP4Read(file); - if (fh == MP4_INVALID_FILE_HANDLE) throw Exception(file, "Open failed"); - getTracks(file); - } - - void Context::create(const char * file) - { - fh = MP4Create(file); - if (fh == MP4_INVALID_FILE_HANDLE) throw Exception(file, "Create file failed"); - } - - void Context::close() - { - if (!isOpen()) return; - MP4Close(fh); - } - - void Context::getTracks(const char * file) - { - int i = 0; - bool audioTrack = false, videoTrack = false; - - if (!isOpen()) throw Exception(file, "File is closed."); - - for (;;) - { - TrackProperties track; - if((track.hint = MP4FindTrackId(fh, i++, MP4_HINT_TRACK_TYPE, 0)) == MP4_INVALID_TRACK_ID) break; - - MP4GetHintTrackRtpPayload(fh, track.hint, &track.codecName, &track.payload, NULL, NULL); - - track.track = MP4GetHintTrackReferenceTrackId(fh, track.hint); - if(track.track == MP4_INVALID_TRACK_ID) continue; - track.clock = MP4GetTrackTimeScale(fh, track.hint); - - if (!strcmp(MP4GetTrackType(fh, track.track), MP4_AUDIO_TRACK_TYPE)) { - audioTrack = true; - - if(!strncmp(track.codecName, "PCM", 3)) - track.packetLength = 20; - else - track.packetLength = track.clock = 0; - - audio = track; - } else if (!strcmp(MP4GetTrackType(fh, track.track), MP4_VIDEO_TRACK_TYPE)) { - videoTrack = true; - - const char * sdp = MP4GetHintTrackSdp(fh, track.hint); - const char * fmtp = strstr(sdp, "fmtp"); - - if (fmtp) { - // finds beginning of 'fmtp' value; - for(fmtp += 5; *fmtp != ' '; ++fmtp); - ++fmtp; - - const char * eol = fmtp; - for(;*eol != '\r' && *eol != '\n'; ++eol); - video.fmtp = std::string(fmtp, eol); - } - video.track = track; - } - } - - if (!audioTrack || !videoTrack) throw Exception(file, "Missing audio/video track."); - } - - bool Context::getVideoPacket(void * buffer, u_int & size, u_int & ts) - { - return getPacket(video.track.hint, video.track.runtime, true, buffer, size, ts); - } - - bool Context::getAudioPacket(void * buffer, u_int & size, u_int & ts) - { - return getPacket(audio.hint, audio.runtime, false, buffer, size, ts); - } - - bool Context::getPacket(MP4TrackId hint, RuntimeProperties & rt, - bool header, void * buffer, u_int & size, u_int & ts) - { - if (rt.frame == 0 || rt.packet == rt.packetsPerFrame) { - ++rt.frame; - if(!MP4ReadRtpHint(fh, hint, rt.frame, &rt.packetsPerFrame)) - return false; - rt.packet = 0; - rt.last_frame = MP4GetSampleTime(fh, hint, rt.frame); - } - - ts = rt.last_frame; - if (!MP4ReadRtpPacket(fh, hint, rt.packet, (uint8_t **) &buffer, &size, 0, header, true)) return false; - ++rt.packet; - return true; - } -} diff --git a/src/mod/applications/mod_mp4/mp4_helper.hpp b/src/mod/applications/mod_mp4/mp4_helper.hpp deleted file mode 100644 index 8f61cd6c6b..0000000000 --- a/src/mod/applications/mod_mp4/mp4_helper.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - -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 -http://www.mozilla.org/MPL/ - -Software distributed under the License is distributed on an "AS IS" -basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -License for the specific language governing rights and limitations -under the License. - -The Original Code is MP4 Helper Library to Freeswitch MP4 module. - -The Initial Developer of the Original Code is -Paulo Rogério Panhoto . -Portions created by the Initial Developer are Copyright (C) -the Initial Developer. All Rights Reserved. - -Contributor(s): - - Seven Du - -*/ - -#ifndef MP4_HELPER_HPP_ -#define MP4_HELPER_HPP_ - -#include -#include -#include -#include - -typedef unsigned int u_int; - -namespace MP4 -{ - class Exception: public std::exception { - public: - Exception(const std::string & file, const std::string & error) - : description_(file + ':' + error) - { - } - - const char * what() const throw() - { - return description_.c_str(); - } - - ~Exception() throw() - { - } - - private: - std::string description_; - }; - - struct RuntimeProperties { - uint32_t frame; // sampleID - uint16_t packetsPerFrame; - uint16_t packet; // packetID - uint32_t last_frame; // timestamp - - RuntimeProperties(): frame(0), packetsPerFrame(0), packet(0) - { - } - }; - - - struct TrackProperties { - MP4TrackId hint; - MP4TrackId track; - - char * codecName; - uint8_t payload; - uint32_t clock; - uint32_t packetLength; // packet Length in time (ms) - - RuntimeProperties runtime; - - TrackProperties(): hint(MP4_INVALID_TRACK_ID), track(MP4_INVALID_TRACK_ID), - codecName(NULL), payload(0), clock(0), packetLength(0) - { - } - }; - - typedef TrackProperties AudioProperties; - - struct VideoProperties { - TrackProperties track; - std::string fmtp; - - VideoProperties() - { - } - - VideoProperties(const TrackProperties & rhs): track(rhs) - { - } - }; - - class Context { - public: - - Context(const char * file, bool create = false); - ~Context(); - - void open(const char * file); - - void create(const char * file); - - void close(); - - // returns: TRUE = has more data, FALSE = end-of-stream or failure - bool getVideoPacket(void * buffer, u_int & size, u_int & ts); - - // returns: TRUE = has more data, FALSE = end-of-stream or failure - bool getAudioPacket(void * buffer, u_int & size, u_int & ts); - - bool isOpen() const { return fh != MP4_INVALID_FILE_HANDLE; } - - bool isSupported() const { return audio.track != MP4_INVALID_TRACK_ID && video.track.track != MP4_INVALID_TRACK_ID; } - - const AudioProperties & audioTrack() const { return audio; } - - const VideoProperties & videoTrack() const { return video; } - - private: - MP4FileHandle fh; - AudioProperties audio; - - VideoProperties video; - - // Prevent copy construction. - Context(const Context &); - - bool getPacket(MP4TrackId hint, RuntimeProperties & rt, - bool header, void * buffer, u_int & size, u_int & ts); - - void getTracks(const char * file); - }; -} -#endif diff --git a/src/mod/applications/mod_mp4v2/Makefile.am b/src/mod/applications/mod_mp4v2/Makefile.am deleted file mode 100644 index f8b8bec05a..0000000000 --- a/src/mod/applications/mod_mp4v2/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4v2 - -mod_LTLIBRARIES = mod_mp4v2.la -mod_mp4v2_la_SOURCES = mod_mp4v2.c -mod_mp4v2_la_CFLAGS = $(AM_CFLAGS) -mod_mp4v2_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4v2_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lmp4v2 diff --git a/src/mod/applications/mod_mp4v2/mod_mp4v2.c b/src/mod/applications/mod_mp4v2/mod_mp4v2.c deleted file mode 100644 index 8faccc4e02..0000000000 --- a/src/mod/applications/mod_mp4v2/mod_mp4v2.c +++ /dev/null @@ -1,772 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2015, Anthony Minessale II - * - * Version: MPL 1.1 - * - * 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 - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Seven Du - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * - * mod_mp4v2 -- MP4 File Format for FreeSWITCH - * - * - * status: For write, codec is hard coded to PCMU for audio and H264 for video - * tested with lib mp4v2-2.0.0 - * Read from mp4 is not supported yet. - */ - -#include - -#include - -#define TIMESCALE 1000 -#define SampleLenFieldSize 4 -#define PTIME 20 -// #define HAS_SPS_PARSER - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v2_load); -SWITCH_MODULE_DEFINITION(mod_mp4v2, mod_mp4v2_load, NULL, NULL); - -struct record_helper { - switch_core_session_t *session; - switch_mutex_t *mutex; - MP4FileHandle fd; - MP4TrackId video_track; - MP4TrackId audio_track; - switch_timer_t timer; - int up; - uint64_t last_pts; -}; - -#ifdef HAS_SPS_PARSER -#include "bs.h" -static void parse_sps_video_size(uint8_t *sps_buffer, int len, int *width, int *height) -{ - sps_t sps = { 0 }; - bs_t b = { 0 }; - - bs_init(&b, sps_buffer, len); - read_sps(&sps, &b); - - *width = ((sps.pic_width_in_mbs_minus1 +1)*16) - sps.frame_crop_left_offset*2 - sps.frame_crop_right_offset*2; - *height= ((2 - sps.frame_mbs_only_flag)* (sps.pic_height_in_map_units_minus1 +1) * 16) - (sps.frame_crop_top_offset * 2) - (sps.frame_crop_bottom_offset * 2); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "H264 Profile: %d size: %dx%d\n", sps.profile_idc, *width, *height); -} -#else -// use hardcoded value -static void parse_sps_video_size(uint8_t *sps_buffer, int len, int *width, int *height) -{ - *width = 1280; - *height = 720; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "We have no idea about the video size without decoding the video or actually parse the SPS, using hardcoded %dx%d\n", *width, *height); -} -#endif - -static void init_video_track(MP4FileHandle mp4, MP4TrackId *video, switch_frame_t *frame) -{ - int width = 0; - int height = 0; - uint8_t *sps_buffer = frame->data; - uint32_t sps_bytes = frame->datalen; - - sps_buffer++; - - if (frame->img) { - width = frame->img->d_w; - height = frame->img->d_h; - } else { - parse_sps_video_size(sps_buffer, sps_bytes, &width, &height); - } - - MP4SetTimeScale(mp4, TIMESCALE); - - *video = MP4AddH264VideoTrack(mp4, TIMESCALE, MP4_INVALID_DURATION, width, height, *(sps_buffer), *(sps_buffer+1), *(sps_buffer+2), SampleLenFieldSize - 1); - - if (*video == MP4_INVALID_TRACK_ID) { - return; - } - - MP4AddH264SequenceParameterSet(mp4, *video, --sps_buffer, sps_bytes); - - /* - MP4SetVideoProfileLevel sets the minumum profile/level of MPEG-4 video support necessary to render the contents of the file. - - ISO/IEC 14496-1:2001 MPEG-4 Systems defines the following values: - 0x00 Reserved - 0x01 Simple Profile @ Level 3 - 0x02 Simple Profile @ Level 2 - 0x03 Simple Profile @ Level 1 - 0x04 Simple Scalable Profile @ Level 2 - 0x05 Simple Scalable Profile @ Level 1 - 0x06 Core Profile @ Level 2 - 0x07 Core Profile @ Level 1 - 0x08 Main Profile @ Level 4 - 0x09 Main Profile @ Level 3 - 0x0A Main Profile @ Level 2 - 0x0B N-Bit Profile @ Level 2 - 0x0C Hybrid Profile @ Level 2 - 0x0D Hybrid Profile @ Level 1 - 0x0E Basic Animated Texture @ Level 2 - 0x0F Basic Animated Texture @ Level 1 - 0x10 Scalable Texture @ Level 3 - 0x11 Scalable Texture @ Level 2 - 0x12 Scalable Texture @ Level 1 - 0x13 Simple Face Animation @ Level 2 - 0x14 Simple Face Animation @ Level 1 - 0x15-0x7F Reserved - 0x80-0xFD User private - 0xFE No audio profile specified - 0xFF No audio required - */ - MP4SetVideoProfileLevel(mp4, 0x7F); -} - -static inline char *get_audio_codec_name(uint8_t audio_type) -{ - switch (audio_type) { - case MP4_MP3_AUDIO_TYPE: - return "MP3"; - case MP4_ULAW_AUDIO_TYPE: - return "PCMU"; - case MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE: - return "L16"; - case MP4_MPEG4_AUDIO_TYPE: - return "AAC"; - default: - return "ERROR"; - } -} - -static int get_aac_sample_rate_index(unsigned int sampleRate) -{ - if (92017 <= sampleRate) return 0; - if (75132 <= sampleRate) return 1; - if (55426 <= sampleRate) return 2; - if (46009 <= sampleRate) return 3; - if (37566 <= sampleRate) return 4; - if (27713 <= sampleRate) return 5; - if (23004 <= sampleRate) return 6; - if (18783 <= sampleRate) return 7; - if (13856 <= sampleRate) return 8; - if (11502 <= sampleRate) return 9; - if (9391 <= sampleRate) return 10; - - return 11; -} - -struct mp4_file_context { - switch_file_handle_t *handle; - switch_memory_pool_t *pool; - MP4FileHandle fd; - MP4TrackId audio; - MP4TrackId video; - uint32_t audio_frame_size; - switch_codec_t audio_codec; - switch_codec_t video_codec; - switch_mutex_t *mutex; - switch_buffer_t *buf; - uint32_t last_chunk_size; - int sps_set; - int pps_set; - switch_timer_t timer; - uint64_t last_pts; - int offset; - int audio_start; - uint8_t audio_type; // MP4 Audio Type - MP4Duration audio_duration; - switch_thread_t *video_thread; - switch_queue_t *video_queue; -}; - -typedef struct mp4_file_context mp4_file_context_t; - -static switch_status_t do_write_video(switch_file_handle_t *handle, switch_frame_t *frame); - -static void *SWITCH_THREAD_FUNC video_write_thread_run(switch_thread_t *thread, void *obj) -{ - mp4_file_context_t *context = (mp4_file_context_t *)obj; - void *pop = NULL; - switch_image_t *last_img = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_status_t encode_status = SWITCH_STATUS_SUCCESS; - uint8_t data[SWITCH_DEFAULT_VIDEO_SIZE]; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video_write_thread start\n"); - - while (switch_queue_pop(context->video_queue, &pop) == SWITCH_STATUS_SUCCESS) { - switch_frame_t frame = { 0 }; - - if (!pop) break; - - if (!last_img) { // first img - last_img = (switch_image_t *)pop; - continue; - } - - frame.data = data; - frame.img = last_img; - // switch_set_flag(&frame, SFF_DYNAMIC); - - do { - frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE; - encode_status = switch_core_codec_encode_video(&context->video_codec, &frame); - - if (encode_status == SWITCH_STATUS_SUCCESS || encode_status == SWITCH_STATUS_MORE_DATA) { - switch_assert((encode_status == SWITCH_STATUS_SUCCESS && frame.m) || !frame.m); - - if (frame.datalen == 0) break; - - status = do_write_video(context->handle, &frame); - } - } while(status == SWITCH_STATUS_SUCCESS && encode_status == SWITCH_STATUS_MORE_DATA); - - switch_img_free(&last_img); - last_img = (switch_image_t *)pop; - } - - switch_img_free(&last_img); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video_write_thread done\n"); - - return NULL; -} - -static void launch_video_write_thread(mp4_file_context_t *context, switch_memory_pool_t *pool) -{ - //switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - // switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&context->video_thread, thd_attr, video_write_thread_run, context, pool); -} - - -static int flush_video_queue(switch_queue_t *q, int min) -{ - void *pop; - - if (switch_queue_size(q) > min) { - while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) { - switch_image_t *img = (switch_image_t *) pop; - switch_img_free(&img); - if (min && switch_queue_size(q) <= min) { - break; - } - } - } - - return switch_queue_size(q); -} - -static switch_status_t mp4_file_open(switch_file_handle_t *handle, const char *path) -{ - mp4_file_context_t *context; - char *ext; - unsigned int flags = 0; - const char *tmp = NULL; - - if ((ext = strrchr(path, '.')) == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n"); - return SWITCH_STATUS_GENERR; - } - ext++; - - if ((context = switch_core_alloc(handle->memory_pool, sizeof(mp4_file_context_t))) == 0) { - return SWITCH_STATUS_MEMERR; - } - - memset(context, 0, sizeof(mp4_file_context_t)); - - context->handle = handle; - context->offset = 0; - - if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_video_offset"))) { - context->offset = atoi(tmp); - } - - context->audio_type = MP4_ULAW_AUDIO_TYPE; // default - - if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_audio_codec"))) { - if (!strcasecmp(tmp, "PCMU")) { - context->audio_type = MP4_ULAW_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "MP3")) { - context->audio_type = MP4_MP3_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "AAC")) { - context->audio_type = MP4_MPEG4_AUDIO_TYPE; - } else if (!strcasecmp(tmp, "L16")) { - context->audio_type = MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE; - } - } - - switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - flags |= SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE; - if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(handle, SWITCH_FILE_WRITE_OVER)) { - flags |= SWITCH_FOPEN_READ; - } else { - flags |= SWITCH_FOPEN_TRUNCATE; - } - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) { - flags |= SWITCH_FOPEN_READ; - } - - if (handle->mm.samplerate) { - handle->samplerate = handle->mm.samplerate; - } else { - handle->mm.samplerate = handle->samplerate; - } - - if (!handle->mm.ab) { - handle->mm.ab = 128; - } - - if (!handle->mm.vb) { - handle->mm.vb = switch_calc_bitrate(handle->mm.vw, handle->mm.vh, 1, handle->mm.fps); - } - - // MP4_CREATE_64BIT_DATA if file > 4G - - if ((context->fd = MP4CreateEx(path, 0, 1, 1, NULL, 0, NULL, 0)) == MP4_INVALID_FILE_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening file %s\n", path); - return SWITCH_STATUS_GENERR; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sample rate: %d, channels: %d\n", handle->samplerate, handle->channels); - - if (context->audio_type == MP4_ULAW_AUDIO_TYPE) { - context->audio = MP4AddULawAudioTrack(context->fd, handle->samplerate); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.sampleSize", 8); - } else if (context->audio_type == MP4_MP3_AUDIO_TYPE) { - // handle->samplerate = 44100; - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_MP3_AUDIO_TYPE); - MP4SetTrackName(context->fd, context->audio, ".mp3"); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - // MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd..mp3.channels", handle->channels); - } else if (context->audio_type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) { - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE); - MP4SetTrackName(context->fd, context->audio, "lpcm"); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.channels", handle->channels); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.sampleSize", 16); - } else if (context->audio_type == MP4_MPEG4_AUDIO_TYPE) { - /* AAC object types */ - #define AAC_MAIN 1 - #define AAC_LOW 2 - #define AAC_SSR 3 - #define AAC_LTP 4 - - uint16_t info = 0; - - info |= AAC_LOW << 11; // aacObjectType (5bit) - info |= get_aac_sample_rate_index(handle->samplerate) << 7; //(4bit) - info |= handle->channels << 3; //(4bit) - info = htons(info); - - context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, 1024, MP4_MPEG4_AUDIO_TYPE); - MP4SetTrackESConfiguration(context->fd, context->audio, (uint8_t *)&info, sizeof(info)); - MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels); - } - - handle->format = 0; - handle->sections = 0; - handle->seekable = 0; - handle->speed = 0; - handle->pos = 0; - handle->private_info = context; - context->pool = handle->memory_pool; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n", - path, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : ""); - - if (switch_core_codec_init(&context->audio_codec, - get_audio_codec_name(context->audio_type), - NULL, - NULL, - handle->samplerate, - PTIME,//ms - handle->channels, SWITCH_CODEC_FLAG_ENCODE, - NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n"); - goto end; - } - - if (context->audio_type == MP4_MP3_AUDIO_TYPE) { // fetch frame size - uint32_t size; - uint32_t flag = 0xFFFFFFFF; - - switch_core_codec_encode(&context->audio_codec, NULL, &flag, 0, 0, - (void *)&context->audio_frame_size, &size, NULL, &flag); - } else if (context->audio_type == MP4_MPEG4_AUDIO_TYPE) { - context->audio_frame_size = 1024; - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) { - switch_codec_settings_t codec_settings = {{ 0 }}; - codec_settings.video.bandwidth = handle->mm.vb; - codec_settings.video.fps = handle->mm.fps; - - if (switch_core_codec_init(&context->video_codec, - "H264", - NULL, - NULL, - 90000, - 0,//ms - 1, SWITCH_CODEC_FLAG_ENCODE, - &codec_settings, handle->memory_pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Codec H264 Activation Success\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video Codec H264 Activation Fail\n"); - goto end; - } - - switch_queue_create(&context->video_queue, 60, handle->memory_pool); - launch_video_write_thread(context, handle->memory_pool); - } - - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - MP4SetAudioProfileLevel(context->fd, 0x7F); - } - - switch_buffer_create_dynamic(&context->buf, 512, 512, 1024000); - - return SWITCH_STATUS_SUCCESS; - -end: - if (context->fd) { - MP4Close(context->fd, 0); - context->fd = NULL; - } - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_truncate(switch_file_handle_t *handle, int64_t offset) -{ - mp4_file_context_t *context = handle->private_info; - switch_status_t status; - - if ((status = switch_file_trunc(context->fd, offset)) == SWITCH_STATUS_SUCCESS) { - handle->pos = 0; - } - - return status; - -} - -static switch_status_t mp4_file_close(switch_file_handle_t *handle) -{ - mp4_file_context_t *context = handle->private_info; - switch_status_t status; - - if (context->fd) { - MP4Close(context->fd, MP4_CLOSE_DO_NOT_COMPUTE_BITRATE); - context->fd = NULL; - } - - if (switch_core_codec_ready(&context->audio_codec)) switch_core_codec_destroy(&context->audio_codec); - if (switch_core_codec_ready(&context->video_codec)) switch_core_codec_destroy(&context->video_codec); - - if (context->timer.interval) { - switch_core_timer_destroy(&context->timer); - } - - if (context->video_queue) { - switch_queue_term(context->video_queue); - flush_video_queue(context->video_queue, 0); - } - - if (context->video_thread) { - switch_thread_join(&status, context->video_thread); - } - - switch_buffer_destroy(&context->buf); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t mp4_file_seek(switch_file_handle_t *handle, unsigned int *cur_sample, int64_t samples, int whence) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "seek not implemented\n"); - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_read(switch_file_handle_t *handle, void *data, size_t *len) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read not implemented\n"); - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_write(switch_file_handle_t *handle, void *data, size_t *len) -{ - uint32_t datalen = *len * 2 * handle->channels; - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint8_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - uint32_t encoded_rate; - mp4_file_context_t *context = handle->private_info; - uint32_t size = 0; - uint32_t flag = 0; - - if (context->audio_type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) { - size = datalen; - memcpy(buf, data, datalen); - } else { - switch_core_codec_encode(&context->audio_codec, NULL, - data, datalen, - handle->samplerate, - buf, &size, &encoded_rate, &flag); - } - - switch_mutex_lock(context->mutex); - - if (!context->timer.interval) { - switch_core_timer_init(&context->timer, "soft", 1, 1, context->pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n"); - } - - if (size > 0) { - MP4WriteSample(context->fd, context->audio, buf, size, context->audio_frame_size ? context->audio_frame_size : *len, 0, 1); - } - - context->audio_duration += *len; - - switch_mutex_unlock(context->mutex); - - return status; -} - -static switch_status_t mp4_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t do_write_video(switch_file_handle_t *handle, switch_frame_t *frame) -{ - uint32_t datalen = frame->datalen; - switch_status_t status = SWITCH_STATUS_SUCCESS; - int is_iframe = 0; - uint32_t size; - uint8_t *hdr = NULL; - uint8_t fragment_type; - uint8_t nal_type; - uint8_t start_bit; - uint8_t end_bit; - mp4_file_context_t *context = handle->private_info; - - hdr = (uint8_t *)frame->data; - fragment_type = hdr[0] & 0x1f; - nal_type = hdr[1] & 0x1f; - start_bit = hdr[1] & 0x80; - end_bit = hdr[1] & 0x40; - - is_iframe = fragment_type == 5 || (fragment_type == 28 && nal_type == 5); - - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%02x %02x %02x | len:%d m:%d st:%d i:%d\n", hdr[0], hdr[1], hdr[2], datalen, frame->m, start_bit, is_iframe); - - if (fragment_type == 7 && !context->sps_set) { //sps - context->sps_set = 1; - - init_video_track(context->fd, &context->video, frame); - if (context->video == MP4_INVALID_TRACK_ID) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error add video track!\n"); - return SWITCH_STATUS_FALSE; - } - } else if (fragment_type == 8 && context->sps_set && !context->pps_set) { //pps - MP4AddH264PictureParameterSet(context->fd, context->video, hdr, datalen); - context->pps_set = 1; - } - - if (fragment_type == 28) { - if (start_bit && end_bit) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF?\n"); - } - - if (start_bit) { - nal_type |= (hdr[0] & 0x60); - - size = htonl(datalen); - switch_buffer_write(context->buf, &size, 4); - switch_buffer_write(context->buf, &nal_type, 1); - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size = datalen - 1; - } else if (end_bit) { - uint32_t used; - const void *data; - uint32_t *chunk_size = NULL; - - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size += datalen - 2; - used = switch_buffer_inuse(context->buf); - switch_buffer_peek_zerocopy(context->buf, &data); - chunk_size = (uint32_t *)((uint8_t *)data + used - context->last_chunk_size - 4); - *chunk_size = htonl(context->last_chunk_size); - } else { - switch_buffer_write(context->buf, hdr + 2, datalen - 2); - context->last_chunk_size += datalen - 2; - } - } else { - size = htonl(datalen); - switch_buffer_write(context->buf, &size, 4); - switch_buffer_write(context->buf, hdr, datalen); - } - - if (!frame->m) { - return SWITCH_STATUS_SUCCESS; - } - - switch_mutex_lock(context->mutex); - - if (context->sps_set && context->pps_set) { - uint32_t used = switch_buffer_inuse(context->buf); - const void *data; - int duration = 0; - int ts = 0; - - if (frame->img && frame->img->user_priv) { - ts = *(int *)frame->img->user_priv; - } else { - switch_core_timer_sync(&context->timer); - ts = context->timer.samplecount; - } - - duration = ts - context->last_pts; - - if (duration <= 0) duration = 1; - - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "samplecount: %u, duration: %u\n", context->timer.samplecount, duration); - switch_buffer_peek_zerocopy(context->buf, &data); - - context->last_pts = ts; - - MP4WriteSample(context->fd, context->video, data, used, duration, 0, is_iframe); - switch_buffer_zero(context->buf); - } - - switch_mutex_unlock(context->mutex); - - { - int delta = context->timer.samplecount * (handle->samplerate / 1000) - context->audio_duration; - - if (delta > (int)handle->samplerate) { - uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; - size_t samples = handle->samplerate / 1000 * PTIME; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missed audio %d samples at %d\n", delta, (int)context->audio_duration / (handle->samplerate / 1000)); - - while ((delta -= samples) > 0) { - mp4_file_write(handle, data, &samples); - samples = handle->samplerate / 1000 * PTIME; - } - } - } - - return status; -} - -static switch_status_t mp4_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame) -{ - mp4_file_context_t *context = handle->private_info; - - if (!frame->img) { - return do_write_video(handle, frame); - } else { - switch_image_t *img = NULL; - - if (!context->timer.interval) { - switch_mutex_lock(context->mutex); - switch_core_timer_init(&context->timer, "soft", 1, 1, context->pool); - switch_mutex_unlock(context->mutex); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "init timer\n"); - } else { - switch_mutex_lock(context->mutex); - switch_core_timer_sync(&context->timer); - switch_mutex_unlock(context->mutex); - } - - switch_img_copy(frame->img, &img); - switch_assert(img); - img->user_priv = malloc(sizeof(int)); - *(int *)img->user_priv = context->timer.samplecount; - - if (switch_queue_trypush(context->video_queue, img) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "video queue full, discard one frame\n"); - } - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t mp4_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t mp4_file_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string) -{ - return SWITCH_STATUS_FALSE; -} - -static char *supported_formats[3] = { 0 }; - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v2_load) -{ - switch_file_interface_t *file_interface; - - supported_formats[0] = "mp4v2"; - supported_formats[1] = "mp4"; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); - file_interface->interface_name = modname; - file_interface->extens = supported_formats; - file_interface->file_open = mp4_file_open; - file_interface->file_close = mp4_file_close; - file_interface->file_truncate = mp4_file_truncate; - file_interface->file_read = mp4_file_read; - file_interface->file_write = mp4_file_write; - file_interface->file_read_video = mp4_file_read_video; - file_interface->file_write_video = mp4_file_write_video; - file_interface->file_seek = mp4_file_seek; - file_interface->file_set_string = mp4_file_set_string; - file_interface->file_get_string = mp4_file_get_string; - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/codecs/mod_mp4v/Makefile.am b/src/mod/codecs/mod_mp4v/Makefile.am deleted file mode 100644 index 59f9fa41ef..0000000000 --- a/src/mod/codecs/mod_mp4v/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_mp4v - -mod_LTLIBRARIES = mod_mp4v.la -mod_mp4v_la_SOURCES = mod_mp4v.c -mod_mp4v_la_CFLAGS = $(AM_CFLAGS) -mod_mp4v_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_mp4v_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/codecs/mod_mp4v/mod_mp4v.c b/src/mod/codecs/mod_mp4v/mod_mp4v.c deleted file mode 100644 index 685e6756c7..0000000000 --- a/src/mod/codecs/mod_mp4v/mod_mp4v.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * 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 - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * mod_mp4v.c -- MP4V Video Codec - * - */ - -#include - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load); -SWITCH_MODULE_DEFINITION(mod_mp4v, mod_mp4v_load, NULL, NULL); - -static switch_status_t switch_mp4v_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) -{ - int encoding, decoding; - - encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); - decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - - if (!(encoding || decoding)) { - return SWITCH_STATUS_FALSE; - } else { - if (codec->fmtp_in) { - codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in); - } - return SWITCH_STATUS_SUCCESS; - } -} - -static switch_status_t switch_mp4v_encode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *decoded_data, - uint32_t decoded_data_len, - uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, - unsigned int *flag) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t switch_mp4v_decode(switch_codec_t *codec, - switch_codec_t *other_codec, - void *encoded_data, - uint32_t encoded_data_len, - uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, - unsigned int *flag) -{ - return SWITCH_STATUS_FALSE; -} - -static switch_status_t switch_mp4v_destroy(switch_codec_t *codec) -{ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load) -{ - switch_codec_interface_t *codec_interface; - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - SWITCH_ADD_CODEC(codec_interface, "MP4V Video (passthru)"); - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_VIDEO, 99, "MP4V-ES", NULL, 90000, 90000, 0, - 0, 0, 0, 0, 1, 1, switch_mp4v_init, switch_mp4v_encode, switch_mp4v_decode, switch_mp4v_destroy); - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */