Exemple #1
0
static void
handle_id3v2_comm (xmms_xform_t *xform, xmms_id3v2_header_t *head,
                   const gchar *key, gchar *buf, gsize len)
{
	/* COMM is weird but it's like this:
	 * $xx enc
	 * $xx xx xx lang
	 * $text $0 desc according to enc
	 * $text $0 comment according to enc
	 */
	const gchar *enc, *desc, *comm;
	gchar *cbuf;
	gsize clen;

	enc = binary_to_enc (buf[0]);
	buf++;
	len--;

	/* Language is always three _bytes_ - we currently don't care */
	buf += 3;
	len -= 3;

	cbuf = convert_id3_text (enc, buf, len, &clen);
	if (!cbuf)
		return;

	desc = cbuf;
	comm = find_nul (cbuf, &clen);

	if (comm && comm[0]) {
		const gchar *metakey;
		gchar *tmp;

		if (desc && desc[0]) {
			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT;
			tmp = g_strdup_printf ("%s_%s", metakey, desc);
			xmms_xform_metadata_set_str (xform, tmp, comm);
			g_free (tmp);
		} else {
			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT;
			xmms_xform_metadata_set_str (xform, metakey, comm);
		}
	}

	g_free (cbuf);

}
Exemple #2
0
static gboolean
xmms_apetag_handle_tag_coverart (xmms_xform_t *xform, const gchar *key,
                                 const gchar *value, gsize length)
{
	const gchar *mime, *ptr;
	gchar *filename;
	gchar hash[33];
	gsize size;

	if (*value == '\0') {
		return FALSE;
	}

	filename = g_strndup (value, length);
	if (!filename) {
		return FALSE;
	}

	if (g_str_has_suffix (filename, "jpg")) {
		mime = "image/jpeg";
	} else if (g_str_has_suffix (filename, "png")) {
		mime = "image/png";
	} else {
		XMMS_DBG ("Unknown image format: %s", filename);
		g_free (filename);
		return FALSE;
	}

	ptr = value + strlen (filename) + 1;
	size = length - (ptr - value);

	if (xmms_bindata_plugin_add ((const guchar *) ptr, size, hash)) {
		const gchar *metakey;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT;
		xmms_xform_metadata_set_str (xform, metakey, hash);

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME;
		xmms_xform_metadata_set_str (xform, metakey, mime);
	}

	g_free (filename);

	return TRUE;
}
Exemple #3
0
static gboolean
xmms_mp4_mediainfo_set_coverart (xmms_xform_t *xform, const gchar *key,
                                 const gchar *value, gsize length)
{
	const gchar *metakey;
	gchar hash[33];

	if (!xmms_bindata_plugin_add ((const guchar *) value, length, hash)) {
		return FALSE;
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT;
	xmms_xform_metadata_set_str (xform, metakey, hash);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME;
	xmms_xform_metadata_set_str (xform, metakey, "image/jpeg");

	return TRUE;
}
Exemple #4
0
static void
handle_id3v2_tcon (xmms_xform_t *xform, xmms_id3v2_header_t *head,
                   const gchar *key, gchar *buf, gsize len)
{
	gint res;
	guint genre_id;
	gchar *val;
	const gchar *tmp;
	const gchar *metakey;

	/* XXX - we should handle it differently v4 separates them with NUL instead of using () */
	/*
	if (head->ver == 4) {
		buf++;
		len -= 1;
	}
	*/
	tmp = binary_to_enc (buf[0]);
	val = convert_id3_text (tmp, &buf[1], len - 1, NULL);
	if (!val)
		return;

	if (head->ver >= 4) {
		res = sscanf (val, "%u", &genre_id);
	} else {
		res = sscanf (val, "(%u)", &genre_id);
	}

	if (res > 0 && genre_id < G_N_ELEMENTS (id3_genres)) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_GENRE;
		xmms_xform_metadata_set_str (xform, metakey,
		                             (gchar *) id3_genres[genre_id]);
	} else {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_GENRE;
		xmms_xform_metadata_set_str (xform, metakey, val);
	}

	g_free (val);
}
Exemple #5
0
static void
handle_id3v2_apic (xmms_xform_t *xform, xmms_id3v2_header_t *head,
                   const gchar *key, gchar *buf, gsize len)
{
	const gchar *typ, *desc, *data, *mime;
	gchar hash[33];

	/* skip encoding */
	buf++;
	len--;
	mime = buf;
	typ = find_nul (buf, &len);

	if (!typ || len == 0) {
		XMMS_DBG ("Unable to read APIC frame, malformed tag?");
		return;
	}

	if (typ[0] != 0x00 && typ[0] != 0x03) {
		XMMS_DBG ("Picture type %02x not handled", typ[0]);
		return;
	}

	desc = typ + 1;
	len--;

	/* XXX desc might be UCS2 and find_nul will not do what we want */
	data = find_nul (desc, &len);

	if (data && xmms_bindata_plugin_add ((const guchar *)data, len, hash)) {
		const gchar *metakey;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT;
		xmms_xform_metadata_set_str (xform, metakey, hash);

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME;
		xmms_xform_metadata_set_str (xform, metakey, mime);
	}
}
Exemple #6
0
static void
handle_id3v2_txxx (xmms_xform_t *xform, xmms_id3v2_header_t *head,
                   const gchar *_key, gchar *buf, gsize len)
{
	const gchar *enc;
	gchar *cbuf;
	const gchar *key, *val;
	const gchar *metakey;
	gsize clen;

	enc = binary_to_enc (buf[0]);
	cbuf = convert_id3_text (enc, &buf[1], len - 1, &clen);
	if (!cbuf)
		return;

	key = cbuf;
	val = find_nul (cbuf, &clen);
	if (!val) {
		g_free (cbuf);
		return;
	}

	if (g_ascii_strcasecmp (key, "MusicBrainz Album Id") == 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_ID;
		xmms_xform_metadata_set_str (xform, metakey, val);
	} else if (g_ascii_strcasecmp (key, "MusicBrainz Artist Id") == 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST_ID;
		xmms_xform_metadata_set_str (xform, metakey, val);
	} else if ((g_ascii_strcasecmp (key, "MusicBrainz Album Artist Id") == 0) &&
	           (g_ascii_strcasecmp (val, MUSICBRAINZ_VA_ID) == 0)) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_COMPILATION;
		xmms_xform_metadata_set_int (xform, metakey, 1);
	} else if (g_ascii_strcasecmp (key, "ASIN") == 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_ASIN;
		xmms_xform_metadata_set_str (xform, metakey, val);
	} else if (g_ascii_strcasecmp (key, "QuodLibet::albumartist") == 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_ARTIST;
		xmms_xform_metadata_set_str (xform, metakey, val);
	} else if (g_ascii_strcasecmp (key, "ALBUMARTISTSORT") == 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_ARTIST_SORT;
		xmms_xform_metadata_set_str (xform, metakey, val);
	} else if (g_ascii_strcasecmp (key, "BARCODE") == 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BARCODE;
		xmms_xform_metadata_set_str (xform, metakey, val);
	} else if (g_ascii_strcasecmp (key, "CATALOGNUMBER") == 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_CATALOGNUMBER;
		xmms_xform_metadata_set_str (xform, metakey, val);
	} else {
		XMMS_DBG ("Unhandled tag 'TXXX:%s' = '%s'", key, val);
	}

	g_free (cbuf);
}
Exemple #7
0
gboolean
xmms_xform_metadata_parse_replay_gain (xmms_xform_t *xform, const gchar *key,
                                       const gchar *value, gsize length)
{
	gchar *endptr = NULL;
	gdouble number;

	number = strtod (value, &endptr);
	if (endptr > value) {
		gchar buffer[8];
		g_snprintf (buffer, sizeof (buffer), "%f",
		            pow (10.0, number / 20));
		xmms_xform_metadata_set_str (xform, key, buffer);
		return TRUE;
	}

	return FALSE;
}
Exemple #8
0
static gboolean
xmms_ofa_init (xmms_xform_t *xform)
{
	xmms_ofa_data_t *data;
	xmms_medialib_entry_t entry;
	char *fp;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_ofa_data_t, 1);
	g_return_val_if_fail (data, FALSE);

	data->thread = g_thread_new ("x2 ofa calc", xmms_ofa_thread, data);
	if (!data->thread) {
		g_free (data);
		return FALSE;
	}

	g_mutex_init (&data->mutex);
	g_cond_init (&data->cond);

	data->bytes_to_read = 44100 * 135 * 4;
	data->buf = g_malloc (data->bytes_to_read);
	entry = xmms_xform_entry_get (xform);

	/* TODO: #2482
	fp = xmms_medialib_entry_property_get_str (entry, "ofa_fingerprint");
	*/
	fp = NULL;
	if (fp) {
		XMMS_DBG ("Entry already has ofa_fingerprint, not recalculating");
		/* keep it! */
		xmms_xform_metadata_set_str (xform, "ofa_fingerprint", fp);
		g_free (fp);
	} else {
		data->run_ofa = TRUE;
	}

	xmms_xform_private_data_set (xform, data);

	xmms_xform_outdata_type_copy (xform);

	return TRUE;
}
Exemple #9
0
static void
add_to_entry (xmms_xform_t *xform,
              xmms_id3v2_header_t *head,
              const gchar *key,
              gchar *val,
              gint len)
{
	gchar *nval;
	const gchar *tmp;

	if (len < 1)
		return;

	tmp = binary_to_enc (val[0]);
	nval = convert_id3_text (tmp, &val[1], len - 1, NULL);
	if (nval) {
		xmms_xform_metadata_set_str (xform, key, nval);
		g_free (nval);
	}
}
Exemple #10
0
static gint
xmms_ofa_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
                      xmms_error_t *error)
{
	xmms_ofa_data_t *data;
	gint read;

	g_return_val_if_fail (xform, -1);

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

	read = xmms_xform_read (xform, buf, len, error);

	if (data->run_ofa && read > 0 && data->pos < data->bytes_to_read) {
		int l = MIN (data->bytes_to_read - data->pos, read);
		memcpy (data->buf + data->pos, buf, l);
		data->pos += l;
		if (data->pos == data->bytes_to_read) {
			g_mutex_lock (&data->mutex);
			data->thread_state = XMMS_OFA_CALCULATE;
			g_cond_signal (&data->cond);
			g_mutex_unlock (&data->mutex);
			data->run_ofa = FALSE;
		}
	} else if (data->pos == data->bytes_to_read){
		if (!data->done) {
			g_mutex_lock (&data->mutex);
			if (data->thread_state == XMMS_OFA_DONE) {
				xmms_xform_metadata_set_str (xform,
				                             "ofa_fingerprint",
				                             data->fp);
				data->done = TRUE;
			}
			g_mutex_unlock (&data->mutex);
		}
	}

	return read;
}
Exemple #11
0
static void
handle_id3v2_ufid (xmms_xform_t *xform, xmms_id3v2_header_t *head,
                   const gchar *key, gchar *buf, gsize len)
{
	const gchar *val;

	val = find_nul (buf, &len);
	if (!val)
		return;

	if (g_ascii_strcasecmp (buf, "http://musicbrainz.org") == 0) {
		const gchar *metakey;
		gchar *val0;
		/* make sure it is NUL terminated */
		val0 = g_strndup (val, len);

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_TRACK_ID,
		xmms_xform_metadata_set_str (xform, metakey, val0);

		g_free (val0);
	}
}
static void
xmms_mpc_collect_metadata (xmms_xform_t *xform)
{
	xmms_mpc_data_t *data;
	xmms_apetag_t *tag;
	gint i, intval;
	const gchar *strval;

	g_return_if_fail (xform);
	data = xmms_xform_private_data_get (xform);
	g_return_if_fail (data);

	tag = xmms_apetag_init (xform);

	if (xmms_apetag_read (tag)) {
		for (i = 0; i < G_N_ELEMENTS (properties); i++) {
			switch (properties[i].type) {
				case INTEGER:
					intval = xmms_apetag_lookup_int (tag, properties[i].vname);
					if (intval > 0) {
						xmms_xform_metadata_set_int (xform, properties[i].xname,
						                             intval);
					}
					break;
				case STRING:
					strval = xmms_apetag_lookup_str (tag, properties[i].vname);
					if (strval != NULL) {
						xmms_xform_metadata_set_str (xform, properties[i].xname,
						                             strval);
					}
					break;
			}
		}
	}

	xmms_apetag_destroy (tag);
}
Exemple #13
0
static gboolean
xmms_gvfs_init (xmms_xform_t *xform)
{
    xmms_gvfs_data_t *data;
    GFile *file;
    GFileInfo *info;
    GFileInputStream *handle;
    GError *error = NULL;
    const gchar *url;

    url = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_URL);
    g_return_val_if_fail (url, FALSE);

    /* This is an ugly hack to handle files with
       chars needing url encoding */
    if (!g_ascii_strncasecmp (url, "file://", 7)) {
        file = g_file_new_for_path (url+7);
    } else {
        file = g_file_new_for_uri (url);
    }
    handle = g_file_read (file, NULL, &error);
    g_object_unref (file);

    if (!handle) {
        xmms_log_error ("Failed to upen url %s for reading: %s",
                        url, error->message);
        return FALSE;
    }

    data = g_new (xmms_gvfs_data_t, 1);
    data->handle = G_INPUT_STREAM (handle);
    xmms_xform_private_data_set (xform, data);

    info = g_file_input_stream_query_info (handle, (char *)query_attributes,
                                           NULL, &error);

    if (!info) {
        xmms_log_info ("failed to query information for %s", url);
    } else {
        int i;

        for (i = 0; i < G_N_ELEMENTS (attr_map); i++) {
            if (!g_file_info_has_attribute (info, attr_map[i].gvfs)) {
                continue;
            }

            switch (attr_map[i].type) {
            case XMMSV_TYPE_STRING: {
                gchar *attr = g_file_info_get_attribute_as_string (info,
                              attr_map[i].gvfs);
                xmms_xform_metadata_set_str (xform, attr_map[i].mlib, attr);
                g_free (attr);
                break;
            }
            case XMMSV_TYPE_INT32: {
                /* right now the xform metadata api only handles strings
                 * and 32 bit ints. however the gvfs api returns uint64 for
                 * the numeric attributes we're interested in and we just
                 * pass that to the xform and pray that it doesn't overflow
                 * as we know it's unsafe.
                 */

                gint64 attr = g_file_info_get_attribute_uint64 (info,
                              attr_map[i].gvfs);
                xmms_xform_metadata_set_int (xform, attr_map[i].mlib, attr);
                break;
            }
            default:
                g_assert_not_reached ();
            }
        }

        g_object_unref (info);
    }

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

    return TRUE;
}
Exemple #14
0
static void
flac_callback_metadata (const FLAC__StreamDecoder *flacdecoder,
                        const FLAC__StreamMetadata *metadata,
                        void *client_data)
{
	xmms_flac_data_t *data;
	xmms_xform_t *xform = (xmms_xform_t *) client_data;
	gint32 filesize;
	const gchar *metakey;

	g_return_if_fail (xform);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (!xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
		filesize = -1;
	}

	data = xmms_xform_private_data_get (xform);

	switch (metadata->type) {
		case FLAC__METADATA_TYPE_STREAMINFO:
			/* FLAC__metadata_object_clone ()? */
			data->bits_per_sample = metadata->data.stream_info.bits_per_sample;
			data->sample_rate = metadata->data.stream_info.sample_rate;
			data->channels = metadata->data.stream_info.channels;
			data->total_samples = metadata->data.stream_info.total_samples;

			if (filesize > 0 && data->total_samples) {
				data->bit_rate = (guint) ((guint64) filesize * 8 *
				                 (guint64) data->sample_rate /
				                 (guint64) data->total_samples);
			}

			XMMS_DBG ("STREAMINFO: BPS %d. Samplerate: %d. Channels: %d.",
			          data->bits_per_sample,
			          data->sample_rate,
			          data->channels);

			break;
		case FLAC__METADATA_TYPE_VORBIS_COMMENT:
			data->vorbiscomment = FLAC__metadata_object_clone (metadata);
			break;
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
		case FLAC__METADATA_TYPE_PICTURE: {
			gchar hash[33];
			if (metadata->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER &&
			    xmms_bindata_plugin_add (metadata->data.picture.data,
			                             metadata->data.picture.data_length,
			                             hash)) {
				const gchar *metakey;
				
				metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT;
				xmms_xform_metadata_set_str (xform, metakey, hash);
				
				metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME;
				xmms_xform_metadata_set_str (xform, metakey, metadata->data.picture.mime_type);
			}
			break;
		}
#endif
		/* if we want to support more metadata types here,
		 * don't forget to add a call to
		 * FLAC__stream_decoder_set_metadata_respond() below.
		 */
		default:
			break;
	}
}
Exemple #15
0
static void
xmms_asf_get_mediainfo (xmms_xform_t *xform)
{
	xmms_asf_data_t *data;
	asf_metadata_t *metadata;
	uint64_t tmp;
	gchar *track = NULL;
	gint i;

	g_return_if_fail (xform);

	data = xmms_xform_private_data_get (xform);
	g_return_if_fail (data);

	if ((tmp = asf_get_duration (data->file)) > 0) {
		xmms_xform_metadata_set_int (xform,
		                             XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION,
		                             tmp/10000);
	}

	if ((tmp = asf_get_max_bitrate (data->file)) > 0) {
		xmms_xform_metadata_set_int (xform,
		                             XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE,
		                             tmp);
	}

	metadata = asf_header_get_metadata (data->file);
	if (!metadata) {
		XMMS_DBG ("No metadata object found in the file");
		return;
	}

	if (metadata->title && metadata->title[0]) {
		xmms_xform_metadata_set_str (xform,
		                             XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE,
		                             metadata->title);
	}

	if (metadata->artist && metadata->artist[0]) {
		xmms_xform_metadata_set_str (xform,
		                             XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST,
		                             metadata->artist);
	}

	if (metadata->description && metadata->description[0]) {
		xmms_xform_metadata_set_str (xform,
		                             XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT,
		                             metadata->description);
	}

	for (i=0; i<metadata->extended_count; i++) {
		char *key, *value;

		key = metadata->extended[i].key;
		value = metadata->extended[i].value;

		if (key == NULL || value == NULL || !strlen (value)) {
			continue;
		} else if (!strcmp (key, "WM/AlbumTitle")) {
			xmms_xform_metadata_set_str (xform,
			                             XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM,
			                             value);
		} else if (!strcmp (key, "WM/Year")) {
			xmms_xform_metadata_set_str (xform,
			                             XMMS_MEDIALIB_ENTRY_PROPERTY_YEAR,
			                             value);
		} else if (!strcmp (key, "WM/Genre")) {
			xmms_xform_metadata_set_str (xform,
			                             XMMS_MEDIALIB_ENTRY_PROPERTY_GENRE,
			                             value);
		} else if ((!track && !strcmp (key, "WM/Track")) || !strcmp (key, "WM/TrackNumber")) {
			/* WM/TrackNumber overrides WM/Track value as specified in the Microsoft
			 * documentation at http://msdn2.microsoft.com/en-us/library/aa392014.aspx */
			track = value;
		} else if (!strcmp (key, "MusicBrainz/Album Id")) {
			xmms_xform_metadata_set_str (xform,
			                             XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM_ID,
			                             value);
		} else if (!strcmp (key, "MusicBrainz/Artist Id")) {
			xmms_xform_metadata_set_str (xform,
			                             XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST_ID,
			                             value);
		} else if (!strcmp (key, "MusicBrainz/Track Id")) {
			xmms_xform_metadata_set_str (xform,
			                             XMMS_MEDIALIB_ENTRY_PROPERTY_TRACK_ID,
			                             value);
		}
	}

	if (track) {
		gint tracknr;
		gchar *end;

		tracknr = strtol (track, &end, 10);
		if (end && *end == '\0') {
			xmms_xform_metadata_set_int (xform,
			                             XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR,
			                             tracknr);
		}
	}

	asf_metadata_destroy (metadata);
}
Exemple #16
0
static gboolean
xmms_gme_init (xmms_xform_t *xform)
{
	xmms_gme_data_t *data;
	gme_err_t init_error;
	GString *file_contents; /* The raw data from the file. */
	gme_info_t *metadata = NULL;
	xmms_config_property_t *val;
	int loops;
	int maxlength;
	const char *subtune_str;
	int subtune = 0;
	long fadelen = -1;
	int samplerate;
	double stereodepth;


	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_gme_data_t, 1);

	xmms_xform_private_data_set (xform, data);

	val = xmms_xform_config_lookup (xform, "samplerate");
	samplerate = xmms_config_property_get_int (val);
	if (samplerate < 1)
		samplerate = GME_DEFAULT_SAMPLE_RATE;
	data->samplerate = samplerate;

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm", /* PCM samples */
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             XMMS_SAMPLE_FORMAT_S16, /* 16-bit signed */
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             2, /* stereo */
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             samplerate,
	                             XMMS_STREAM_TYPE_END);

	file_contents = g_string_new ("");

	for (;;) {
		xmms_error_t error;
		gchar buf[4096];
		gint ret;

		ret = xmms_xform_read (xform, buf, sizeof (buf), &error);
		if (ret == -1) {
			XMMS_DBG ("Error reading emulated music data");
			return FALSE;
		}
		if (ret == 0) {
			break;
		}
		g_string_append_len (file_contents, buf, ret);
	}

	init_error = gme_open_data (file_contents->str, file_contents->len, &data->emu, samplerate);

	g_string_free (file_contents, TRUE);

	if (init_error) {
		XMMS_DBG ("gme_open_data returned an error: %s", init_error);
		return FALSE;
	}

	if (xmms_xform_metadata_get_str (xform, "subtune", &subtune_str)) {
		subtune = strtol (subtune_str, NULL, 10);
		XMMS_DBG ("Setting subtune to %d", subtune);
		if ((subtune < 0 || subtune > gme_track_count (data->emu))) {
			XMMS_DBG ("Invalid subtune index");
			return FALSE;
		}
	} else {
		xmms_xform_metadata_set_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_SUBTUNES, gme_track_count (data->emu));
	}

	/*
	 *  Get metadata here
	 */
	init_error = gme_track_info (data->emu, &metadata, subtune);
	if (init_error) {
		XMMS_DBG ("Couldn't get GME track info: %s", init_error);
		init_error = "";
	} else {
		xmms_xform_metadata_set_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE, metadata->song);
		xmms_xform_metadata_set_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST, metadata->author);
		xmms_xform_metadata_set_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM, metadata->game);
		xmms_xform_metadata_set_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT, metadata->comment);
		xmms_xform_metadata_set_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_YEAR, metadata->copyright);
		xmms_xform_metadata_set_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_GENRE, metadata->system);  /* I mapped genre to the system type */

		val = xmms_xform_config_lookup (xform, "loops");
		loops = xmms_config_property_get_int (val);

		XMMS_DBG ("intro_length = %d, loops = %d, loop_length = %d", metadata->intro_length, loops, metadata->loop_length);

		if (metadata->intro_length > 0) {
			if ((loops > 0) && (metadata->loop_length > 0)) {
				fadelen = metadata->intro_length + loops * metadata->loop_length;
				XMMS_DBG ("fadelen now = %ld", fadelen);
			} else {
				fadelen = metadata->length;
				XMMS_DBG ("fadelen now = %ld", fadelen);
			}
		}
	}

	val = xmms_xform_config_lookup (xform, "maxlength");
	maxlength = xmms_config_property_get_int (val);

	XMMS_DBG ("maxlength = %d seconds", maxlength);

	if (maxlength > 0 && (fadelen < 0 || (maxlength * 1000L < fadelen))) {
		fadelen = maxlength * 1000L;
		XMMS_DBG ("fadelen now = %ld", fadelen);
	}

	XMMS_DBG ("gme.fadelen = %ld", fadelen);

	val = xmms_xform_config_lookup (xform, "stereodepth");
	stereodepth = xmms_config_property_get_float (val);
	if (stereodepth >= 0.0 && stereodepth <= 1.0) {
		XMMS_DBG ("Setting stereo depth to %f.", stereodepth);
		gme_set_stereo_depth (data->emu, stereodepth);
	} else {
		XMMS_DBG ("gme.stereodepth = %f out of range 0.0 - 1.0; not setting.", stereodepth);
	}

	init_error = gme_start_track (data->emu, subtune);
	if (init_error) {
		XMMS_DBG ("gme_start_track returned an error: %s", init_error);
		gme_free_info (metadata);
		return FALSE;
	}

	if (fadelen > 0) {
		XMMS_DBG ("Setting song length and fade length...");
		xmms_xform_metadata_set_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION, fadelen);
		gme_set_fade (data->emu, fadelen);
	}

	gme_free_info (metadata);
	return TRUE;
}
Exemple #17
0
static gboolean
xmms_xform_metadata_parse_string (xmms_xform_t *xform, const gchar *key,
                                  const gchar *value, gsize length)
{
	return xmms_xform_metadata_set_str (xform, key, value);
}
Exemple #18
0
static gboolean
handle_image_comment (xmms_xform_t *xform, const gchar *key,
                      const gchar *encoded_value, gsize length)
{
	gsize len;
	guchar *value;

	guint32 typ, mime_len, desc_len, img_len;
	guchar *pos, *end, *mime_data, *img_data;
	gchar hash[33];

#if GLIB_CHECK_VERSION(2,12,0)
	value = g_base64_decode (encoded_value, &len);
#else
	/* TODO: Implement/backport base64 decoding */
	return;
#endif

	pos = value;
	end = value + len;

	if (pos + sizeof (guint32) > end) {
		XMMS_DBG ("Malformed picture comment");
		goto finish;
	}

	typ = decode_uint32 (&pos);
	if (typ != 0 && typ != 3) {
		XMMS_DBG ("Picture type %d not handled", typ);
		goto finish;
	}

	if (pos + sizeof (guint32) > end) {
		XMMS_DBG ("Malformed picture comment");
		goto finish;
	}

	mime_len = decode_uint32 (&pos);
	mime_data = pos;
	pos += mime_len;

	if (pos + sizeof (guint32) > end) {
		XMMS_DBG ("Malformed picture comment");
		goto finish;
	}

	desc_len = decode_uint32 (&pos);
	pos += desc_len;

	decode_uint32 (&pos); /* width */
	decode_uint32 (&pos); /* height */
	decode_uint32 (&pos); /* depth */
	decode_uint32 (&pos); /* indexed palette length */

	if (pos + sizeof (guint32) > end) {
		XMMS_DBG ("Malformed picture comment");
		goto finish;
	}

	img_len = decode_uint32 (&pos);
	img_data = pos;

	if (img_data + img_len > end) {
		XMMS_DBG ("Malformed picture comment");
		goto finish;
	}

	if (xmms_bindata_plugin_add (img_data, img_len, hash)) {
		const gchar *metakey;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT;
		xmms_xform_metadata_set_str (xform, metakey, hash);

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME;
		mime_data[mime_len] = '\0';
		xmms_xform_metadata_set_str (xform, metakey, (gchar *)mime_data);
	}

finish:
	g_free (value);
	return TRUE;
}
Exemple #19
0
static xmms_xform_t *
chain_setup (xmms_medialib_entry_t entry, const gchar *url, GList *goal_formats)
{
	xmms_xform_t *xform, *last;
	gchar *durl, *args;

	if (!entry) {
		entry = 1; /* FIXME: this is soooo ugly, don't do this */
	}

	xform = xmms_xform_new (NULL, NULL, 0, goal_formats);

	durl = g_strdup (url);

	args = strchr (durl, '?');
	if (args) {
		gchar **params;
		gint i;
		*args = 0;
		args++;
		xmms_medialib_decode_url (args);

		params = g_strsplit (args, "&", 0);

		for (i = 0; params && params[i]; i++) {
			gchar *v;
			v = strchr (params[i], '=');
			if (v) {
				*v = 0;
				v++;
				xmms_xform_metadata_set_str (xform, params[i], v);
			} else {
				xmms_xform_metadata_set_int (xform, params[i], 1);
			}
		}
		g_strfreev (params);
	}
	xmms_medialib_decode_url (durl);

	xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE,
	                             "application/x-url", XMMS_STREAM_TYPE_URL,
	                             durl, XMMS_STREAM_TYPE_END);

	g_free (durl);

	last = xform;

	do {
		xform = xmms_xform_find (last, entry, goal_formats);
		if (!xform) {
			xmms_log_error ("Couldn't set up chain for '%s' (%d)",
			                url, entry);
			xmms_object_unref (last);

			return NULL;
		}
		xmms_object_unref (last);
		last = xform;
	} while (!has_goalformat (xform, goal_formats));

	outdata_type_metadata_collect (last);

	return last;
}
Exemple #20
0
static void
xmms_asf_get_mediainfo (xmms_xform_t *xform)
{
    xmms_asf_data_t *data;
    asf_metadata_t *metadata;
    uint64_t tmp;
    gint i;

    g_return_if_fail (xform);

    data = xmms_xform_private_data_get (xform);
    g_return_if_fail (data);

    if ((tmp = asf_get_duration (data->file)) > 0) {
        xmms_xform_metadata_set_int (xform,
                                     XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION,
                                     tmp/10000);
    }

    if ((tmp = asf_get_max_bitrate (data->file)) > 0) {
        xmms_xform_metadata_set_int (xform,
                                     XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE,
                                     tmp);
    }

    metadata = asf_header_get_metadata (data->file);
    if (!metadata) {
        XMMS_DBG ("No metadata object found in the file");
        return;
    }

    if (metadata->title && metadata->title[0]) {
        xmms_xform_metadata_set_str (xform,
                                     XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE,
                                     metadata->title);
    }

    if (metadata->artist && metadata->artist[0]) {
        xmms_xform_metadata_set_str (xform,
                                     XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST,
                                     metadata->artist);
    }

    if (metadata->description && metadata->description[0]) {
        xmms_xform_metadata_set_str (xform,
                                     XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT,
                                     metadata->description);
    }

    for (i = 0; i < metadata->extended_count; i++) {
        const char *key, *value;
        guint16 length;

        key = metadata->extended[i].key;
        value = metadata->extended[i].value;
        length = metadata->extended[i].length;

        if (!xmms_xform_metadata_mapper_match (xform, key, value, length)) {
            XMMS_DBG ("Unhandled tag '%s' = '%s'", key, value);
        }
    }

    asf_metadata_destroy (metadata);
}
Exemple #21
0
static gboolean
xmms_asf_handle_tag_coverart (xmms_xform_t *xform, const gchar *key,
                              const gchar *value, gsize length)
{
    const guint8 *uptr;
    const gchar *ptr;
    gchar *mime;
    gchar hash[33];
    guint32 picture_length;
    gsize size;
    GError *err = NULL;

    uptr = (const guchar *) value;

    /* check picture type */
    if (uptr[0] != 0x00 && uptr[0] != 0x03) {
        return FALSE;
    }

    /* step past picture type */
    uptr++;

    picture_length =
        ((guint32) uptr[3] << 24) |
        ((guint32) uptr[2] << 16) |
        ((guint32) uptr[1] <<  8) |
        ((guint32) uptr[0]);
    if (picture_length == 0) {
        return FALSE;
    }

    /* step past picture size */
    uptr += sizeof (guint32);

    ptr = (const gchar *) uptr;

    /* parse the UTF-16 mime type */
    size = xmms_asf_utf16_strnlen (ptr, (value + length) - ptr);
    mime = g_convert (ptr, size, "UTF-8", "UTF-16", NULL, NULL, &err);
    ptr += size + 2;

    if (mime == NULL || mime[0] == '\0') {
        return FALSE;
    }

    /* step past picture description */
    size = xmms_asf_utf16_strnlen (ptr, (value + length) - ptr);
    ptr += size + 2;

    uptr = (const guchar *) ptr;

    if (xmms_bindata_plugin_add (uptr, picture_length, hash)) {
        const gchar *metakey;

        metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT;
        xmms_xform_metadata_set_str (xform, metakey, hash);

        metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME;
        xmms_xform_metadata_set_str (xform, metakey, mime);
    }

    g_free (mime);

    return TRUE;
}
Exemple #22
0
static void
xmms_sid_get_songlength (xmms_xform_t *xform)
{
	xmms_config_property_t *config;
	const gchar *tmp, *md5sum, *songlength_path;
	gint subtune = 1;
	GIOChannel* io;
	GString *buf;

	g_return_if_fail (xform);

	config = xmms_xform_config_lookup (xform, "songlength_path");
	g_return_if_fail (config);
	songlength_path = xmms_config_property_get_string (config);
	if (!songlength_path[0])
		return;

	if (xmms_xform_metadata_get_str (xform, "subtune", &tmp)) {
		subtune = atoi (tmp);
	}

	if (!xmms_xform_metadata_get_str (xform, "HVSCfingerprint", &md5sum)) {
		return;
	}

	io = g_io_channel_new_file (songlength_path, "r", NULL);
	if (!io) {
		xmms_log_error ("Unable to load songlengths database '%s'", songlength_path);
		return;
	}

	buf = g_string_new ("");
	while (g_io_channel_read_line_string (io, buf, NULL, NULL) == G_IO_STATUS_NORMAL) {
		if (buf->len > 33 && g_ascii_strncasecmp (buf->str, md5sum, 32) == 0) {
			gint cur = 0;
			gchar *b;

			b = buf->str + 33;
			while (*b) {
				gint min, sec;

				/* read timestamp */
				if (sscanf (b, "%d:%d", &min, &sec) != 2) {
					/* no more timestamps on this line */
					break;
				} else {
					cur++;
				}

				if (cur == subtune) {
					const gchar *metakey;
					gchar ms_str[10 + 1]; /* LONG_MAX in str, \w NULL */
					glong ms;

					ms = (min * 60 + sec) * 1000;

					metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
					xmms_xform_metadata_set_int (xform, metakey, ms);

					if (g_snprintf (ms_str, 10 + 1, "%ld", ms) > 0) {
						metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_STARTMS;
						xmms_xform_metadata_set_str (xform, metakey, "0");

						metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_STOPMS;
						xmms_xform_metadata_set_str (xform, metakey, ms_str);
					}

					goto done;
				}

				/* forward to next possible timestamp */
				b = strchr (b, ' ');
				if (!b) {
					/* no more timestamps on this line */
					break;
				}
				b++;
			}
		}
	}
	xmms_log_info ("Couldn't find sid tune in songlength.txt");
done:
	g_io_channel_unref (io);
}
Exemple #23
0
static gboolean
xmms_modplug_init (xmms_xform_t *xform)
{
	xmms_modplug_data_t *data;
	const gchar *metakey;
	gint filesize;
	xmms_config_property_t *cfgv;
	gint i;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_modplug_data_t, 1);

	xmms_xform_private_data_set (xform, data);

	for (i = 0; i < G_N_ELEMENTS (config_params); i++) {
		cfgv = xmms_xform_config_lookup (xform, config_params[i].key);
		xmms_config_property_callback_set (cfgv,
		                                   xmms_modplug_config_changed,
		                                   data);

		xmms_modplug_config_changed (XMMS_OBJECT (cfgv), NULL, data);
	}

	/* mFrequency and mResamplingMode are set in config_changed */
	data->settings.mChannels = 2;
	data->settings.mBits = 16;
	ModPlug_SetSettings (&data->settings);

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             XMMS_SAMPLE_FORMAT_S16,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             2,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->settings.mFrequency,
	                             XMMS_STREAM_TYPE_END);

	data->buffer = g_string_new ("");

	for (;;) {
		xmms_error_t error;
		gchar buf[4096];
		gint ret;

		ret = xmms_xform_read (xform, buf, sizeof (buf), &error);
		if (ret == -1) {
			XMMS_DBG ("Error reading mod");
			return FALSE;
		}
		if (ret == 0) {
			break;
		}
		g_string_append_len (data->buffer, buf, ret);
	}

	data->mod = ModPlug_Load (data->buffer->str, data->buffer->len);
	if (!data->mod) {
		XMMS_DBG ("Error loading mod");
		return FALSE;
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
		xmms_xform_metadata_set_int (xform, metakey,
		                             ModPlug_GetLength (data->mod));
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE;
	xmms_xform_metadata_set_str (xform, metakey, ModPlug_GetName (data->mod));

	return TRUE;
}
Exemple #24
0
static gboolean
xmms_cdda_init (xmms_xform_t *xform)
{
	CdIo_t *cdio = NULL;
	cdrom_drive_t *drive = NULL;
	const gchar *url;
	gchar **url_data = NULL;
	gchar *url_end;
	xmms_cdda_data_t *data;
	guint playtime;
	lsn_t first_lsn;
	track_t track;
	gchar *disc_id = NULL;
	gchar *cddb_id = NULL;
	xmms_config_property_t *val;
	const gchar *device;
	const gchar *metakey;
	gboolean ret = TRUE;

	g_return_val_if_fail (xform, FALSE);
	url = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_URL);

	if (g_ascii_strcasecmp (url, "cdda://") == 0) {
		xmms_xform_outdata_type_add (xform,
		                             XMMS_STREAM_TYPE_MIMETYPE,
		                             "application/x-xmms2-playlist-entries",
		                             XMMS_STREAM_TYPE_END);
		return TRUE;
	}

	val = xmms_xform_config_lookup (xform, "device");
	device = xmms_config_property_get_string (val);

	if (!get_disc_ids (device, &disc_id, &cddb_id, 0)) {
		return FALSE;
	}

	url += 7;
	url_data = g_strsplit (url, "/", 2);

	if (g_ascii_strcasecmp (url_data[0], disc_id)) {
		xmms_log_error ("Wrong disc inserted.");
		ret = FALSE;
		goto end;
	}

	if (url_data[1] == NULL) {
		xmms_log_error ("Missing track number.");
		ret = FALSE;
		goto end;
	}

	track = strtol (url_data[1], &url_end, 10);
	if (url_data[1] == url_end) {
		xmms_log_error ("Invalid track, need a number.");
		ret = FALSE;
		goto end;
	}

	cdio = open_cd (xform);
	if (!cdio) {
		ret = FALSE;
		goto end;
	}

	drive = cdio_cddap_identify_cdio (cdio, 1, NULL);
	if (!drive) {
		xmms_log_error ("Failed to identify drive.");
		ret = FALSE;
		goto end;
	}

	if (cdio_cddap_open (drive)) {
		xmms_log_error ("Unable to open disc.");
		ret = FALSE;
		goto end;
	}

	first_lsn = cdio_cddap_track_firstsector (drive, track);
	if (first_lsn == -1) {
		xmms_log_error ("No such track.");
		ret = FALSE;
		goto end;
	}

	data = g_new (xmms_cdda_data_t, 1);
	data->cdio = cdio;
	data->drive = drive;
	data->track = track;
	data->first_lsn = first_lsn;
	data->last_lsn = cdio_cddap_track_lastsector (drive, data->track);
	data->current_lsn = first_lsn;
	data->buf_used = CDIO_CD_FRAMESIZE_RAW;

	playtime = (data->last_lsn - data->first_lsn) *
	           1000.0 / CDIO_CD_FRAMES_PER_SEC;

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
	xmms_xform_metadata_set_int (xform, metakey, playtime);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
	xmms_xform_metadata_set_int (xform, metakey, 141120);

	xmms_xform_metadata_set_str (xform, "disc_id", url_data[0]);
	xmms_xform_metadata_set_str (xform, "cddb_id", cddb_id);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR;
	xmms_xform_metadata_set_int (xform, metakey, track);

	xmms_xform_private_data_set (xform, data);

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             XMMS_SAMPLE_FORMAT_S16,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             2,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             44100,
	                             XMMS_STREAM_TYPE_END);

