1 contributor
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <pcap.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <mpg123.h> //Decode
#include <twolame.h> //Encode
#include <sndfile.h> //Dump
#define APP_NAME "mp3gw"
#define APP_VERSION "0.0.1"
#define APP_DATE "2014-05-06"
#define APP_DESCRIPTION "Small utility to transcode on the fly mp3 stream"
#define APP_USER_AGENT "mp3gw/0.0.1 (2014-05-06)"
//~ #define APP_FAKE_USER_AGENT "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; WOW64; Trident/4.0; SLCC1)"
#define APP_FAKE_USER_AGENT "Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130912 Firefox/17.0"
#ifndef MAX_SIZE
#define MAX_SIZE 256
#endif //MAX_SIZE
#ifndef MAX_DOTTED_IP_SIZE
#define MAX_DOTTED_IP_SIZE 16
#endif //MAX_DOTTED_IP_SIZE
#ifndef MAX_LISTEN
#define MAX_LISTEN 10
#endif //MAX_LISTEN
#ifndef RECV_BUFF_SIZE
//~ #define RECV_BUFF_SIZE 4096
//~ #define RECV_BUFF_SIZE 8192
#define RECV_BUFF_SIZE 16384
//~ #define RECV_BUFF_SIZE 32768
#endif //RECV_BUFF_SIZE
#ifndef SEND_BUFF_SIZE
#define SEND_BUFF_SIZE 1024
#endif //SEND_BUFF_SIZE
#ifndef CLI_DEFAULT_PORT
#define CLI_DEFAULT_PORT 80
#endif //CLI_DEFAULT_PORT
//~ #define _DEBUG
//~ #ifdef _DEBUG
//~ #define DEBUG_PRINT(...) { fprintf( stderr, "%s:%d : ", __FILE__,__LINE__);fprintf( stderr, __VA_ARGS__ );fprintf( stderr,"\n"); }
//~ #else
//~ #define DEBUG_PRINT(...)
//~ #endif //_DEBUG
#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINT(...) do{ fprintf( stderr,"[DEBUG]%s:%d:%s() ",__FILE__,__LINE__,__FUNCTION__);fprintf( stderr, __VA_ARGS__ ); } while( false )
#else
#define DEBUG_PRINT(...)
#endif
#define INFO_PRINT(...) do{ fprintf( stderr,"[INFO]");fprintf( stderr, __VA_ARGS__ ); } while( false )
#define WARN_PRINT(...) do{ fprintf( stderr,"[WARN]");fprintf( stderr, __VA_ARGS__ ); } while( false )
#define ERR_PRINT(...) do{ fprintf( stderr,"[ERROR]");fprintf( stderr, __VA_ARGS__ ); } while( false )
#define CRIT_PRINT(...) do{ fprintf( stderr,"[CRITICAL]");fprintf( stderr, __VA_ARGS__ ); } while( false )
typedef struct client_cnx_t_ {
char ip_addr[MAX_SIZE];
char uri[MAX_SIZE];
char ip_addr_hr[MAX_DOTTED_IP_SIZE];
uint16_t tcp_port;
} client_cnx_t;
//MPG123 Constants & Definitions
static mpg123_handle *hdlMPG = NULL;
//Twolame Constants & Definitions
static twolame_options *encodeOptions = NULL;
const int32_t MP3_OUTPUT_bitrate = 64;//in kbps
//~ const int32_t MP3_OUTPUT_bitrate = 32;//in kbps
//~ const int32_t MP3_OUTPUT_bitrate = 64;//in kbps
//~ const int32_t MP3_OUTPUT_mode = TWOLAME_MONO;//TWOLAME_MONO or TWOLAME_STEREO
const int32_t MP3_OUTPUT_mode = TWOLAME_STEREO;//TWOLAME_MONO or TWOLAME_STEREO
//SNDFILE Constants & Definitions
#define WAVDUMP
#define MP3DUMP
//~ #define USE_RESAMPLE
#ifdef WAVDUMP
const char *cst_output_dump_file = "output.wav";
#endif //WAVDUMP
#ifdef MP3DUMP
const char *cst_output_dump_file_mp3 = "output.mp3";
static FILE* mp3file = NULL;
#endif //MP3DUMP
#ifdef USE_RESAMPLE
#define DOWNSAMPLING_FACTOR_2 2
#define DOWNSAMPLING_FACTOR_4 4
#endif //USE_RESAMPLE
static client_cnx_t s_cli_connection;
static int32_t sock_cli = 0;
static int32_t sock_srv = 0;
static int32_t sock_srv_cli = 0;
static int32_t s_keep_running = 1;
static int32_t s_exit_program = 0;
static uint16_t s_srv_port = 0;
static pthread_t thread_id;
static int32_t s_input_stream_channels = 0;
void usage()
{
printf( "%s (%s) %s\nDescription :\n\t%s\nUsage :\n\t%s -a <server_ip> -p <server_port> -u <uri> -P <local_port>\n", APP_NAME, APP_VERSION, APP_DATE, APP_DESCRIPTION, APP_NAME );
}
int32_t MsgSend(int sock, uint8_t *msg, int32_t len )
{
int nbSent = write(sock,msg,len);
DEBUG_PRINT("Sent %d bytes\n", nbSent );
//~ DEBUG_PRINT("Sent :\n%.*s\n", len, msg );
return nbSent;
}
int32_t MsgPayloadStart(char *msg, int32_t len)
{
char seed[]="\r\n\r\n";
char substr[4]="";
int32_t pos = 0;
bool found = false;
while( ( false == found ) && ( pos < len ) )
{
strncpy(substr,(msg+pos),strlen(seed));
if( 0 == strncmp(substr,seed,strlen(seed)) )
{
found=true;
DEBUG_PRINT("End-of-Headers found at %d\n", pos );
return pos;
}
pos+=strlen(seed);
}
return 0;
}
void options(int32_t num_args, char** args )
{
int32_t i = 0;
for( i = 1; i < num_args; i++ )
{
if( 0 == strcmp( "-a", args[i] ) )
{
if( NULL != args[i+1] )
{
strncpy( s_cli_connection.ip_addr, args[i+1], MAX_SIZE );
i++;
}
}
else if( 0 == strcmp( "-p", args[i] ) )
{
if( NULL != args[i+1] )
{
s_cli_connection.tcp_port = atoi(args[i+1]);
i++;
}
}
else if( 0 == strcmp( "-u", args[i] ) )
{
if( NULL != args[i+1] )
{
strncpy( s_cli_connection.uri, args[i+1], MAX_SIZE );
i++;
}
}
else if( 0 == strcmp( "-P", args[i] ) )
{
if( NULL != args[i+1] )
{
s_srv_port = atoi(args[i+1]);
i++;
}
}
}
}
void sig_int_handler()
{
DEBUG_PRINT("sig_int_handler");
s_keep_running = 0;
s_exit_program = 1;
if( 0 != hdlMPG )
{
mpg123_delete(hdlMPG);
hdlMPG = 0;
}
if( NULL != encodeOptions )
{
twolame_close(&encodeOptions);
encodeOptions=NULL;
}
#ifdef MP3DUMP
if( NULL != mp3file )
{
fclose(mp3file);
mp3file = NULL;
}
#endif //MP3DUMP
//~ exit(0);
close(sock_cli);
close(sock_srv);
close(sock_srv_cli);
}
int32_t parse_payload(uint16_t sizeBuff, uint8_t *Buff )
{
int32_t retVal = 0;
uint8_t response_ok[MAX_SIZE]= "HTTP/1.1 200 OK\r\n";
retVal = memcmp( response_ok, Buff, strlen((char*)response_ok) );
if( 0 == retVal )
{
DEBUG_PRINT("==========================");
DEBUG_PRINT( "HTTP Headers present" );
DEBUG_PRINT("%s", Buff);
DEBUG_PRINT("==========================");
}
//TODO: Return begining of payload offset
return retVal;
}
void *thread_loop(void *);
void twolameCreate()
{
INFO_PRINT("libtwolame/%s\n", get_twolame_version());
encodeOptions = twolame_init();
twolame_set_version(encodeOptions, TWOLAME_MPEG1);
twolame_set_bitrate(encodeOptions, MP3_OUTPUT_bitrate);
twolame_set_mode(encodeOptions, MP3_OUTPUT_mode);
twolame_set_emphasis(encodeOptions, TWOLAME_EMPHASIS_N );
//~ twolame_set_emphasis(encodeOptions, TWOLAME_EMPHASIS_5 );
//~ twolame_set_emphasis(encodeOptions, TWOLAME_EMPHASIS_C );
}
void mpg123Create()
{
int32_t ret = 0;
INFO_PRINT("libmpg123 API version %d\n", MPG123_API_VERSION);
mpg123_init();
hdlMPG = mpg123_new(NULL, &ret);
if(NULL == hdlMPG)
{
ERR_PRINT("libmpg123 new %s\n", mpg123_plain_strerror(ret));
return;
}
mpg123_open_feed(hdlMPG);
if( NULL == hdlMPG )
{
ERR_PRINT("libmpg123 open" );
}
}
#ifdef USE_RESAMPLE
void downsample_signed16_by_2(const uint16_t sz_data_in, const int16_t *data_in, uint16_t *sz_data_out, int16_t *data_out)
{
uint16_t i = 0;
if( 1 == s_input_stream_channels )
{
for(i = 0; i < sz_data_in; i=i+DOWNSAMPLING_FACTOR_2 )
{
data_out[i/DOWNSAMPLING_FACTOR_2] = (data_in[ i ]/DOWNSAMPLING_FACTOR_2) + (data_in[ i+1 ]/DOWNSAMPLING_FACTOR_2);
*sz_data_out=i/DOWNSAMPLING_FACTOR_2;
}
}
else
{
for(i = 1; i < (sz_data_in/s_input_stream_channels); i=i+DOWNSAMPLING_FACTOR_2 )
{
data_out[i/DOWNSAMPLING_FACTOR_2] = (data_in[ i ]/DOWNSAMPLING_FACTOR_2) + (data_in[ i+1 ]/DOWNSAMPLING_FACTOR_2);
//~ data_out[i/DOWNSAMPLING_FACTOR_2] = data_in[ i ];
*sz_data_out=i/DOWNSAMPLING_FACTOR_2;
}
}
*sz_data_out = sizeof(int16_t)*(*sz_data_out);
}
#endif //USE_RESAMPLE
void monorealizer(const uint16_t sz_data_in, const int16_t *data_in, uint16_t *sz_data_out, int16_t *data_out)
{
DEBUG_PRINT("monorealizer");
//~ uint16_t i = 0;
//~ for(i = 0; i < sz_data_in/2; i=i+2 )
//~ {
//~ data_out[i/2] = (data_in[ i ]/2) - (data_in[ i+1 ]/2);
//~ data_out[i/2] = (data_in[ i ]/2) + (data_in[ i+1 ]/2);
//~ data_out[i/2] = ( data_in[ i ] + data_in[ i+1 ] )/2;
//~ data_out[i/2] = ( data_in[ i ] - data_in[ i+1 ] )/2;
//~ *sz_data_out=i/2;
//~ }
//~ *sz_data_out = sizeof(int16_t)*(*sz_data_out);
*sz_data_out = sz_data_in;
memcpy(data_out,data_in,sizeof(int16_t)*sz_data_in);
}
int32_t main(int32_t argc, char **argv )
{
char srvMesg[MAX_SIZE];
struct sockaddr_in local_serv_addr;
struct sockaddr_in local_cli_addr;
time_t ticks;
if( 1 == argc )
{
usage();
exit(-1);
}
signal(SIGINT, sig_int_handler);
//This is dirty
struct sigaction new_actn, old_actn;
new_actn.sa_handler = SIG_IGN;
sigemptyset (&new_actn.sa_mask);
new_actn.sa_flags = 0;
sigaction (SIGPIPE, &new_actn, &old_actn);
printf( "%s/%s (%s)\n", APP_NAME, APP_VERSION, APP_DATE );
options( argc, argv );
INFO_PRINT("Listening on port %d\n", s_srv_port );
sock_srv = socket(AF_INET , SOCK_STREAM , 0);
if( sock_srv < 0 )
{
CRIT_PRINT("opening socket");
exit(1);
}
local_serv_addr.sin_family = AF_INET;
local_serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_serv_addr.sin_port = htons(s_srv_port);
int32_t optval = 1;
setsockopt(sock_srv, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
if( 0 != bind(sock_srv, (struct sockaddr*)&local_serv_addr, sizeof(local_serv_addr)) )
{
CRIT_PRINT("binding socket");
exit(4);
}
listen(sock_srv, MAX_LISTEN);
int32_t c = sizeof(struct sockaddr_in);
//~ while( (sock_srv_cli = accept(sock_srv, (struct sockaddr *)&local_cli_addr, (socklen_t*)&c)) )
//~ while(1)
while(0 == s_exit_program)
{
sock_srv_cli = accept(sock_srv, (struct sockaddr *)&local_cli_addr, (socklen_t*)&c);
ticks = time(NULL);
if( 0 == s_exit_program )
{
snprintf(srvMesg, sizeof(srvMesg), "%.24s : incoming Connection from %s:%d\n", ctime(&ticks), inet_ntoa(local_cli_addr.sin_addr), ntohs(local_cli_addr.sin_port) );
INFO_PRINT("%s", srvMesg );
s_keep_running = 1;
if( 0 > (pthread_create( &thread_id, NULL , thread_loop , (void*) &sock_srv_cli) ) )
{
CRIT_PRINT("thread creation\n");
return 1;
}
if( 0 == s_exit_program )
{
INFO_PRINT("Listening on port %d\n", s_srv_port );
}
}
//Now join the thread , so that we dont terminate before the thread
//~ pthread_join( thread_id, NULL);
//~ pthread_detach(thread_id);
}
close(sock_srv);
DEBUG_PRINT("clean exit\n");
return 0;
}
void *thread_loop(void *socket_desc)
{
DEBUG_PRINT("START\n");
struct sockaddr_in serv_addr;
struct hostent *server;
uint8_t recvBuff[RECV_BUFF_SIZE];
uint8_t sendBuff[SEND_BUFF_SIZE];
uint16_t numRecvBuff=0;
uint16_t numSendBuff=0;
int32_t ret=0;
#ifdef USE_RESAMPLE
uint8_t downBuff[SEND_BUFF_SIZE];
uint16_t numDownBuff=0;
#endif //USE_RESAMPLE
int64_t input_stream_rate;
int32_t input_stream_channels;
int32_t input_stream_enc;
#ifdef WAVDUMP
SNDFILE* sndfile = NULL;
SF_INFO sfinfo;
#endif //WAVDUMP
int32_t mp2fill_size = 0;
uint8_t* snd_buffer = NULL;
size_t snd_buffer_size = 0;
memset(recvBuff, 0,RECV_BUFF_SIZE);
memset(sendBuff, 0,SEND_BUFF_SIZE);
#ifdef USE_RESAMPLE
memset(downBuff, 0,SEND_BUFF_SIZE);
#endif //USE_RESAMPLE
#ifdef MP3DUMP
mp3file = fopen(cst_output_dump_file_mp3, "wb");
#endif //MP3DUMP
int sock = *(int*)socket_desc;
INFO_PRINT("Connecting to %s:%d\n", s_cli_connection.ip_addr, s_cli_connection.tcp_port );
sock_cli = socket(AF_INET, SOCK_STREAM, 0);
if (sock_cli < 0)
{
CRIT_PRINT("opening socket\n");
exit(1);
}
server = gethostbyname(s_cli_connection.ip_addr);
if (server == NULL) {
CRIT_PRINT("no such host\n");
exit(2);
}
mpg123Create();
twolameCreate();
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(s_cli_connection.tcp_port);
strncpy( s_cli_connection.ip_addr_hr, inet_ntoa(serv_addr.sin_addr), MAX_DOTTED_IP_SIZE );
INFO_PRINT("Redirecting to %s:%d\n", s_cli_connection.ip_addr_hr, s_cli_connection.tcp_port );
if (connect(sock_cli, (const struct sockaddr*)&serv_addr, sizeof(serv_addr) ) < 0)
{
CRIT_PRINT("connecting\n");
exit(3);
}
sprintf( (char*)sendBuff, "GET http://%s:%d/%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\nIcy-MetaData: 0\r\nConnection: close\r\n\r\n",
s_cli_connection.ip_addr,
s_cli_connection.tcp_port,
s_cli_connection.uri,
s_cli_connection.ip_addr,
//~ APP_USER_AGENT );
APP_FAKE_USER_AGENT );
DEBUG_PRINT("Sending Request\n");
//~ numSendBuff = write(sock_cli,sendBuff,strlen((char*)sendBuff));
numSendBuff = MsgSend(sock_cli,sendBuff,strlen((char*)sendBuff));
//~ DEBUG_PRINT("Sent %d bytes\n",numSendBuff);
uint64_t bytesReceived = 0;
uint64_t pktReceived = 0;
uint64_t pktSent = 0;
int32_t retSockWrite = 0;
while( (1 == s_keep_running) && (0 == s_exit_program) )
{
bzero(recvBuff,RECV_BUFF_SIZE);
numRecvBuff += read(sock_cli,recvBuff,RECV_BUFF_SIZE);
int pktBuff=1;
while( numRecvBuff < RECV_BUFF_SIZE )
{
//~ DEBUG_PRINT("Buffering %d packet (%d/%d)\n", pktBuff++, numRecvBuff, RECV_BUFF_SIZE);
numRecvBuff += read(sock_cli,(recvBuff+numRecvBuff),RECV_BUFF_SIZE);
}
INFO_PRINT("Done Buffering\n");
if( NULL != hdlMPG )
{
//Strip HTTP Headers needed
int payload_start = MsgPayloadStart((char*)recvBuff,numRecvBuff);
ret = mpg123_decode(hdlMPG,(recvBuff + payload_start),(numRecvBuff-payload_start),sendBuff,SEND_BUFF_SIZE,(size_t*)&numSendBuff);
//~ int i = 0;
//~ for( i = payload_start; i < (numRecvBuff-payload_start); i++ )
//~ {
//~ printf("%c", recvBuff[i]);
//~ }
//~ printf("\n");
if( 0 != payload_start )
{
int nbsent = MsgSend(sock , recvBuff, payload_start);
DEBUG_PRINT("Sent to client %d bytes\n", nbsent );
}
if(ret == MPG123_NEW_FORMAT)
{
snd_buffer_size = mpg123_outblock(hdlMPG);
mpg123_getformat(hdlMPG, &input_stream_rate, &input_stream_channels, &input_stream_enc);
INFO_PRINT("Input Stream : %li Hz %i channels\n", input_stream_rate, input_stream_channels);
if(input_stream_enc != MPG123_ENC_SIGNED_16 && input_stream_enc != MPG123_ENC_FLOAT_32)
{
ERR_PRINT("Bad encoding: 0x%x\n", input_stream_enc );
}
mpg123_format_none(hdlMPG);
mpg123_format(hdlMPG, input_stream_rate, input_stream_channels, input_stream_enc);
s_input_stream_channels=input_stream_channels;
#ifdef WAVDUMP
bzero(&sfinfo, sizeof(sfinfo) );
sfinfo.samplerate = input_stream_rate;
sfinfo.channels = input_stream_channels;
sfinfo.format = SF_FORMAT_WAV|(input_stream_enc == MPG123_ENC_SIGNED_16 ? SF_FORMAT_PCM_16 : SF_FORMAT_FLOAT);
INFO_PRINT("Creating WAV with %i channels and %liHz.\n", input_stream_channels, input_stream_rate);
sndfile = sf_open(cst_output_dump_file, SFM_WRITE, &sfinfo);
if( MPG123_ENC_SIGNED_16 == input_stream_enc )
{
sf_write_short(sndfile, (short*)sendBuff, numSendBuff/sizeof(short));
}
else
{
sf_write_float(sndfile, (float*)sendBuff, numSendBuff/sizeof(float));
}
#endif //WAVDUMP
if( NULL == snd_buffer )
{
snd_buffer = malloc( snd_buffer_size );
}
twolame_set_num_channels(encodeOptions, input_stream_channels );
#ifndef USE_RESAMPLE
twolame_set_in_samplerate(encodeOptions, input_stream_rate);
twolame_set_out_samplerate(encodeOptions, input_stream_rate);
INFO_PRINT( "libtwolame samplerate : %ld Hz\n",input_stream_rate );
#else
twolame_set_in_samplerate(encodeOptions, input_stream_rate/DOWNSAMPLING_FACTOR_2);
twolame_set_out_samplerate(encodeOptions, input_stream_rate/DOWNSAMPLING_FACTOR_2);
INFO_PRINT( "libtwolame samplerate : %ld Hz\n",input_stream_rate/DOWNSAMPLING_FACTOR_2 );
#endif //USE_RESAMPLE
INFO_PRINT( "libtwolame bitrate : %d kbps\n",MP3_OUTPUT_bitrate );
//~ twolame_set_verbosity(encodeOptions, 4);
//~ twolame_print_config(encodeOptions);
if( TWOLAME_MONO == MP3_OUTPUT_mode )
{
INFO_PRINT( "libtwolame channels : Mono\n" );
}
else
{
INFO_PRINT( "libtwolame channels : Stereo\n" );
}
if (twolame_init_params(encodeOptions) != 0) {
CRIT_PRINT("twolame_init_params\n");
exit(15);
}
if( MPG123_ENC_SIGNED_16 == input_stream_enc )
{
INFO_PRINT( "Sample format : MPG123_ENC_SIGNED_16\n" );
}
else
{
INFO_PRINT( "Sample format : MPG123_ENC_FLOAT_32\n" );
}
if( MPG123_ENC_SIGNED_16 == input_stream_enc )
{
//TODO : Add Monorealizer
if( input_stream_channels == 1 )
{
#ifndef USE_RESAMPLE
mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
#else
downsample_signed16_by_2(numSendBuff/sizeof(int16_t), (const int16_t*)sendBuff, &numDownBuff, (int16_t*)&downBuff);
mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)downBuff, numDownBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
#endif //USE_RESAMPLE
}
else
{
//~ monorealizer( numSendBuff/sizeof(int16_t), (const int16_t*)sendBuff, &numDownBuff, (int16_t*)&downBuff);
//~ mp2fill_size = twolame_encode_buffer(encodeOptions, (const int16_t*)sendBuff, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
}
#ifdef MP3DUMP
fwrite(snd_buffer, sizeof(uint8_t), mp2fill_size, mp3file);
#endif //MP3DUMP
}
else
{
mp2fill_size = twolame_encode_buffer_float32(encodeOptions, (const float*)sendBuff, NULL, numSendBuff/sizeof(float),snd_buffer, snd_buffer_size);
}
//~ int nbsent = write(sock , snd_buffer, mp2fill_size);
if( 0 != mp2fill_size )
{
int nbsent = MsgSend(sock , snd_buffer, mp2fill_size);
DEBUG_PRINT("Sent to client %d bytes (expecting %d bytes)\n", nbsent, mp2fill_size );
}
}
else if( ( ret != MPG123_OK ) && ( ret != MPG123_NEED_MORE ) )
{
ERR_PRINT("mpg123_decode format is %d\n", ret );
}
//~ while(ret != MPG123_ERR && ret != MPG123_NEED_MORE)
while(ret == MPG123_OK )
{
ret = mpg123_decode(hdlMPG,NULL,0,sendBuff,SEND_BUFF_SIZE,(size_t*)&numSendBuff);
#ifdef WAVDUMP
if( MPG123_ENC_SIGNED_16 == input_stream_enc )
{
sf_write_short(sndfile, (int16_t*)sendBuff, numSendBuff/sizeof(int16_t));
}
else
{
sf_write_float(sndfile, (float*)sendBuff, numSendBuff/sizeof(float));
}
#endif //WAVDUMP
if( MPG123_ENC_SIGNED_16 == input_stream_enc )
{
#ifndef USE_RESAMPLE
mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
#else
downsample_signed16_by_2(numSendBuff/sizeof(int16_t), (const int16_t*)sendBuff, &numDownBuff, (int16_t*)&downBuff);
mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)downBuff, numDownBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
#endif //USE_RESAMPLE
#ifdef MP3DUMP
fwrite(snd_buffer, sizeof(unsigned char), mp2fill_size, mp3file);
#endif //MP3DUMP
}
else
{
mp2fill_size = twolame_encode_buffer_float32(encodeOptions, (const float*)sendBuff, NULL, numSendBuff/sizeof(float),snd_buffer, snd_buffer_size);
}
retSockWrite = write(sock , snd_buffer, mp2fill_size);
if( 0 > retSockWrite )
{
if( 0 != s_keep_running )
{
ERR_PRINT("write failed\n");
s_keep_running = 0;
}
}
}
//~ write(sock , recvBuff , numRecvBuff);
if( 0 != mp2fill_size )
{
int nbsent = MsgSend(sock , snd_buffer, mp2fill_size);
DEBUG_PRINT("Sent to client %d bytes (expecting %d bytes)\n", nbsent, mp2fill_size );
}
}
else
{
ERR_PRINT("hdlMPG NULL\n" );
}
pktReceived++;
bytesReceived+=numRecvBuff;
numRecvBuff=0;
pktSent++;
printf( "Received %ld packets (%ld bytes)/Sent %ld packets\r\b", pktReceived, bytesReceived, pktSent );
}
if (NULL != snd_buffer )
{
free(snd_buffer);
}
close(sock_cli);
printf( "\nStopping after receiving %ld packets \n", pktReceived );
#ifdef MP3DUMP
if( NULL != mp3file )
{
fclose(mp3file);
mp3file = NULL;
}
#endif //MP3DUMP
if( 0 != hdlMPG )
{
mpg123_delete(hdlMPG);
hdlMPG = 0;
}
if( NULL != encodeOptions )
{
twolame_close(&encodeOptions);
encodeOptions=NULL;
}
close(sock);
return 0;
}