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 read_data (xmms_magic_checker_t *c, guint needed) { xmms_error_t e; if (needed > c->alloc) { c->alloc = needed; c->buf = g_realloc (c->buf, c->alloc); } xmms_error_reset (&e); return xmms_xform_peek (c->xform, c->buf, needed, &e); }
static gchar * get_root_node_name (xmms_xform_t *xform) { guint8 buf[BUFFER_SIZE]; gint read, i, start, len; gchar *ret = NULL; xmms_error_t error; xmms_error_reset (&error); read = xmms_xform_peek (xform, buf, BUFFER_SIZE, &error); if (read < 1) { xmms_log_error ("Couldn't get data: %s", xmms_error_message_get (&error)); return NULL; } start = -1; len = 0; for (i = 0; i < read; i++) { if (start < 0) { if (buf[i] == '<' && buf[i + 1] != '!' && buf[i + 1] != '?') { start = i; } } else { if (isalpha (buf[i])) { len++; } else if (len) { ret = g_malloc (len + 1); memcpy (ret, buf + start + 1, len); ret[len] = '\0'; break; } } } return ret; }
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; }
static gboolean xmms_wave_init (xmms_xform_t *xform) { xmms_wave_data_t *data; xmms_error_t error; xmms_sample_format_t sample_fmt; xmms_wave_format_t fmt; guint8 buf[1024]; gint read; g_return_val_if_fail (xform, FALSE); data = g_new0 (xmms_wave_data_t, 1); g_return_val_if_fail (data, FALSE); xmms_xform_private_data_set (xform, data); read = xmms_xform_peek (xform, (gchar *) buf, sizeof (buf), &error); if (read < WAVE_HEADER_MIN_SIZE) { xmms_log_error ("Could not read wave header"); return FALSE; } fmt = read_wave_header (data, buf, read); switch (fmt) { case WAVE_FORMAT_UNDEFINED: xmms_log_error ("Not a valid Wave stream"); return FALSE; case WAVE_FORMAT_MP3: xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "audio/mpeg", XMMS_STREAM_TYPE_END); break; case WAVE_FORMAT_PCM: xmms_wave_get_media_info (xform); if (read < data->header_size) { xmms_log_info ("Wave header too big?"); return FALSE; } /* skip over the header */ xmms_xform_read (xform, (gchar *) buf, data->header_size, &error); sample_fmt = (data->bits_per_sample == 8 ? XMMS_SAMPLE_FORMAT_U8 : XMMS_SAMPLE_FORMAT_S16); 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->samplerate, XMMS_STREAM_TYPE_END); } return TRUE; }