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;
}
Beispiel #2
0
static gint
xmms_faad_read_some (xmms_xform_t *xform, xmms_error_t *err)
{
	xmms_faad_data_t *data;
	NeAACDecFrameInfo frameInfo;
	gpointer sample_buffer;
	guint bytes_read = 0;

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

	while (data->outbuf->len == 0) {
		gboolean need_read;

		/* MP4 demuxer always gives full packets so we need different handling */
		if (data->filetype == FAAD_TYPE_MP4)
			need_read = (data->buffer_length == 0);
		else
			need_read = (data->buffer_length < data->buffer_size);

		if (need_read) {
			bytes_read = xmms_xform_read (xform,
			                              (gchar *) data->buffer + data->buffer_length,
			                              data->buffer_size - data->buffer_length,
			                              err);

			if (bytes_read <= 0 && data->buffer_length == 0) {
				XMMS_DBG ("EOF");
				return 0;
			}

			data->buffer_length += bytes_read;
		}

		sample_buffer = NeAACDecDecode (data->decoder, &frameInfo, data->buffer,
		                               data->buffer_length);

		g_memmove (data->buffer, data->buffer + frameInfo.bytesconsumed,
		           data->buffer_length - frameInfo.bytesconsumed);
		data->buffer_length -= frameInfo.bytesconsumed;
		bytes_read = frameInfo.samples * xmms_sample_size_get (data->sampleformat);

		if (bytes_read > 0 && frameInfo.error == 0) {
			if (data->samplerate != frameInfo.samplerate ||
			    data->channels != frameInfo.channels) {
				/* We should inform output to change parameters somehow */
				xmms_log_error ("Output format changed in the middle of a read!");
				data->samplerate = frameInfo.samplerate;
				data->channels = frameInfo.channels;
			}
			g_string_append_len (data->outbuf, sample_buffer, bytes_read);
		} else if (frameInfo.error > 0) {
			xmms_log_error ("ERROR %d in faad decoding: %s", frameInfo.error,
			                NeAACDecGetErrorMessage (frameInfo.error));
			return -1;
		}
	}
	return data->outbuf->len;
}
Beispiel #3
0
static gint
xmms_replaygain_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
                      xmms_error_t *error)
{
    xmms_replaygain_data_t *data;
    xmms_sample_format_t fmt;
    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->has_replaygain || !data->enabled) {
        return read;
    }

    fmt = xmms_xform_indata_get_int (xform, XMMS_STREAM_TYPE_FMT_FORMAT);
    len /= xmms_sample_size_get (fmt);

    data->apply (buf, len, data->gain);

    return read;
}
Beispiel #4
0
static guint
find_offset (xmms_xform_t *xform)
{
	xmms_error_t err;
	guint8 buf[BUFFER_SIZE];
	gboolean done = FALSE;
	guint offset = 0;
	gint read, i;

	do {
		xmms_error_reset (&err);
		read = xmms_xform_peek (xform, buf, BUFFER_SIZE, &err);

		/* check for failures */
		if (read < 1) {
			return 0;
		}

		/* find first non-nul character */
		for (i = 0; i < read; i++) {
			if (buf[i] != '\0') {
				done = TRUE;
				break;
			}
		}

		offset += i;

		/* skip over the NULs */
		xmms_error_reset (&err);
		xmms_xform_read (xform, buf, i, &err);
	} while (!done);

	return offset;
}
static gint
xmms_normalize_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
                     xmms_error_t *error)
{
	xmms_normalize_data_t *data;
	gint read;

	g_return_val_if_fail (xform, -1);

	data = xmms_xform_private_data_get (xform);

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

	if (read > 0) {
		if (data->dirty) {
			compress_reconfigure (data->compress,
			                      data->use_anticlip,
			                      data->target,
			                      data->max_gain,
			                      data->smooth,
			                      data->buckets);
			data->dirty = FALSE;
		}

		compress_do (data->compress, buf, read);
	}

	return read;
}
Beispiel #6
0
static FLAC__StreamDecoderReadStatus
flac_callback_read (const FLAC__StreamDecoder *flacdecoder,
                    FLAC__byte buffer[],
                    read_callback_size_t *bytes,
                    void *client_data)
{
	xmms_xform_t *xform = (xmms_xform_t *) client_data;
	xmms_error_t error;
	gint ret;

#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	g_return_val_if_fail (xform,
	                      FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR);
