Exemple #1
0
static xmmsv_t *
xmms_playback_client_volume_get (xmms_output_t *output, xmms_error_t *error)
{
	xmmsv_t *ret;
	xmms_volume_map_t map;

	if (!output->plugin) {
		xmms_error_set (error, XMMS_ERROR_GENERIC,
		                "couldn't get volume, output plugin not loaded");
		return NULL;
	}

	if (!xmms_output_plugin_method_volume_get_available (output->plugin)) {
		xmms_error_set (error, XMMS_ERROR_GENERIC,
		                "operation not supported");
		return NULL;
	}

	xmms_error_set (error, XMMS_ERROR_GENERIC,
	                "couldn't get volume");

	xmms_volume_map_init (&map);

	/* ask the plugin how much channels it would like to set */
	if (!xmms_output_plugin_method_volume_get (output->plugin, output,
	                                           NULL, NULL, &map.num_channels)) {
		return NULL;
	}

	/* check for sane values */
	g_return_val_if_fail (map.num_channels > 0, NULL);
	g_return_val_if_fail (map.num_channels <= VOLUME_MAX_CHANNELS, NULL);

	map.names = g_new (const gchar *, map.num_channels);
	map.values = g_new (guint, map.num_channels);

	map.status = xmms_output_plugin_method_volume_get (output->plugin, output,
	                                                   map.names, map.values,
	                                                   &map.num_channels);

	if (!map.status || !map.num_channels) {
		return NULL; /* error is set (-> no leak) */
	}

	ret = xmms_volume_map_to_dict (&map);

	/* success! */
	xmms_error_reset (error);

	return ret;
}
Exemple #2
0
static gint
read_data (xmms_magic_checker_t *c, guint needed)
{
	xmms_error_t e;

	if (needed > c->alloc) {
		c->alloc = needed;
		c->buf = g_realloc (c->buf, c->alloc);
	}

	xmms_error_reset (&e);

	return xmms_xform_peek (c->xform, c->buf, needed, &e);
}
Exemple #3
0
static mpc_bool_t
xmms_mpc_callback_seek (READER_OBJ *p_obj, mpc_int32_t offset)
{
    xmms_xform_t *xform = READER_DATA (p_obj);
    xmms_error_t err;
    gint ret;

    g_return_val_if_fail (xform, -1);

    xmms_error_reset (&err);

    ret = xmms_xform_seek (xform, (gint64) offset, XMMS_XFORM_SEEK_SET, &err);

    return (ret == -1) ? FALSE : TRUE;
}
Exemple #4
0
static FLAC__StreamDecoderSeekStatus
flac_callback_seek (const FLAC__StreamDecoder *flacdecoder,
                    FLAC__uint64 offset, void *client_data)
{
	xmms_error_t err;
	xmms_xform_t *xform = (xmms_xform_t *) client_data;
	gint retval;

	xmms_error_reset (&err);

	retval = xmms_xform_seek (xform, (gint64) offset,
	                          XMMS_XFORM_SEEK_SET, &err);

	return (retval == -1) ? FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
	                      : FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
Exemple #5
0
static FLAC__StreamDecoderTellStatus
flac_callback_tell (const FLAC__StreamDecoder *flacdecoder,
                    FLAC__uint64 *offset, void *client_data)
{
	xmms_error_t err;
	xmms_xform_t *xform = (xmms_xform_t *) client_data;

	g_return_val_if_fail (xform,
	                      FLAC__STREAM_DECODER_TELL_STATUS_ERROR);

	xmms_error_reset (&err);

	*offset = xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_CUR, &err);

	return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
Exemple #6
0
static gboolean
xmms_m3u_browse (xmms_xform_t *xform,
                 const gchar *url,
                 xmms_error_t *error)
{
	gchar line[XMMS_XFORM_MAX_LINE_SIZE];
	gchar *tmp;
	gchar *title = NULL;
	const gchar *d;

	g_return_val_if_fail (xform, FALSE);

	xmms_error_reset (error);

	if (!xmms_xform_read_line (xform, line, error)) {
		XMMS_DBG ("Error reading m3u-file");
		return FALSE;
	}

	d = xmms_xform_get_url (xform);

	do {
		if (line[0] == '#') {
			if (!title) {
				title = get_extinf (line);
			}
		} else {
			tmp = xmms_build_playlist_url (d, line);
			xmms_xform_browse_add_symlink (xform, NULL, tmp);

			if (title) {
				xmms_xform_browse_add_entry_property_str (xform,
				                                          "title",
				                                          title);
				g_free (title);
				title = NULL;
			}

			g_free (tmp);
		}

	} while (xmms_xform_read_line (xform, line, error));

	g_free (title);

	return TRUE;
}
int
CSourceAdapter::Read (void * pBuffer, unsigned int nBytesToRead,
                      unsigned int * pBytesRead)
{
	int ret = 0;
	xmms_error_t error;

	xmms_error_reset (&error);

	ret = xmms_xform_read (xform,
	                       (gchar *)pBuffer,
	                       nBytesToRead,
	                       &error);
	*pBytesRead = ret;

	return (error.code == XMMS_ERROR_NONE) ? ERROR_SUCCESS : ERROR_IO_READ;
}
Exemple #8
0
/**
 * Queries the medialib and returns an xmmsv_t with the info requested
 *
 * @param coll The collection to find
 * @param fetch Specifies what to fetch
 * @return An xmmsv_t with the structure requested in fetch
 */
xmmsv_t *
xmms_medialib_query (xmms_medialib_session_t *session, xmmsv_t *coll,
                     xmmsv_t *fetch, xmms_error_t *err)
{
	s4_sourcepref_t *sourcepref;
	s4_resultset_t *set;
	xmmsv_t *ret;
	xmms_fetch_info_t *info;
	xmms_fetch_spec_t *spec;

	xmms_error_reset (err);

	sourcepref = xmms_medialib_session_get_source_preferences (session);

	info = xmms_fetch_info_new (sourcepref);
	spec = xmms_fetch_spec_new (fetch, info, sourcepref, err);

	s4_sourcepref_unref (sourcepref);

	if (spec == NULL) {
		xmms_fetch_spec_free (spec);
		xmms_fetch_info_free (info);
		return NULL;
	}

	set = xmms_medialib_query_recurs (session, coll, info);
	ret = xmms_medialib_query_to_xmmsv (set, spec);
	s4_resultset_free (set);

	xmms_fetch_spec_free (spec);
	xmms_fetch_info_free (info);

	if (ret == NULL) {
		if (err) {
			xmms_error_set (err, XMMS_ERROR_NOENT, "Failed to retrieve query "
			                "result. This is probably a bug in xmms2d.");
		}
		return NULL;
	}

	xmms_medialib_session_track_garbage (session, ret);

	return ret;
}
Exemple #9
0
int64_t
xmms_asf_seek_callback (void *opaque, int64_t position)
{
    xmms_xform_t *xform;
    xmms_asf_data_t *data;
    xmms_error_t error;
    gint ret;

    g_return_val_if_fail (opaque, -1);
    xform = opaque;

    xmms_error_reset (&error);

    data = xmms_xform_private_data_get (xform);
    g_return_val_if_fail (data, -1);

    ret = xmms_xform_seek (xform, position, XMMS_XFORM_SEEK_SET, &error);

    return ret;
}
Exemple #10
0
int32_t
xmms_asf_read_callback (void *opaque, void *buffer, int32_t size)
{
    xmms_xform_t *xform;
    xmms_asf_data_t *data;
    xmms_error_t error;
    gint ret;

    g_return_val_if_fail (opaque, 0);
    g_return_val_if_fail (buffer, 0);
    xform = opaque;

    xmms_error_reset (&error);

    data = xmms_xform_private_data_get (xform);
    g_return_val_if_fail (data, 0);

    ret = xmms_xform_read (xform, buffer, size, &error);

    return ret;
}
Exemple #11
0
xmms_medialib_entry_t
xmms_mock_entry (xmms_medialib_t *medialib, gint tracknr, const gchar *artist,
                 const gchar *album, const gchar *title)
{
	xmms_medialib_session_t *session;
	xmms_medialib_entry_t entry;
	xmms_error_t err;
	gchar *path;

	xmms_error_reset (&err);

	path = g_strconcat (artist, album, title, NULL);

	session = xmms_medialib_session_begin (medialib);

	entry = xmms_medialib_entry_new (session, path, &err);

	xmms_medialib_entry_property_set_int (session, entry,
	                                      XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR,
	                                      tracknr);
	xmms_medialib_entry_property_set_str (session, entry,
	                                      XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST,
	                                      artist);
	xmms_medialib_entry_property_set_str (session, entry,
	                                      XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM,
	                                      album);
	xmms_medialib_entry_property_set_str (session, entry,
	                                      XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE,
	                                      title);
	xmms_medialib_entry_property_set_int (session, entry,
	                                      XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS,
	                                      XMMS_MEDIALIB_ENTRY_STATUS_OK);

	xmms_medialib_session_commit (session);

	g_free (path);

	return entry;
}
Exemple #12
0
gint
xmms_output_read (xmms_output_t *output, char *buffer, gint len)
{
	gint ret;
	xmms_error_t err;

	xmms_error_reset (&err);

	g_return_val_if_fail (output, -1);
	g_return_val_if_fail (buffer, -1);

	g_mutex_lock (output->filler_mutex);
	xmms_ringbuf_wait_used (output->filler_buffer, len, output->filler_mutex);
	ret = xmms_ringbuf_read (output->filler_buffer, buffer, len);
	if (ret == 0 && xmms_ringbuf_iseos (output->filler_buffer)) {
		xmms_output_status_set (output, XMMS_PLAYBACK_STATUS_STOP);
		g_mutex_unlock (output->filler_mutex);
		return -1;
	}
	g_mutex_unlock (output->filler_mutex);

	update_playtime (output, ret);

	if (ret < len) {
		XMMS_DBG ("Underrun %d of %d (%d)", ret, len, xmms_sample_frame_size_get (output->format));

		if ((ret % xmms_sample_frame_size_get (output->format)) != 0) {
			xmms_log_error ("***********************************");
			xmms_log_error ("* Read non-multiple of sample size,");
			xmms_log_error ("*  you probably hear noise now :)");
			xmms_log_error ("***********************************");
		}
		output->buffer_underruns++;
	}

	output->bytes_written += ret;

	return ret;
}
Exemple #13
0
static gchar *
get_root_node_name (xmms_xform_t *xform)
{
	guint8 buf[BUFFER_SIZE];
	gint read, i, start, len;
	gchar *ret = NULL;
	xmms_error_t error;

	xmms_error_reset (&error);

	read = xmms_xform_peek (xform, buf, BUFFER_SIZE, &error);
	if (read < 1) {
		xmms_log_error ("Couldn't get data: %s", xmms_error_message_get (&error));
		return NULL;
	}

	start = -1;
	len = 0;
	for (i = 0; i < read; i++) {
		if (start < 0) {
			if (buf[i] == '<' && buf[i + 1] != '!' && buf[i + 1] != '?') {
				start = i;
			}
		} else {
			if (isalpha (buf[i])) {
				len++;
			} else if (len) {
				ret = g_malloc (len + 1);
				memcpy (ret, buf + start + 1, len);
				ret[len] = '\0';
				break;
			}
		}

	}

	return ret;
}
Exemple #14
0
static int
opus_callback_seek (void *datasource, opus_int64 offset, int whence)
{
	xmms_xform_t *xform = datasource;
	xmms_error_t err;
	gint ret;

	g_return_val_if_fail (xform, -1);

	xmms_error_reset (&err);

	if (whence == SEEK_CUR) {
		whence = XMMS_XFORM_SEEK_CUR;
	} else if (whence == SEEK_SET) {
		whence = XMMS_XFORM_SEEK_SET;
	} else if (whence == SEEK_END) {
		whence = XMMS_XFORM_SEEK_END;
	}

	ret = xmms_xform_seek (xform, (gint64) offset, whence, &err);

	return (ret == -1) ? -1 : 0;
}
Exemple #15
0
static gboolean
xmms_daap_init (xmms_xform_t *xform)
{
	gint dbid;
	GSList *dbid_list = NULL;
	xmms_daap_data_t *data;
	xmms_daap_login_data_t *login_data;
	xmms_error_t err;
	const gchar *url;
	const gchar *metakey;
	gchar *command, *hash;
	guint filesize;

	g_return_val_if_fail (xform, FALSE);

	url = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_URL);

	g_return_val_if_fail (url, FALSE);

	data = g_new0 (xmms_daap_data_t, 1);

	xmms_error_reset (&err);

	if (!get_data_from_url (url, &(data->host), &(data->port), &command, &err)) {
		goto init_error;
	}

	hash = g_strdup_printf ("%s:%u", data->host, data->port);

	login_data = g_hash_table_lookup (login_sessions, hash);
	if (!login_data) {
		XMMS_DBG ("creating login data for %s", hash);
		login_data = g_new0 (xmms_daap_login_data_t, 1);

		login_data->request_id = 1;
		login_data->logged_in = TRUE;

		login_data->session_id = daap_command_login (data->host, data->port,
		                                             login_data->request_id,
		                                             &err);
		if (xmms_error_iserror (&err)) {
			g_free (login_data);
			goto init_error;
		}

		g_hash_table_insert (login_sessions, hash, login_data);
	}

	login_data->revision_id = daap_command_update (data->host, data->port,
	                                               login_data->session_id,
	                                               login_data->request_id);
	dbid_list = daap_command_db_list (data->host, data->port,
	                                  login_data->session_id,
	                                  login_data->revision_id,
	                                  login_data->request_id);
	if (!dbid_list) {
		goto init_error;
	}

	/* XXX: see XXX in the browse function above */
	dbid = ((cc_item_record_t *) dbid_list->data)->dbid;
	/* want to request a stream, but don't read the data yet */
	data->conn = daap_command_init_stream (data->host, data->port,
	                                       login_data->session_id,
	                                       login_data->revision_id,
	                                       login_data->request_id, dbid,
	                                       command, &filesize);

	if (! data->conn) {
		goto init_error;
	}
	login_data->request_id++;

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	xmms_xform_metadata_set_int (xform, metakey, filesize);

	xmms_xform_private_data_set (xform, data);

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "application/octet-stream",
	                             XMMS_STREAM_TYPE_END);

	g_slist_foreach (dbid_list, (GFunc) cc_item_record_free, NULL);
	g_slist_free (dbid_list);
	g_free (command);

	return TRUE;