end:
	/* These are to be destroyed in every cases... */
	g_free (cddb_id);
	g_free (disc_id);
	g_strfreev (url_data);

	/* destroy cdio/drive in case of failure */
	if (!ret) {
		if (drive) {
			cdio_cddap_close_no_free_cdio (drive);
		}
		if (cdio) {
			cdio_destroy (cdio);
		}
	}

	return ret;
}
Exemple #25
0
static gboolean
xmms_id3v1_parse (xmms_xform_t *xform, guchar *buf)
{
	xmms_config_property_t *config;
	const char *encoding;
	const gchar *metakey;
	xmmsv_t *bb;
	unsigned char data[32];

	bb = xmmsv_new_bitbuffer_ro (buf, 128);

	xmmsv_bitbuffer_get_data (bb, data, 3);

	if (memcmp (data, "TAG", 3) != 0) {
		xmmsv_unref (bb);
		return FALSE;
	}

	XMMS_DBG ("Found ID3v1 TAG!");

	config = xmms_xform_config_lookup (xform, "id3v1_encoding");
	g_return_val_if_fail (config, FALSE);
	encoding = xmms_config_property_get_string (config);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE;
	xmmsv_bitbuffer_get_data (bb, data, 30);
	xmms_id3v1_set (xform, metakey, data, 30, encoding);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST;
	xmmsv_bitbuffer_get_data (bb, data, 30);
	xmms_id3v1_set (xform, metakey, data, 30, encoding);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM;
	xmmsv_bitbuffer_get_data (bb, data, 30);
	xmms_id3v1_set (xform, metakey, data, 30, encoding);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_YEAR;
	xmmsv_bitbuffer_get_data (bb, data, 4);
	xmms_id3v1_set (xform, metakey, data, 4, encoding);

	xmmsv_bitbuffer_get_data (bb, data, 30);

	/* v1.1 */
	if (data[28] == '\0' && data[29]) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT;
		xmms_id3v1_set (xform, metakey, data, 28, encoding);
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR;
		if (!xmms_xform_metadata_has_val (xform, metakey)) {
			xmms_xform_metadata_set_int (xform, metakey, data[29]);
		}
	} else {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT;
		xmms_id3v1_set (xform, metakey, data, 30, encoding);
	}


	xmmsv_bitbuffer_get_data (bb, data, 1);
	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_GENRE;
	if (data[0] >= G_N_ELEMENTS (id3_genres)) {
		xmms_xform_metadata_set_str (xform, metakey, "Unknown");
	} else {
		xmms_xform_metadata_set_str (xform, metakey, id3_genres[data[0]]);
	}


	xmmsv_unref (bb);
	return TRUE;
}