mp3splt-gtk 0.9.3.1519
Loading...
Searching...
No Matches
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-2014 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
48gint 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
179static 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
217static 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
261static 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
280static gboolean snackamp_is_connected(ui_state *ui)
281{
282 return ui->pi->connected;
283}
284
286void 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
352static 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
445static 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
473
475void 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
494void 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
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
565void 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
void snackamp_jump(gint position, ui_state *ui)
jump to time
gint snackamp_get_volume(ui_state *ui)
returns volume
void snackamp_start(ui_state *ui)
starts snackamp
void snackamp_set_volume(gint volume, ui_state *ui)
sets volume
void snackamp_prev(ui_state *ui)
changes to previous song
gchar * snackamp_get_filename(ui_state *ui)
returns the filename
void snackamp_start_with_songs(GList *list, ui_state *ui)
starts snackamp with songs
void snackamp_next(ui_state *ui)
changes to next song
gint snackamp_is_running(ui_state *ui)
returns TRUE if snackamp is running; if not, FALSE
gchar * snackamp_get_title_song(ui_state *ui)
returns the title of the song
void snackamp_get_song_infos(gchar *total_infos, ui_state *ui)
gets informations about the song
gint snackamp_get_playlist_number(ui_state *ui)
returns the number of songs of the playlist
void snackamp_pause(ui_state *ui)
pause a song
gint disconnect_snackamp(ui_state *ui)
disconnecting with the player possibly returns an error
gint snackamp_is_paused(ui_state *ui)
returns TRUE if snackamp is paused, else FALSE
gint snackamp_is_playing(ui_state *ui)
returns TRUE if snackamp is playing, else FALSE
void snackamp_play(ui_state *ui)
plays a song
void snackamp_play_last_file(ui_state *ui)
plays the last file of the playlist
gint connect_snackamp(gint port, ui_state *ui)
connecting to the player to the port port
void snackamp_stop(ui_state *ui)
stops playing a song
void snackamp_add_files(GList *list, ui_state *ui)
add files to the snackamp playlist
gint snackamp_get_time_elapsed(ui_state *ui)
returns elapsed time
void snackamp_select_last_file(ui_state *ui)
selects the last file in the playlist
gint snackamp_get_total_time(ui_state *ui)
returns total time of the current song