Showing 2 changed files with 739 additions and 0 deletions
+29
Makefile
... ...
@@ -0,0 +1,29 @@
1
+TARGET ?= $(notdir $(realpath .))
2
+
3
+CFLAGS +=-Wall -O2 -I/usr/local/include/
4
+
5
+ifeq ($(STATIC),y)
6
+LDFLAGS +=-lpthread -ltwolame -lmpg123 -lsndfile
7
+else
8
+LDFLAGS +=-lpthread -ltwolame -lmpg123 -lsndfile
9
+endif
10
+
11
+ifeq ($(DEBUG),y)
12
+CFLAGS +=-g -D_DEBUG
13
+endif 
14
+
15
+$(warning Building $(TARGET))
16
+
17
+SRC ?= $(wildcard *.c)
18
+OBJS := $(SRC:%.c=%.o)
19
+
20
+all: $(TARGET)
21
+
22
+init: $(DEPS)
23
+	$(foreach DIR, $(DEPS), $(MAKE) -C $(DIR); )
24
+	
25
+$(TARGET): init $(OBJS)
26
+	$(CC) $(OBJS) $(CFLAGS) $(USER_LDFLAGS) $(LDFLAGS) -o $@
27
+
28
+clean:
29
+	rm -f *.o $(TARGET) $(OBJS)
+710
main.c
... ...
@@ -0,0 +1,710 @@
1
+#include <stdio.h>
2
+#include <stdlib.h>
3
+#include <stdint.h>
4
+#include <stdbool.h>
5
+#include <string.h>
6
+#include <pcap.h>
7
+#include <netinet/in.h>
8
+#include <arpa/inet.h>
9
+#include <sys/socket.h>
10
+#include <netdb.h>
11
+#include <unistd.h>
12
+#include <signal.h>
13
+#include <time.h> 
14
+#include <pthread.h>
15
+
16
+#include <mpg123.h> //Decode
17
+#include <twolame.h> //Encode
18
+#include <sndfile.h> //Dump
19
+
20
+#define APP_NAME "mp3gw"
21
+#define APP_VERSION "0.0.1"
22
+#define APP_DATE "2014-05-06"
23
+#define APP_DESCRIPTION "Small utility to transcode on the fly mp3 stream"
24
+
25
+#define APP_USER_AGENT "mp3gw/0.0.1 (2014-05-06)"
26
+//~ #define APP_FAKE_USER_AGENT "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; WOW64; Trident/4.0; SLCC1)"
27
+#define APP_FAKE_USER_AGENT "Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130912 Firefox/17.0"
28
+
29
+
30
+#ifndef MAX_SIZE
31
+	#define MAX_SIZE 256
32
+#endif //MAX_SIZE
33
+
34
+#ifndef MAX_DOTTED_IP_SIZE
35
+	#define MAX_DOTTED_IP_SIZE 16
36
+#endif //MAX_DOTTED_IP_SIZE
37
+
38
+#ifndef MAX_LISTEN
39
+	#define MAX_LISTEN 10
40
+#endif //MAX_LISTEN
41
+
42
+#ifndef RECV_BUFF_SIZE
43
+	//~ #define RECV_BUFF_SIZE 4096
44
+	//~ #define RECV_BUFF_SIZE 8192
45
+	#define RECV_BUFF_SIZE 16384
46
+	//~ #define RECV_BUFF_SIZE 32768
47
+#endif //RECV_BUFF_SIZE
48
+
49
+#ifndef SEND_BUFF_SIZE
50
+	#define SEND_BUFF_SIZE 1024
51
+#endif //SEND_BUFF_SIZE
52
+
53
+#ifndef CLI_DEFAULT_PORT
54
+	#define CLI_DEFAULT_PORT 80
55
+#endif //CLI_DEFAULT_PORT
56
+
57
+//~ #define _DEBUG
58
+//~ #ifdef _DEBUG
59
+	//~ #define DEBUG_PRINT(...) { fprintf( stderr, "%s:%d : ", __FILE__,__LINE__);fprintf( stderr, __VA_ARGS__ );fprintf( stderr,"\n"); }
60
+//~ #else
61
+	//~ #define DEBUG_PRINT(...)
62
+//~ #endif //_DEBUG
63
+
64
+#define DEBUG
65
+#ifdef DEBUG
66
+#define DEBUG_PRINT(...) do{ fprintf( stderr,"[DEBUG]%s:%d:%s() ",__FILE__,__LINE__,__FUNCTION__);fprintf( stderr, __VA_ARGS__ ); } while( false )
67
+#else
68
+#define DEBUG_PRINT(...)
69
+#endif
70
+
71
+#define INFO_PRINT(...) do{ fprintf( stderr,"[INFO]");fprintf( stderr, __VA_ARGS__ ); } while( false )
72
+#define WARN_PRINT(...) do{ fprintf( stderr,"[WARN]");fprintf( stderr, __VA_ARGS__ ); } while( false )
73
+#define ERR_PRINT(...) do{ fprintf( stderr,"[ERROR]");fprintf( stderr, __VA_ARGS__ ); } while( false )
74
+#define CRIT_PRINT(...) do{ fprintf( stderr,"[CRITICAL]");fprintf( stderr, __VA_ARGS__ ); } while( false )
75
+
76
+typedef struct client_cnx_t_ {
77
+	char ip_addr[MAX_SIZE];
78
+	char uri[MAX_SIZE];
79
+	char ip_addr_hr[MAX_DOTTED_IP_SIZE];
80
+	uint16_t tcp_port;
81
+} client_cnx_t;
82
+
83
+
84
+//MPG123 Constants & Definitions
85
+static mpg123_handle *hdlMPG = NULL;
86
+
87
+//Twolame Constants & Definitions
88
+static twolame_options *encodeOptions = NULL;
89
+const int32_t MP3_OUTPUT_bitrate = 64;//in kbps
90
+//~ const int32_t MP3_OUTPUT_bitrate = 32;//in kbps
91
+//~ const int32_t MP3_OUTPUT_bitrate = 64;//in kbps
92
+//~ const int32_t MP3_OUTPUT_mode = TWOLAME_MONO;//TWOLAME_MONO or TWOLAME_STEREO
93
+const int32_t MP3_OUTPUT_mode = TWOLAME_STEREO;//TWOLAME_MONO or TWOLAME_STEREO
94
+
95
+//SNDFILE Constants & Definitions
96
+#define WAVDUMP
97
+#define MP3DUMP
98
+//~ #define USE_RESAMPLE
99
+
100
+#ifdef WAVDUMP
101
+	const char *cst_output_dump_file = "output.wav";
102
+#endif //WAVDUMP
103
+
104
+#ifdef MP3DUMP
105
+	const char *cst_output_dump_file_mp3 = "output.mp3";
106
+	static FILE* mp3file = NULL;
107
+#endif //MP3DUMP
108
+
109
+#ifdef USE_RESAMPLE
110
+	#define DOWNSAMPLING_FACTOR_2 2
111
+	#define DOWNSAMPLING_FACTOR_4 4
112
+#endif //USE_RESAMPLE
113
+
114
+static client_cnx_t s_cli_connection;
115
+static int32_t sock_cli = 0;
116
+static int32_t sock_srv = 0;
117
+static int32_t sock_srv_cli = 0;
118
+static int32_t s_keep_running = 1;
119
+static int32_t s_exit_program = 0;
120
+static uint16_t s_srv_port = 0;
121
+static pthread_t thread_id;
122
+static int32_t s_input_stream_channels = 0;
123
+
124
+void usage()
125
+{	
126
+	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 );
127
+}
128
+
129
+int32_t MsgSend(int sock, uint8_t *msg, int32_t len )
130
+{
131
+	 int nbSent = write(sock,msg,len);
132
+	 DEBUG_PRINT("Sent %d bytes\n", nbSent );
133
+	 //~ DEBUG_PRINT("Sent :\n%.*s\n", len, msg );
134
+	 return nbSent;	 
135
+}
136
+
137
+int32_t MsgPayloadStart(char *msg, int32_t len)
138
+{
139
+	char seed[]="\r\n\r\n";
140
+	char substr[4]="";
141
+	int32_t pos = 0;
142
+	bool found = false;
143
+	while( ( false == found ) && ( pos < len ) )
144
+	{
145
+		strncpy(substr,(msg+pos),strlen(seed));
146
+		if( 0 == strncmp(substr,seed,strlen(seed)) )
147
+		{
148
+			found=true;
149
+			DEBUG_PRINT("End-of-Headers found at %d\n", pos );
150
+			return pos;
151
+		}
152
+		pos+=strlen(seed);
153
+	}
154
+	return 0;
155
+}
156
+void options(int32_t num_args, char** args )
157
+{
158
+	int32_t i = 0;
159
+	for( i = 1; i < num_args; i++ )
160
+	{
161
+		if( 0 == strcmp( "-a", args[i] ) )
162
+		{
163
+			if( NULL != args[i+1] )
164
+			{
165
+				strncpy( s_cli_connection.ip_addr, args[i+1], MAX_SIZE );
166
+				i++;
167
+			}
168
+		}
169
+		else if( 0 == strcmp( "-p", args[i] ) )
170
+		{
171
+			if( NULL != args[i+1] )
172
+			{
173
+				s_cli_connection.tcp_port = atoi(args[i+1]);
174
+				i++;
175
+			}
176
+		}
177
+		else if( 0 == strcmp( "-u", args[i] ) )
178
+		{
179
+			if( NULL != args[i+1] )
180
+			{
181
+				strncpy( s_cli_connection.uri, args[i+1], MAX_SIZE );
182
+				i++;
183
+			}
184
+		}
185
+		else if( 0 == strcmp( "-P", args[i] ) )
186
+		{
187
+			if( NULL != args[i+1] )
188
+			{
189
+				s_srv_port = atoi(args[i+1]);
190
+				i++;
191
+			}
192
+		}
193
+	}	
194
+}
195
+
196
+void sig_int_handler()
197
+{
198
+	DEBUG_PRINT("sig_int_handler");
199
+	s_keep_running = 0;
200
+	s_exit_program = 1;
201
+	if( 0 != hdlMPG )
202
+	{
203
+		mpg123_delete(hdlMPG);
204
+		hdlMPG = 0;
205
+	}
206
+	if( NULL != encodeOptions )
207
+	{
208
+		twolame_close(&encodeOptions);
209
+		encodeOptions=NULL;
210
+	}
211
+	
212
+#ifdef MP3DUMP
213
+	if( NULL != mp3file )
214
+	{
215
+		fclose(mp3file);
216
+		mp3file = NULL;
217
+	}
218
+#endif //MP3DUMP
219
+	//~ exit(0);
220
+	
221
+	close(sock_cli);
222
+	close(sock_srv);
223
+	close(sock_srv_cli);
224
+}
225
+
226
+int32_t parse_payload(uint16_t sizeBuff, uint8_t *Buff )
227
+{
228
+	int32_t retVal = 0;
229
+	uint8_t response_ok[MAX_SIZE]= "HTTP/1.1 200 OK\r\n";
230
+	retVal = memcmp( response_ok, Buff, strlen((char*)response_ok) );
231
+	if( 0 == retVal )
232
+	{
233
+		DEBUG_PRINT("==========================");
234
+		DEBUG_PRINT( "HTTP Headers present" );
235
+		DEBUG_PRINT("%s", Buff);
236
+		DEBUG_PRINT("==========================");
237
+	}
238
+	//TODO: Return begining of payload offset
239
+	return retVal;
240
+}
241
+
242
+void *thread_loop(void *);
243
+
244
+void twolameCreate()
245
+{
246
+	INFO_PRINT("libtwolame/%s\n", get_twolame_version());
247
+	encodeOptions = twolame_init();
248
+	twolame_set_version(encodeOptions, TWOLAME_MPEG1);
249
+	twolame_set_bitrate(encodeOptions, MP3_OUTPUT_bitrate);
250
+	twolame_set_mode(encodeOptions, MP3_OUTPUT_mode);
251
+	twolame_set_emphasis(encodeOptions,  TWOLAME_EMPHASIS_N );
252
+	//~ twolame_set_emphasis(encodeOptions,  TWOLAME_EMPHASIS_5 );
253
+	//~ twolame_set_emphasis(encodeOptions,  TWOLAME_EMPHASIS_C  );
254
+}
255
+
256
+void mpg123Create()
257
+{
258
+	int32_t ret = 0;
259
+	INFO_PRINT("libmpg123 API version %d\n", MPG123_API_VERSION);
260
+	mpg123_init();
261
+	hdlMPG = mpg123_new(NULL, &ret);
262
+	if(NULL == hdlMPG)
263
+	{
264
+		ERR_PRINT("libmpg123 new %s\n", mpg123_plain_strerror(ret));
265
+		return;
266
+	}
267
+	mpg123_open_feed(hdlMPG);
268
+	if( NULL == hdlMPG )
269
+	{
270
+		ERR_PRINT("libmpg123 open" );
271
+	}
272
+}
273
+
274
+#ifdef USE_RESAMPLE
275
+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)
276
+{
277
+	uint16_t i = 0;
278
+	if( 1 == s_input_stream_channels )
279
+	{
280
+		for(i = 0; i < sz_data_in; i=i+DOWNSAMPLING_FACTOR_2 )
281
+		{
282
+			data_out[i/DOWNSAMPLING_FACTOR_2] = (data_in[ i ]/DOWNSAMPLING_FACTOR_2) + (data_in[ i+1 ]/DOWNSAMPLING_FACTOR_2);
283
+			*sz_data_out=i/DOWNSAMPLING_FACTOR_2;
284
+		}
285
+	}
286
+	else
287
+	{
288
+		for(i = 1; i < (sz_data_in/s_input_stream_channels); i=i+DOWNSAMPLING_FACTOR_2 )
289
+		{
290
+			data_out[i/DOWNSAMPLING_FACTOR_2] = (data_in[ i ]/DOWNSAMPLING_FACTOR_2) + (data_in[ i+1 ]/DOWNSAMPLING_FACTOR_2);
291
+			//~ data_out[i/DOWNSAMPLING_FACTOR_2] = data_in[ i ];
292
+			*sz_data_out=i/DOWNSAMPLING_FACTOR_2;
293
+		}	
294
+	}
295
+	
296
+	*sz_data_out = sizeof(int16_t)*(*sz_data_out);
297
+}
298
+#endif //USE_RESAMPLE
299
+
300
+void monorealizer(const uint16_t sz_data_in, const int16_t *data_in, uint16_t *sz_data_out, int16_t *data_out)
301
+{
302
+	DEBUG_PRINT("monorealizer");
303
+	//~ uint16_t i = 0;
304
+	//~ for(i = 0; i < sz_data_in/2; i=i+2 )
305
+	//~ {
306
+		//~ data_out[i/2] = (data_in[ i ]/2) - (data_in[ i+1 ]/2);
307
+		//~ data_out[i/2] = (data_in[ i ]/2) + (data_in[ i+1 ]/2);
308
+		//~ data_out[i/2] = ( data_in[ i ] + data_in[ i+1 ] )/2;
309
+		//~ data_out[i/2] = ( data_in[ i ] - data_in[ i+1 ] )/2;
310
+		//~ *sz_data_out=i/2;
311
+	//~ }	
312
+	//~ *sz_data_out = sizeof(int16_t)*(*sz_data_out);
313
+	*sz_data_out = sz_data_in;
314
+	memcpy(data_out,data_in,sizeof(int16_t)*sz_data_in);
315
+}
316
+
317
+int32_t main(int32_t argc, char **argv )
318
+{
319
+	char srvMesg[MAX_SIZE];
320
+
321
+	struct sockaddr_in local_serv_addr;
322
+	struct sockaddr_in local_cli_addr;
323
+
324
+	time_t ticks;
325
+	
326
+	if( 1 == argc )
327
+	{
328
+		usage();
329
+		exit(-1);
330
+	}
331
+	signal(SIGINT, sig_int_handler);
332
+	
333
+	//This is dirty
334
+    struct sigaction new_actn, old_actn;
335
+	new_actn.sa_handler = SIG_IGN;
336
+	sigemptyset (&new_actn.sa_mask);
337
+	new_actn.sa_flags = 0;
338
+	sigaction (SIGPIPE, &new_actn, &old_actn);
339
+	
340
+	printf( "%s/%s (%s)\n", APP_NAME, APP_VERSION, APP_DATE );
341
+	options( argc, argv );
342
+	
343
+	INFO_PRINT("Listening on port %d\n", s_srv_port );
344
+	sock_srv = socket(AF_INET , SOCK_STREAM , 0);
345
+    if( sock_srv < 0 )
346
+    {
347
+        CRIT_PRINT("opening socket");
348
+        exit(1);
349
+    }
350
+	local_serv_addr.sin_family = AF_INET;
351
+    local_serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
352
+    local_serv_addr.sin_port = htons(s_srv_port);
353
+    int32_t optval = 1;
354
+	setsockopt(sock_srv, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
355
+		
356
+    if( 0 != bind(sock_srv, (struct sockaddr*)&local_serv_addr, sizeof(local_serv_addr)) )
357
+    {
358
+		CRIT_PRINT("binding socket");
359
+		exit(4);
360
+	}
361
+	listen(sock_srv, MAX_LISTEN);
362
+	
363
+	int32_t c = sizeof(struct sockaddr_in);
364
+	//~ while( (sock_srv_cli = accept(sock_srv, (struct sockaddr *)&local_cli_addr, (socklen_t*)&c)) )
365
+	//~ while(1)
366
+	while(0 == s_exit_program)
367
+    {
368
+		sock_srv_cli = accept(sock_srv, (struct sockaddr *)&local_cli_addr, (socklen_t*)&c);
369
+		ticks = time(NULL);
370
+		if( 0 == s_exit_program )
371
+		{
372
+			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) );
373
+			INFO_PRINT("%s", srvMesg );
374
+			s_keep_running = 1;
375
+			if( 0 > (pthread_create( &thread_id, NULL ,  thread_loop , (void*) &sock_srv_cli) ) )
376
+			{
377
+				CRIT_PRINT("thread creation\n");
378
+				return 1;
379
+			}
380
+			if( 0 == s_exit_program )
381
+			{
382
+				INFO_PRINT("Listening on port %d\n", s_srv_port );
383
+			}
384
+		}
385
+         
386
+        //Now join the thread , so that we dont terminate before the thread
387
+		//~ pthread_join( thread_id, NULL);
388
+		//~ pthread_detach(thread_id);
389
+    }
390
+	close(sock_srv);
391
+	DEBUG_PRINT("clean exit\n");
392
+	return 0;
393
+}
394
+
395
+void *thread_loop(void *socket_desc)
396
+{
397
+	DEBUG_PRINT("START\n");
398
+	struct sockaddr_in serv_addr;
399
+	struct hostent *server;
400
+	uint8_t recvBuff[RECV_BUFF_SIZE];
401
+	uint8_t sendBuff[SEND_BUFF_SIZE];
402
+	uint16_t numRecvBuff=0;
403
+	uint16_t numSendBuff=0;
404
+	int32_t ret=0;
405
+
406
+#ifdef USE_RESAMPLE
407
+	uint8_t downBuff[SEND_BUFF_SIZE];
408
+	uint16_t numDownBuff=0;
409
+#endif //USE_RESAMPLE
410
+
411
+	int64_t input_stream_rate;
412
+	int32_t input_stream_channels;
413
+	int32_t input_stream_enc;
414
+	
415
+	#ifdef WAVDUMP
416
+		SNDFILE* sndfile = NULL;
417
+		SF_INFO sfinfo;
418
+	#endif //WAVDUMP
419
+	
420
+	int32_t  mp2fill_size = 0;
421
+	uint8_t* snd_buffer = NULL;
422
+	size_t snd_buffer_size = 0;
423
+	
424
+	memset(recvBuff, 0,RECV_BUFF_SIZE);
425
+	memset(sendBuff, 0,SEND_BUFF_SIZE);
426
+	#ifdef USE_RESAMPLE
427
+		memset(downBuff, 0,SEND_BUFF_SIZE);
428
+	#endif //USE_RESAMPLE
429
+	
430
+	#ifdef MP3DUMP
431
+		mp3file = fopen(cst_output_dump_file_mp3, "wb");
432
+	#endif //MP3DUMP
433
+		
434
+	int sock = *(int*)socket_desc;
435
+          
436
+	INFO_PRINT("Connecting to %s:%d\n", s_cli_connection.ip_addr, s_cli_connection.tcp_port );
437
+		
438
+	sock_cli = socket(AF_INET, SOCK_STREAM, 0);
439
+    if (sock_cli < 0) 
440
+    {
441
+        CRIT_PRINT("opening socket\n");
442
+        exit(1);
443
+    }
444
+    
445
+    server = gethostbyname(s_cli_connection.ip_addr);
446
+    if (server == NULL) {
447
+        CRIT_PRINT("no such host\n");
448
+        exit(2);
449
+    }
450
+    
451
+	mpg123Create();
452
+	twolameCreate();
453
+        
454
+    memset(&serv_addr, 0, sizeof(serv_addr));
455
+    serv_addr.sin_family = AF_INET;
456
+    bcopy((char *)server->h_addr, 
457
+           (char *)&serv_addr.sin_addr.s_addr,
458
+                server->h_length);
459
+    serv_addr.sin_port = htons(s_cli_connection.tcp_port);
460
+    strncpy( s_cli_connection.ip_addr_hr, inet_ntoa(serv_addr.sin_addr), MAX_DOTTED_IP_SIZE );
461
+    INFO_PRINT("Redirecting to %s:%d\n", s_cli_connection.ip_addr_hr, s_cli_connection.tcp_port );
462
+    
463
+    if (connect(sock_cli, (const struct sockaddr*)&serv_addr, sizeof(serv_addr) ) < 0) 
464
+    {
465
+		CRIT_PRINT("connecting\n");
466
+		exit(3);
467
+    }
468
+	
469
+    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",
470
+			s_cli_connection.ip_addr,
471
+			s_cli_connection.tcp_port,
472
+			s_cli_connection.uri,
473
+			s_cli_connection.ip_addr,
474
+			//~ APP_USER_AGENT );
475
+			APP_FAKE_USER_AGENT );
476
+
477
+    DEBUG_PRINT("Sending Request\n");
478
+    //~ numSendBuff = write(sock_cli,sendBuff,strlen((char*)sendBuff));
479
+    numSendBuff = MsgSend(sock_cli,sendBuff,strlen((char*)sendBuff));
480
+    //~ DEBUG_PRINT("Sent %d bytes\n",numSendBuff);
481
+    uint64_t bytesReceived = 0;
482
+	uint64_t pktReceived = 0;
483
+	uint64_t pktSent = 0;
484
+	int32_t	retSockWrite = 0;
485
+    while( (1 == s_keep_running) && (0 == s_exit_program) )
486
+    {
487
+		bzero(recvBuff,RECV_BUFF_SIZE);
488
+		numRecvBuff += read(sock_cli,recvBuff,RECV_BUFF_SIZE);
489
+		int pktBuff=1;
490
+		while( numRecvBuff < RECV_BUFF_SIZE )
491
+		{
492
+			//~ DEBUG_PRINT("Buffering %d packet (%d/%d)\n", pktBuff++, numRecvBuff, RECV_BUFF_SIZE);
493
+			numRecvBuff += read(sock_cli,(recvBuff+numRecvBuff),RECV_BUFF_SIZE);
494
+		}
495
+		INFO_PRINT("Done Buffering\n");
496
+		if( NULL != hdlMPG )
497
+		{
498
+			//Strip HTTP Headers needed
499
+			int payload_start = MsgPayloadStart((char*)recvBuff,numRecvBuff);
500
+			ret = mpg123_decode(hdlMPG,(recvBuff + payload_start),(numRecvBuff-payload_start),sendBuff,SEND_BUFF_SIZE,(size_t*)&numSendBuff);
501
+			//~ int i = 0;
502
+			//~ for( i = payload_start; i < (numRecvBuff-payload_start); i++ )
503
+			//~ {
504
+				//~ printf("%c", recvBuff[i]);
505
+			//~ }
506
+			//~ printf("\n");
507
+			if( 0 != payload_start )
508
+			{
509
+				int nbsent = MsgSend(sock , recvBuff, payload_start);
510
+				DEBUG_PRINT("Sent to client %d bytes\n", nbsent );
511
+			}
512
+			if(ret == MPG123_NEW_FORMAT)
513
+			{
514
+				snd_buffer_size = mpg123_outblock(hdlMPG);
515
+				mpg123_getformat(hdlMPG, &input_stream_rate, &input_stream_channels, &input_stream_enc);
516
+				INFO_PRINT("Input Stream : %li Hz %i channels\n", input_stream_rate, input_stream_channels);
517
+				if(input_stream_enc != MPG123_ENC_SIGNED_16 && input_stream_enc != MPG123_ENC_FLOAT_32)
518
+				{
519
+					ERR_PRINT("Bad encoding: 0x%x\n", input_stream_enc );
520
+				}
521
+				mpg123_format_none(hdlMPG);
522
+				mpg123_format(hdlMPG, input_stream_rate, input_stream_channels, input_stream_enc);
523
+				s_input_stream_channels=input_stream_channels;
524
+				
525
+				#ifdef WAVDUMP
526
+					bzero(&sfinfo, sizeof(sfinfo) );
527
+					sfinfo.samplerate = input_stream_rate;
528
+					sfinfo.channels = input_stream_channels;
529
+					sfinfo.format = SF_FORMAT_WAV|(input_stream_enc == MPG123_ENC_SIGNED_16 ? SF_FORMAT_PCM_16 : SF_FORMAT_FLOAT);
530
+					INFO_PRINT("Creating WAV with %i channels and %liHz.\n", input_stream_channels, input_stream_rate);
531
+					sndfile = sf_open(cst_output_dump_file, SFM_WRITE, &sfinfo);
532
+
533
+					if( MPG123_ENC_SIGNED_16 == input_stream_enc )
534
+					{
535
+						sf_write_short(sndfile, (short*)sendBuff, numSendBuff/sizeof(short));
536
+					}
537
+					else
538
+					{
539
+						sf_write_float(sndfile, (float*)sendBuff, numSendBuff/sizeof(float));
540
+					}
541
+				#endif //WAVDUMP
542
+				
543
+				if( NULL == snd_buffer )
544
+				{
545
+					snd_buffer = malloc( snd_buffer_size );
546
+				}
547
+
548
+				twolame_set_num_channels(encodeOptions, input_stream_channels );
549
+				#ifndef USE_RESAMPLE
550
+					twolame_set_in_samplerate(encodeOptions, input_stream_rate);
551
+					twolame_set_out_samplerate(encodeOptions, input_stream_rate);
552
+					INFO_PRINT( "libtwolame samplerate : %ld Hz\n",input_stream_rate );
553
+				#else
554
+					twolame_set_in_samplerate(encodeOptions, input_stream_rate/DOWNSAMPLING_FACTOR_2);
555
+					twolame_set_out_samplerate(encodeOptions, input_stream_rate/DOWNSAMPLING_FACTOR_2);
556
+					INFO_PRINT( "libtwolame samplerate : %ld Hz\n",input_stream_rate/DOWNSAMPLING_FACTOR_2 );
557
+				#endif //USE_RESAMPLE
558
+				
559
+				INFO_PRINT( "libtwolame bitrate    : %d kbps\n",MP3_OUTPUT_bitrate );
560
+				//~ twolame_set_verbosity(encodeOptions, 4);
561
+				//~ twolame_print_config(encodeOptions);
562
+				if( TWOLAME_MONO == MP3_OUTPUT_mode )
563
+				{
564
+					INFO_PRINT( "libtwolame channels   : Mono\n" );
565
+				}
566
+				else
567
+				{
568
+					INFO_PRINT( "libtwolame channels   : Stereo\n" );
569
+				}
570
+				
571
+				if (twolame_init_params(encodeOptions) != 0) {
572
+					CRIT_PRINT("twolame_init_params\n");
573
+					exit(15);
574
+				}
575
+				if( MPG123_ENC_SIGNED_16 == input_stream_enc )
576
+				{
577
+					INFO_PRINT( "Sample format : MPG123_ENC_SIGNED_16\n" );
578
+				}
579
+				else
580
+				{
581
+					INFO_PRINT( "Sample format : MPG123_ENC_FLOAT_32\n" );
582
+				}
583
+				if( MPG123_ENC_SIGNED_16 == input_stream_enc )
584
+				{
585
+					//TODO : Add Monorealizer
586
+					if( input_stream_channels == 1 )
587
+					{
588
+						#ifndef USE_RESAMPLE
589
+							mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
590
+						#else
591
+							downsample_signed16_by_2(numSendBuff/sizeof(int16_t), (const int16_t*)sendBuff, &numDownBuff, (int16_t*)&downBuff);
592
+							mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)downBuff, numDownBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
593
+						#endif //USE_RESAMPLE
594
+					}
595
+					else
596
+					{
597
+						//~ monorealizer( numSendBuff/sizeof(int16_t), (const int16_t*)sendBuff, &numDownBuff, (int16_t*)&downBuff);
598
+						//~ mp2fill_size = twolame_encode_buffer(encodeOptions, (const int16_t*)sendBuff, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
599
+						mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
600
+					}					
601
+					#ifdef MP3DUMP
602
+						fwrite(snd_buffer, sizeof(uint8_t), mp2fill_size, mp3file);
603
+					#endif //MP3DUMP
604
+				}
605
+				else
606
+				{
607
+					mp2fill_size = twolame_encode_buffer_float32(encodeOptions, (const float*)sendBuff, NULL, numSendBuff/sizeof(float),snd_buffer, snd_buffer_size);
608
+				}
609
+				//~ int nbsent = write(sock , snd_buffer, mp2fill_size);
610
+				if( 0 != mp2fill_size )
611
+				{
612
+					int nbsent = MsgSend(sock , snd_buffer, mp2fill_size);
613
+					DEBUG_PRINT("Sent to client %d bytes (expecting %d bytes)\n", nbsent, mp2fill_size );
614
+				}
615
+			}
616
+			else if( ( ret != MPG123_OK ) && ( ret != MPG123_NEED_MORE ) )
617
+			{
618
+				ERR_PRINT("mpg123_decode format is %d\n", ret );
619
+			}
620
+			
621
+			//~ while(ret != MPG123_ERR && ret != MPG123_NEED_MORE)
622
+			while(ret == MPG123_OK )
623
+			{
624
+				ret = mpg123_decode(hdlMPG,NULL,0,sendBuff,SEND_BUFF_SIZE,(size_t*)&numSendBuff);
625
+				#ifdef WAVDUMP
626
+					if( MPG123_ENC_SIGNED_16 == input_stream_enc )
627
+					{
628
+						sf_write_short(sndfile, (int16_t*)sendBuff, numSendBuff/sizeof(int16_t));
629
+					}
630
+					else
631
+					{
632
+						sf_write_float(sndfile, (float*)sendBuff, numSendBuff/sizeof(float));
633
+					}
634
+				#endif //WAVDUMP
635
+						
636
+				if( MPG123_ENC_SIGNED_16 == input_stream_enc )
637
+				{
638
+					#ifndef USE_RESAMPLE
639
+						mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)sendBuff, numSendBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
640
+					#else
641
+						downsample_signed16_by_2(numSendBuff/sizeof(int16_t), (const int16_t*)sendBuff, &numDownBuff, (int16_t*)&downBuff);
642
+						mp2fill_size = twolame_encode_buffer_interleaved(encodeOptions, (const int16_t*)downBuff, numDownBuff/sizeof(int16_t),snd_buffer, snd_buffer_size);
643
+					#endif //USE_RESAMPLE
644
+										
645
+					#ifdef MP3DUMP
646
+						fwrite(snd_buffer, sizeof(unsigned char), mp2fill_size, mp3file);
647
+					#endif //MP3DUMP					
648
+				}
649
+				else
650
+				{
651
+					mp2fill_size = twolame_encode_buffer_float32(encodeOptions, (const float*)sendBuff, NULL, numSendBuff/sizeof(float),snd_buffer, snd_buffer_size);
652
+				}
653
+
654
+				retSockWrite = write(sock , snd_buffer, mp2fill_size);
655
+				if( 0 > retSockWrite )
656
+				{
657
+					if( 0 != s_keep_running )
658
+					{
659
+						ERR_PRINT("write failed\n");
660
+						s_keep_running = 0;
661
+					}
662
+				}
663
+			}
664
+			//~ write(sock , recvBuff , numRecvBuff);
665
+			if( 0 != mp2fill_size )
666
+			{
667
+				int nbsent = MsgSend(sock , snd_buffer, mp2fill_size);
668
+				DEBUG_PRINT("Sent to client %d bytes (expecting %d bytes)\n", nbsent, mp2fill_size );
669
+			}
670
+		}
671
+		else
672
+		{
673
+			ERR_PRINT("hdlMPG NULL\n" );
674
+		}
675
+		
676
+		pktReceived++;
677
+		bytesReceived+=numRecvBuff;
678
+		numRecvBuff=0;
679
+		pktSent++;		
680
+		printf( "Received %ld packets (%ld bytes)/Sent %ld packets\r\b", pktReceived, bytesReceived, pktSent );
681
+	}
682
+    if (NULL != snd_buffer )
683
+    {
684
+		free(snd_buffer);
685
+	}
686
+    close(sock_cli);
687
+	printf( "\nStopping after receiving %ld packets                      \n", pktReceived );
688
+	
689
+	#ifdef MP3DUMP
690
+		if( NULL != mp3file )
691
+		{
692
+			fclose(mp3file);
693
+			mp3file = NULL;
694
+		}
695
+	#endif //MP3DUMP
696
+	
697
+	if( 0 != hdlMPG )
698
+	{
699
+		mpg123_delete(hdlMPG);
700
+		hdlMPG = 0;
701
+	}
702
+	if( NULL != encodeOptions )
703
+	{
704
+		twolame_close(&encodeOptions);
705
+		encodeOptions=NULL;
706
+	}
707
+
708
+	close(sock);
709
+	return 0;
710
+}