/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> * * 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 <anthm@freeswitch.org> * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Mathieu Rene <mrene@avgs.ca> * * fs_encode.c -- Encode a native file * */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif #ifndef WIN32 /*GRC: #include <linux/limits.h> */ #ifdef HAVE_SETRLIMIT #include <sys/resource.h> #endif #endif // C #include <dirent.h> //#include <stdio.h> // #include <strings.h> // C++ //#include <string> // Freeswitch #include <switch.h> /* Picky compiler */ #ifdef __ICC #pragma warning (disable:167) #endif #define PATH_MAX 4096 int encode_wav_file(int DEBUG, const char* input, int channels, int rate, int ptime, switch_codec_t* pcmu_codec, switch_codec_t* g729_codec); int encode_chunk(int DEBUG,char* buf, size_t bufsize, size_t len, int rate, switch_codec_t* codec, switch_file_handle_t fh_output); void substring(const char [], char[], int, int); static void cleanup_globals() { switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir); switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir); switch_safe_free(SWITCH_GLOBAL_dirs.log_dir); } int main(int argc, char *argv[]) { int i; int r = 1; switch_bool_t verbose = SWITCH_FALSE; int DEBUG = 0; const char* err = NULL; int cmd_fail = 0; const char *fmtp = ""; const char *input; int ptime = 20; int channels = 1; int rate = 8000; int bitrate = 0; switch_memory_pool_t *pool = NULL; switch_codec_t pcmu_codec = { 0 }; switch_codec_t g729_codec = { 0 }; DIR* dir = NULL; struct dirent* ent = NULL; const char* dot = NULL; int num_converted = 0; char filename[PATH_MAX]; const char* slash = ""; const char* loadable_modules[] = {"mod_dahdi_codec","mod_spandsp","mod_sndfile", "mod_native_file"}; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { case 'c': i++; return 255; } break; case 'k': i++; return 255; } break; case 'm': i++; return 255; } break; case 'f': fmtp = argv[++i]; break; case 'p': break; case 'r': break; case 'b': break; case 'v': verbose = SWITCH_TRUE; DEBUG = 1; break; default: cmd_fail = 1; } } else { break; } } if (DEBUG) if (argc - i < 1 || cmd_fail) { goto usage; } input = argv[i++]; if (zstr(input)) { goto usage; } if (switch_core_init(SCF_MINIMAL, verbose, &err) != SWITCH_STATUS_SUCCESS) { goto end; } if (DEBUG){ } switch_loadable_module_init(SWITCH_FALSE); switch_loadable_module_load_module((char*)"", (char*)"CORE_PCM_MODULE", SWITCH_TRUE, &err); switch_loadable_module_load_module((char*)"", (char*)"CORE_SPEEX_MODULE", SWITCH_TRUE, &err); switch_loadable_module_load_module((char*)"", (char*)"CORE_SOFTTIMER_MODULE", SWITCH_TRUE, &err); if (DEBUG) fprintf(stderr, "GRC: Loadable modules: %d\n",(int)(sizeof(loadable_modules)/sizeof(loadable_modules[0]))); for (i = 0; i < (int)(sizeof(loadable_modules)/sizeof(loadable_modules[0])); i++) { if (switch_loadable_module_load_module((char*) SWITCH_GLOBAL_dirs.mod_dir, (char*)loadable_modules[i], SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { goto end; } if (DEBUG) fprintf(stderr, "GRC: Inistialized Loadable module: %s -- %s\n",(char*)loadable_modules[i],err); } switch_core_new_memory_pool(&pool); slash = "/"; } if (DEBUG) { fprintf(stderr, "About to initialize PCMU codec for PCMU@%dh@%di Channels %d Bitrate %d\n", rate, ptime, channels, bitrate); } i=switch_core_codec_init_with_bitrate(&pcmu_codec, "PCMU", NULL,fmtp,rate, ptime, channels, bitrate,(uint32_t)SWITCH_CODEC_FLAG_ENCODE, NULL,pool); /* switch_codec_t*, const char*, const char*, uint32_t, int, int, uint32_t, uint32_t, const switch_codec_settings_t*, switch_memory_pool_t**/ if (i != SWITCH_STATUS_SUCCESS) { goto end; } i=0; if (DEBUG) fprintf(stderr, "About to initialize G729 codec for G729@%dh@%di Channels %d Bitrate %d\n", rate, ptime, channels, bitrate); i = switch_core_codec_init_with_bitrate(&g729_codec, "G729", NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE, NULL, pool); if (i != SWITCH_STATUS_SUCCESS) { goto end; } if ((dir = opendir(input)) != NULL) { while ((ent = readdir(dir)) != NULL) { if (ent->d_type == 8) { //DT_REG if (encode_wav_file(DEBUG, filename, channels, rate, ptime, &pcmu_codec, &g729_codec)) { num_converted++; } else { goto end; } } } } } else { goto end; } r = 0; end: if (dir) { closedir (dir); } switch_core_codec_destroy(&pcmu_codec); switch_core_codec_destroy(&g729_codec); if (pool) { switch_core_destroy_memory_pool(&pool); } cleanup_globals(); return r; usage: cleanup_globals(); return 1; } void substring(const char s[], char sub[], int p, int l) { int c = 0; while (c < l) { sub[c] = s[p+c-1]; c++; } sub[c] = '\0'; } int encode_wav_file(int DEBUG,const char* input, int channels, int rate, int ptime, switch_codec_t* pcmu_codec, switch_codec_t* g729_codec) { //using namespace std; int pos = 0; char* charpos; int r = 1; switch_file_handle_t fh_wav = { 0 }; switch_file_handle_t fh_pcmu = { 0 }; switch_file_handle_t fh_g729 = { 0 }; char buf[2048]; char basename[PATH_MAX]; char pcmu_output[PATH_MAX]; char g729_output[PATH_MAX]; switch_size_t len = (rate*ptime)/1000; int blocksize = len; switch_assert(sizeof(buf) >= len * 2); //string tmp = input; //size_t pos = tmp.find_last_of('.'); if (charpos == NULL) { return 0; } //string basename = tmp.substr(0, pos); //string pcmu_output = basename + ".PCMU"; //string g729_output = basename + ".G729"; pos = charpos - input; //substring(input,basename,0,pos); basename[pos]='\0'; if (DEBUG){ } if (switch_core_file_open(&fh_wav, input, channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { goto end; } if (switch_core_file_open(&fh_pcmu, pcmu_output, channels, pcmu_codec->implementation->actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_NATIVE, NULL) != SWITCH_STATUS_SUCCESS) { goto end; } if (switch_core_file_open(&fh_g729, g729_output, channels, g729_codec->implementation->actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_NATIVE, NULL) != SWITCH_STATUS_SUCCESS) { goto end; } while (switch_core_file_read(&fh_wav, buf, &len) == SWITCH_STATUS_SUCCESS) { if (!encode_chunk(DEBUG,(char*)buf, sizeof(buf), len, rate, pcmu_codec, fh_pcmu) || !encode_chunk(DEBUG,(char*)buf, sizeof(buf), len, rate, g729_codec, fh_g729)) { goto end; } len = blocksize; } r = 1; end: if (fh_wav.file_interface) { switch_core_file_close(&fh_wav); } if (fh_pcmu.file_interface) { switch_core_file_close(&fh_pcmu); } if (fh_g729.file_interface) { switch_core_file_close(&fh_g729); } return r; } int encode_chunk(int DEBUG,char* buf, size_t bufsize, size_t len, int rate, switch_codec_t* codec, switch_file_handle_t fh_output) { char encode_buf[2048]; uint32_t encoded_len = bufsize; uint32_t encoded_rate = rate; unsigned int flags = 0; if (switch_core_codec_encode(codec, NULL, buf, len*2, rate, encode_buf, &encoded_len, &encoded_rate, &flags) != SWITCH_STATUS_SUCCESS) { return 0; } len = encoded_len; if (switch_core_file_write(&fh_output, encode_buf, &len) != SWITCH_STATUS_SUCCESS) { return 0; } if (len != encoded_len) { return 0; } return 1; }