Example #1
0
/******************** Song ingo retrival ************************************/
static int  getSong(void) {
	mpd_Status *status;
	mpd_InfoEntity *info;

	/* Get status */
	mpd_sendStatusCommand(D.conn);
	if (error()) return 0;
	status = mpd_getStatus(D.conn);
	if (error()) return 0;
	pdie_on(!status, "get status");

	mpd_nextListOkCommand(D.conn);
	if (error()) {
		mpd_freeStatus(status);
		return 0;
	}

	/* Copy status */
	D.cur.state  = status->state;
	D.cur.songid = status->songid;
	D.cur.pos    = status->elapsedTime;
	D.cur.len    = status->totalTime;
	mpd_freeStatus(status);

	/* Same song, return */
	if (D.cur.songid == D.old.songid) {
		return 1;
	}

	if (D.info) {
		mpd_freeInfoEntity(D.info);
		D.info = 0;
	}

	/* Get song */
	mpd_sendCurrentSongCommand(D.conn);
	if (error()) {
		return 0;
	}
	info = mpd_getNextInfoEntity(D.conn);
	if (error()) {
		return 0;
	}

	if (!info) {
		return
			D.cur.state == MPD_STATUS_STATE_PLAY ||
			D.cur.state == MPD_STATUS_STATE_PAUSE;
	}

	if (info->type != MPD_INFO_ENTITY_TYPE_SONG) {
		mpd_freeInfoEntity(info);
		return 0;
	}

	D.info = info;
	return 1;
}
Example #2
0
File: mpd.c Project: mattx86/aprq2
/*
=================
MPD_Status - show info about currently playing song
=================
*/
void MPD_Status(void)
{
	mpd_Status		*status;
	mpd_InfoEntity	*entity = NULL;
	mpd_Song		*song = 0;
	char			title[MP3_MAXSONGTITLE];


	if(!MP3_Status())
		return;

	mpd_sendStatusCommand(conn);

	if( (status = mpd_getStatus(conn)) == NULL)
	{
		Com_Printf("MPD: %s\n", conn->errorStr);
		mpd_finishCommand(conn);
		return;
	}
	mpd_finishCommand(conn);

	if( status->state == MPD_STATUS_STATE_STOP) {
		/* Playback stopped */
		Com_Printf("MPD: not playing\n");
		mpd_freeStatus(status);
		return;
	}

	if( status->state == MPD_STATUS_STATE_PLAY || MPD_STATUS_STATE_PAUSE )
	{
		mpd_sendCurrentSongCommand(conn);
		while((entity = mpd_getNextInfoEntity(conn)))
		{
			if(entity->type != MPD_INFO_ENTITY_TYPE_SONG)
			{
				mpd_freeInfoEntity(entity);
				continue;
			}

			song = entity->info.song;
			if(song->title == NULL || song->artist == NULL)
				Com_sprintf(title, sizeof(title), "%s [%i:%02i]", (song->title) ? song->title : song->file, status->totalTime / 60, status->totalTime % 60);
			else
				Com_sprintf(title, sizeof(title), "%s - %s [%i:%02i]", song->artist, song->title, status->totalTime / 60, status->totalTime % 60);

			COM_MakePrintable(title);
			Com_Printf("%s\n", title);

			mpd_freeInfoEntity(entity);
			break;
		}
		mpd_finishCommand(conn);
	}

	mpd_freeStatus(status);
}
Example #3
0
int cmd_volume ( int argc, char ** argv, mpd_Connection * conn )
{
        struct int_value_change ch;

	if(argc==1) {
                if(!parse_int_value_change(argv[0], &ch))
			DIE("\"%s\" is not an integer\n", argv[0]);
	} else {
		mpd_Status *status;

		status = getStatus(conn);

		printf("volume:%3i%c   \n",status->volume,'%');

		mpd_freeStatus(status);

		return 0;
	}

	if (ch.is_relative)
		mpd_sendVolumeCommand(conn,ch.value);
	else
		mpd_sendSetvolCommand(conn,ch.value);

	my_finishCommand(conn);
	return 1;
}
Example #4
0
int
cmd_playlist(mpd_unused int argc, mpd_unused char **argv, mpd_Connection *conn)
{
	mpd_InfoEntity * entity;
	mpd_Status * status;
	int count = 0;

	mpd_sendStatusCommand(conn);
	printErrorAndExit(conn);
	status = mpd_getStatus(conn);
	printErrorAndExit(conn);
	mpd_finishCommand(conn);
	mpd_sendPlaylistInfoCommand(conn,-1);
	printErrorAndExit(conn);

	while((entity = mpd_getNextInfoEntity(conn))) {
		if(entity->type==MPD_INFO_ENTITY_TYPE_SONG) {
			struct mpd_song *song = entity->info.song;

			printf("%s%i) ", (status->song == count)?">":" ", 1+count);
			pretty_print_song(song);
			printf("\n");

			count++;
		}
		mpd_freeInfoEntity(entity);
	}

	my_finishCommand(conn);
	mpd_freeStatus(status);

	return 0;
}
Example #5
0
int cmd_play ( int argc, char ** argv, mpd_Connection * conn )
{
	int song;
	int i;

	if(0==argc) song = MPD_PLAY_AT_BEGINNING;
	else {
		mpd_Status *status;

		for(i=0;i<argc-1;i++)
			printf("skipping: %s\n",argv[i]);

                if(!parse_songnum(argv[i], &song))
			DIE("error parsing song numbers from: %s\n",argv[i]);

		song--;

		/* This is necessary, otherwise mpc will output the wrong playlist number */
		status = getStatus(conn);
		i = status->playlistLength;
		mpd_freeStatus(status);
		if(song >= i)
			DIE("song number greater than playlist length.\n");
	}

	mpd_sendPlayCommand(conn,song);
	my_finishCommand(conn);

	return 1;
}
Example #6
0
static int mpdclient_playlist_update(void *data) {
	mpd_Status * status;
	mpd_InfoEntity *entity;
	int i;

	mpd_sendCommandListOkBegin(conn);
	mpd_sendStatusCommand(conn);
	mpd_sendPlChangesCommand(conn, cur_playlist);
	mpd_sendCommandListEnd(conn);

	if((status = mpd_getStatus(conn))==NULL) {
		fprintf(stderr,"%s\n",conn->errorStr);
		mpd_closeConnection(conn);
		return 1;
	}

	cur_playlist = status->playlist;
	cur_song = status->songid;

	mpd_nextListOkCommand(conn);

	evas_event_freeze(evas);

	while((entity = mpd_getNextInfoEntity(conn))) {
		if(entity->type!=MPD_INFO_ENTITY_TYPE_SONG) {
			mpd_freeInfoEntity(entity);
			continue;
		}

		music_song_insert(entity->info.song);

		mpd_freeInfoEntity(entity);
	}

	for (i = status->playlistLength; i < music_song_count(); i++) {
		music_song_remove(i);
	}

	if (status->state == MPD_STATUS_STATE_PLAY ||
			status->state == MPD_STATUS_STATE_PAUSE) {
		music_song_update(status->song, status->totalTime);
	} else {
		music_song_update(-1, 0);
	}

	layout_update(status->state == MPD_STATUS_STATE_PLAY, status->volume);
	evas_event_thaw(evas);

	mpd_finishCommand(conn);
	mpd_freeStatus(status);
	return 1;
}
Example #7
0
int
cmd_crop(mpd_unused int argc, mpd_unused char **argv, mpd_Connection *conn)
{
	mpd_Status *status = getStatus( conn );
	int length = ( status->playlistLength - 1 );

	if( status->playlistLength == 0 ) {

		mpd_freeStatus(status);
		DIE( "You have to have a playlist longer than 1 song in length to crop" );

	} else if( status->state == 3 || status->state == 2 ) { /* If playing or paused */

		mpd_sendCommandListBegin( conn );
		printErrorAndExit( conn );

		while( length >= 0 )
		{
			if( length != status->song )
			{
				mpd_sendDeleteCommand( conn, length );
				printErrorAndExit( conn );
			}
			length--;
		}

		mpd_sendCommandListEnd( conn );
		my_finishCommand( conn );
		mpd_freeStatus( status );
		return ( 0 );

	} else {

		mpd_freeStatus(status);
		DIE( "You need to be playing to crop the playlist\n" );

	}
}
Example #8
0
MPDStatus MPDConnection::status() {
	if (!isConnected())
		return MPDStatus();

	Q_ASSERT(d->connection);
	mpd_call(MPDConnection::status, Status);
	mpd_Status *status = mpd_getStatus(d->connection);
	if (!finishCommand() || !status)
		return MPDStatus();

	MPDStatus ret(status);
	mpd_freeStatus(status);
	return ret;
}
Example #9
0
File: mpd.c Project: mattx86/aprq2
static char *MPD_SongTitle ( void )
{
	mpd_Status		*status;
	mpd_InfoEntity	*entity = NULL;
	mpd_Song		*song = 0;
	static char title[MP3_MAXSONGTITLE]; 

	title[0] = 0;

	if(!MP3_Status())
		return title;

	mpd_sendCommandListOkBegin(conn);
	mpd_sendStatusCommand(conn);
	mpd_sendCurrentSongCommand(conn);
	mpd_sendCommandListEnd(conn);

	if( (status = mpd_getStatus(conn)) == NULL)
	{
		return title;
	}

	mpd_nextListOkCommand(conn);

	while((entity = mpd_getNextInfoEntity(conn)))
	{
		if(entity->type != MPD_INFO_ENTITY_TYPE_SONG)
		{
			mpd_freeInfoEntity(entity);
			continue;
		}

		song = entity->info.song;
		if(song->title == NULL || song->artist == NULL)
			Com_sprintf(title, sizeof(title), "%s [%i:%02i]", song->file, status->totalTime / 60, status->totalTime % 60);
		else
			Com_sprintf(title, sizeof(title), "%s - %s [%i:%02i]", song->artist, song->title, status->totalTime / 60, status->totalTime % 60);

		COM_MakePrintable(title);

		mpd_freeInfoEntity(entity);
		break;
	}

	mpd_freeStatus(status);
	mpd_finishCommand(conn);

	return title;
}
Example #10
0
int mpd_status_queue_update(MpdObj *mi)
{

	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_INFO,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mi->status != NULL)
	{
		mpd_freeStatus(mi->status);
		mi->status = NULL;
	}
	return MPD_OK;
}
Example #11
0
int cmd_current(mpd_unused int argc, mpd_unused char ** argv, mpd_Connection *conn)
{
	mpd_Status * status;
	mpd_InfoEntity * entity;

	mpd_sendCommandListOkBegin(conn);
	printErrorAndExit(conn);
	mpd_sendStatusCommand(conn);
	printErrorAndExit(conn);
	mpd_sendCurrentSongCommand(conn);
	printErrorAndExit(conn);
	mpd_sendCommandListEnd(conn);
	printErrorAndExit(conn);

	status = mpd_getStatus(conn);
	printErrorAndExit(conn);

	if (status->state == MPD_STATUS_STATE_PLAY ||
	    status->state == MPD_STATUS_STATE_PAUSE) {
		mpd_nextListOkCommand(conn);
		printErrorAndExit(conn);

		while((entity = mpd_getNextInfoEntity(conn))) {
			struct mpd_song *song = entity->info.song;

			if(entity->type!=MPD_INFO_ENTITY_TYPE_SONG) {
				mpd_freeInfoEntity(entity);
				continue;
			}

			pretty_print_song(song);
			printf("\n");

			mpd_freeInfoEntity(entity);

			break;
		}

		printErrorAndExit(conn);

		mpd_finishCommand(conn);
		printErrorAndExit(conn);
	}
	mpd_freeStatus(status);

	return 0;
}
Example #12
0
void mpd_free(MpdObj *mi)
{
	debug_printf(DEBUG_INFO, "destroying MpdObj object\n");
	if(mi->connected)
	{
		/* disconnect */
		debug_printf(DEBUG_WARNING, "Connection still running, disconnecting\n");
		mpd_disconnect(mi);
	}
	if(mi->hostname)
	{
		free(mi->hostname);
	}
	if(mi->password)
	{
		free(mi->password);
	}
	if(mi->error_msg)
	{
		free(mi->error_msg);
	}
	if(mi->connection)
	{
		/* obsolete */
		mpd_closeConnection(mi->connection);
	}
	if(mi->status)
	{
		mpd_freeStatus(mi->status);
	}
	if(mi->stats)
	{
		mpd_freeStats(mi->stats);
	}
	if(mi->CurrentSong)
	{
		mpd_freeSong(mi->CurrentSong);
	}
	mpd_free_queue_ob(mi);
	mpd_server_free_commands(mi);		
	free(mi);
}
Example #13
0
int cmd_consume ( int argc, char ** argv, mpd_Connection * conn )
{
	int mode;

	if(argc==1) {
		mode = get_boolean(argv[0]);
		if (mode < 0)
			return -1;
	}
	else {
		mpd_Status * status;
		status = getStatus(conn);
		mode = !status->consume;
		mpd_freeStatus(status);
	}

	mpd_sendConsumeCommand(conn,mode);
	my_finishCommand(conn);

	return 1;
}
Example #14
0
File: mpd.c Project: mattx86/aprq2
/*
=================
MPD_SetVol - set volume
=================
*/
void MPD_SetVol(void)
{
	mpd_Status		*status;


	if(!MP3_Status())
		return;

	if(Cmd_Argc() < 2)
	{
		mpd_sendStatusCommand(conn);

		if( (status = mpd_getStatus(conn)) == NULL)
		{
			Com_Printf("MPD: %s\n", conn->errorStr);
		} else {
			Com_Printf("MPD: volume %i\%\n", status->volume);
			mpd_freeStatus(status);
		}
		mpd_finishCommand(conn);
	} else {
Example #15
0
int cmd_crossfade ( int argc, char ** argv, mpd_Connection * conn )
{
	int seconds;

	if(argc==1) {
                if(!parse_int(argv[0], &seconds) || seconds<0)
			DIE("\"%s\" is not 0 or positive integer\n",argv[0]);

		mpd_sendCrossfadeCommand(conn,seconds);
		my_finishCommand(conn);
	}
	else {
		mpd_Status * status;
		status = getStatus(conn);

		printf("crossfade: %i\n",status->crossfade);

		mpd_freeStatus(status);
		printErrorAndExit(conn);
	}
	return 0;
}
Example #16
0
int cmd_repeat ( int argc, char ** argv, mpd_Connection * conn )
{
	int mode;

	if(argc==1) {
		mode = get_boolean(argv[0]);
		if (mode < 0)
			return -1;
	}
	else {
		mpd_Status * status;
		status = getStatus(conn);
		mode = !status->repeat;
		mpd_freeStatus(status);
	}


	mpd_sendRepeatCommand(conn,mode);
	printErrorAndExit(conn);
	my_finishCommand(conn);
	printErrorAndExit(conn);

	return 1;
}
Example #17
0
int mpd_status_update(MpdObj *mi)
{
	ChangedStatusType what_changed=0;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_INFO,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}



	if(mi->status != NULL)
	{
		mpd_freeStatus(mi->status);
		mi->status = NULL;
	}
	mpd_sendStatusCommand(mi->connection);
	mi->status = mpd_getStatus(mi->connection);
	if(mi->status == NULL)
	{
		debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n");
		mpd_unlock_conn(mi);
		return MPD_STATUS_FAILED;
	}
	if(mpd_unlock_conn(mi))
	{
		debug_printf(DEBUG_ERROR, "Failed to unlock");
		return MPD_LOCK_FAILED;
	}
	/*
	 * check for changes 
	 */
	/* first save the old status */
	memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState));

	/* playlist change */
	if(mi->CurrentState.playlistid != mi->status->playlist)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Playlist has changed!");

		/* We can't trust the current song anymore. so we remove it */
		/* tags might have been updated */
		if(mi->CurrentSong != NULL)
		{
			mpd_freeSong(mi->CurrentSong);
			mi->CurrentSong = NULL;
		}

		/* set MPD_CST_PLAYLIST to be changed */
		what_changed |= MPD_CST_PLAYLIST;

        if(mi->CurrentState.playlistLength == mi->status->playlistLength)
        {
//            what_changed |= MPD_CST_SONGID; 
        }
		/* save new id */
		mi->CurrentState.playlistid = mi->status->playlist;
	}
	
	if(mi->CurrentState.storedplaylistid != mi->status->storedplaylist)
	{
		/* set MPD_CST_QUEUE to be changed */
		what_changed |= MPD_CST_STORED_PLAYLIST;


		/* save new id */
		mi->CurrentState.storedplaylistid = mi->status->storedplaylist;
	}


	/* state change */
	if(mi->CurrentState.state != mi->status->state)
	{
		what_changed |= MPD_CST_STATE;
		mi->CurrentState.state = mi->status->state;
	}

	if(mi->CurrentState.songid != mi->status->songid)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Songid has changed %i %i!", mi->OldState.songid, mi->status->songid);

		what_changed |= MPD_CST_SONGID;
		/* save new songid */
		mi->CurrentState.songid = mi->status->songid;

	}
	if(mi->CurrentState.songpos != mi->status->song)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Songpos has changed %i %i!", mi->OldState.songpos, mi->status->song);

		what_changed |= MPD_CST_SONGPOS;
		/* save new songid */
		mi->CurrentState.songpos = mi->status->song;

	}
    if(mi->CurrentState.nextsongid != mi->status->nextsongid || mi->CurrentState.nextsongpos != mi->status->nextsong)
    {
		what_changed |= MPD_CST_NEXTSONG;
		/* save new songid */
		mi->CurrentState.nextsongpos = mi->status->nextsong;
        mi->CurrentState.nextsongid = mi->status->nextsongid;
    }
	
	if(mi->CurrentState.single != mi->status->single)
	{
		what_changed |= MPD_CST_SINGLE_MODE;
		mi->CurrentState.single = mi->status->single;
	}
	if(mi->CurrentState.consume != mi->status->consume)
	{
		what_changed |= MPD_CST_CONSUME_MODE;
		mi->CurrentState.consume = mi->status->consume;
	}
	if(mi->CurrentState.repeat != mi->status->repeat)
	{
		what_changed |= MPD_CST_REPEAT;
		mi->CurrentState.repeat = mi->status->repeat;
	}
	if(mi->CurrentState.random != mi->status->random)
	{
		what_changed |= MPD_CST_RANDOM;
		mi->CurrentState.random = mi->status->random;
	}
	if(mi->CurrentState.volume != mi->status->volume)
	{
		what_changed |= MPD_CST_VOLUME;
		mi->CurrentState.volume = mi->status->volume;
	}
	if(mi->CurrentState.xfade != mi->status->crossfade)
	{
		what_changed |= MPD_CST_CROSSFADE;
		mi->CurrentState.xfade = mi->status->crossfade;
	}
	if(mi->CurrentState.totaltime != mi->status->totalTime)
	{
		what_changed |= MPD_CST_TOTAL_TIME;
		mi->CurrentState.totaltime = mi->status->totalTime;
	}
	if(mi->CurrentState.elapsedtime != mi->status->elapsedTime)
	{
		what_changed |= MPD_CST_ELAPSED_TIME;
		mi->CurrentState.elapsedtime = mi->status->elapsedTime;
	}

	/* Check if bitrate changed, happens with vbr encodings. */
	if(mi->CurrentState.bitrate != mi->status->bitRate)
	{
		what_changed |= MPD_CST_BITRATE;
		mi->CurrentState.bitrate = mi->status->bitRate;
	}

	/* The following 3 probly only happen on a song change, or is it possible in one song/stream? */
	/* Check if the sample rate changed */
	if(mi->CurrentState.samplerate != mi->status->sampleRate)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.samplerate = mi->status->sampleRate;
	}
	
	/* check if the sampling depth changed */
	if(mi->CurrentState.bits != mi->status->bits)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.bits = mi->status->bits;
	}
	
	/* Check if the amount of audio channels changed */
	if(mi->CurrentState.channels != mi->status->channels)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.channels = mi->status->channels;
	}

    if(mi->status->error)
    {
        what_changed |= MPD_CST_SERVER_ERROR;
        strcpy(mi->CurrentState.error,mi->status->error);
        mpd_sendClearErrorCommand(mi->connection);
        mpd_finishCommand(mi->connection);
    }
    else
    {
        mi->CurrentState.error[0] ='\0';
    }

	/* Check if the updating changed,
	 * If it stopped, also update the stats for the new db-time.
	 */
	if(mi->CurrentState.updatingDb != mi->status->updatingDb )
	{
		what_changed |= MPD_CST_UPDATING;
		if(!mi->status->updatingDb)
		{
			mpd_stats_update_real(mi, &what_changed);
		}
		mi->CurrentState.updatingDb = mi->status->updatingDb;
	}


    mi->CurrentState.playlistLength = mi->status->playlistLength;


    /* Detect changed outputs */
    if(!mi->has_idle)
    {
        if(mi->num_outputs >0 )
        {
            mpd_OutputEntity *output = NULL;
            mpd_sendOutputsCommand(mi->connection);
            while (( output = mpd_getNextOutput(mi->connection)) != NULL)
            {   
                if(mi->num_outputs < output->id)
                {
                    mi->num_outputs++;
                    mi->output_states = realloc(mi->output_states,mi->num_outputs*sizeof(int));
                    mi->output_states[mi->num_outputs] = output->enabled;
                    what_changed |= MPD_CST_OUTPUT;
                }
                if(mi->output_states[output->id] != output->enabled)
                {
                    mi->output_states[output->id] = output->enabled;
                    what_changed |= MPD_CST_OUTPUT;
                }
                mpd_freeOutputElement(output);
            }
            mpd_finishCommand(mi->connection);
        }
        else
        {
            /* if no outputs, lets fetch them */
            mpd_server_update_outputs(mi);
            if(mi->num_outputs == 0)
            {
                assert("No outputs defined? that cannot be\n");
            }
            what_changed |= MPD_CST_OUTPUT;
        }
    }else {
        char *name;
        int update_stats = 0;
        mpd_sendGetEventsCommand(mi->connection);    
        while((name = mpd_getNextEvent(mi->connection))){
            if(strcmp(name, "output") == 0){
                what_changed |= MPD_CST_OUTPUT;
            }else if (strcmp(name, "database") == 0) {
                if((what_changed&MPD_CST_DATABASE) == 0)
                {
                    update_stats = 1;
                }
                what_changed |= MPD_CST_DATABASE;
            }else if (strcmp(name, "stored_playlist")==0) {
                what_changed |= MPD_CST_STORED_PLAYLIST;
            }else if (strcmp(name, "tag") == 0) {
                what_changed |= MPD_CST_PLAYLIST;
            }else if (strcmp (name, "sticker") == 0) {
                what_changed |= MPD_CST_STICKER;
            }
            free(name);
       }
       mpd_finishCommand(mi->connection);
       if(update_stats) {
           mpd_stats_update_real(mi, &what_changed);
       }
    }

  
	/* Run the callback */
	if((mi->the_status_changed_callback != NULL) && what_changed)
	{
		mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata );
	}

        /* We could have lost connection again during signal handling... so before we return check again if we are connected */
	if(!mpd_check_connected(mi))
	{
		return MPD_NOT_CONNECTED;
	}
	return MPD_OK;
}
Example #18
0
int mpd_disconnect(MpdObj *mi)
{

	/* lock */
	mpd_lock_conn(mi);
	debug_printf(DEBUG_INFO, "disconnecting\n");

	if(mi->connection)
	{
		mpd_closeConnection(mi->connection);
		mi->connection = NULL;
	}
	if(mi->status)
	{
		mpd_freeStatus(mi->status);
		mi->status = NULL;
	}
	if(mi->stats)
	{
		mpd_freeStats(mi->stats);
		mi->stats = NULL;
	}
	if(mi->CurrentSong)
	{
		mpd_freeSong(mi->CurrentSong);
		mi->CurrentSong = NULL;
	}
	mi->CurrentState.playlistid = -1;
	mi->CurrentState.queueid = -2;
	mi->CurrentState.storedplaylistid = -1;
	mi->CurrentState.state = -1;
	mi->CurrentState.songid = -1;
	mi->CurrentState.songpos = -1;
	mi->CurrentState.dbUpdateTime = 0;
	mi->CurrentState.updatingDb = 0;
	mi->CurrentState.repeat = -1;
	mi->CurrentState.random = -1;
	mi->CurrentState.volume = -2;
	mi->CurrentState.xfade	= -1;
	mi->CurrentState.totaltime = 0;
	mi->CurrentState.elapsedtime = 0;
	mi->CurrentState.bitrate = 0;
	mi->CurrentState.samplerate = 0; 
	mi->CurrentState.channels = 0; 
	mi->CurrentState.bits = 0;
    mi->CurrentState.playlistLength = 0;
    mi->CurrentState.error[0] = '\0';
	/* search stuff */
	mi->search_type = MPD_SEARCH_TYPE_NONE;
	/* no need to initialize, but set it to anything anyway*/
	mi->search_field = MPD_TAG_ITEM_ARTIST;



	
	memcpy(&(mi->OldState), &(mi->CurrentState) , sizeof(MpdServerState));

	mpd_free_queue_ob(mi);
	mpd_server_free_commands(mi);	
	/*don't reset errors */
	/* Remove this signal, we don't actually disconnect */
	if(mi->connected)
	{
		/* set disconnect flag */
		mi->connected = FALSE;

		if(mi->the_connection_changed_callback != NULL)
		{
			mi->the_connection_changed_callback( mi, FALSE, mi->the_connection_changed_signal_userdata );
		}
	}
	debug_printf(DEBUG_INFO, "Disconnect completed\n");
	return MPD_OK;
}
Example #19
0
int cmd_del ( int argc, char ** argv, mpd_Connection * conn )
{
	int i,j;
	char * s;
	char * t;
	char * t2;
	int range[2];
	int songsDeleted = 0;
	int plLength = 0;
	char * songsToDel;
	mpd_Status * status;

	status = getStatus(conn);

	plLength = status->playlistLength;

	songsToDel = malloc(plLength);
	memset(songsToDel,0,plLength);

	for(i=0;i<argc;i++) {
		if(argv[i][0]=='#') s = &(argv[i][1]);
		else s = argv[i];

		range[0] = strtol(s,&t,10);

		/* If argument is 0 current song and we're not stopped */
		if(range[0] == 0 && strlen(s) == 1 && \
			(status->state == MPD_STATUS_STATE_PLAY ||
			status->state == MPD_STATUS_STATE_PAUSE))
			range[0] = status->song+1;

		if(s==t)
			DIE("error parsing song numbers from: %s\n",argv[i]);
		else if(*t=='-') {
			range[1] = strtol(t+1,&t2,10);
			if(t+1==t2 || *t2!='\0')
				DIE("error parsing range from: %s\n",argv[i]);
		}
		else if(*t==')' || *t=='\0') range[1] = range[0];
		else
			DIE("error parsing song numbers from: %s\n",argv[i]);

		if(range[0]<=0 || range[1]<=0) {
			if (range[0]==range[1])
				DIE("song number must be positive: %i\n",range[0]);
			else
				DIE("song numbers must be positive: %i to %i\n",range[0],range[1]);
		}

		if(range[1]<range[0])
			DIE("song range must be from low to high: %i to %i\n",range[0],range[1]);

		if(range[1]>plLength)
			DIE("song number does not exist: %i\n",range[1]);

		for(j=range[0];j<=range[1];j++) songsToDel[j-1] = 1;
	}

	mpd_sendCommandListBegin(conn);
	printErrorAndExit(conn);
	for(i=0;i<plLength;i++) {
		if(songsToDel[i]) {
			mpd_sendDeleteCommand(conn,i-songsDeleted);
			printErrorAndExit(conn);
			songsDeleted++;
		}
	}
	mpd_sendCommandListEnd(conn);
	my_finishCommand(conn);

	mpd_freeStatus(status);
	free(songsToDel);
	return 0;
}
Example #20
0
int
cmd_seek(mpd_unused int argc, mpd_unused char **argv, mpd_Connection *conn)
{
	mpd_Status * status;
	char * arg = argv[0];
	char * test;

	int seekchange;
	int total_secs;
	int seekto;
        int rel = 0;

	status = getStatus(conn);

	if(status->state==MPD_STATUS_STATE_STOP)
		DIE("not currently playing\n");

	/* Detect +/- if exists point to the next char */
        if(*arg == '+') rel = 1;
        else if(*arg == '-') rel = -1;

	if(rel != 0) arg++;

	/* If seeking by percent */
	if( arg[strlen(arg)-1] == '%' ) {

		double perc;

		/* Remove the % */
		arg[ strlen(arg) - 1 ] = '\0';

		/* percent seek, strtod is needed for percent with decimals */
		perc = strtod(arg,&test);

		if(( *test!='\0' ) || (!rel && (perc<0 || perc>100)) || (rel && perc>abs(100)))
			DIE("\"%s\" is not an number between 0 and 100\n",arg);

		seekchange = perc*status->totalTime/100+0.5;

	} else { /* If seeking by absolute seek time */

		if( strchr( arg, ':' )) {
			char * sec_ptr;
			char * min_ptr;
			char * hr_ptr;

			int hr = 0;
			int min = 0;
			int sec = 0;

			/* Take the seconds off the end of arg */
			sec_ptr = strrchr( arg, ':' );

			/* Remove ':' and move the pointer one byte up */
			* sec_ptr = '\0';
			++sec_ptr;

			/* If hour is in the argument, else just point to the arg */
			if(( min_ptr = strrchr( arg, ':' ))) {

				/* Remove ':' and move the pointer one byte up */
				* min_ptr = '\0';
				++min_ptr;

				/* If the argument still exists, it's the hour  */
				if( arg != NULL ) {
					hr_ptr = arg;
					hr = strtol( hr_ptr, &test, 10 );

					if( *test != '\0' || ( ! rel && hr < 0 ))
						DIE("\"%s\" is not a positive number\n", sec_ptr);
				}
			} else {
				min_ptr = arg;
			}

			/* Change the pointers to a integer  */
			sec = strtol( sec_ptr, &test, 10 );

			if( *test != '\0' || ( ! rel && sec < 0 ))
				DIE("\"%s\" is not a positive number\n", sec_ptr);

			min = strtol( min_ptr, &test, 10 );

			if( *test != '\0' || ( ! rel && min < 0 ))
				DIE("\"%s\" is not a positive number\n", min_ptr);

			/* If mins exist, check secs. If hrs exist, check mins  */
			if( min && strlen(sec_ptr) != 2 )
				DIE("\"%s\" is not two digits\n", sec_ptr);
			else if( hr && strlen(min_ptr) != 2 )
				DIE("\"%s\" is not two digits\n", min_ptr);

			/* Finally, make sure they're not above 60 if higher unit exists */
			if( min && sec > 60 )
				DIE("\"%s\" is greater than 60\n", sec_ptr);
			else if( hr && min > 60 )
				DIE("\"%s\" is greater than 60\n", min_ptr);

			total_secs = ( hr * 3600 ) + ( min * 60 ) + sec;

		} else {

			/* absolute seek (in seconds) */
			total_secs = strtol( arg, &test, 10 ); /* get the # of seconds */

			if( *test != '\0' || ( ! rel && total_secs < 0 ))
				DIE("\"%s\" is not a positive number\n", arg);
		}
		seekchange = total_secs;
	}

	/* This detects +/- and is necessary due to the parsing of HH:MM:SS numbers*/
	if(rel == 1) {
		seekto = status->elapsedTime + seekchange;
	} else if (rel == -1) {
		seekto = status->elapsedTime - seekchange;
	} else {
		seekto = seekchange;
	}

	if(seekto > status->totalTime)
		DIE("Seek amount would seek past the end of the song\n");

	mpd_sendSeekIdCommand(conn,status->songid,seekto);
	printErrorAndExit(conn);
	my_finishCommand(conn);
	printErrorAndExit(conn);
	mpd_freeStatus(status);
	printErrorAndExit(conn);
	return 1;
}
Example #21
0
int mpd_status_update(MpdObj *mi)
{
	ChangedStatusType what_changed=0;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_INFO,"Where not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}


	if(mi->status != NULL)
	{
		mpd_freeStatus(mi->status);
		mi->status = NULL;
	}
	mpd_sendStatusCommand(mi->connection);
	mi->status = mpd_getStatus(mi->connection);
	if(mi->status == NULL)
	{
		debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n");
		mpd_unlock_conn(mi);
		return MPD_STATUS_FAILED;
	}
	if(mpd_unlock_conn(mi))
	{
		debug_printf(DEBUG_ERROR, "Failed to unlock");
		return MPD_LOCK_FAILED;
	}
	/*
	 * check for changes 
	 */
	/* first save the old status */
	memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState));

	/* playlist change */
	if(mi->CurrentState.playlistid != mi->status->playlist)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Playlist has changed!");

		/* We can't trust the current song anymore. so we remove it */
		/* tags might have been updated */
		if(mi->CurrentSong != NULL)
		{
			mpd_freeSong(mi->CurrentSong);
			mi->CurrentSong = NULL;
		}

		/* set MPD_CST_PLAYLIST to be changed */
		what_changed |= MPD_CST_PLAYLIST;

		/* save new id */
		mi->CurrentState.playlistid = mi->status->playlist;
	}


	/* state change */
	if(mi->CurrentState.state != mi->status->state)
	{
		what_changed |= MPD_CST_STATE;
		mi->CurrentState.state = mi->status->state;
	}

	if(mi->CurrentState.songid != mi->status->songid)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songid, mi->status->songid);

		what_changed |= MPD_CST_SONGID;
		/* save new songid */
		mi->CurrentState.songid = mi->status->songid;

	}
	if(mi->CurrentState.songpos != mi->status->song)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songpos, mi->status->song);

		what_changed |= MPD_CST_SONGPOS;
		/* save new songid */
		mi->CurrentState.songpos = mi->status->song;

	}
	
	if(mi->CurrentState.repeat != mi->status->repeat)
	{
		what_changed |= MPD_CST_REPEAT;
		mi->CurrentState.repeat = mi->status->repeat;
	}
	if(mi->CurrentState.random != mi->status->random)
	{
		what_changed |= MPD_CST_RANDOM;
		mi->CurrentState.random = mi->status->random;
	}
	if(mi->CurrentState.volume != mi->status->volume)
	{
		what_changed |= MPD_CST_VOLUME;
		mi->CurrentState.volume = mi->status->volume;
	}
	if(mi->CurrentState.xfade != mi->status->crossfade)
	{
		what_changed |= MPD_CST_CROSSFADE;
		mi->CurrentState.xfade = mi->status->crossfade;
	}
	if(mi->CurrentState.totaltime != mi->status->totalTime)
	{
		what_changed |= MPD_CST_TOTAL_TIME;
		mi->CurrentState.totaltime = mi->status->totalTime;
	}
	if(mi->CurrentState.elapsedtime != mi->status->elapsedTime)
	{
		what_changed |= MPD_CST_ELAPSED_TIME;
		mi->CurrentState.elapsedtime = mi->status->elapsedTime;
	}

	/* Check if bitrate changed, happens with vbr encodings. */
	if(mi->CurrentState.bitrate != mi->status->bitRate)
	{
		what_changed |= MPD_CST_BITRATE;
		mi->CurrentState.bitrate = mi->status->bitRate;
	}

	/* The following 3 probly only happen on a song change, or is it possible in one song/stream? */
	/* Check if the sample rate changed */
	if(mi->CurrentState.samplerate != mi->status->sampleRate)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.samplerate = mi->status->sampleRate;
	}
	
	/* check if the sampling depth changed */
	if(mi->CurrentState.bits != mi->status->bits)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.bits = mi->status->bits;
	}
	
	/* Check if the amount of audio channels changed */
	if(mi->CurrentState.channels != mi->status->channels)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.channels = mi->status->channels;
	}

	/* Check if the updating changed,
	 * If it stopped, also update the stats for the new db-time.
	 */
	if(mi->CurrentState.updatingDb != mi->status->updatingDb )
	{
		what_changed |= MPD_CST_UPDATING;
		if(!mi->status->updatingDb)
		{
			mpd_stats_update_real(mi, &what_changed);
		}
		mi->CurrentState.updatingDb = mi->status->updatingDb;
	}

	/* Run the callback */
	if((mi->the_status_changed_callback != NULL) && what_changed)
	{
		mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata );
	}

	/* We could have lost connection again during signal handling... so before we return check again if we are connected */
	if(!mpd_check_connected(mi))
	{
		return MPD_NOT_CONNECTED;
	}
	return MPD_OK;
}
Example #22
0
static void *update_mpd_thread(void *arg)
{
	static mpd_Connection *conn = NULL;
	mpd_Status *status;
	mpd_InfoEntity *entity;
	timed_thread *me = *(timed_thread **)arg;
	const char *emptystr = "";

	while (1) {
		if (!conn)
			conn = mpd_newConnection(mpd_host, mpd_port, 10);

		if (*mpd_password) {
			mpd_sendPasswordCommand(conn, mpd_password);
			mpd_finishCommand(conn);
		}

		timed_thread_lock(me);

		if (conn->error || conn == NULL) {
			NORM_ERR("MPD error: %s\n", conn->errorStr);
			mpd_closeConnection(conn);
			conn = 0;
			clear_mpd();

			mpd_info.status = "MPD not responding";
			timed_thread_unlock(me);
			if (timed_thread_test(me, 0)) {
				timed_thread_exit(me);
			}
			continue;
		}

		mpd_sendStatusCommand(conn);
		if ((status = mpd_getStatus(conn)) == NULL) {
			NORM_ERR("MPD error: %s\n", conn->errorStr);
			mpd_closeConnection(conn);
			conn = 0;
			clear_mpd();

			mpd_info.status = "MPD not responding";
			timed_thread_unlock(me);
			if (timed_thread_test(me, 0)) {
				timed_thread_exit(me);
			}
			continue;
		}
		mpd_finishCommand(conn);
		if (conn->error) {
			// fprintf(stderr, "%s\n", conn->errorStr);
			mpd_closeConnection(conn);
			conn = 0;
			timed_thread_unlock(me);
			if (timed_thread_test(me, 0)) {
				timed_thread_exit(me);
			}
			continue;
		}

		mpd_info.vol = status->volume;
		if (status->random == 0) {
			mpd_info.random = "Off";
		} else if (status->random == 1) {
			mpd_info.random = "On";
		} else {
			mpd_info.random = "";
		}
		if (status->repeat == 0) {
			mpd_info.repeat = "Off";
		} else if (status->repeat == 1) {
			mpd_info.repeat = "On";
		} else {
			mpd_info.repeat = "";
		}
		/* if (status->error) {
			printf("error: %s\n", status->error);
		} */

		switch (status->state) {
			case MPD_STATUS_STATE_PLAY:
				mpd_info.status = "Playing";
				break;
			case MPD_STATUS_STATE_STOP:
				mpd_info.status = "Stopped";
				break;
			case MPD_STATUS_STATE_PAUSE:
				mpd_info.status = "Paused";
				break;
			default:
				mpd_info.status = "";
				clear_mpd();
				break;
		}

		if (status->state == MPD_STATUS_STATE_PLAY ||
		    status->state == MPD_STATUS_STATE_PAUSE) {
			mpd_info.is_playing = 1;
			mpd_info.bitrate = status->bitRate;
			mpd_info.progress = (float) status->elapsedTime /
				status->totalTime;
			mpd_info.elapsed = status->elapsedTime;
			mpd_info.length = status->totalTime;
		} else {
			mpd_info.progress = 0;
			mpd_info.is_playing = 0;
			mpd_info.elapsed = 0;
		}

		if (conn->error) {
			// fprintf(stderr, "%s\n", conn->errorStr);
			mpd_closeConnection(conn);
			conn = 0;
			timed_thread_unlock(me);
			if (timed_thread_test(me, 0)) {
				timed_thread_exit(me);
			}
			continue;
		}

		mpd_sendCurrentSongCommand(conn);
		while ((entity = mpd_getNextInfoEntity(conn))) {
			mpd_Song *song = entity->info.song;

			if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
				mpd_freeInfoEntity(entity);
				continue;
			}
#define SONGSET(x) {                            \
	free(mpd_info.x);                       \
	if(song->x)                             \
		mpd_info.x = strmdup(song->x);  \
	else                                    \
		mpd_info.x = strmdup(emptystr); \
}
			SONGSET(artist);
			SONGSET(albumartist);
			SONGSET(album);
			SONGSET(title);
			SONGSET(date);
			SONGSET(track);
			SONGSET(name);
			SONGSET(file);
#undef SONGSET
			if (entity != NULL) {
				mpd_freeInfoEntity(entity);
				entity = NULL;
			}
		}
		mpd_finishCommand(conn);
		if (conn->error) {
			// fprintf(stderr, "%s\n", conn->errorStr);
			mpd_closeConnection(conn);
			conn = 0;
			timed_thread_unlock(me);
			if (timed_thread_test(me, 0)) {
				timed_thread_exit(me);
			}
			continue;
		}

		timed_thread_unlock(me);
		if (conn->error) {
			// fprintf(stderr, "%s\n", conn->errorStr);
			mpd_closeConnection(conn);
			conn = 0;
			if (timed_thread_test(me, 0)) {
				timed_thread_exit(me);
			}
			continue;
		}

		mpd_freeStatus(status);
		/* if (conn) {
			mpd_closeConnection(conn);
			conn = 0;
		} */
		if (timed_thread_test(me, 0)) {
			timed_thread_exit(me);
		}
		continue;
	}
	/* never reached */
}
Example #23
0
static void
_mpdule_update_song (Instance * inst)
{
  mpd_Connection *mpd;
  Evas_Object *mpdule;
  Evas_Object *o_popup;

  if (!inst->mpd)
    return;
  mpd = inst->mpd;
  mpdule = inst->mpdule;
  o_popup = inst->o_popup;
  mpd_sendStatusCommand (mpd);
  if (mpd->error == 0)
    {
      mpd_Status *status = mpd_getStatus (mpd);

      if (status)
	{
	  if (status->state == MPD_STATUS_STATE_UNKNOWN)
	    {
	      edje_object_part_text_set (mpdule, "mpdule.status",
					 D_ ("Unknown"));
	      edje_object_part_text_set (o_popup, "mpdule.status",
					 D_ ("Unknown"));
	    }
	  else if (status->state == MPD_STATUS_STATE_STOP)
	    {
	      edje_object_part_text_set (mpdule, "mpdule.status",
					 D_ ("Stopped"));
	      edje_object_part_text_set (o_popup, "mpdule.status",
					 D_ ("Stopped"));
	    }
	  else if (status->state == MPD_STATUS_STATE_PLAY)
	    {
	      edje_object_part_text_set (mpdule, "mpdule.status",
					 D_ ("Playing"));
	      edje_object_part_text_set (o_popup, "mpdule.status",
					 D_ ("Playing"));
	    }
	  else if (status->state == MPD_STATUS_STATE_PAUSE)
	    {
	      edje_object_part_text_set (mpdule, "mpdule.status",
					 D_ ("Paused"));
	      edje_object_part_text_set (o_popup, "mpdule.status",
					 D_ ("Paused"));
	    }

	  if (status->state > MPD_STATUS_STATE_STOP)
	    {
	      mpd_sendCurrentSongCommand (mpd);
	      mpd_InfoEntity *entity = NULL;

	      while ((entity = mpd_getNextInfoEntity (mpd)))
		{
		  if (entity->type == MPD_INFO_ENTITY_TYPE_SONG &&
		      entity->info.song->id == status->songid)
		    {
		      mpd_Song *song = entity->info.song;

		      if (song->artist)
			{
			  edje_object_part_text_set (mpdule, "mpdule.artist",
						     song->artist);
			  edje_object_part_text_set (o_popup, "mpdule.artist",
						     song->artist);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.artist",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.artist",
						     "");
			}
		      if (song->title)
			{
			  edje_object_part_text_set (mpdule, "mpdule.title",
						     song->title);
			  edje_object_part_text_set (o_popup, "mpdule.title",
						     song->title);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.title",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.title",
						     "");
			}
		      if (song->album)
			{
			  edje_object_part_text_set (mpdule, "mpdule.album",
						     song->album);
			  edje_object_part_text_set (o_popup, "mpdule.album",
						     song->album);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.album",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.album",
						     "");
			}
		      if (song->track)
			{
			  edje_object_part_text_set (mpdule, "mpdule.track",
						     song->track);
			  edje_object_part_text_set (o_popup, "mpdule.track",
						     song->track);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.track",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.track",
						     "");
			}
		      if (song->date)
			{
			  edje_object_part_text_set (mpdule, "mpdule.date",
						     song->date);
			  edje_object_part_text_set (o_popup, "mpdule.date",
						     song->date);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.date",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.date",
						     "");
			}
		      if (song->genre)
			{
			  edje_object_part_text_set (mpdule, "mpdule.genre",
						     song->genre);
			  edje_object_part_text_set (o_popup, "mpdule.genre",
						     song->genre);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.genre",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.genre",
						     "");
			}
		      if (song->composer)
			{
			  edje_object_part_text_set (mpdule,
						     "mpdule.composer",
						     song->composer);
			  edje_object_part_text_set (o_popup,
						     "mpdule.composer",
						     song->composer);
			}
		      else
			{
			  edje_object_part_text_set (mpdule,
						     "mpdule.composer", "");
			  edje_object_part_text_set (o_popup,
						     "mpdule.composer", "");
			}
		      if (song->time)
			{
			  //char * songtime;
			  //sprintf(songtime, "%i", song->time);
			  //edje_object_part_text_set (mpdule, "mpdule.time", songtime);
			  //edje_object_part_text_set (o_popup, "mpdule.time", songtime);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.time",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.time",
						     "");
			}
		      if (song->file)
			{
			  edje_object_part_text_set (mpdule, "mpdule.file",
						     song->file);
			  edje_object_part_text_set (o_popup, "mpdule.file",
						     song->file);
			}
		      else
			{
			  edje_object_part_text_set (mpdule, "mpdule.file",
						     "");
			  edje_object_part_text_set (o_popup, "mpdule.file",
						     "");
			}
		    }

		  mpd_freeInfoEntity (entity);
		}
	    }

	  mpd_freeStatus (status);
	}
    }
  else
    {
      _mpdule_disconnect (inst);
      _mpdule_connect (inst);
    }
}