mp3splt-gtk

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

snackamp_control.c
Go to the documentation of this file.
1 /**********************************************************
2 *
3 * mp3splt-gtk -- utility based on mp3splt,
4 * for mp3/ogg splitting without decoding
5 *
6 * Copyright: (C) 2005-2012 Alexandru Munteanu
7 * Contact: io_fx@yahoo.fr
8 *
9 * http://mp3splt.sourceforge.net/
10 *
11 *********************************************************/
12
13 /**********************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 * USA.
29 *
30 *********************************************************/
31
32 /*!********************************************************
33 * \file
34 * Snackamp control
35 *
36 * this file contains functions to control the snackamp
37 * player
38 **********************************************************/
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <gtk/gtk.h>
43 #include <glib/gi18n.h>
44 #include <glib.h>
45 #include <glib/gprintf.h>
46 #include <string.h>
47 #include <time.h>
48 #include <ctype.h>
49 #include <unistd.h>
50
51 #ifdef __WIN32__
52 #include <winsock2.h>
53 #define usleep(x) Sleep(x*1000)
54 #else
55 #include <netdb.h>
56 #include <sys/socket.h>
57 #include <sys/types.h>
58 #include <netinet/in.h>
59 #endif
60
61 #include "player.h"
62 #include "snackamp_control.h"
63
64 //file descriptors for line buffering
65 FILE *in, *out;
66 //if we are connected or not
67 gboolean connected = FALSE;
68
69 #ifdef __WIN32__
70 SOCKET socket_id;
71 #else
72 gint socket_id;
73 #endif
74
79 gint connect_snackamp(gint port)
80 {
81 //socket and internet structures
82 struct sockaddr_in host;
83 struct hostent *h;
84 gint return_err = 0;
85
86 #ifdef __WIN32__
87 long winsockinit;
88 WSADATA winsock;
89 winsockinit = WSAStartup(0x0101,&winsock);
90 #endif
91
92 //prepare host..
93 if((h = gethostbyname("localhost"))==NULL)
94 {
95 //fprintf(stderr, "could not get host by name\n");
96 return_err = 1;
97 }
98
99 //we prepare socket
100 host.sin_family = AF_INET;
101 host.sin_addr.s_addr =
102 ((struct in_addr *) (h->h_addr)) ->s_addr;
103 host.sin_port=htons(port);
104
105 //if no error, continue
106 if (return_err == 0)
107 {
108 //initialize socket
109 if((socket_id=socket(AF_INET, SOCK_STREAM, 0))==-1)
110 {
111 //fprintf(stderr, "error initialising socket\n");
112 return_err = 2;
113 }
114 }
115
116 //if no error, continue
117 if (return_err == 0)
118 {
119 //make connection
120 if ((connect(socket_id,
121 (void *)&host, sizeof(host)))==-1)
122 {
123 //fprintf(stderr, "cannot connect to host\n");
124 return_err = 3;
125 }
126 }
127
128 //if no error, continue
129 if (return_err == 0)
130 {
131 /* !@Crap */
132 #ifdef __WIN32__
133 #else
134 //we prepare file descriptors for
135 //
136 if (NULL==(in=fdopen(socket_id, "r")) ||
137 NULL==(out=fdopen(socket_id, "w")))
138 {
139 //fprintf(stderr, "cannot prepare file descriptors..\n");
140 return_err = 4;
141 }
142 #endif
143 }
144
145 //if no err
146 if (return_err == 0)
147 {
148 //we set the line buffering
149 setvbuf(out, NULL, _IOLBF, 0);
150 connected = TRUE;
151 }
152
153 //if socket errors, disconnect snackamp
154 if (return_err >= 2)
155 disconnect_snackamp();
156
157 return return_err;
158 }
159
160 gchar *cut_begin_end(gchar *result)
161 {
162 //we cut the beginning OK
163 gchar *test;
164
165 if (strchr(result,' ') != NULL)
166 {
167 test = strchr(result, ' ');
168 g_snprintf(result, strlen(result),
169 "%s",test+1);
170 }
171
172 //we cut the \n at the end
173 gint result_str = strlen(result);
174 if (result_str >= 2)
175 result[result_str - 2] = '\0';
176
177 return result;
178 }
179
183 gint disconnect_snackamp()
184 {
185 connected = FALSE;
186 //we close the socket
187 #ifdef __WIN32__
188 return closesocket(socket_id);
189 #else
190 return close(socket_id);
191 #endif
192 }
193
199 gchar *snackamp_socket_send_message(gchar *message)
200 {
201 gchar *result = malloc(1024 * sizeof(gchar *));
202 strcpy(result,"disconnected");
203
204 #ifdef __WIN32__
205 gboolean r = TRUE;
206
207 gint err1 =
208 send(socket_id, message, strlen(message), 0);
209 if (err1 <= 0)
210 {
211 disconnect_snackamp();
212 }
213 else
214 {
215 gint err = recv(socket_id, result, 1024, 0);
216 if (err <= 0)
217 {
218 disconnect_snackamp();
219 r = FALSE;
220 }
221 }
222 #else
223 //we send message
224 fputs(message, out);
225 //we get the result
226 fgets(result, 1024, in);
227 #endif
228
229 //if on win32 we put the \0 when we find \n because no line buffering
230 #ifdef __WIN32__
231 if (r)
232 {
233 if (strchr(result,'\n') != NULL)
234 {
235 gchar *line_end;
236 line_end = strchr(result,'\n') + 1;
237 *line_end = '\0';
238 }
239 }
240 #endif
241
242 //must be freed after
243 return result;
244 }
245
247 gint get_integer_from_string(gchar *result)
248 {
249 gint our_integer = 0;
250 gint i = 0;
251 gchar *number = NULL;
252 while ((isdigit(result[i])==0) &&
253 (result[i]!='\0') && (result[i]!='-'))
254 {
255 i++;
256 number = result + i;
257 }
258 if (! (number == (result + strlen(result))))
259 {
260 our_integer = atoi (number);
261 }
262
263 return our_integer;
264 }
265
267 gboolean snackamp_is_connected()
268 {
269 return connected;
270 }
271
273 void snackamp_get_song_infos(gchar *total_infos)
274 {
275 gchar rate_str[32] = { '\0' };
276 gchar freq_str[32] = { '\0' };
277 gchar nch_str[32] = { '\0' };
278 gchar *ptr = NULL;
279
280 gchar *result;
281 result = snackamp_socket_send_message("xmms_remote_get_info\n");
282 result = cut_begin_end(result);
283
284 //we get the stereo/mono
285 char *a = strstr(result, " ");
286 if (a != NULL)
287 {
288 if (strstr(a+1, " ") != NULL)
289 ptr = strstr(a+1, " ")+1;
290
291 gint i = 0;
292 //we get the rate
293 while (result[i] != ' '
294 && isdigit(result[i])
295 && i<16)
296 {
297 g_sprintf(rate_str,
298 "%s%c",rate_str,result[i]);
299 i++;
300 }
301
302 //we cut the beginning
303 if (strchr(result, ' ') != NULL)
304 {
305 gchar *test;
306 test = strchr(result,' ');
307 g_snprintf(result, strlen(result),
308 "%s",test+1);
309 }
310
311 //we get the freq
312 i = 0;
313 while (result[i] != ' '
314 && isdigit(result[i])
315 && i<16)
316 {
317 g_sprintf(freq_str,
318 "%s%c",freq_str,result[i]);
319 i++;
320 }
321
322 //channels int
323 gint nch;
324 nch = atoi(ptr);
325
326 if (nch == 2)
327 {
328 snprintf(nch_str, 32, "%s", _("stereo"));
329 }
330 else
331 {
332 snprintf(nch_str, 32, "%s", _("mono"));
333 }
334
335 gchar *_Kbps = _("Kbps");
336 gchar *_Khz = _("Khz");
337
338 g_snprintf(total_infos, 512,
339 "%s %s %s %s %s",
340 rate_str,_Kbps,freq_str, _Khz,nch_str);
341 }
342 else
343 {
344 g_snprintf(total_infos, 512,
345 "disconnected");
346 }
347
348 //free memory
349 g_free(result);
350 }
351
356 gchar *snackamp_get_filename()
357 {
358 //we get the current song position
359 gchar *result;
360 gint playlist_pos = snackamp_get_playlist_pos();
361
362 //we get the current file
363 gchar temp[100];
364 g_snprintf(temp, 100,
365 "%s %d\n",
366 "xmms_remote_get_playlist_file",playlist_pos);
367
368 result = snackamp_socket_send_message(temp);
369 result = cut_begin_end(result);
370
371 return result;
372 }
373
375 gint snackamp_get_playlist_pos()
376 {
377 gchar *result;
378 gint number = 0;
379 result = snackamp_socket_send_message("xmms_remote_get_playlist_pos\n");
380 number = get_integer_from_string(result);
381 g_free(result);
382
383 return number;
384 }
385
387 void snackamp_stop()
388 {
389 gchar *result;
390 result = snackamp_socket_send_message("xmms_remote_stop\n");
391 g_free(result);
392 }
393
395 gint snackamp_get_playlist_number()
396 {
397 gchar *result;
398 gint number = 0;
399 result = snackamp_socket_send_message("xmms_remote_get_playlist_length\n");
400 number = get_integer_from_string(result);
401 g_free(result);
402
403 //if we have no song in the playlist we stop it
404 if (number == -1)
405 {
406 snackamp_stop();
407 }
408
409 return number;
410 }
411
416 gchar *snackamp_get_title_song()
417 {
418 gchar *result;
419 gint playlist_pos = snackamp_get_playlist_pos();
420
421 //we get the current file
422 gchar temp[100];
423 g_snprintf(temp, 100,"%s %d\n",
424 "xmms_remote_get_playlist_title",playlist_pos);
425 result = snackamp_socket_send_message(temp);
426 result = cut_begin_end(result);
427
428 return result;
429 }
430
432 gint snackamp_get_time_elapsed()
433 {
434 gchar *result;
435 gint pos;
436 result = snackamp_socket_send_message("xmms_remote_get_output_time\n");
437 pos = get_integer_from_string(result);
438 g_free(result);
439
440 return pos;
441 }
442
444 void snackamp_start()
445 {
446 gint timer;
447 time_t lt;
448
449 static gchar *exec_command;
450 exec_command = "snackAmp";
451 gchar *exec_this = g_strdup_printf("%s &", exec_command);
452 system(exec_this);
453
454 timer = time(&lt);
455 while ((!snackamp_is_running()) &&
456 ((time(&lt) - timer) < 8))
457 {
458 usleep(0);
459 }
460
461 g_free(exec_this);
462 }
463
465 void snackamp_set_playlist_pos(gint pos)
466 {
467 gchar *result;
468 gchar temp[100];
469 g_snprintf(temp, 100, "%s %d\n",
470 "xmms_remote_set_playlist_pos",pos);
471 result = snackamp_socket_send_message(temp);
472 g_free(result);
473 }
474
476 void snackamp_select_last_file()
477 {
478 //we get last song position
479 gint last_song = snackamp_get_playlist_number();
480 snackamp_set_playlist_pos(last_song-1);
481 }
482
484 void snackamp_play()
485 {
486 gchar *result;
487 result = snackamp_socket_send_message("xmms_remote_play\n");
488 g_free(result);
489 }
490
492 void snackamp_play_last_file()
493 {
494 snackamp_select_last_file();
495 snackamp_play();
496 }
497
499 void snackamp_add_files(GList *list)
500 {
501 gchar *song;
502 gchar *result;
503
504 gint i = 0;
505 gchar *local;
506 gint malloc_int;
507
508 //for all songs
509 while ((song = g_list_nth_data(list, i)) != NULL)
510 {
511 malloc_int = strlen(song) + 30;
512 local = malloc(malloc_int * sizeof(gchar *));
513 g_snprintf(local,malloc_int,"%s {%s}\n",
514 "xmms_remote_playlist_add ", song);
515 result = snackamp_socket_send_message(local);
516 g_free(result);
517 g_free(local);
518 i++;
519 }
520 }
521
523 void snackamp_set_volume(gint volume)
524 {
525 //we get the current file
526 gchar *result;
527 gchar temp[100];
528 g_snprintf(temp, 100, "%s %d\n",
529 "xmms_remote_set_main_volume",volume);
530 result = snackamp_socket_send_message(temp);
531 g_free(result);
532 }
533
535 gint snackamp_get_volume()
536 {
537 gchar *result;
538 gint vol;
539 result = snackamp_socket_send_message("xmms_remote_get_main_volume\n");
540 vol = get_integer_from_string(result);
541 g_free(result);
542
543 return vol;
544 }
545
547 void snackamp_start_with_songs(GList *list)
548 {
549 snackamp_start();
550 snackamp_add_files(list);
551 }
552
554 gint snackamp_is_running()
555 {
556 gint result = FALSE;
557
558 //if we are not connected
559 if (!connected)
560 {
561 //if we can connect to snackamp, the player is running
562 if (connect_snackamp(8775) == 0)
563 {
564 result = TRUE;
565 }
566 }
567 else
568 //if we are connected
569 {
570 result = TRUE;
571 }
572
573 return result;
574 }
575
577 void snackamp_pause()
578 {
579 gchar *result;
580 result = snackamp_socket_send_message("xmms_remote_pause\n");
581 g_free(result);
582 }
583
585 void snackamp_next()
586 {
587 gchar *result;
588 result = snackamp_socket_send_message("xmms_remote_playlist_next\n");
589 g_free(result);
590 }
591
593 void snackamp_prev()
594 {
595 gint playlist_pos = snackamp_get_playlist_pos();
596
597 //if we are not at the beginning
598 if (playlist_pos > 0)
599 {
600 gchar *result;
601 result = snackamp_socket_send_message("xmms_remote_playlist_prev\n");
602 g_free(result);
603 }
604 else
605 {
606 //we play the last song
607 snackamp_play_last_file();
608 }
609 }
610
612 void snackamp_jump(gint position)
613 {
614 //we have the position in miliseconds, we get it in hundreths of
615 //seconds
616 gint hundr_secs_pos = position / 10;
617 //we get only the hundreth of seconds
618 gint hundr_secs = hundr_secs_pos % 100;
619 if (hundr_secs == 1)
620 {
621 hundr_secs = 0;
622 }
623 //we have the seconds left
624 gint secs = hundr_secs_pos / 100;
625 gfloat total_pos = hundr_secs + secs * 100;
626 total_pos /= 100;
627
628 gchar *result;
629 gchar temp[100];
630 g_snprintf(temp, 100, "%s %f\n",
631 "xmms_remote_jump_to_time",
632 total_pos);
633
634 result = snackamp_socket_send_message(temp);
635 g_free(result);
636 }
637
639 gint snackamp_get_total_time()
640 {
641 gchar *result;
642 gint hundr_secs;
643 result = snackamp_socket_send_message("xmms_remote_get_playlist_time\n");
644 //we get and convert to hundreth of seconds
645 hundr_secs = get_integer_from_string(result) * 1000;
646 g_free(result);
647
648 return hundr_secs;
649 }
650
652 gint snackamp_is_playing()
653 {
654 //if we are connected to snackamp
655 if (snackamp_is_connected())
656 {
657 gchar *result;
658 gint i;
659 result = snackamp_socket_send_message("xmms_remote_is_playing\n");
660 i = atoi(result);
661 g_free(result);
662
663 if (i == 0)
664 return FALSE;
665 else
666 return TRUE;
667 }
668 else
669 return FALSE;
670 }
671
676 gint snackamp_is_paused()
677 {
678 //if we are connected to snackamp
679 if (snackamp_is_connected())
680 {
681 gint i;
682 gchar *result;
683 result = snackamp_socket_send_message("xmms_remote_is_paused\n");
684 result = cut_begin_end(result);
685
686 i = atoi(result);
687 g_free(result);
688
689 if (i == 1)
690 return TRUE;
691 else
692 return FALSE;
693 }
694 else
695 return FALSE;
696 }
697
698 /*//quits player
699 gint snackamp_quit()
700 {
701 return 1;
702 }
703 */