Пример #1
0
static gboolean
xmms_asf_handle_tag_old_tracknr (xmms_xform_t *xform, const gchar *key,
                                 const gchar *value, gsize length)
{
    gint ivalue;

    /* WM/TrackNumber overrides WM/Track value as specified in the Microsoft
     * documentation at http://msdn2.microsoft.com/en-us/library/aa392014.aspx
     * so lets check if something else has set the tracknr property before us.
     */
    if (xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR, &ivalue)) {
        return FALSE;
    }

    /* Ok, nothing set, lets handle "WM/Track" as "WM/TrackNumber" */
    if (!xmms_xform_metadata_mapper_match (xform, "WM/TrackNumber", value, length)) {
        return FALSE;
    }

    /* Last quirk, WM/Track is 0-indexed, need to fix that */
    xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR, &ivalue);
    xmms_xform_metadata_set_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR, ivalue + 1);

    return TRUE;
}
Пример #2
0
static gboolean
xmms_metadata_test_xform_init (xmms_xform_t *xform)
{
	const gchar *musicbrainz_va_id = "89ad4ac3-39f7-470e-963a-56509c546377";
	const gchar *title, *rpgain;
	gint track, compilation;

	CU_ASSERT_FALSE (xmms_xform_metadata_mapper_match (xform, "missing", "missing", -1));

	/* Basic string mapping */
	CU_ASSERT_TRUE (xmms_xform_metadata_mapper_match (xform, "title", "the title", -1));
	CU_ASSERT_TRUE (xmms_xform_metadata_get_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE, &title));
	CU_ASSERT_STRING_EQUAL ("the title", title);

	/* Mapping track number, without total tracks */
	CU_ASSERT_TRUE (xmms_xform_metadata_mapper_match (xform, "tracknr", "1", -1));
	CU_ASSERT_TRUE (xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR, &track));
	CU_ASSERT_EQUAL (1, track);

	/* Broken track number */
	CU_ASSERT_FALSE (xmms_xform_metadata_mapper_match (xform, "tracknr", "bad", -1));

	/* Mapping compilation indicator to boolean compilation */
	CU_ASSERT_TRUE (xmms_xform_metadata_mapper_match (xform, "compilation", "1", -1));
	CU_ASSERT_TRUE (xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_COMPILATION, &compilation));
	CU_ASSERT_EQUAL (TRUE, compilation);

	/* Mapping compilation indicator to boolean compilation */
	CU_ASSERT_TRUE (xmms_xform_metadata_mapper_match (xform, "compilation", musicbrainz_va_id, -1));
	CU_ASSERT_TRUE (xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_COMPILATION, &compilation));
	CU_ASSERT_EQUAL (TRUE, compilation);


	/* Mapping replaygain to the format the replaygain xform expects */
	CU_ASSERT_TRUE (xmms_xform_metadata_mapper_match (xform, "replaygain_track_gain", "-14.69", -1));
	CU_ASSERT_TRUE (xmms_xform_metadata_get_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_TRACK, &rpgain));
	CU_ASSERT_STRING_EQUAL ("0.18428", rpgain);
	CU_ASSERT_TRUE (xmms_xform_metadata_mapper_match (xform, "replaygain_track_gain", "-14.69 dB", -1));
	CU_ASSERT_TRUE (xmms_xform_metadata_get_str (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_TRACK, &rpgain));
	CU_ASSERT_STRING_EQUAL ("0.18428", rpgain);


	CU_ASSERT_TRUE (xmms_xform_metadata_mapper_match (xform, "coverart", "test", 10));

	xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "audio/pcm", XMMS_STREAM_TYPE_END);

	return TRUE;
}
Пример #3
0
static void
xmms_wave_get_media_info (xmms_xform_t *xform)
{
	xmms_wave_data_t *data;
	gdouble playtime;
	guint samples_total, bitrate;
	gint filesize;
	const gchar *metakey;

	g_return_if_fail (xform);

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

	samples_total = data->bytes_total / (data->bits_per_sample / 8);
	playtime = (gdouble) samples_total / data->samplerate / data->channels;

	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, playtime * 1000);
	}

	bitrate = data->bits_per_sample * data->samplerate / data->channels;
	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
	xmms_xform_metadata_set_int (xform, metakey, bitrate);
}
Пример #4
0
static void
xmms_mpc_cache_streaminfo (xmms_xform_t *xform)
{
    xmms_mpc_data_t *data;
    gint bitrate, duration, filesize;
    gchar buf[8];
    const gchar *metakey;

    g_return_if_fail (xform);

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

    XMMS_DBG ("stream version = %d", data->info.stream_version);

    metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
    if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
        duration = mpc_streaminfo_get_length (&data->info) * 1000;
        metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
        xmms_xform_metadata_set_int (xform, metakey, duration);
    }

    bitrate = (data->info.bitrate) ? data->info.bitrate :
              data->info.average_bitrate;

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

    if (data->info.gain_album) {
        g_snprintf (buf, sizeof (buf), "%f",
                    xmms_mpc_normalize_gain ((gdouble) data->info.gain_album));
        metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_ALBUM;
        xmms_xform_metadata_set_str (xform, metakey, buf);
    }

    if (data->info.gain_title) {
        g_snprintf (buf, sizeof (buf), "%f",
                    xmms_mpc_normalize_gain ((gdouble) data->info.gain_title));
        metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_TRACK;
        xmms_xform_metadata_set_str (xform, metakey, buf);
    }

    if (data->info.peak_album) {
        g_snprintf (buf, sizeof (buf), "%f",
                    xmms_mpc_normalize_peak ((gdouble) data->info.peak_album));
        metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PEAK_ALBUM;
        xmms_xform_metadata_set_str (xform, metakey, buf);
    }

    if (data->info.peak_title) {
        g_snprintf (buf, sizeof (buf), "%f",
                    xmms_mpc_normalize_peak ((gdouble) data->info.peak_title));
        metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PEAK_TRACK;
        xmms_xform_metadata_set_str (xform, metakey, buf);
    }
}
Пример #5
0
static gboolean
xmms_id3v2_init (xmms_xform_t *xform)
{
	xmms_id3v2_data_t *data;
	xmms_id3v2_header_t head;
	xmms_error_t err;
	guchar hbuf[20];
	gint filesize;
	guchar *buf;
	gint res;
	const gchar *metakey;

	xmms_error_reset (&err);

	if (xmms_xform_read (xform, hbuf, 10, &err) != 10) {
		XMMS_DBG ("Couldn't read id3v2 header...");
		return FALSE;
	}

	data = g_new0 (xmms_id3v2_data_t, 1);
	xmms_xform_private_data_set (xform, data);

	if (!xmms_id3v2_is_header (hbuf, &head)) {
		XMMS_DBG ("Couldn't parse id3v2 header!?");
		return FALSE;
	}

	/* Total data length is the length of header data plus header bytes */
	data->len = head.len + 10;

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
		xmms_xform_metadata_set_int (xform, metakey, filesize - head.len);
	}


	buf = g_malloc (head.len);

	res = xmms_xform_read (xform, buf, head.len, &err);
	if (res != head.len) {
		XMMS_DBG ("Couldn't read id3v2 %d bytes of id3-data data (%d)", head.len, res);
		return FALSE;
	}

	xmms_id3v2_parse (xform, buf, &head);

	g_free (buf);

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "application/octet-stream",
	                             XMMS_STREAM_TYPE_END);
	return TRUE;
}
int
CSourceAdapter::GetSize ()
{
	const gchar *metakey;
	gint32 size = -1;

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	xmms_xform_metadata_get_int (xform, metakey, &size);

	return size;
}
Пример #7
0
static sf_count_t
xmms_sf_virtual_get_filelen (void *priv)
{
	xmms_xform_t *xform = priv;
	gint filesize = 0; /* Return length 0 in case of failure. */

	xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE,
	                             &filesize);

	return filesize;
}
Пример #8
0
static uint32_t
wavpack_get_length (void *id)
{
	xmms_xform_t *xform = id;
	gint filesize;
	const gchar *metakey;

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

	return filesize;
}
Пример #9
0
static FLAC__StreamDecoderLengthStatus
flac_callback_length (const FLAC__StreamDecoder *flacdecoder,
                      FLAC__uint64 *stream_length, void *client_data)
{
	xmms_xform_t *xform = (xmms_xform_t *) client_data;
	const gchar *metakey;
	gint val;

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (xmms_xform_metadata_get_int (xform, metakey, &val)) {
		*stream_length = val;
		return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
	}

	return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
}
Пример #10
0
static mpc_int32_t
xmms_mpc_callback_get_size (READER_OBJ *p_obj)
{
    xmms_xform_t *xform = READER_DATA (p_obj);
    const gchar *metakey;
    gint ret;

    g_return_val_if_fail (xform, -1);

    metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
    if (xmms_xform_metadata_get_int (xform, metakey, &ret)) {
        return ret;
    }

    return -1;
}
Пример #11
0
static gint64
xmms_gme_seek (xmms_xform_t *xform, gint64 samples,
               xmms_xform_seek_mode_t whence, xmms_error_t *err)
{
	xmms_gme_data_t *data;
	gint64 target_time;
	gint duration;
	int samplerate;

	g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1);
	g_return_val_if_fail (xform, -1);

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

	samplerate = data->samplerate;

	if (samples < 0) {
		xmms_error_set (err, XMMS_ERROR_INVAL,
		                "Trying to seek before start of stream");
		return -1;
	}

	target_time = (samples / samplerate) * 1000;
	xmms_xform_metadata_get_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION, &duration);

	if (target_time > duration) {
		xmms_error_set (err, XMMS_ERROR_INVAL,
		                "Trying to seek past end of stream");
		return -1;
	}

	gme_seek (data->emu, target_time);

	return (gme_tell (data->emu) / 1000) * samplerate;
}
Пример #12
0
static void
xmms_faad_get_mediainfo (xmms_xform_t *xform)
{
	xmms_faad_data_t *data;
	const gchar *metakey;

	g_return_if_fail (xform);

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

	if (data->filetype == FAAD_TYPE_ADIF) {
		guint skip_size, bitrate;
		gint32 duration;

		skip_size = (data->buffer[4] & 0x80) ? 9 : 0;
		bitrate = ((guint) (data->buffer[4 + skip_size] & 0x0F) << 19) |
		          ((guint) data->buffer[5 + skip_size] << 11) |
		          ((guint) data->buffer[6 + skip_size] << 3) |
		          ((guint) data->buffer[7 + skip_size] & 0xE0);

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

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
		if (xmms_xform_metadata_get_int (xform, metakey, &duration)) {
			duration = ((float) duration * 8000.f) / ((float) bitrate) + 0.5f;

			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
			xmms_xform_metadata_set_int (xform, metakey, duration);
		}
	} else if (data->filetype == FAAD_TYPE_ADTS) {
		gint32 val = faad_mpeg_samplerates[(data->buffer[2] & 0x3c) >> 2];
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SAMPLERATE;
		xmms_xform_metadata_set_int (xform, metakey, val);
	}
Пример #13
0
static void
xmms_sndfile_get_media_info (xmms_xform_t *xform)
{
	xmms_sndfile_data_t *data;
	gdouble playtime;
	guint bitrate;
	gint filesize = 0, bps = -1;
	const gchar *metakey, *str;

	g_return_if_fail (xform);

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

	playtime = (gdouble) data->sf_info.frames / data->sf_info.samplerate;

	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, playtime * 1000);
	}

	switch (data->sf_info.format) {
		case SF_FORMAT_PCM_S8:
			bps = 8;
			break;
		case SF_FORMAT_PCM_16:
			bps = 16;
			break;
		case SF_FORMAT_PCM_24:
			bps = 24;
			break;
		case SF_FORMAT_PCM_32:
			bps = 32;
			break;
		case SF_FORMAT_PCM_U8:
			bps = 8;
			break;
		case SF_FORMAT_FLOAT:
			bps = 32;
			break;
		case SF_FORMAT_DOUBLE:
			bps = 64;
			break;
		case SF_FORMAT_ULAW:
		case SF_FORMAT_ALAW:
		case SF_FORMAT_IMA_ADPCM:
		case SF_FORMAT_MS_ADPCM:
		case SF_FORMAT_GSM610:
		case SF_FORMAT_VOX_ADPCM:
		case SF_FORMAT_G721_32:
		case SF_FORMAT_G723_24:
		case SF_FORMAT_G723_40:
		case SF_FORMAT_DWVW_12:
		case SF_FORMAT_DWVW_16:
		case SF_FORMAT_DWVW_24:
		case SF_FORMAT_DWVW_N:
		case SF_FORMAT_DPCM_8:
		case SF_FORMAT_DPCM_16:
		case SF_FORMAT_VORBIS:
		default:
			break;
	}

	if (bps >= 0) {
		bitrate = bps * data->sf_info.samplerate / data->sf_info.channels;
	} else {
		/* Approximate bitrate for compressed formats from the total file
		 * length and sample rate. */
		bitrate = filesize / (data->sf_info.frames / data->sf_info.samplerate);
	}

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

	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_ARTIST,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST);
	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_ALBUM,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM);
	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_COMMENT,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_COMMENT);
	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_COPYRIGHT,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_COPYRIGHT);
	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_DATE,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_YEAR); /* Verify! */
