#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //Decode #include //Encode #include //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 -p -u -P \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; }