init_error:
	if (data) {
		if (data->host)
			g_free (data->host);
		g_free (data);
	}
	return FALSE;
}
Exemple #16
0
static gboolean
xmms_faad_init (xmms_xform_t *xform)
{
	xmms_faad_data_t *data;
	xmms_error_t error;

	NeAACDecConfigurationPtr config;
	gint bytes_read;
	gulong samplerate;
	guchar channels;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_faad_data_t, 1);
	data->outbuf = g_string_new (NULL);
	data->buffer_size = FAAD_BUFFER_SIZE;

	xmms_xform_private_data_set (xform, data);

	data->decoder = NeAACDecOpen ();
	config = NeAACDecGetCurrentConfiguration (data->decoder);
	config->defObjectType = LC;
	config->defSampleRate = 44100;
	config->outputFormat = FAAD_FMT_16BIT;
	config->downMatrix = 0;
	config->dontUpSampleImplicitSBR = 0;
	NeAACDecSetConfiguration (data->decoder, config);

	switch (config->outputFormat) {
	case FAAD_FMT_16BIT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_S16;
		break;
	case FAAD_FMT_24BIT:
		/* we don't have 24-bit format to use in xmms2 */
		data->sampleformat = XMMS_SAMPLE_FORMAT_S32;
		break;
	case FAAD_FMT_32BIT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_S32;
		break;
	case FAAD_FMT_FLOAT:
		data->sampleformat = XMMS_SAMPLE_FORMAT_FLOAT;
		break;
	case FAAD_FMT_DOUBLE:
		data->sampleformat = XMMS_SAMPLE_FORMAT_DOUBLE;
		break;
	}

	while (data->buffer_length < 8) {
		xmms_error_reset (&error);
		bytes_read = xmms_xform_read (xform,
		                              (gchar *) data->buffer + data->buffer_length,
		                              data->buffer_size - data->buffer_length,
		                              &error);
		data->buffer_length += bytes_read;

		if (bytes_read < 0) {
			xmms_log_error ("Error while trying to read data on init");
			goto err;
		} else if (bytes_read == 0) {
			XMMS_DBG ("Not enough bytes to check the AAC header");
			goto err;
		}
	}

	/* which type of file are we dealing with? */
	data->filetype = FAAD_TYPE_UNKNOWN;
	if (xmms_xform_auxdata_has_val (xform, "decoder_config")) {
		data->filetype = FAAD_TYPE_MP4;
	} else if (!strncmp ((char *) data->buffer, "ADIF", 4)) {
		data->filetype = FAAD_TYPE_ADIF;
	} else {
		int i;

		/* ADTS mpeg file can be a stream and start in the middle of a
		 * frame so we need to have extra loop check here */
		for (i=0; i<data->buffer_length-1; i++) {
			if (data->buffer[i] == 0xff && (data->buffer[i+1]&0xf6) == 0xf0) {
				data->filetype = FAAD_TYPE_ADTS;
				g_memmove (data->buffer, data->buffer+i, data->buffer_length-i);
				data->buffer_length -= i;
				break;
			}
		}
	}

	if (data->filetype == FAAD_TYPE_ADTS || data->filetype == FAAD_TYPE_ADIF) {
		bytes_read = NeAACDecInit (data->decoder, data->buffer,
		                          data->buffer_length, &samplerate,
		                          &channels);
	} else if (data->filetype == FAAD_TYPE_MP4) {
		const guchar *tmpbuf;
		gsize tmpbuflen;
		guchar *copy;

		if (!xmms_xform_auxdata_get_bin (xform, "decoder_config", &tmpbuf,
		                                 &tmpbuflen)) {
			XMMS_DBG ("AAC decoder config data found but it's wrong type! (something broken?)");
			goto err;
		}

		copy = g_memdup (tmpbuf, tmpbuflen);
		bytes_read = NeAACDecInit2 (data->decoder, copy, tmpbuflen,
		                           &samplerate, &channels);
		g_free (copy);
	}

	if (bytes_read < 0) {
		XMMS_DBG ("Error initializing decoder library.");
		goto err;
	}

	/* Get mediainfo and skip the possible header */
	xmms_faad_get_mediainfo (xform);
	g_memmove (data->buffer, data->buffer + bytes_read,
	           data->buffer_length - bytes_read);
	data->buffer_length -= bytes_read;

	data->samplerate = samplerate;
	data->channels = channels;

	/* Because for HE AAC files some versions of libfaad return the wrong
	 * samplerate in init, we have to do one read and let it decide the
	 * real parameters. After changing sample parameters and format is
	 * supported, this hack should be removed and handled in read instead. */
	{
		gchar tmpbuf[1024];

		xmms_error_reset (&error);
		bytes_read = xmms_faad_read (xform, tmpbuf, 1024, &error);
		if (bytes_read <= 0) {
			XMMS_DBG ("First read from faad decoder failed!");
			return FALSE;
		}
		g_string_prepend_len (data->outbuf, tmpbuf, bytes_read);
	}

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             data->sampleformat,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->samplerate,
	                             XMMS_STREAM_TYPE_END);

	XMMS_DBG ("AAC decoder inited successfully!");

	return TRUE;