/*	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_LICENSE,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_???); */
/*	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_SOFTWARE,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_???); */
	SF2XMMS_META_TRANSCODE (str, data->sndfile, xform, SF_STR_TITLE,
	                        XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE);

	/* We could fetch ID3 tags here as soon as libsndfile will support this -
	 * Erik of libsndfile has to provide the generic chunk handling though.
	 */
}
Пример #14
0
static gboolean
xmms_vorbis_init (xmms_xform_t *xform)
{
	xmms_vorbis_data_t *data;
	vorbis_info *vi;
	gint ret;
	guint playtime;
	const gchar *metakey;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_vorbis_data_t, 1),

	data->callbacks.read_func = vorbis_callback_read;
	data->callbacks.close_func = vorbis_callback_close;
	data->callbacks.tell_func = vorbis_callback_tell;
	data->callbacks.seek_func = vorbis_callback_seek;

	data->current = -1;

	xmms_xform_private_data_set (xform, data);

	ret = ov_open_callbacks (xform, &data->vorbisfile, NULL, 0,
	                         data->callbacks);
	if (ret) {
		return FALSE;
	}

	vi = ov_info (&data->vorbisfile, -1);

	playtime = ov_time_total (&data->vorbisfile, -1);
	if (playtime != OV_EINVAL) {
		gint filesize;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
		if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
			xmms_vorbis_set_duration (xform, playtime);
		}
	}

	if (vi && vi->bitrate_nominal) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
		xmms_xform_metadata_set_int (xform, metakey,
		                             (gint) vi->bitrate_nominal);
	}

	xmms_vorbis_read_metadata (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,
	                             vi->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             vi->rate,
	                             XMMS_STREAM_TYPE_END);


	return TRUE;
}
Пример #15
0
static gboolean
xmms_mad_init (xmms_xform_t *xform)
{
	struct mad_frame frame;
	struct mad_stream stream;
	xmms_error_t err;
	guchar buf[40960];
	xmms_mad_data_t *data;
	int len;
	const gchar *metakey;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_mad_data_t, 1);

	mad_stream_init (&data->stream);
	mad_frame_init (&data->frame);
	mad_synth_init (&data->synth);

	xmms_xform_private_data_set (xform, data);

	data->buffer_length = 0;

	data->synthpos = 0x7fffffff;

	mad_stream_init (&stream);
	mad_frame_init (&frame);

	len = xmms_xform_peek (xform, buf, 40960, &err);
	mad_stream_buffer (&stream, buf, len);

	while (mad_frame_decode (&frame, &stream) == -1) {
		if (!MAD_RECOVERABLE (stream.error)) {
			XMMS_DBG ("couldn't decode %02x %02x %02x %02x",buf[0],buf[1],buf[2],buf[3]);
			mad_frame_finish (&frame);
			mad_stream_finish (&stream);
			return FALSE;
		}
	}

	data->channels = frame.header.mode == MAD_MODE_SINGLE_CHANNEL ? 1 : 2;
	data->samplerate = frame.header.samplerate;


	if (frame.header.flags & MAD_FLAG_PROTECTION) {
		XMMS_DBG ("Frame has protection enabled");
		if (stream.anc_ptr.byte > stream.buffer + 2) {
			stream.anc_ptr.byte = stream.anc_ptr.byte - 2;
		}
	}

	data->samples_to_play = -1;

	data->xing = xmms_xing_parse (stream.anc_ptr);
	if (data->xing) {
		xmms_xing_lame_t *lame;
		XMMS_DBG ("File with Xing header!");

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_IS_VBR;
		xmms_xform_metadata_set_int (xform, metakey, 1);

		if (xmms_xing_has_flag (data->xing, XMMS_XING_FRAMES)) {
			guint duration;
			mad_timer_t timer;

			timer = frame.header.duration;
			mad_timer_multiply (&timer, xmms_xing_get_frames (data->xing));
			duration = mad_timer_count (timer, MAD_UNITS_MILLISECONDS);

			XMMS_DBG ("XING duration %d", duration);

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

			if (xmms_xing_has_flag (data->xing, XMMS_XING_BYTES) && duration) {
				guint tmp;

				tmp = xmms_xing_get_bytes (data->xing) * ((guint64)8000) / duration;
				XMMS_DBG ("XING bitrate %d", tmp);
				metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
				xmms_xform_metadata_set_int (xform, metakey, tmp);
			}
		}

		lame = xmms_xing_get_lame (data->xing);
		if (lame) {
			/* FIXME: add a check for ignore_lame_headers from the medialib */
			data->frames_to_skip = 1;
			data->samples_to_skip = lame->start_delay;
			data->samples_to_play = ((guint64) xmms_xing_get_frames (data->xing) * 1152ULL) -
			                        lame->start_delay - lame->end_padding;
			XMMS_DBG ("Samples to skip in the beginning: %d, total: %" G_GINT64_FORMAT,
			          data->samples_to_skip, data->samples_to_play);
			/*
			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_ALBUM;
			xmms_xform_metadata_set_int (xform, metakey, lame->audiophile_gain);

			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PEAK_TRACK;
			xmms_xform_metadata_set_int (xform, metakey, lame->peak_amplitude);

			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_GAIN_TRACK;
			xmms_xform_metadata_set_int (xform, metakey, lame->radio_gain);
			*/
		}

	} else {
		gint filesize;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
		xmms_xform_metadata_set_int (xform, metakey, frame.header.bitrate);

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
		if (!xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;

			if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
				gint32 val;

				val = (gint32) (filesize * (gdouble) 8000.0 / frame.header.bitrate);

				metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
				xmms_xform_metadata_set_int (xform, metakey, val);
			}
		}
	}

	/* seeking needs bitrate */
	data->bitrate = frame.header.bitrate;

	if (xmms_id3v1_get_tags (xform) < 0) {
		mad_stream_finish (&data->stream);
		mad_frame_finish (&data->frame);
		mad_synth_finish (&data->synth);
		if (data->xing) {
			xmms_xing_free (data->xing);
		}
		return FALSE;
	}

	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,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->samplerate,
	                             XMMS_STREAM_TYPE_END);

	mad_frame_finish (&frame);
	mad_stream_finish (&stream);

	return TRUE;
}
Пример #16
0
static gboolean
xmms_flac_init (xmms_xform_t *xform)
{
	xmms_flac_data_t *data;
	xmms_sample_format_t sample_fmt;
	FLAC__bool retval;
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	FLAC__StreamDecoderState init_status;
#else
	FLAC__StreamDecoderInitStatus init_status;
#endif
	gint filesize;
	const gchar *metakey;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_flac_data_t, 1);

	xmms_xform_private_data_set (xform, data);

	data->flacdecoder = FLAC__stream_decoder_new ();

	/* we don't need to explicitly tell the decoder to respond to
	 * FLAC__METADATA_TYPE_STREAMINFO here, it always does.
	 */
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	FLAC__seekable_stream_decoder_set_metadata_respond (data->flacdecoder,
	                                                    FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__seekable_stream_decoder_set_eof_callback (data->flacdecoder,
	                                                flac_callback_eof);
	FLAC__seekable_stream_decoder_set_read_callback (data->flacdecoder,
	                                                 flac_callback_read);
	FLAC__seekable_stream_decoder_set_seek_callback (data->flacdecoder,
	                                                 flac_callback_seek);
	FLAC__seekable_stream_decoder_set_tell_callback (data->flacdecoder,
	                                                 flac_callback_tell);
	FLAC__seekable_stream_decoder_set_write_callback (data->flacdecoder,
	                                                  flac_callback_write);
	FLAC__seekable_stream_decoder_set_error_callback (data->flacdecoder,
	                                                  flac_callback_error);
	FLAC__seekable_stream_decoder_set_length_callback (data->flacdecoder,
	                                                   flac_callback_length);
	FLAC__seekable_stream_decoder_set_metadata_callback (data->flacdecoder,
	                                                     flac_callback_metadata);

	FLAC__seekable_stream_decoder_set_client_data (data->flacdecoder, xform);

	init_status = FLAC__seekable_stream_decoder_init (data->flacdecoder);

	if (init_status != FLAC__SEEKABLE_STREAM_DECODER_OK) {
		const gchar *errmsg = FLAC__seekable_stream_decoder_get_resolved_state_string (data->flacdecoder);
		XMMS_DBG ("FLAC init failed: %s", errmsg);
		goto err;
	}
#else
	FLAC__stream_decoder_set_metadata_respond (data->flacdecoder,
	                                           FLAC__METADATA_TYPE_VORBIS_COMMENT);
	FLAC__stream_decoder_set_metadata_respond (data->flacdecoder,
	                                           FLAC__METADATA_TYPE_PICTURE);

	init_status =
		FLAC__stream_decoder_init_stream (data->flacdecoder,
		                                  flac_callback_read,
		                                  flac_callback_seek,
		                                  flac_callback_tell,
		                                  flac_callback_length,
		                                  flac_callback_eof,
		                                  flac_callback_write,
		                                  flac_callback_metadata,
		                                  flac_callback_error,
		                                  xform);

	if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
		XMMS_DBG ("FLAC init failed: %s",
		          FLAC__stream_decoder_get_resolved_state_string (data->flacdecoder));
		goto err;
	}
