mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-30 15:14:17 +00:00
ok gsm works
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@206 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
1 parent
ad4559308b
commit
b4845b9ff1
14 files changed
+169
-136
No files matched your search
@@ -34,10 +34,14 @@
|
||||
|
||||
static const char modname[] = "mod_codec_gsm";
|
||||
|
||||
struct gsm_context {
|
||||
gsm encoder;
|
||||
gsm decoder;
|
||||
};
|
||||
|
||||
static switch_status switch_gsm_init(switch_codec *codec, switch_codec_flag flags, const struct switch_codec_settings *codec_settings)
|
||||
{
|
||||
gsm context;
|
||||
struct gsm_context *context;
|
||||
int encoding, decoding;
|
||||
|
||||
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
|
||||
@@ -46,18 +50,26 @@ static switch_status switch_gsm_init(switch_codec *codec, switch_codec_flag flag
|
||||
if (!(encoding || decoding)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
} else {
|
||||
context = gsm_create();
|
||||
}
|
||||
context = switch_core_alloc(codec->memory_pool, sizeof(*context));
|
||||
if (encoding) context->encoder = gsm_create();
|
||||
if (decoding) context->decoder = gsm_create();
|
||||
}
|
||||
|
||||
codec->private = context;
|
||||
codec->private = context;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static switch_status switch_gsm_destroy(switch_codec *codec)
|
||||
{
|
||||
gsm_destroy((gsm)codec->private);
|
||||
struct gsm_context *context = codec->private;
|
||||
int encoding = (codec->flags & SWITCH_CODEC_FLAG_ENCODE);
|
||||
int decoding = (codec->flags & SWITCH_CODEC_FLAG_DECODE);
|
||||
|
||||
if (encoding) gsm_destroy(context->encoder);
|
||||
if (decoding) gsm_destroy(context->decoder);
|
||||
|
||||
codec->private = NULL;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -71,24 +83,23 @@ static switch_status switch_gsm_encode(switch_codec *codec,
|
||||
size_t *encoded_data_len,
|
||||
unsigned int *flag)
|
||||
{
|
||||
gsm context = codec->private;
|
||||
struct gsm_context *context = codec->private;
|
||||
int cbret = 0;
|
||||
|
||||
if (!context) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
if (decoded_data_len % 160 == 0) {
|
||||
if (decoded_data_len % 320 == 0) {
|
||||
unsigned int new_len = 0;
|
||||
gsm_signal *ddp = decoded_data;
|
||||
gsm_byte *edp = encoded_data;
|
||||
int x;
|
||||
int loops = (int) decoded_data_len / 160;
|
||||
|
||||
int loops = (int) decoded_data_len / 320;
|
||||
for(x = 0; x < loops && new_len < *encoded_data_len; x++) {
|
||||
gsm_encode(context, ddp, edp);
|
||||
edp += 10;
|
||||
ddp += 80;
|
||||
new_len += 10;
|
||||
gsm_encode(context->encoder, ddp, edp);
|
||||
edp += 33;
|
||||
ddp += 160;
|
||||
new_len += 33;
|
||||
}
|
||||
if( new_len <= *encoded_data_len ) {
|
||||
*encoded_data_len = new_len;
|
||||
@@ -124,9 +135,9 @@ static switch_status switch_gsm_decode(switch_codec *codec,
|
||||
int x;
|
||||
unsigned int new_len = 0;
|
||||
for(x = 0; x < loops && new_len < *decoded_data_len; x++) {
|
||||
gsm_decode(&context, ddp, edp);
|
||||
ddp += 80;
|
||||
edp += 10;
|
||||
gsm_decode(context->decoder, edp, ddp);
|
||||
ddp += 160;
|
||||
edp += 33;
|
||||
new_len += 320;
|
||||
}
|
||||
if (new_len <= *decoded_data_len) {
|
||||
@@ -139,7 +150,6 @@ static switch_status switch_gsm_decode(switch_codec *codec,
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "yo this frame is an odd size [%d]\n", encoded_data_len);
|
||||
}
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -154,7 +164,7 @@ static const switch_codec_implementation gsm_8k_implementation = {
|
||||
/*.encoded_bytes_per_frame*/ 33,
|
||||
/*.number_of_channels*/ 1,
|
||||
/*.pref_frames_per_packet*/ 1,
|
||||
/*.max_frames_per_packet*/ 7,
|
||||
/*.max_frames_per_packet*/ 1,
|
||||
/*.init*/ switch_gsm_init,
|
||||
/*.encode*/ switch_gsm_encode,
|
||||
/*.decode*/ switch_gsm_decode,
|
||||
|
||||
@@ -190,7 +190,6 @@ static void audio_bridge_function(switch_core_session *session, char *data)
|
||||
time_t start;
|
||||
|
||||
peer_channel = switch_core_session_get_channel(peer_session);
|
||||
|
||||
memset(&other_audio_thread, 0, sizeof(other_audio_thread));
|
||||
memset(&this_audio_thread, 0, sizeof(this_audio_thread));
|
||||
other_audio_thread.objs[0] = session;
|
||||
@@ -226,6 +225,7 @@ static void audio_bridge_function(switch_core_session *session, char *data)
|
||||
|
||||
if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
|
||||
switch_channel_answer(caller_channel);
|
||||
|
||||
switch_core_session_launch_thread(session, audio_bridge_thread, (void *) &other_audio_thread);
|
||||
audio_bridge_thread(NULL, (void *) &this_audio_thread);
|
||||
switch_channel_hangup(peer_channel);
|
||||
|
||||
@@ -367,8 +367,7 @@ static switch_status exosip_outgoing_channel(switch_core_session *session, switc
|
||||
{
|
||||
if ((*new_session = switch_core_session_request(&exosip_endpoint_interface, NULL))) {
|
||||
struct private_object *tech_pvt;
|
||||
switch_channel *channel, *orig_channel;
|
||||
switch_caller_profile *caller_profile, *originator_caller_profile = NULL;
|
||||
switch_channel *channel;
|
||||
|
||||
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
|
||||
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
||||
@@ -384,6 +383,8 @@ static switch_status exosip_outgoing_channel(switch_core_session *session, switc
|
||||
|
||||
if (outbound_profile) {
|
||||
char name[128];
|
||||
switch_caller_profile *caller_profile;
|
||||
|
||||
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
||||
switch_channel_set_caller_profile(channel, caller_profile);
|
||||
tech_pvt->caller_profile = caller_profile;
|
||||
@@ -394,16 +395,6 @@ static switch_status exosip_outgoing_channel(switch_core_session *session, switc
|
||||
switch_core_session_destroy(new_session);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
/* (session == NULL) means it was originated from the core not from another channel */
|
||||
if (session && (orig_channel = switch_core_session_get_channel(session))) {
|
||||
switch_caller_profile *cloned_profile;
|
||||
|
||||
if ((originator_caller_profile = switch_channel_get_caller_profile(orig_channel))) {
|
||||
cloned_profile = switch_caller_profile_clone(*new_session, originator_caller_profile);
|
||||
switch_channel_set_originator_caller_profile(channel, cloned_profile);
|
||||
}
|
||||
}
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
|
||||
|
||||
@@ -477,7 +477,7 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit
|
||||
if ((*new_session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
|
||||
struct private_object *tech_pvt;
|
||||
switch_channel *channel, *orig_channel;
|
||||
switch_caller_profile *caller_profile, *originator_caller_profile = NULL;
|
||||
switch_caller_profile *caller_profile;
|
||||
unsigned int req = 0, cap = 0;
|
||||
|
||||
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
|
||||
@@ -523,17 +523,6 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit
|
||||
caller_profile->destination_number,
|
||||
NULL, 0, req, cap);
|
||||
|
||||
|
||||
/* (session == NULL) means it was originated from the core not from another channel */
|
||||
if (session && (orig_channel = switch_core_session_get_channel(session))) {
|
||||
switch_caller_profile *cloned_profile;
|
||||
|
||||
if ((originator_caller_profile = switch_channel_get_caller_profile(orig_channel))) {
|
||||
cloned_profile = switch_caller_profile_clone(*new_session, originator_caller_profile);
|
||||
switch_channel_set_originator_caller_profile(channel, cloned_profile);
|
||||
}
|
||||
}
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
@@ -904,8 +893,10 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IAX_EVENT_BUSY:
|
||||
case IAX_EVENT_HANGUP:
|
||||
case IAX_EVENT_REJECT:
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Rejected call.\n");
|
||||
case IAX_EVENT_BUSY:
|
||||
case IAX_EVENT_HANGUP:
|
||||
if (tech_pvt) {
|
||||
switch_channel *channel;
|
||||
|
||||
@@ -941,9 +932,6 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Call transfer occurred.\n");
|
||||
//session[0] = iaxevent->session;
|
||||
break;
|
||||
case IAX_EVENT_REJECT:
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Rejected call.\n");
|
||||
break;
|
||||
case IAX_EVENT_DTMF:
|
||||
if (tech_pvt) {
|
||||
switch_channel *channel;
|
||||
|
||||
@@ -44,17 +44,27 @@ void playback_function(switch_core_session *session, char *data)
|
||||
switch_file_t *fd;
|
||||
char buf[960];
|
||||
char dtmf[128];
|
||||
char *ext;
|
||||
int interval = 0, samples = 0;
|
||||
size_t len = 0, ilen = 0;
|
||||
switch_frame write_frame;
|
||||
switch_timer timer;
|
||||
switch_core_thread_session thread_session;
|
||||
switch_codec codec;
|
||||
char *codec_name;
|
||||
int x;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
|
||||
if (!(ext = strrchr(data, '.'))) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ext++;
|
||||
|
||||
switch_channel_answer(channel);
|
||||
|
||||
write_frame.data = buf;
|
||||
@@ -65,19 +75,20 @@ void playback_function(switch_core_session *session, char *data)
|
||||
switch_channel_hangup(channel);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OPEN FILE %s\n", data);
|
||||
|
||||
interval = 20;
|
||||
len = 320;
|
||||
samples = 160;
|
||||
|
||||
codec_name = "L16";
|
||||
|
||||
|
||||
#if 0
|
||||
interval = 30;
|
||||
len = 480;
|
||||
samples = 240;
|
||||
interval = 20;
|
||||
len = 33;
|
||||
samples = 160;
|
||||
codec_name = "gsm";
|
||||
#endif
|
||||
|
||||
write_frame.samples = samples;
|
||||
@@ -91,7 +102,7 @@ void playback_function(switch_core_session *session, char *data)
|
||||
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "setup timer success %d bytes per %d ms!\n", len, interval);
|
||||
|
||||
if (switch_core_codec_init(&codec, "L16", 8000, interval, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL) == SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_core_codec_init(&codec, codec_name, 8000, interval, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Raw Codec Activated\n");
|
||||
write_frame.codec = &codec;
|
||||
} else {
|
||||
|
||||
@@ -297,7 +297,7 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit
|
||||
if ((*new_session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
|
||||
struct private_object *tech_pvt;
|
||||
switch_channel *channel, *orig_channel;
|
||||
switch_caller_profile *caller_profile, *originator_caller_profile = NULL;
|
||||
switch_caller_profile *caller_profile;
|
||||
|
||||
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
|
||||
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
||||
@@ -323,17 +323,6 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
/* (session == NULL) means it was originated from the core not from another channel */
|
||||
if (session && (orig_channel = switch_core_session_get_channel(session))) {
|
||||
switch_caller_profile *cloned_profile;
|
||||
|
||||
if ((originator_caller_profile = switch_channel_get_caller_profile(orig_channel))) {
|
||||
cloned_profile = switch_caller_profile_clone(*new_session, originator_caller_profile);
|
||||
switch_channel_set_originator_caller_profile(channel, cloned_profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
|
||||
@@ -348,8 +348,8 @@ static switch_status woomerachan_outgoing_channel(switch_core_session *session,
|
||||
if ((*new_session = switch_core_session_request(&woomerachan_endpoint_interface, NULL))) {
|
||||
struct private_object *tech_pvt;
|
||||
switch_channel *channel, *orig_channel;
|
||||
switch_caller_profile *caller_profile, *originator_caller_profile = NULL;
|
||||
|
||||
|
||||
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) {
|
||||
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
||||
tech_pvt->profile = &default_profile;
|
||||
@@ -364,6 +364,8 @@ static switch_status woomerachan_outgoing_channel(switch_core_session *session,
|
||||
|
||||
if (outbound_profile) {
|
||||
char name[128];
|
||||
switch_caller_profile *caller_profile;
|
||||
|
||||
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
||||
switch_channel_set_caller_profile(channel, caller_profile);
|
||||
tech_pvt->caller_profile = caller_profile;
|
||||
@@ -375,16 +377,6 @@ static switch_status woomerachan_outgoing_channel(switch_core_session *session,
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
/* (session == NULL) means it was originated from the core not from another channel */
|
||||
if (session && (orig_channel = switch_core_session_get_channel(session))) {
|
||||
switch_caller_profile *cloned_profile;
|
||||
|
||||
if ((originator_caller_profile = switch_channel_get_caller_profile(orig_channel))) {
|
||||
cloned_profile = switch_caller_profile_clone(*new_session, originator_caller_profile);
|
||||
switch_channel_set_originator_caller_profile(channel, cloned_profile);
|
||||
}
|
||||
}
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
|
||||
Reference in new issue
Block a user