err:
	g_string_free (data->outbuf, TRUE);
	g_free (data);

	return FALSE;
}
Exemple #17
0
static gboolean
xmms_pls_browse (xmms_xform_t *xform, const char *url, xmms_error_t *error)
{
	gchar buffer[XMMS_XFORM_MAX_LINE_SIZE];
	gint num = -1;
	gchar **val;
	const gchar *plspath;
	xmms_pls_entry_t entry;

	g_return_val_if_fail (xform, FALSE);

	xmms_error_reset (error);

	plspath = xmms_xform_get_url (xform);

	if (!xmms_xform_read_line (xform, buffer, error)) {
		XMMS_DBG ("Error reading pls-file");
		return FALSE;
	}

	/* for completeness' sake, check for the pls header here again, too
	 * (it's already done in the magic check)
	 */
	if (g_ascii_strncasecmp (buffer, "[playlist]", 10) != 0) {
		XMMS_DBG ("Not a PLS file");
		return FALSE;
	}

	memset (&entry, 0, sizeof (entry));
	entry.num=-1;

	while (xmms_xform_read_line (xform, buffer, error)) {
		gchar *np, *ep;

		if (g_ascii_strncasecmp (buffer, "File", 4) == 0) {
			np = &buffer[4];
			val = &entry.file;
		} else if (g_ascii_strncasecmp (buffer, "Title", 5) == 0) {
			np = &buffer[5];
			val = &entry.title;
		} else {
			continue;
		}

		num = strtol (np, &ep, 10);
		if (!ep || *ep != '=') {
			XMMS_DBG ("Broken line '%s', skipping", buffer);
			continue;
		}

		ep++; /* Skip the '=' */

		/* Remove leading and trailing whitespace from the value. */
		g_strstrip (ep);

		/* Ignore empty values. */
		if (!*ep) {
			XMMS_DBG ("Ignoring empty value in line '%s'", buffer);
			continue;
		}

		if (entry.num != num && entry.num != -1) {
			xmms_pls_add_entry (xform, plspath, &entry);
		}

		*val = g_strdup (ep);
		entry.num = num;
	}

	xmms_pls_add_entry (xform, plspath, &entry);

	return TRUE;
}
Exemple #18
0
static void *
xmms_output_filler (void *arg)
{
	xmms_output_t *output = (xmms_output_t *)arg;
	xmms_xform_t *chain = NULL;
	gboolean last_was_kill = FALSE;
	char buf[4096];
	xmms_error_t err;
	gint ret;

	xmms_error_reset (&err);

	g_mutex_lock (output->filler_mutex);
	while (output->filler_state != FILLER_QUIT) {
		if (output->filler_state == FILLER_STOP) {
			if (chain) {
				xmms_object_unref (chain);
				chain = NULL;
			}
			xmms_ringbuf_set_eos (output->filler_buffer, TRUE);
			g_cond_wait (output->filler_state_cond, output->filler_mutex);
			last_was_kill = FALSE;
			continue;
		}
		if (output->filler_state == FILLER_KILL) {
			if (chain) {
				xmms_object_unref (chain);
				chain = NULL;
				output->filler_state = FILLER_RUN;
				last_was_kill = TRUE;
			} else {
				output->filler_state = FILLER_STOP;
			}
			continue;
		}
		if (output->filler_state == FILLER_SEEK) {
			if (!chain) {
				XMMS_DBG ("Seek without chain, ignoring..");
				output->filler_state = FILLER_STOP;
				continue;
			}

			ret = xmms_xform_this_seek (chain, output->filler_seek, XMMS_XFORM_SEEK_SET, &err);
			if (ret == -1) {
				XMMS_DBG ("Seeking failed: %s", xmms_error_message_get (&err));
			} else {
				XMMS_DBG ("Seek ok! %d", ret);

				output->filler_skip = output->filler_seek - ret;
				if (output->filler_skip < 0) {
					XMMS_DBG ("Seeked %d samples too far! Updating position...",
					          -output->filler_skip);

					output->filler_skip = 0;
					output->filler_seek = ret;
				}

				xmms_ringbuf_clear (output->filler_buffer);
				xmms_ringbuf_hotspot_set (output->filler_buffer, seek_done, NULL, output);
			}
			output->filler_state = FILLER_RUN;
		}

		if (!chain) {
			xmms_medialib_entry_t entry;
			xmms_output_song_changed_arg_t *arg;
			xmms_medialib_session_t *session;

			g_mutex_unlock (output->filler_mutex);

			entry = xmms_playlist_current_entry (output->playlist);
			if (!entry) {
				XMMS_DBG ("No entry from playlist!");
				output->filler_state = FILLER_STOP;
				g_mutex_lock (output->filler_mutex);
				continue;
			}

			chain = xmms_xform_chain_setup (entry, output->format_list, FALSE);
			if (!chain) {
				session = xmms_medialib_begin_write ();
				if (xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS) == XMMS_MEDIALIB_ENTRY_STATUS_NEW) {
					xmms_medialib_end (session);
					xmms_medialib_entry_remove (entry);
				} else {
					xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE);
					xmms_medialib_entry_send_update (entry);
					xmms_medialib_end (session);
				}

				if (!xmms_playlist_advance (output->playlist)) {
					XMMS_DBG ("End of playlist");
					output->filler_state = FILLER_STOP;
				}
				g_mutex_lock (output->filler_mutex);
				continue;
			}

			arg = g_new0 (xmms_output_song_changed_arg_t, 1);
			arg->output = output;
			arg->chain = chain;
			arg->flush = last_was_kill;
			xmms_object_ref (chain);

			last_was_kill = FALSE;

			g_mutex_lock (output->filler_mutex);
			xmms_ringbuf_hotspot_set (output->filler_buffer, song_changed, song_changed_arg_free, arg);
		}

		xmms_ringbuf_wait_free (output->filler_buffer, sizeof (buf), output->filler_mutex);

		if (output->filler_state != FILLER_RUN) {
			XMMS_DBG ("State changed while waiting...");
			continue;
		}
		g_mutex_unlock (output->filler_mutex);

		ret = xmms_xform_this_read (chain, buf, sizeof (buf), &err);

		g_mutex_lock (output->filler_mutex);

		if (ret > 0) {
			gint skip = MIN (ret, output->toskip);

			output->toskip -= skip;
			if (ret > skip) {
				xmms_ringbuf_write_wait (output->filler_buffer,
				                         buf + skip,
				                         ret - skip,
				                         output->filler_mutex);
			}
		} else {
			if (ret == -1) {
				/* print error */
				xmms_error_reset (&err);
			}
			xmms_object_unref (chain);
			chain = NULL;
			if (!xmms_playlist_advance (output->playlist)) {
				XMMS_DBG ("End of playlist");
				output->filler_state = FILLER_STOP;
			}
		}

	}
	g_mutex_unlock (output->filler_mutex);
	return NULL;
}
Exemple #19
0
/**
 * TODO: Should check for '/' in the key, and set source if found.
 */