#endif

	retval = FLAC__stream_decoder_process_until_end_of_metadata (data->flacdecoder);
	if (!retval)
		goto err;

	if (data->vorbiscomment) {
		handle_comments (xform, data);
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
	xmms_xform_metadata_set_int (xform, metakey, (gint) data->bit_rate);

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
		gint32 val = (gint32) data->total_samples / data->sample_rate * 1000;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
		xmms_xform_metadata_set_int (xform, metakey, val);
	}

	if (data->bits_per_sample == 8) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S8;
	} else if (data->bits_per_sample == 16) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S16;
	} else if (data->bits_per_sample == 24) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S32;
	} else if (data->bits_per_sample == 32) {
		sample_fmt = XMMS_SAMPLE_FORMAT_S32;
	} else {
		goto err;
	}

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

	data->buffer = g_string_new (NULL);

	return TRUE;

err:

	FLAC__stream_decoder_finish (data->flacdecoder);
	FLAC__stream_decoder_delete (data->flacdecoder);
	g_free (data);
	xmms_xform_private_data_set (xform, NULL);

	return FALSE;

}
Пример #17
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;
	}
}
Пример #18
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;
}
Пример #19
0
static gboolean
xmms_opus_init (xmms_xform_t *xform)
{
	xmms_opus_data_t *data;
	gint ret;
	guint playtime;
	const gchar *metakey;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_opus_data_t, 1),

	data->callbacks.read = opus_callback_read;
	data->callbacks.close = opus_callback_close;
	data->callbacks.tell = opus_callback_tell;
	data->callbacks.seek = opus_callback_seek;

	data->current = -1;

	xmms_xform_private_data_set (xform, data);

	data->opusfile = op_open_callbacks (xform, &data->callbacks, NULL, 0,
	                         &ret);
	if (ret) {
		return FALSE;
	}

	playtime = op_pcm_total (data->opusfile, -1) / 48000;

	if (playtime != OP_EINVAL) {
		gint filesize;

		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
		if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
			xmms_opus_set_duration (xform, playtime);
		}
	}

	xmms_opus_read_metadata (xform, data);

	/*
	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             XMMS_SAMPLE_FORMAT_FLOAT,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             48000,
	                             XMMS_STREAM_TYPE_END);
	*/

	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,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             48000,
	                             XMMS_STREAM_TYPE_END);

	return TRUE;
}
Пример #20
0
static gboolean
xmms_mpg123_init (xmms_xform_t *xform)
{
	xmms_mpg123_data_t *data;
	const long *rates;
	size_t num_rates;
	int encoding;
	off_t length;
	int i, result;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_mpg123_data_t, 1);
	xmms_xform_private_data_set (xform, data);

	/* Get the total size of this stream and store it for later */
	if (xmms_xform_metadata_get_int (xform,
	                                 XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE,
	                                 &result)) {
		data->filesize = result;
	}

	mpg123_rates (&rates, &num_rates);

	data->param = mpg123_new_pars (&result);
	g_return_val_if_fail (data->param, FALSE);

	/* Create a quiet (stderr) decoder with auto choosen optimization.
	 * Stuff set here should be tunable via plugin config properties!
	 * You can also change some things during playback...
	 */
	mpg123_par (data->param, MPG123_ADD_FLAGS, MPG123_QUIET, 0);
	mpg123_par (data->param, MPG123_ADD_FLAGS, MPG123_GAPLESS, 0);
	/* choose: MPG123_RVA_OFF, MPG123_RVA_MIX, MPG123_RVA_ALBUM
	 * xmms2 has its own ReplayGain plugin to handle the RVA field */
	mpg123_par (data->param, MPG123_RVA, MPG123_RVA_OFF, 0);

	/* You could choose a decoder from the list provided by
	 * mpg123_supported_decoders () and give that as second parameter.
	 */
	data->decoder = mpg123_parnew (data->param, NULL, &result);
	if (data->decoder == NULL) {
		xmms_log_error ("%s", mpg123_plain_strerror (result));
		goto bad;
	}

	/* Prepare for buffer input feeding. */
	result = mpg123_open_feed (data->decoder);
	if (result != MPG123_OK) {
		goto mpg123_bad;
	}

	/* Let's always decode to signed 16bit for a start.
	   Any mpg123-supported sample rate is accepted. */
	if (MPG123_OK != mpg123_format_none (data->decoder)) {
		goto mpg123_bad;
	}

	for (i = 0; i < num_rates; i++) {
		result = mpg123_format (data->decoder, rates[i],
		                        MPG123_MONO | MPG123_STEREO,
		                        MPG123_ENC_SIGNED_16);
		if (result != MPG123_OK) {
			goto mpg123_bad;
		}
	}

	/* Fetch ID3v1 data from the end of file if possible */
	result = xmms_id3v1_get_tags (xform);
	if (result < 0) {
		xmms_log_error ("Seeking error when reading ID3v1 tags");
		goto bad;
	} else if (data->filesize > result) {
		/* Reduce the size of tag data from the filesize */
		data->filesize -= result;
	}

	/* Read data from input until decoded data is available from decoder */
	do {
		/* Parse stream and get info. */
		gint ret;
		xmms_error_t err;

		ret = xmms_xform_read (xform, data->buf, BUFSIZE, &err);
		if (ret < 0) {
			xmms_log_error ("Error when trying to find beginning of stream");
			goto bad;
		} else if (ret == 0) {
			/* EOF reached before format was found, handled after loop */
			break;
		}

		/* With zero output size nothing is actually outputted */
		result = mpg123_decode (data->decoder, data->buf,
		                        (size_t) ret, NULL, 0, NULL);
	} while (result == MPG123_NEED_MORE); /* Keep feeding... */

	if (result != MPG123_NEW_FORMAT) {
		xmms_log_error ("Unable to find beginning of stream (%s)!",
		                result == MPG123_ERR ? mpg123_strerror (data->decoder)
		                : "unexpected EOF");
		goto bad;
	}

	result = mpg123_getformat (data->decoder, &data->samplerate,
	                           &data->channels, &encoding);
	if (result != MPG123_OK) {
		goto mpg123_bad;
	}

	/* Set the filesize so it can be used for duration estimation */
	if (data->filesize > 0) {
		mpg123_set_filesize (data->decoder, data->filesize);
	}

	/* Get duration in samples, convert to ms and save to xmms2 */
	length = mpg123_length (data->decoder);
	if (length > 0 &&
	    !xmms_xform_metadata_get_int (xform,
		                              XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION,
		                              &i)) {
		length = (off_t) ((gfloat) length / data->samplerate * 1000);
		xmms_xform_metadata_set_int (xform,
		                             XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION,
		                             (gint) length);
	}

	XMMS_DBG ("mpg123: got stream with %li Hz %i channels, encoding %i",
	          data->samplerate, data->channels, encoding);

	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,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             (gint) data->samplerate,
	                             XMMS_STREAM_TYPE_END);
	return TRUE;

mpg123_bad:
	xmms_log_error ("mpg123 error: %s", mpg123_strerror (data->decoder));

bad:
	mpg123_delete (data->decoder);
	mpg123_delete_pars (data->param);
	g_free (data);

	return FALSE;
}