snackamp_control.c
Go to the documentation of this file.
/**********************************************************
*
* mp3splt-gtk -- utility based on mp3splt,
* for mp3/ogg splitting without decoding
*
* Copyright: (C) 2005-2012 Alexandru Munteanu
* Contact: m@ioalex.net
*
* http://mp3splt.sourceforge.net/
*
*********************************************************/
/**********************************************************
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*********************************************************/
/*!********************************************************
* \file
* Snackamp control
*
* this file contains functions to control the snackamp
* player
**********************************************************/
#define _WIN32_WINNT 0x0501
#include "snackamp_control.h"
gint connect_snackamp(gint port, ui_state *ui)
{
gint return_err = 0;
#ifdef __WIN32__
long winsockinit;
WSADATA winsock;
winsockinit = WSAStartup(0x0101,&winsock);
#endif
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *result;
char *port_as_string = alloca(16);
snprintf(port_as_string, 16, "%d", port);
int return_code = getaddrinfo("localhost", port_as_string, &hints, &result);
if (return_code != 0) {
return_err = 1;
}
if (return_err == 0)
{
struct addrinfo *result_p;
for (result_p = result; result_p != NULL; result_p = result_p->ai_next)
{
return_err = 0;
ui->pi->socket_id = socket(result_p->ai_family, result_p->ai_socktype, result_p->ai_protocol);
if (ui->pi->socket_id == -1)
{
return_err = 2;
continue;
}
if (connect(ui->pi->socket_id, result_p->ai_addr, result_p->ai_addrlen) != -1)
{
break;
}
return_err = 3;
close(ui->pi->socket_id);
}
freeaddrinfo(result);
}
if (return_err == 0)
{
#ifdef __WIN32__
#else
if (NULL == (ui->pi->in = fdopen(ui->pi->socket_id, "r")) ||
NULL == (ui->pi->out = fdopen(ui->pi->socket_id, "w")))
{
return_err = 4;
}
#endif
}
if (return_err == 0)
{
setvbuf(ui->pi->out, NULL, _IOLBF, 0);
ui->pi->connected = TRUE;
}
if (return_err >= 2)
{
disconnect_snackamp(ui);
}
return return_err;
}
/*gint connect_snackamp(gint port, ui_state *ui)
{
struct sockaddr_in host;
struct hostent *h;
gint return_err = 0;
#ifdef __WIN32__
long winsockinit;
WSADATA winsock;
winsockinit = WSAStartup(0x0101,&winsock);
#endif
if((h = gethostbyname("localhost"))==NULL)
{
return_err = 1;
}
host.sin_family = AF_INET;
host.sin_addr.s_addr = ((struct in_addr *) (h->h_addr)) ->s_addr;
host.sin_port=htons(port);
if (return_err == 0)
{
if ((ui->pi->socket_id = socket(AF_INET, SOCK_STREAM, 0))==-1)
{
return_err = 2;
}
}
if (return_err == 0)
{
if ((connect(ui->pi->socket_id, (void *)&host, sizeof(host)))==-1)
{
return_err = 3;
}
}
if (return_err == 0)
{
#ifdef __WIN32__
#else
if (NULL == (ui->pi->in = fdopen(ui->pi->socket_id, "r")) ||
NULL == (ui->pi->out = fdopen(ui->pi->socket_id, "w")))
{
return_err = 4;
}
#endif
}
if (return_err == 0)
{
setvbuf(ui->pi->out, NULL, _IOLBF, 0);
ui->pi->connected = TRUE;
}
if (return_err >= 2)
{
disconnect_snackamp(ui);
}
return return_err;
}*/
static gchar *cut_begin_end(gchar *result)
{
if (strchr(result,' ') != NULL)
{
gchar *test = strchr(result, ' ');
g_snprintf(result, strlen(result), "%s",test+1);
}
//cut the \n at the end
gint result_str = strlen(result);
if (result_str >= 2)
{
result[result_str - 2] = '\0';
}
return result;
}
gint disconnect_snackamp(ui_state *ui)
{
ui->pi->connected = FALSE;
#ifdef __WIN32__
gint result = closesocket(ui->pi->socket_id);
WSACleanup();
return result;
#else
return close(ui->pi->socket_id);
#endif
}
static gchar *snackamp_socket_send_message(gchar *message, ui_state *ui)
{
gchar *result = malloc(1024 * sizeof(gchar *));
strcpy(result,"disconnected");
#ifdef __WIN32__
gboolean r = TRUE;
gint err1 = send(ui->pi->socket_id, message, strlen(message), 0);
if (err1 <= 0)
{
disconnect_snackamp(ui);
}
else
{
gint err = recv(ui->pi->socket_id, result, 1024, 0);
if (err <= 0)
{
disconnect_snackamp(ui);
r = FALSE;
}
}
#else
fputs(message, ui->pi->out);
fgets(result, 1024, ui->pi->in);
#endif
//if on win32 we put the \0 when we find \n because no line buffering
#ifdef __WIN32__
if (r)
{
if (strchr(result,'\n') != NULL)
{
gchar *line_end;
line_end = strchr(result,'\n') + 1;
*line_end = '\0';
}
}
#endif
return result;
}
static gint get_integer_from_string(gchar *result)
{
gint our_integer = 0;
gint i = 0;
gchar *number = NULL;
while ((isdigit(result[i])==0) && (result[i]!='\0') && (result[i]!='-'))
{
i++;
number = result + i;
}
if (! (number == (result + strlen(result))))
{
our_integer = atoi (number);
}
return our_integer;
}
static gboolean snackamp_is_connected(ui_state *ui)
{
return ui->pi->connected;
}
void snackamp_get_song_infos(gchar *total_infos, ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_get_info\n", ui);
result = cut_begin_end(result);
//stereo/mono
char *a = strstr(result, " ");
if (a == NULL)
{
g_snprintf(total_infos, 512, "disconnected");
g_free(result);
return;
}
gchar rate_str[32] = { '\0' };
gchar freq_str[32] = { '\0' };
gchar nch_str[32] = { '\0' };
gchar *ptr = NULL;
if (strstr(a+1, " ") != NULL)
{
ptr = strstr(a+1, " ") + 1;
}
//rate
gint i = 0;
while (result[i] != ' ' && isdigit(result[i]) && i < 16)
{
g_sprintf(rate_str, "%s%c",rate_str,result[i]);
i++;
}
//cut the beginning
if (strchr(result, ' ') != NULL)
{
gchar *test = strchr(result,' ');
g_snprintf(result, strlen(result), "%s",test+1);
}
//freq
i = 0;
while (result[i] != ' ' && isdigit(result[i]) && i < 16)
{
g_sprintf(freq_str, "%s%c",freq_str,result[i]);
i++;
}
//channels int
gint nch = atoi(ptr);
if (nch == 2)
{
snprintf(nch_str, 32, "%s", _("stereo"));
}
else
{
snprintf(nch_str, 32, "%s", _("mono"));
}
gchar *_Kbps = _("Kbps");
gchar *_Khz = _("Khz");
g_snprintf(total_infos, 512, "%s %s %s %s %s", rate_str, _Kbps, freq_str, _Khz, nch_str);
g_free(result);
}
static gint snackamp_get_playlist_pos(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_get_playlist_pos\n", ui);
gint number = get_integer_from_string(result);
g_free(result);
return number;
}
gchar *snackamp_get_filename(ui_state *ui)
{
gint playlist_pos = snackamp_get_playlist_pos(ui);
//we get the current file
gchar temp[100];
g_snprintf(temp, 100, "%s %d\n", "xmms_remote_get_playlist_file", playlist_pos);
gchar *result = snackamp_socket_send_message(temp, ui);
result = cut_begin_end(result);
return result;
}
void snackamp_stop(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_stop\n", ui);
g_free(result);
}
gint snackamp_get_playlist_number(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_get_playlist_length\n", ui);
gint number = get_integer_from_string(result);
g_free(result);
if (number == -1)
{
snackamp_stop(ui);
}
return number;
}
gchar *snackamp_get_title_song(ui_state *ui)
{
gint playlist_pos = snackamp_get_playlist_pos(ui);
gchar temp[100];
g_snprintf(temp, 100,"%s %d\n", "xmms_remote_get_playlist_title",playlist_pos);
gchar *result = snackamp_socket_send_message(temp, ui);
result = cut_begin_end(result);
return result;
}
gint snackamp_get_time_elapsed(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_get_output_time\n", ui);
gint pos = get_integer_from_string(result);
g_free(result);
return pos;
}
void snackamp_start(ui_state *ui)
{
static gchar *exec_command = "snackAmp";
gchar *exec_this = g_strdup_printf("%s &", exec_command);
system(exec_this);
time_t lt;
gint timer = time(&lt);
while ((!snackamp_is_running(ui)) && ((time(&lt) - timer) < 8))
{
usleep(0);
}
g_free(exec_this);
}
static void snackamp_set_playlist_pos(gint pos, ui_state *ui)
{
gchar temp[100];
g_snprintf(temp, 100, "%s %d\n", "xmms_remote_set_playlist_pos",pos);
gchar *result = snackamp_socket_send_message(temp, ui);
g_free(result);
}
void snackamp_select_last_file(ui_state *ui)
{
gint last_song = snackamp_get_playlist_number(ui);
snackamp_set_playlist_pos(last_song - 1, ui);
}
void snackamp_play(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_play\n", ui);
g_free(result);
}
void snackamp_play_last_file(ui_state *ui)
{
snackamp_select_last_file(ui);
snackamp_play(ui);
}
void snackamp_add_files(GList *list, ui_state *ui)
{
gint i = 0;
gchar *song = NULL;
while ((song = g_list_nth_data(list, i)) != NULL)
{
gint malloc_int = strlen(song) + 30;
gchar *local = malloc(malloc_int * sizeof(gchar *));
g_snprintf(local, malloc_int, "%s {%s}\n", "xmms_remote_playlist_add ", song);
gchar *result = snackamp_socket_send_message(local, ui);
g_free(result);
g_free(local);
i++;
}
}
void snackamp_set_volume(gint volume, ui_state *ui)
{
gchar temp[100];
g_snprintf(temp, 100, "%s %d\n", "xmms_remote_set_main_volume", volume);
gchar *result = snackamp_socket_send_message(temp, ui);
g_free(result);
}
gint snackamp_get_volume(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_get_main_volume\n", ui);
gint vol = get_integer_from_string(result);
g_free(result);
return vol;
}
void snackamp_start_with_songs(GList *list, ui_state *ui)
{
snackamp_start(ui);
snackamp_add_files(list, ui);
}
gint snackamp_is_running(ui_state *ui)
{
if (ui->pi->connected)
{
return TRUE;
}
if (connect_snackamp(8775, ui) == 0)
{
return TRUE;
}
return FALSE;
}
void snackamp_pause(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_pause\n", ui);
g_free(result);
}
void snackamp_next(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_playlist_next\n", ui);
g_free(result);
}
void snackamp_prev(ui_state *ui)
{
gint playlist_pos = snackamp_get_playlist_pos(ui);
if (playlist_pos > 0)
{
gchar *result = snackamp_socket_send_message("xmms_remote_playlist_prev\n", ui);
g_free(result);
return;
}
snackamp_play_last_file(ui);
}
void snackamp_jump(gint position, ui_state *ui)
{
gint hundr_secs_pos = position / 10;
gint hundr_secs = hundr_secs_pos % 100;
if (hundr_secs == 1)
{
hundr_secs = 0;
}
gint secs = hundr_secs_pos / 100;
gfloat total_pos = hundr_secs + secs * 100;
total_pos /= 100;
gchar temp[100];
g_snprintf(temp, 100, "%s %f\n", "xmms_remote_jump_to_time", total_pos);
gchar *result = snackamp_socket_send_message(temp, ui);
g_free(result);
}
gint snackamp_get_total_time(ui_state *ui)
{
gchar *result = snackamp_socket_send_message("xmms_remote_get_playlist_time\n", ui);
gint hundr_secs = get_integer_from_string(result) * 1000;
g_free(result);
return hundr_secs;
}
gint snackamp_is_playing(ui_state *ui)
{
if (!snackamp_is_connected(ui))
{
return FALSE;
}
gchar *result = snackamp_socket_send_message("xmms_remote_is_playing\n", ui);
gint i = atoi(result);
g_free(result);
if (i == 0)
{
return FALSE;
}
return TRUE;
}
gint snackamp_is_paused(ui_state *ui)
{
if (!snackamp_is_connected(ui))
{
return FALSE;
}
gchar *result = snackamp_socket_send_message("xmms_remote_is_paused\n", ui);
result = cut_begin_end(result);
gint i = atoi(result);
g_free(result);
if (i == 1)
{
return TRUE;
}
return FALSE;
}