static void
populate_medialib (xmms_medialib_t *medialib, xmmsv_t *content)
{
	xmms_medialib_session_t *session;
	xmms_medialib_entry_t entry = 0;
	xmmsv_list_iter_t *lit;

	session = xmms_medialib_session_begin (medialib);

	xmmsv_get_list_iter (content, &lit);
	while (xmmsv_list_iter_valid (lit)) {
		xmmsv_dict_iter_t *dit;
		xmms_error_t err;
		xmmsv_t *dict;

		xmms_error_reset (&err);

		xmmsv_list_iter_entry (lit, &dict);

		if (xmmsv_dict_has_key (dict, "url")) {
			const gchar *url;
			xmmsv_dict_entry_get_string (dict, "url", &url);
			entry = xmms_medialib_entry_new (session, url, &err);
		} else {
			gchar *url;
			url = g_strdup_printf ("file://%d.mp3", entry + 1);
			entry = xmms_medialib_entry_new (session, url, &err);
			g_free (url);
		}

		xmmsv_get_dict_iter (dict, &dit);

		while (xmmsv_dict_iter_valid (dit)) {
			const gchar *key, *source;
			gchar **parts;
			xmmsv_t *container;

			xmmsv_dict_iter_pair (dit, &key, &container);

			parts = g_strsplit (key, "/", 2);

			key = (parts[1] != NULL) ? parts[1] : key;
			source = (parts[1] != NULL) ? parts[0] : NULL;

			if (xmmsv_is_type (container, XMMSV_TYPE_STRING)) {
				const gchar *value;

				xmmsv_get_string (container, &value);

				if (source != NULL) {
					xmms_medialib_entry_property_set_str_source (session, entry, key, value, source);
				} else {
					xmms_medialib_entry_property_set_str (session, entry, key, value);
				}
			} else {
				gint32 value;

				xmmsv_get_int (container, &value);

				if (source != NULL) {
					xmms_medialib_entry_property_set_int_source (session, entry, key, value, source);
				} else {
					xmms_medialib_entry_property_set_int (session, entry, key, value);
				}
			}

			g_strfreev (parts);

			xmmsv_dict_iter_next (dit);
		}

		xmmsv_list_iter_next (lit);
	}

	xmms_medialib_session_commit (session);
}
Exemple #20
0
static gboolean
xmms_cue_browse (xmms_xform_t *xform,
                 const gchar *url,
                 xmms_error_t *error)
{
	gchar line[XMMS_XFORM_MAX_LINE_SIZE];
	cue_track track;
	gchar *p;

	g_return_val_if_fail (xform, FALSE);

	memset (&track, 0, sizeof (cue_track));

	if (!xmms_xform_read_line (xform, line, error)) {
		xmms_error_set (error, XMMS_ERROR_INVAL, "error reading cue-file!");
		return FALSE;
	}

	do {
		p = skip_white_space (line);
		if (g_ascii_strncasecmp (p, "FILE", 4) == 0) {
			if (track.file[0]) {
				add_track (xform, &track);
			}
			p = skip_to_char (p, '"');
			p ++;
			save_to_char (p, '"', track.file);
		} else if (g_ascii_strncasecmp (p, "TRACK", 5) == 0) {
			p = skip_to_char (p, ' ');
			p = skip_white_space (p);
			p = skip_to_char (p, ' ');
			p = skip_white_space (p);
			if (g_ascii_strncasecmp (p, "AUDIO", 5) == 0) {
				cue_track *t = g_new0 (cue_track, 1);
				track.tracks = g_list_prepend (track.tracks, t);
			}
		} else if (g_ascii_strncasecmp (p, "INDEX", 5) == 0) {
			cue_track *t = g_list_nth_data (track.tracks, 0);
			if (!t) {
				continue;
			}
			p = skip_to_char (p, ' ');
			p = skip_white_space (p);
			p = skip_to_char (p, ' ');
			p = skip_white_space (p);
			add_index (t, p);
		} else if (g_ascii_strncasecmp (p, "TITLE", 5) == 0) {
			cue_track *t = g_list_nth_data (track.tracks, 0);

			p = skip_to_char (p, '"');
			p ++;

			if (!t) {
				save_to_char (p, '"', track.album);
			} else {
				save_to_char (p, '"', t->title);
			}
		} else if (g_ascii_strncasecmp (p, "PERFORMER", 9) == 0) {
			cue_track *t = g_list_nth_data (track.tracks, 0);

			p = skip_to_char (p, '"');
			p ++;

			if (!t) {
				save_to_char (p, '"', track.artist);
			} else {
				save_to_char (p, '"', t->artist);
			}
		}
	} while (xmms_xform_read_line (xform, line, error));

	if (track.file[0]) {
		add_track (xform, &track);
	}

	xmms_error_reset (error);

	return TRUE;
}