#else
	g_return_val_if_fail (xform,
	                      FLAC__STREAM_DECODER_READ_STATUS_ABORT);
#endif

	ret = xmms_xform_read (xform, (gchar *)buffer, *bytes, &error);
	*bytes = ret;

#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	return (ret <= 0) ? FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR
	                  : FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
#else
	return (ret <= 0) ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
	                  : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
#endif
}
Beispiel #7
0
static uint32_t
xmms_mp4_read_callback (void *user_data, void *buffer, uint32_t length)
{
	xmms_xform_t *xform;
	xmms_mp4_data_t *data;
	xmms_error_t error;
	gint ret;

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

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

	if (data->buffer_length == 0) {
		guint bytes_read;

		bytes_read = xmms_xform_read (xform, (gchar *) data->buffer,
		                              data->buffer_size, &error);

		if (bytes_read <= 0 && data->buffer_length == 0) {
			return bytes_read;
		}

		data->buffer_length += bytes_read;
	}

	ret = MIN (length, data->buffer_length);
	g_memmove (buffer, data->buffer, ret);
	g_memmove (data->buffer, data->buffer + ret, data->buffer_length - ret);
	data->buffer_length -= ret;

	return ret;
}
Beispiel #8
0
static gint
xmms_wave_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
                xmms_error_t *error)
{
	xmms_wave_data_t *data;
	gint ret;

	g_return_val_if_fail (xform, -1);

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

	ret = xmms_xform_read (xform, (gchar *) buf, len, error);
	if (ret <= 0) {
		return ret;
	}

#if G_BYTE_ORDER == G_BIG_ENDIAN
	if (data->bits_per_sample == 16) {
		gint16 *s = (gint16 *) buf;
		gint i;

		for (i = 0; i < (ret / 2); i++) {
			s[i] = GINT16_FROM_LE (s[i]);
		}
	}
#endif

	return ret;
}
static sf_count_t
xmms_sf_virtual_read (void *buffer, sf_count_t count, void *priv)
{
	xmms_xform_t *xform = priv;
	gint64 ret = 0; /* Return read byte count of 0 in case of failure. */
	xmms_error_t err;

	ret = xmms_xform_read (xform, buffer, count, &err);

	return ret;
}
Beispiel #10
0
static mpc_int32_t
xmms_mpc_callback_read (READER_OBJ *p_obj, void *buffer, mpc_int32_t size)
{
    xmms_xform_t *xform = READER_DATA (p_obj);
    xmms_error_t err;

    g_return_val_if_fail (xform, -1);

    xmms_error_reset (&err);

    return xmms_xform_read (xform, (gchar *) buffer, size, &err);
}
Beispiel #11
0
static gboolean
xmms_xspf_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error)
{
	int ret;
	char buf[4096];
	xmlParserCtxtPtr ctx;
	xmlDocPtr doc;

	g_return_val_if_fail (xform, FALSE);

	xmms_error_reset (error);

	ctx = xmlCreatePushParserCtxt (NULL, NULL, buf, 0, NULL);

	if (!ctx) {
		xmms_error_set (error, XMMS_ERROR_OOM, "Could not allocate xml parser");
		return FALSE;
	}

	while ((ret = xmms_xform_read (xform, buf, sizeof (buf), error)) > 0) {
		if ((xmlParseChunk (ctx, buf, ret, 0)) != 0) {
			break;
		}
	}

	if (ret < 0) {
		xmms_error_set (error, XMMS_ERROR_GENERIC,
		                "failed to read data from previous xform");
		xmlFreeParserCtxt (ctx);
		return FALSE;
	}

	xmlParseChunk (ctx, buf, 0, 1);

	if (ctx->lastError.message) {
		xmms_error_set (error, XMMS_ERROR_INVAL, ctx->lastError.message);
		xmlFreeParserCtxt (ctx);
		return FALSE;
	}

	doc = ctx->myDoc;

	if (!xmms_xspf_browse_add_entries (xform, doc, error)) {
		xmlFreeParserCtxt (ctx);
		return FALSE;
	}

	xmms_error_reset (error);
	xmlFreeParserCtxt (ctx);

	return TRUE;
}
Beispiel #12
0
static gboolean
xmms_rss_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error)
{
	int ret;
	char buffer[1024];
	xmlSAXHandler handler;
	xmlParserCtxtPtr ctx;
	xmms_rss_data_t data;

	g_return_val_if_fail (xform, FALSE);

	memset (&handler, 0, sizeof (handler));
	memset (&data, 0, sizeof (data));

	handler.startElement = (startElementSAXFunc) xmms_rss_start_element;
	handler.error = (errorSAXFunc) xmms_rss_error;
	handler.fatalError = (fatalErrorSAXFunc) xmms_rss_error;

	data.xform = xform;
	data.error = error;
	data.parse_failure = FALSE;

	xmms_error_reset (error);

	ctx = xmlCreatePushParserCtxt (&handler, &data, buffer, 0, NULL);
	if (!ctx) {
		xmms_error_set (error, XMMS_ERROR_OOM,
		                "Could not allocate xml parser");
		return FALSE;
	}

	while ((ret = xmms_xform_read (xform, buffer, sizeof (buffer), error)) > 0) {
		xmlParseChunk (ctx, buffer, ret, 0);
	}

	if (ret < 0) {
		xmms_error_set (error, XMMS_ERROR_GENERIC, "xmms_xform_read failed");
		return FALSE;
	}

	if (data.parse_failure)
		return FALSE;

	xmlParseChunk (ctx, buffer, 0, 1);

	xmms_error_reset (error);
	xmlFreeParserCtxt (ctx);

	return TRUE;
}
Beispiel #13
0
static int
opus_callback_read (void *datasource, unsigned char *ptr, int size)
{
	xmms_opus_data_t *data;
	xmms_xform_t *xform = datasource;
	xmms_error_t error;
	size_t ret;

	g_return_val_if_fail (xform, 0);

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

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

	return ret;
}
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;
}
Beispiel #15
0
static size_t
vorbis_callback_read (void *ptr, size_t size, size_t nmemb,
                      void *datasource)
{
	xmms_vorbis_data_t *data;
	xmms_xform_t *xform = datasource;
	xmms_error_t error;
	size_t ret;

	g_return_val_if_fail (xform, 0);

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

	ret = xmms_xform_read (xform, ptr, size * nmemb, &error);

	return ret / size;
}
Beispiel #16
0
gchar *
xmms_xform_read_line (xmms_xform_t *xform, gchar *line, xmms_error_t *err)
{
	gchar *p;

	g_return_val_if_fail (xform, NULL);
	g_return_val_if_fail (line, NULL);

	p = strchr (xform->lr.buf, '\n');

	if (!p) {
		gint l, r;

		l = (XMMS_XFORM_MAX_LINE_SIZE - 1) - (xform->lr.bufend - xform->lr.buf);
		if (l) {
			r = xmms_xform_read (xform, xform->lr.bufend, l, err);
			if (r < 0) {
				return NULL;
			}
			xform->lr.bufend += r;
		}
		if (xform->lr.bufend <= xform->lr.buf)
			return NULL;

		*(xform->lr.bufend) = '\0';
		p = strchr (xform->lr.buf, '\n');
		if (!p) {
			p = xform->lr.bufend;
		}
	}

	if (p > xform->lr.buf && *(p-1) == '\r') {
		*(p-1) = '\0';
	} else {
		*p = '\0';
	}

	strcpy (line, xform->lr.buf);
	memmove (xform->lr.buf, p + 1, xform->lr.bufend - p);
	xform->lr.bufend -= (p - xform->lr.buf) + 1;
	*xform->lr.bufend = '\0';

	return line;
}
Beispiel #17
0
static gint
xmms_id3v1_get_tags (xmms_xform_t *xform)
{
	xmms_config_property_t *config;
	gint enabled;
	xmms_error_t err;
	gint64 res;
	guchar buf[128];
	gint ret = 0;

	config = xmms_xform_config_lookup (xform, "id3v1_enable");
	g_return_val_if_fail (config, -1);
	enabled = xmms_config_property_get_int (config);

	if (!enabled) {
		XMMS_DBG ("ID3v1 tags disabled.");
		return 0;
	}

	xmms_error_reset (&err);

	res = xmms_xform_seek (xform, -128, XMMS_XFORM_SEEK_END, &err);
	if (res == -1) {
		XMMS_DBG ("Couldn't seek - not getting id3v1 tag");
		return 0;
	}

	if (xmms_xform_read (xform, buf, 128, &err) == 128) {
		if (xmms_id3v1_parse (xform, buf)) {
			ret = 128;
		}
	} else {
		XMMS_DBG ("Read of 128 bytes failed?!");
		xmms_error_reset (&err);
	}

	res = xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_SET, &err);
	if (res == -1) {
		XMMS_DBG ("Couldn't seek after getting id3 tag?!? very bad");
		return -1;
	}

	return ret;
}
Beispiel #18
0
static void
fill (xmms_xform_t *xform, xmms_ringbuf_priv_t *priv)
{
	xmms_error_t err;
	char buf[4096];
	int res;

	res = xmms_xform_read (xform, buf, sizeof (buf), &err);
	if (res > 0) {
		xmms_ringbuf_write_wait (priv->buffer, buf, res, &priv->buffer_lock);
	} else if (res == -1) {
		/* XXX copy error */
		g_mutex_lock (&priv->state_lock);
		priv->state = STATE_WANT_STOP;
	} else {
		xmms_ringbuf_set_eos (priv->buffer, TRUE);
		priv->state = STATE_WANT_STOP;
	}
}
Beispiel #19
0
static gint
xmms_eq_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
              xmms_error_t *error)
{
	xmms_equalizer_data_t *priv;
	gint read, chan;

	g_return_val_if_fail (xform, -1);

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

	read = xmms_xform_read (xform, buf, len, error);
	chan = xmms_xform_indata_get_int (xform, XMMS_STREAM_TYPE_FMT_CHANNELS);
	if (read > 0 && priv->enabled) {
		iir (buf, read, chan, priv->extra_filtering);
	}

	return read;
}
Beispiel #20
0
static FLAC__StreamDecoderReadStatus
flac_callback_read (const FLAC__StreamDecoder *flacdecoder, FLAC__byte buffer[],
                    size_t *bytes, void *client_data)
{
	xmms_xform_t *xform = (xmms_xform_t *) client_data;
	xmms_error_t error;
	gint ret;

	g_return_val_if_fail (xform, FLAC__STREAM_DECODER_READ_STATUS_ABORT);

	ret = xmms_xform_read (xform, (gchar *)buffer, *bytes, &error);
	if (ret == 0) {
		return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
	} else if (ret < 0) {
		return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
	} else {
		*bytes = ret;
		return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
	}
}
Beispiel #21
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;
}
Beispiel #22
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;
}
Beispiel #23
0
static gint
xmms_vis_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
              xmms_error_t *error)
{
	gint read, chan;

	g_return_val_if_fail (xform, -1);

	chan = xmms_xform_indata_get_int (xform, XMMS_STREAM_TYPE_FMT_CHANNELS);

	/* perhaps rework this later */
	if (len > XMMSC_VISUALIZATION_WINDOW_SIZE * chan * sizeof (short)) {
		len = XMMSC_VISUALIZATION_WINDOW_SIZE * chan * sizeof (short);
	}

	read = xmms_xform_read (xform, buf, len, error);
	if (read > 0) {
		send_data (chan, read / sizeof (short), buf);
	}

	return read;
}
Beispiel #24
0
static int32_t
wavpack_read_bytes (void *id, void *buf, int32_t bcount)
{
	xmms_xform_t *xform = id;
	xmms_wavpack_data_t *data;
	xmms_error_t error;
	gint64 ret;
	gboolean did_pushback = FALSE;

	g_return_val_if_fail (xform, -1);

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

	/* if we have pushback data, consume it */
	if (data->pushback_set && bcount > 0) {
		((guint8 *)buf)[0] = data->pushback_byte;
		buf++;
		bcount--;

		data->pushback_set = FALSE;

		did_pushback = TRUE;

		if (bcount == 0) {
			return 1;
		}
	}

	ret = xmms_xform_read (xform, buf, bcount, &error);

	if (ret != -1 && did_pushback) {
		/* adjust return value if we consumed the pushback byte */
		ret++;
	}

	return ret;
}
static gint
xmms_converter_plugin_read (xmms_xform_t *xform, void *buffer, gint len, xmms_error_t *error)
{
	xmms_conv_xform_data_t *data;
	char buf[1024];

	data = xmms_xform_private_data_get (xform);

	if (!data->outlen) {
		int r = xmms_xform_read (xform, buf, sizeof (buf), error);
		if (r <= 0) {
			return r;
		}
		xmms_sample_convert (data->conv, buf, r, &data->outbuf, &data->outlen);
	}

	len = MIN (len, data->outlen);
	memcpy (buffer, data->outbuf, len);
	data->outlen -= len;
	data->outbuf += len;

	return len;
}
Beispiel #26
0
static gint
xmms_mad_read (xmms_xform_t *xform, gpointer buf, gint len, xmms_error_t *err)
{
	xmms_mad_data_t *data;
	xmms_samples16_t *out = (xmms_samples16_t *)buf;
	gint ret;
	gint j;
	gint read = 0;

	data = xmms_xform_private_data_get (xform);

	j = 0;

	while (read < len) {

		/* use already synthetized frame first */
		if (data->synthpos < data->synth.pcm.length) {
			out[j++] = scale_linear (data->synth.pcm.samples[0][data->synthpos]);
			if (data->channels == 2) {
				out[j++] = scale_linear (data->synth.pcm.samples[1][data->synthpos]);
				read += 2 * xmms_sample_size_get (XMMS_SAMPLE_FORMAT_S16);
			} else {
				read += xmms_sample_size_get (XMMS_SAMPLE_FORMAT_S16);
			}
			data->synthpos++;
			continue;
		}

		/* then try to decode another frame */
		if (mad_frame_decode (&data->frame, &data->stream) != -1) {

			/* mad_synthpop_frame - go Depeche! */
			mad_synth_frame (&data->synth, &data->frame);

			if (data->frames_to_skip) {
				data->frames_to_skip--;
				data->synthpos = 0x7fffffff;
			} else if (data->samples_to_skip) {
				if (data->samples_to_skip > data->synth.pcm.length) {
					data->synthpos = 0x7fffffff;
					data->samples_to_skip -= data->synth.pcm.length;
				} else {
					data->synthpos = data->samples_to_skip;
					data->samples_to_skip = 0;
				}
			} else {
				if (data->samples_to_play == 0) {
					return read;
				} else if (data->samples_to_play > 0) {
					if (data->synth.pcm.length > data->samples_to_play) {
						data->synth.pcm.length = data->samples_to_play;
					}
					data->samples_to_play -= data->synth.pcm.length;
				}
				data->synthpos = 0;
			}
			continue;
		}


		/* if there is no frame to decode stream more data */
		if (data->stream.next_frame) {
			guchar *buffer = data->buffer;
			const guchar *nf = data->stream.next_frame;
			memmove (data->buffer, data->stream.next_frame,
			         data->buffer_length = (&buffer[data->buffer_length] - nf));
		}

		ret = xmms_xform_read (xform,
		                       (gchar *)data->buffer + data->buffer_length,
		                       4096 - data->buffer_length,
		                       err);

		if (ret <= 0) {
			return ret;
		}

		data->buffer_length += ret;
		mad_stream_buffer (&data->stream, data->buffer, data->buffer_length);
	}

	return read;
}
Beispiel #27
0
static gboolean
xmms_mp4_init (xmms_xform_t *xform)
{
	xmms_mp4_data_t *data;
	xmms_error_t error;

	gint bytes_read;

	guchar *tmpbuf;
	guint tmpbuflen;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_mp4_data_t, 1);
	data->outbuf = g_string_new (NULL);
	data->buffer_size = MP4_BUFFER_SIZE;

	xmms_xform_private_data_set (xform, data);

	data->sampleid = 1;
	data->numsamples = 0;

	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 < 8) {
		XMMS_DBG ("Not enough bytes to check the MP4 header");
		goto err;
	}

	/*
	 * MP4 not supported (yet) on non-seekable transport
	 * this needs little tweaking in mp4ff at least
	 */
	if (xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_CUR, &error) < 0) {
		XMMS_DBG ("Non-seekable transport on MP4 not yet supported");
		goto err;
	}

	data->mp4ff_cb = g_new0 (mp4ff_callback_t, 1);
	data->mp4ff_cb->read = xmms_mp4_read_callback;
	data->mp4ff_cb->seek = xmms_mp4_seek_callback;
	data->mp4ff_cb->user_data = xform;

	data->mp4ff = mp4ff_open_read (data->mp4ff_cb);
	if (!data->mp4ff) {
		XMMS_DBG ("Error opening mp4 demuxer\n");
		goto err;;
	}

	data->track = xmms_mp4_get_track (xform, data->mp4ff);
	if (data->track < 0) {
		XMMS_DBG ("Can't find suitable audio track from MP4 file\n");
		goto err;
	}
	data->numsamples = mp4ff_num_samples (data->mp4ff, data->track);

	mp4ff_get_decoder_config (data->mp4ff, data->track, &tmpbuf,
	                          &tmpbuflen);
	xmms_xform_auxdata_set_bin (xform, "decoder_config", tmpbuf, tmpbuflen);
	g_free (tmpbuf);

	xmms_mp4_get_mediainfo (xform);

	XMMS_DBG ("MP4 demuxer inited successfully!");

	return TRUE;

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

	return FALSE;
}
Beispiel #28
0
static gint
xmms_vocoder_read (xmms_xform_t *xform, xmms_sample_t *buffer, gint len,
                   xmms_error_t *error)
{
	xmms_vocoder_data_t *data;
	guint size;

	g_return_val_if_fail (xform, -1);

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

	size = MIN (data->outbuf->len, len);
	while (size == 0) {
		int i, dpos;
		gint16 *samples = (gint16 *) data->iobuf;

		if (!data->enabled) {
			return xmms_xform_read (xform, buffer, len, error);
		}

		if (!data->resdata.input_frames) {
			dpos = pvocoder_get_chunk (data->pvoc, data->procbuf);
			while (dpos != 0) {
				int ret, read = 0;

				memset (data->procbuf, 0, data->bufsize *
				        sizeof (pvocoder_sample_t));
				while (read < data->bufsize * sizeof (gint16)) {
					ret = xmms_xform_read (xform,
					                       data->iobuf+read,
					                       data->bufsize *
					                       sizeof (gint16)-read,
					                       error);
					if (ret <= 0) {
						if (!ret && !read) {
							/* end of file */
							return 0;
						} else if (ret < 0) {
							return ret;
						}
						break;
					}
					read += ret;
				}

				for (i=0; i<data->bufsize; i++) {
					data->procbuf[i] = (pvocoder_sample_t) samples[i] / 32767;
				}
				pvocoder_add_chunk (data->pvoc, data->procbuf);
				dpos = pvocoder_get_chunk (data->pvoc, data->procbuf);
			}
			data->resdata.data_in = data->procbuf;
			data->resdata.input_frames = data->winsize;
		}
		src_process (data->resampler, &data->resdata);
		data->resdata.data_in += data->resdata.input_frames_used * data->channels;
		data->resdata.input_frames -= data->resdata.input_frames_used;

		for (i=0; i<data->resdata.output_frames_gen * data->channels; i++) {
			samples[i] = data->resbuf[i] * 32767;
		}
		g_string_append_len (data->outbuf, data->iobuf,
		                     data->resdata.output_frames_gen *
		                     data->channels *
		                     sizeof (gint16));
		size = MIN (data->outbuf->len, len);
	}

	memcpy (buffer, data->outbuf->str, size);
	g_string_erase (data->outbuf, 0, size);

	return size;
}
Beispiel #29
0
static gboolean
xmms_apetag_read (xmms_xform_t *xform)
{
	guchar buffer[32], *tagdata;
	xmms_error_t error;
	guint version, tag_size, items, flags;
	gint64 tag_position;
	gint pos, i, ret;

	g_return_val_if_fail (xform, FALSE);

	/* Try to find the 32-byte footer from the end of file */
	tag_position = xmms_xform_seek (xform, -32, XMMS_XFORM_SEEK_END, &error);
	if (tag_position < 0) {
		/* Seeking failed, failed to read tags */
		return FALSE;
	}

	/* Read footer data if seeking was possible */
	ret = xmms_xform_read (xform, buffer, 32, &error);
	if (ret != 32) {
		xmms_log_error ("Failed to read APE tag footer");
		return FALSE;
	}

	/* Check that the footer is valid, if not continue searching */
	if (memcmp (buffer, "APETAGEX", 8)) {
		/* Try to find the 32-byte footer before 128-byte ID3v1 tag */
		tag_position = xmms_xform_seek (xform, -160, XMMS_XFORM_SEEK_END, &error);
		if (tag_position < 0) {
			/* Seeking failed, failed to read tags */
			xmms_log_error ("Failed to seek to APE tag footer");
			return FALSE;
		}

		/* Read footer data if seeking was possible */
		ret = xmms_xform_read (xform, buffer, 32, &error);
		if (ret != 32) {
			xmms_log_error ("Failed to read APE tag footer");
			return FALSE;
		}

		if (memcmp (buffer, "APETAGEX", 8)) {
			/* Didn't find any APE tag from the file */
			return FALSE;
		}
	}

	version = xmms_apetag_get_le32 (buffer + 8);
	tag_size = xmms_apetag_get_le32 (buffer + 12);
	items = xmms_apetag_get_le32 (buffer + 16);
	flags = xmms_apetag_get_le32 (buffer + 20);

	if (flags & APE_TAG_FLAG_IS_HEADER) {
		/* We need a footer, not a header... */
		return FALSE;
	}

	if (version != 1000 && version != 2000) {
		xmms_log_error ("Invalid tag version, the writer is probably corrupted!");
		return FALSE;
	}

	/* Seek to the beginning of the actual tag data */
	ret = xmms_xform_seek (xform, tag_position - tag_size + 32,
	                       XMMS_XFORM_SEEK_SET, &error);
	if (ret < 0) {
		xmms_log_error ("Couldn't seek to the tag starting position, returned %d", ret);
		return FALSE;
	}

	tagdata = g_malloc (tag_size);
	ret = xmms_xform_read (xform, tagdata, tag_size, &error);
	if (ret != tag_size) {
		xmms_log_error ("Couldn't read the tag data, returned %d", ret);
		g_free (tagdata);
		return FALSE;
	}

	pos = 0;
	for (i = 0; i < items; i++) {
		gint itemlen, flags;
		gchar *key, *item;

		itemlen = xmms_apetag_get_le32 (tagdata + pos);
		pos += 4;
		flags = xmms_apetag_get_le32 (tagdata + pos);
		pos += 4;
		key = (gchar *) tagdata + pos;
		pos += strlen (key) + 1;

		switch (flags & APE_TAG_FLAG_DATA_TYPE) {
			case APE_TAG_DATA_TYPE_UTF8:
				item = g_strndup ((gchar *) tagdata + pos, itemlen);
				break;
			case APE_TAG_DATA_TYPE_BINARY:
				item = g_malloc (itemlen);
				memcpy (item, tagdata + pos, itemlen);
				break;
			case APE_TAG_DATA_TYPE_LOCATOR:
				item = NULL;
				break;
		}

		if (item != NULL && !xmms_xform_metadata_mapper_match (xform, key, item, itemlen)) {
			if ((flags & APE_TAG_FLAG_DATA_TYPE) == APE_TAG_DATA_TYPE_UTF8) {
				XMMS_DBG ("Unhandled tag '%s' = '%s'", key, item);
			} else {
				XMMS_DBG ("Unhandled tag '%s' = '(binary)'", key);
			}
		}

		g_free (item);
		pos += itemlen;
	}
	g_free (tagdata);

	return TRUE;
}
Beispiel #30
-1
static gint
xmms_mpg123_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
                  xmms_error_t *err)
{
	xmms_mpg123_data_t *data;
	int result = MPG123_OK;
	size_t read = 0;

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

	while (read == 0) {
		gint ret = 0;

		if (result == MPG123_NEED_MORE) {
			ret = xmms_xform_read (xform, data->buf, BUFSIZE, err);
			if (ret < 0) {
				return ret;
			} else if (ret == 0) {
				data->eof_found = TRUE;
			}
		}

		result = mpg123_decode (data->decoder, data->buf, (size_t) ret,
		                        buf, len, &read);

		if (result == MPG123_NEED_MORE && data->eof_found) {
			/* We need more data, but there's none available
			 * so libmpg123 apparently missed an EOF */
			result = MPG123_DONE;
			break;
		} else if (result != MPG123_OK && result != MPG123_NEED_MORE) {
			/* This is some uncommon result like EOF, handle outside
			 * the loop */
			break;
		}
	}

	if (result == MPG123_DONE) {
		/* This is just normal EOF reported from libmpg123 */
		XMMS_DBG ("Got EOF while decoding stream");
		return 0;
	} else if (result == MPG123_NEW_FORMAT) {
		/* FIXME: When we can handle format changes, modify this */
		xmms_error_set (err,
		                XMMS_ERROR_GENERIC,
		                "The output format changed, XMMS2 can't handle that");
		return -1;
	} else if (result == MPG123_ERR) {
		xmms_error_set (err,
		                XMMS_ERROR_GENERIC,
		                mpg123_strerror (data->decoder));
		return -1;
	}

	return (gint) read;
}