I¡¯m trying to write a function that will open a sound file in PCMU format and transcode it to G722. My function is based on the fs_encoder.c file from FreeSWITCH itself. It works, sort of. It does successfully create a playable G722 file, but it plays back at 2X the speed as the PCMU and sounds like Alvin & the Chipmunks. The G722 file is also about half the size of the PCMU but I expected them to be about the same. Other snippets we have in both PCMU and G722, that play correctly, are about the same.
I¡¯ve tried changing the rates around in but nothing seems to work.
Below is the code, anyone see my bug?
Thanks in advance,Kevin
#include <switch.h>#include <switch_version.h>
void fs_encode(int argc, char** argv, switch_stream_handle_t* stream){switch_status_t status;switch_memory_pool_t* pool = NULL;switch_file_handle_t fh_input = { 0 };switch_file_handle_t fh_output = { 0 };int channels = 1;uint32_t rate = 8000;int ptime = 20;int bitrate = 0;const char* input = "/etc/freeswitch/conf/sounds/three.PCMU";const char* inFormat = "PCMU";const char* output = "/out.G722";const char* outFormat = "G722";switch_codec_t inCodec = { 0 };switch_codec_t outCodec = { 0 };const char* fmtp = "";
int blocksize = 0;
char readBuf[2048];switch_size_t len = sizeof(readBuf)/2;
char decode_buf[2048];uint32_t decoded_len = 0;uint32_t decoded_rate = 0;
char encode_buf[2048];uint32_t encoded_len = 0;uint32_t encoded_rate = 0;unsigned int flags = 0;
switch_core_new_memory_pool(&pool);
stream->write_function(stream, "Opening input file %s\n", input);status = switch_core_file_open(&fh_input, input, channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Couldn't open input file %s. Status = %d\n", input, status);goto end;}
stream->write_function(stream, "Opening output file %s\n", output);status = switch_core_file_open(&fh_output, output, channels, rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_NATIVE, NULL);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Couldn't open output file %s. Status = %d\n", output, status);goto end;}
stream->write_function(stream, "Opening a %s codec\n", inFormat);status = switch_core_codec_init_with_bitrate(&inCodec, inFormat, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_DECODE, NULL, pool);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Couldn't initialize codec for %s@%dh@%di\n", inFormat, rate, ptime);goto end;}
stream->write_function(stream, "Opening a %s codec\n", outFormat);status = switch_core_codec_init_with_bitrate(&outCodec, outFormat, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE, NULL, pool);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Couldn't initialize codec for %s@%dh@%di\n", outFormat, rate, ptime);goto end;}
blocksize = len = (rate*ptime)/1000;switch_assert(sizeof(readBuf) >= len * 2);stream->write_function(stream, "Frame size is %d\n", blocksize);do{stream->write_function(stream, "loop\n");
/////////////////////////////////////////////////////////////////////////////////////// Read input datalen = blocksize;stream->write_function(stream, "Attempt to read %d bytes from %s\n",len,input);status = switch_core_file_read(&fh_input, readBuf, &len);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Read error %d\n",status);goto end;}stream->write_function(stream, "Read %d bytes from %s\n",len,input);/////////////////////////////////////////////////////////////////////////////////////// Decode datastream->write_function(stream, "Attempt to decode %d bytes\n",len);decoded_len = sizeof(decode_buf);decoded_rate = rate;status = switch_core_codec_decode(&inCodec, NULL, readBuf, len, rate, decode_buf, &decoded_len, &decoded_rate, &flags);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Codec decode error %d\n",status);goto end;}stream->write_function(stream, "Decoded %d bytes with %d rate\n",decoded_len,decoded_rate);
/////////////////////////////////////////////////////////////////////////////////////// Encode datastream->write_function(stream, "Attempt to encode %d bytes\n",decoded_len);encoded_len = sizeof(encode_buf);status = switch_core_codec_encode(&outCodec, NULL, decode_buf, decoded_len, decoded_rate, encode_buf, &encoded_len, &encoded_rate, &flags);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Codec encode error %d\n",status);goto end;}stream->write_function(stream, "Encoded %d bytes with %d rate\n",encoded_len,encoded_rate);len = encoded_len;/////////////////////////////////////////////////////////////////////////////////////// Write datastream->write_function(stream, "Write %d bytes\n",encoded_len);status = switch_core_file_write(&fh_output, encode_buf, &encoded_len);if( status != SWITCH_STATUS_SUCCESS ){stream->write_function(stream, "Write error %d\n",status);goto end;}} while(1);
end:if( fh_input.file_interface ){switch_core_file_close(&fh_input);}if( fh_output.file_interface ){switch_core_file_close(&fh_output);}
switch_core_codec_destroy(&outCodec);switch_core_codec_destroy(&inCodec);
if( pool ){switch_core_destroy_memory_pool(&pool);}}
_________________________________________________________________________
Professional FreeSWITCH Consulting Services:
consulting@freeswitch.org
http://www.freeswitchsolutions.com
FreeSWITCH-powered IP PBX: The CudaTel Communication Server
http://www.cudatel.com
Official FreeSWITCH Sites
http://www.freeswitch.org
http://wiki.freeswitch.org
http://www.cluecon.com
FreeSWITCH-dev mailing list
FreeSWITCH-dev@lists.freeswitch.org
http://lists.freeswitch.org/mailman/listinfo/freeswitch-dev
UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-dev
http://www.freeswitch.org