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: m@ioalex.net
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 #define _WIN32_WINNT 0x0501
41 
42 #include "snackamp_control.h"
43 
48 gint connect_snackamp(gint port, ui_state *ui)
49 {
50  gint return_err = 0;
51 
52 #ifdef __WIN32__
53  long winsockinit;
54  WSADATA winsock;
55  winsockinit = WSAStartup(0x0101,&winsock);
56 #endif
57 
58  struct addrinfo hints;
59  memset(&hints, 0, sizeof(struct addrinfo));
60  hints.ai_family = AF_UNSPEC;
61  hints.ai_socktype = SOCK_STREAM;
62 
63  struct addrinfo *result;
64 
65  char *port_as_string = alloca(16);
66  snprintf(port_as_string, 16, "%d", port);
67 
68  int return_code = getaddrinfo("localhost", port_as_string, &hints, &result);
69  if (return_code != 0) {
70  return_err = 1;
71  }
72 
73  if (return_err == 0)
74  {
75  struct addrinfo *result_p;
76  for (result_p = result; result_p != NULL; result_p = result_p->ai_next)
77  {
78  return_err = 0;
79 
80  ui->pi->socket_id = socket(result_p->ai_family, result_p->ai_socktype, result_p->ai_protocol);
81  if (ui->pi->socket_id == -1)
82  {
83  return_err = 2;
84  continue;
85  }
86 
87  if (connect(ui->pi->socket_id, result_p->ai_addr, result_p->ai_addrlen) != -1)
88  {
89  break;
90  }
91 
92  return_err = 3;
93  close(ui->pi->socket_id);
94  }
95 
96  freeaddrinfo(result);
97  }
98 
99  if (return_err == 0)
100  {
101 #ifdef __WIN32__
102 #else
103  if (NULL == (ui->pi->in = fdopen(ui->pi->socket_id, "r")) ||
104  NULL == (ui->pi->out = fdopen(ui->pi->socket_id, "w")))
105  {
106  return_err = 4;
107  }
108 #endif
109  }
110 
111  if (return_err == 0)
112  {
113  setvbuf(ui->pi->out, NULL, _IOLBF, 0);
114  ui->pi->connected = TRUE;
115  }
116 
117  if (return_err >= 2)
118  {
120  }
121 
122  return return_err;
123 }
124 
125 /*gint connect_snackamp(gint port, ui_state *ui)
126 {
127  struct sockaddr_in host;
128  struct hostent *h;
129  gint return_err = 0;
130 #ifdef __WIN32__
131  long winsockinit;
132  WSADATA winsock;
133  winsockinit = WSAStartup(0x0101,&winsock);
134 #endif
135  if((h = gethostbyname("localhost"))==NULL)
136  {
137  return_err = 1;
138  }
139  host.sin_family = AF_INET;
140  host.sin_addr.s_addr = ((struct in_addr *) (h->h_addr)) ->s_addr;
141  host.sin_port=htons(port);
142  if (return_err == 0)
143  {
144  if ((ui->pi->socket_id = socket(AF_INET, SOCK_STREAM, 0))==-1)
145  {
146  return_err = 2;
147  }
148  }
149  if (return_err == 0)
150  {
151  if ((connect(ui->pi->socket_id, (void *)&host, sizeof(host)))==-1)
152  {
153  return_err = 3;
154  }
155  }
156  if (return_err == 0)
157  {
158 #ifdef __WIN32__
159 #else
160  if (NULL == (ui->pi->in = fdopen(ui->pi->socket_id, "r")) ||
161  NULL == (ui->pi->out = fdopen(ui->pi->socket_id, "w")))
162  {
163  return_err = 4;
164  }
165 #endif
166  }
167  if (return_err == 0)
168  {
169  setvbuf(ui->pi->out, NULL, _IOLBF, 0);
170  ui->pi->connected = TRUE;
171  }
172  if (return_err >= 2)
173  {
174  disconnect_snackamp(ui);
175  }
176  return return_err;
177 }*/
178 
179 static gchar *cut_begin_end(gchar *result)
180 {
181  if (strchr(result,' ') != NULL)
182  {
183  gchar *test = strchr(result, ' ');
184  g_snprintf(result, strlen(result), "%s",test+1);
185  }
186 
187  //cut the \n at the end
188  gint result_str = strlen(result);
189  if (result_str >= 2)
190  {
191  result[result_str - 2] = '\0';
192  }
193 
194  return result;
195 }
196 
201 {
202  ui->pi->connected = FALSE;
203 #ifdef __WIN32__
204  gint result = closesocket(ui->pi->socket_id);
205  WSACleanup();
206  return result;
207 #else
208  return close(ui->pi->socket_id);
209 #endif
210 }
211 
217 static gchar *snackamp_socket_send_message(gchar *message, ui_state *ui)
218 {
219  gchar *result = malloc(1024 * sizeof(gchar *));
220  strcpy(result,"disconnected");
221 
222 #ifdef __WIN32__
223  gboolean r = TRUE;
224 
225  gint err1 = send(ui->pi->socket_id, message, strlen(message), 0);
226  if (err1 <= 0)
227  {
229  }
230  else
231  {
232  gint err = recv(ui->pi->socket_id, result, 1024, 0);
233  if (err <= 0)
234  {
236  r = FALSE;
237  }
238  }
239 #else
240  fputs(message, ui->pi->out);
241  fgets(result, 1024, ui->pi->in);
242 #endif
243 
244  //if on win32 we put the \0 when we find \n because no line buffering
245 #ifdef __WIN32__
246  if (r)
247  {
248  if (strchr(result,'\n') != NULL)
249  {
250  gchar *line_end;
251  line_end = strchr(result,'\n') + 1;
252  *line_end = '\0';
253  }
254  }
255 #endif
256 
257  return result;
258 }
259 
261 static gint get_integer_from_string(gchar *result)
262 {
263  gint our_integer = 0;
264  gint i = 0;
265  gchar *number = NULL;
266  while ((isdigit(result[i])==0) && (result[i]!='\0') && (result[i]!='-'))
267  {
268  i++;
269  number = result + i;
270  }
271  if (! (number == (result + strlen(result))))
272  {
273  our_integer = atoi (number);
274  }
275 
276  return our_integer;
277 }
278 
280 static gboolean snackamp_is_connected(ui_state *ui)
281 {
282  return ui->pi->connected;
283 }
284 
286 void snackamp_get_song_infos(gchar *total_infos, ui_state *ui)
287 {
288  gchar *result = snackamp_socket_send_message("xmms_remote_get_info\n", ui);
289  result = cut_begin_end(result);
290 
291  //stereo/mono
292  char *a = strstr(result, " ");
293  if (a == NULL)
294  {
295  g_snprintf(total_infos, 512, "disconnected");
296  g_free(result);
297  return;
298  }
299 
300  gchar rate_str[32] = { '\0' };
301  gchar freq_str[32] = { '\0' };
302  gchar nch_str[32] = { '\0' };
303  gchar *ptr = NULL;
304 
305  if (strstr(a+1, " ") != NULL)
306  {
307  ptr = strstr(a+1, " ") + 1;
308  }
309 
310  //rate
311  gint i = 0;
312  while (result[i] != ' ' && isdigit(result[i]) && i < 16)
313  {
314  g_sprintf(rate_str, "%s%c",rate_str,result[i]);
315  i++;
316  }
317 
318  //cut the beginning
319  if (strchr(result, ' ') != NULL)
320  {
321  gchar *test = strchr(result,' ');
322  g_snprintf(result, strlen(result), "%s",test+1);
323  }
324 
325  //freq
326  i = 0;
327  while (result[i] != ' ' && isdigit(result[i]) && i < 16)
328  {
329  g_sprintf(freq_str, "%s%c",freq_str,result[i]);
330  i++;
331  }
332 
333  //channels int
334  gint nch = atoi(ptr);
335  if (nch == 2)
336  {
337  snprintf(nch_str, 32, "%s", _("stereo"));
338  }
339  else
340  {
341  snprintf(nch_str, 32, "%s", _("mono"));
342  }
343 
344  gchar *_Kbps = _("Kbps");
345  gchar *_Khz = _("Khz");
346  g_snprintf(total_infos, 512, "%s %s %s %s %s", rate_str, _Kbps, freq_str, _Khz, nch_str);
347 
348  g_free(result);
349 }
350 
352 static gint snackamp_get_playlist_pos(ui_state *ui)
353 {
354  gchar *result = snackamp_socket_send_message("xmms_remote_get_playlist_pos\n", ui);
355  gint number = get_integer_from_string(result);
356  g_free(result);
357  return number;
358 }
359 
365 {
366  gint playlist_pos = snackamp_get_playlist_pos(ui);
367 
368  //we get the current file
369  gchar temp[100];
370  g_snprintf(temp, 100, "%s %d\n", "xmms_remote_get_playlist_file", playlist_pos);
371 
372  gchar *result = snackamp_socket_send_message(temp, ui);
373  result = cut_begin_end(result);
374 
375  return result;
376 }
377 
380 {
381  gchar *result = snackamp_socket_send_message("xmms_remote_stop\n", ui);
382  g_free(result);
383 }
384 
387 {
388  gchar *result = snackamp_socket_send_message("xmms_remote_get_playlist_length\n", ui);
389  gint number = get_integer_from_string(result);
390  g_free(result);
391 
392  if (number == -1)
393  {
394  snackamp_stop(ui);
395  }
396 
397  return number;
398 }
399 
405 {
406  gint playlist_pos = snackamp_get_playlist_pos(ui);
407 
408  gchar temp[100];
409  g_snprintf(temp, 100,"%s %d\n", "xmms_remote_get_playlist_title",playlist_pos);
410 
411  gchar *result = snackamp_socket_send_message(temp, ui);
412  result = cut_begin_end(result);
413 
414  return result;
415 }
416 
419 {
420  gchar *result = snackamp_socket_send_message("xmms_remote_get_output_time\n", ui);
421  gint pos = get_integer_from_string(result);
422  g_free(result);
423 
424  return pos;
425 }
426 
429 {
430  static gchar *exec_command = "snackAmp";
431  gchar *exec_this = g_strdup_printf("%s &", exec_command);
432  system(exec_this);
433 
434  time_t lt;
435  gint timer = time(&lt);
436  while ((!snackamp_is_running(ui)) && ((time(&lt) - timer) < 8))
437  {
438  usleep(0);
439  }
440 
441  g_free(exec_this);
442 }
443 
445 static void snackamp_set_playlist_pos(gint pos, ui_state *ui)
446 {
447  gchar temp[100];
448  g_snprintf(temp, 100, "%s %d\n", "xmms_remote_set_playlist_pos",pos);
449  gchar *result = snackamp_socket_send_message(temp, ui);
450  g_free(result);
451 }
452 
455 {
456  gint last_song = snackamp_get_playlist_number(ui);
457  snackamp_set_playlist_pos(last_song - 1, ui);
458 }
459 
462 {
463  gchar *result = snackamp_socket_send_message("xmms_remote_play\n", ui);
464  g_free(result);
465 }
466 
469 {
471  snackamp_play(ui);
472 }
473 
475 void snackamp_add_files(GList *list, ui_state *ui)
476 {
477  gint i = 0;
478  gchar *song = NULL;
479  while ((song = g_list_nth_data(list, i)) != NULL)
480  {
481  gint malloc_int = strlen(song) + 30;
482  gchar *local = malloc(malloc_int * sizeof(gchar *));
483  g_snprintf(local, malloc_int, "%s {%s}\n", "xmms_remote_playlist_add ", song);
484 
485  gchar *result = snackamp_socket_send_message(local, ui);
486  g_free(result);
487 
488  g_free(local);
489  i++;
490  }
491 }
492 
494 void snackamp_set_volume(gint volume, ui_state *ui)
495 {
496  gchar temp[100];
497  g_snprintf(temp, 100, "%s %d\n", "xmms_remote_set_main_volume", volume);
498  gchar *result = snackamp_socket_send_message(temp, ui);
499  g_free(result);
500 }
501 
504 {
505  gchar *result = snackamp_socket_send_message("xmms_remote_get_main_volume\n", ui);
506  gint vol = get_integer_from_string(result);
507  g_free(result);
508 
509  return vol;
510 }
511 
513 void snackamp_start_with_songs(GList *list, ui_state *ui)
514 {
515  snackamp_start(ui);
516  snackamp_add_files(list, ui);
517 }
518 
521 {
522  if (ui->pi->connected)
523  {
524  return TRUE;
525  }
526 
527  if (connect_snackamp(8775, ui) == 0)
528  {
529  return TRUE;
530  }
531 
532  return FALSE;
533 }
534 
537 {
538  gchar *result = snackamp_socket_send_message("xmms_remote_pause\n", ui);
539  g_free(result);
540 }
541 
544 {
545  gchar *result = snackamp_socket_send_message("xmms_remote_playlist_next\n", ui);
546  g_free(result);
547 }
548 
551 {
552  gint playlist_pos = snackamp_get_playlist_pos(ui);
553 
554  if (playlist_pos > 0)
555  {
556  gchar *result = snackamp_socket_send_message("xmms_remote_playlist_prev\n", ui);
557  g_free(result);
558  return;
559  }
560 
562 }
563 
565 void snackamp_jump(gint position, ui_state *ui)
566 {
567  gint hundr_secs_pos = position / 10;
568  gint hundr_secs = hundr_secs_pos % 100;
569  if (hundr_secs == 1)
570  {
571  hundr_secs = 0;
572  }
573 
574  gint secs = hundr_secs_pos / 100;
575  gfloat total_pos = hundr_secs + secs * 100;
576  total_pos /= 100;
577 
578  gchar temp[100];
579  g_snprintf(temp, 100, "%s %f\n", "xmms_remote_jump_to_time", total_pos);
580 
581  gchar *result = snackamp_socket_send_message(temp, ui);
582  g_free(result);
583 }
584 
587 {
588  gchar *result = snackamp_socket_send_message("xmms_remote_get_playlist_time\n", ui);
589  gint hundr_secs = get_integer_from_string(result) * 1000;
590  g_free(result);
591 
592  return hundr_secs;
593 }
594 
597 {
598  if (!snackamp_is_connected(ui))
599  {
600  return FALSE;
601  }
602 
603  gchar *result = snackamp_socket_send_message("xmms_remote_is_playing\n", ui);
604  gint i = atoi(result);
605  g_free(result);
606 
607  if (i == 0)
608  {
609  return FALSE;
610  }
611 
612  return TRUE;
613 }
614 
620 {
621  if (!snackamp_is_connected(ui))
622  {
623  return FALSE;
624  }
625 
626  gchar *result = snackamp_socket_send_message("xmms_remote_is_paused\n", ui);
627  result = cut_begin_end(result);
628 
629  gint i = atoi(result);
630  g_free(result);
631 
632  if (i == 1)
633  {
634  return TRUE;
635  }
636 
637  return FALSE;
638 }
639