mp3splt-gtk
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)
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 
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  {
212  }
213  else
214  {
215  gint err = recv(socket_id, result, 1024, 0);
216  if (err <= 0)
217  {
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 
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 
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 
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 
388 {
389  gchar *result;
390  result = snackamp_socket_send_message("xmms_remote_stop\n");
391  g_free(result);
392 }
393 
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 
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 
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 
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 
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 
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 
485 {
486  gchar *result;
487  result = snackamp_socket_send_message("xmms_remote_play\n");
488  g_free(result);
489 }
490 
493 {
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 
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 
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 
578 {
579  gchar *result;
580  result = snackamp_socket_send_message("xmms_remote_pause\n");
581  g_free(result);
582 }
583 
586 {
587  gchar *result;
588  result = snackamp_socket_send_message("xmms_remote_playlist_next\n");
589  g_free(result);
590 }
591 
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
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 
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 
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 
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 */