static xmmsv_t * xmms_playback_client_volume_get (xmms_output_t *output, xmms_error_t *error) { xmmsv_t *ret; xmms_volume_map_t map; if (!output->plugin) { xmms_error_set (error, XMMS_ERROR_GENERIC, "couldn't get volume, output plugin not loaded"); return NULL; } if (!xmms_output_plugin_method_volume_get_available (output->plugin)) { xmms_error_set (error, XMMS_ERROR_GENERIC, "operation not supported"); return NULL; } xmms_error_set (error, XMMS_ERROR_GENERIC, "couldn't get volume"); xmms_volume_map_init (&map); /* ask the plugin how much channels it would like to set */ if (!xmms_output_plugin_method_volume_get (output->plugin, output, NULL, NULL, &map.num_channels)) { return NULL; } /* check for sane values */ g_return_val_if_fail (map.num_channels > 0, NULL); g_return_val_if_fail (map.num_channels <= VOLUME_MAX_CHANNELS, NULL); map.names = g_new (const gchar *, map.num_channels); map.values = g_new (guint, map.num_channels); map.status = xmms_output_plugin_method_volume_get (output->plugin, output, map.names, map.values, &map.num_channels); if (!map.status || !map.num_channels) { return NULL; /* error is set (-> no leak) */ } ret = xmms_volume_map_to_dict (&map); /* success! */ xmms_error_reset (error); return ret; }
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 mpc_bool_t xmms_mpc_callback_seek (READER_OBJ *p_obj, mpc_int32_t offset) { xmms_xform_t *xform = READER_DATA (p_obj); xmms_error_t err; gint ret; g_return_val_if_fail (xform, -1); xmms_error_reset (&err); ret = xmms_xform_seek (xform, (gint64) offset, XMMS_XFORM_SEEK_SET, &err); return (ret == -1) ? FALSE : TRUE; }
static FLAC__StreamDecoderSeekStatus flac_callback_seek (const FLAC__StreamDecoder *flacdecoder, FLAC__uint64 offset, void *client_data) { xmms_error_t err; xmms_xform_t *xform = (xmms_xform_t *) client_data; gint retval; xmms_error_reset (&err); retval = xmms_xform_seek (xform, (gint64) offset, XMMS_XFORM_SEEK_SET, &err); return (retval == -1) ? FLAC__STREAM_DECODER_SEEK_STATUS_ERROR : FLAC__STREAM_DECODER_SEEK_STATUS_OK; }
static FLAC__StreamDecoderTellStatus flac_callback_tell (const FLAC__StreamDecoder *flacdecoder, FLAC__uint64 *offset, void *client_data) { xmms_error_t err; xmms_xform_t *xform = (xmms_xform_t *) client_data; g_return_val_if_fail (xform, FLAC__STREAM_DECODER_TELL_STATUS_ERROR); xmms_error_reset (&err); *offset = xmms_xform_seek (xform, 0, XMMS_XFORM_SEEK_CUR, &err); return FLAC__STREAM_DECODER_TELL_STATUS_OK; }
static gboolean xmms_m3u_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error) { gchar line[XMMS_XFORM_MAX_LINE_SIZE]; gchar *tmp; gchar *title = NULL; const gchar *d; g_return_val_if_fail (xform, FALSE); xmms_error_reset (error); if (!xmms_xform_read_line (xform, line, error)) { XMMS_DBG ("Error reading m3u-file"); return FALSE; } d = xmms_xform_get_url (xform); do { if (line[0] == '#') { if (!title) { title = get_extinf (line); } } else { tmp = xmms_build_playlist_url (d, line); xmms_xform_browse_add_symlink (xform, NULL, tmp); if (title) { xmms_xform_browse_add_entry_property_str (xform, "title", title); g_free (title); title = NULL; } g_free (tmp); } } while (xmms_xform_read_line (xform, line, error)); g_free (title); return TRUE; }
int CSourceAdapter::Read (void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead) { int ret = 0; xmms_error_t error; xmms_error_reset (&error); ret = xmms_xform_read (xform, (gchar *)pBuffer, nBytesToRead, &error); *pBytesRead = ret; return (error.code == XMMS_ERROR_NONE) ? ERROR_SUCCESS : ERROR_IO_READ; }
/** * Queries the medialib and returns an xmmsv_t with the info requested * * @param coll The collection to find * @param fetch Specifies what to fetch * @return An xmmsv_t with the structure requested in fetch */ xmmsv_t * xmms_medialib_query (xmms_medialib_session_t *session, xmmsv_t *coll, xmmsv_t *fetch, xmms_error_t *err) { s4_sourcepref_t *sourcepref; s4_resultset_t *set; xmmsv_t *ret; xmms_fetch_info_t *info; xmms_fetch_spec_t *spec; xmms_error_reset (err); sourcepref = xmms_medialib_session_get_source_preferences (session); info = xmms_fetch_info_new (sourcepref); spec = xmms_fetch_spec_new (fetch, info, sourcepref, err); s4_sourcepref_unref (sourcepref); if (spec == NULL) { xmms_fetch_spec_free (spec); xmms_fetch_info_free (info); return NULL; } set = xmms_medialib_query_recurs (session, coll, info); ret = xmms_medialib_query_to_xmmsv (set, spec); s4_resultset_free (set); xmms_fetch_spec_free (spec); xmms_fetch_info_free (info); if (ret == NULL) { if (err) { xmms_error_set (err, XMMS_ERROR_NOENT, "Failed to retrieve query " "result. This is probably a bug in xmms2d."); } return NULL; } xmms_medialib_session_track_garbage (session, ret); return ret; }
int64_t xmms_asf_seek_callback (void *opaque, int64_t position) { xmms_xform_t *xform; xmms_asf_data_t *data; xmms_error_t error; gint ret; g_return_val_if_fail (opaque, -1); xform = opaque; xmms_error_reset (&error); data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); ret = xmms_xform_seek (xform, position, XMMS_XFORM_SEEK_SET, &error); return ret; }
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; }
xmms_medialib_entry_t xmms_mock_entry (xmms_medialib_t *medialib, gint tracknr, const gchar *artist, const gchar *album, const gchar *title) { xmms_medialib_session_t *session; xmms_medialib_entry_t entry; xmms_error_t err; gchar *path; xmms_error_reset (&err); path = g_strconcat (artist, album, title, NULL); session = xmms_medialib_session_begin (medialib); entry = xmms_medialib_entry_new (session, path, &err); xmms_medialib_entry_property_set_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_TRACKNR, tracknr); xmms_medialib_entry_property_set_str (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST, artist); xmms_medialib_entry_property_set_str (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_ALBUM, album); xmms_medialib_entry_property_set_str (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE, title); xmms_medialib_entry_property_set_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS, XMMS_MEDIALIB_ENTRY_STATUS_OK); xmms_medialib_session_commit (session); g_free (path); return entry; }
gint xmms_output_read (xmms_output_t *output, char *buffer, gint len) { gint ret; xmms_error_t err; xmms_error_reset (&err); g_return_val_if_fail (output, -1); g_return_val_if_fail (buffer, -1); g_mutex_lock (output->filler_mutex); xmms_ringbuf_wait_used (output->filler_buffer, len, output->filler_mutex); ret = xmms_ringbuf_read (output->filler_buffer, buffer, len); if (ret == 0 && xmms_ringbuf_iseos (output->filler_buffer)) { xmms_output_status_set (output, XMMS_PLAYBACK_STATUS_STOP); g_mutex_unlock (output->filler_mutex); return -1; } g_mutex_unlock (output->filler_mutex); update_playtime (output, ret); if (ret < len) { XMMS_DBG ("Underrun %d of %d (%d)", ret, len, xmms_sample_frame_size_get (output->format)); if ((ret % xmms_sample_frame_size_get (output->format)) != 0) { xmms_log_error ("***********************************"); xmms_log_error ("* Read non-multiple of sample size,"); xmms_log_error ("* you probably hear noise now :)"); xmms_log_error ("***********************************"); } output->buffer_underruns++; } output->bytes_written += ret; return ret; }
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 int opus_callback_seek (void *datasource, opus_int64 offset, int whence) { xmms_xform_t *xform = datasource; xmms_error_t err; gint ret; g_return_val_if_fail (xform, -1); xmms_error_reset (&err); if (whence == SEEK_CUR) { whence = XMMS_XFORM_SEEK_CUR; } else if (whence == SEEK_SET) { whence = XMMS_XFORM_SEEK_SET; } else if (whence == SEEK_END) { whence = XMMS_XFORM_SEEK_END; } ret = xmms_xform_seek (xform, (gint64) offset, whence, &err); return (ret == -1) ? -1 : 0; }
static gboolean xmms_daap_init (xmms_xform_t *xform) { gint dbid; GSList *dbid_list = NULL; xmms_daap_data_t *data; xmms_daap_login_data_t *login_data; xmms_error_t err; const gchar *url; const gchar *metakey; gchar *command, *hash; guint filesize; g_return_val_if_fail (xform, FALSE); url = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_URL); g_return_val_if_fail (url, FALSE); data = g_new0 (xmms_daap_data_t, 1); xmms_error_reset (&err); if (!get_data_from_url (url, &(data->host), &(data->port), &command, &err)) { goto init_error; } hash = g_strdup_printf ("%s:%u", data->host, data->port); login_data = g_hash_table_lookup (login_sessions, hash); if (!login_data) { XMMS_DBG ("creating login data for %s", hash); login_data = g_new0 (xmms_daap_login_data_t, 1); login_data->request_id = 1; login_data->logged_in = TRUE; login_data->session_id = daap_command_login (data->host, data->port, login_data->request_id, &err); if (xmms_error_iserror (&err)) { g_free (login_data); goto init_error; } g_hash_table_insert (login_sessions, hash, login_data); } login_data->revision_id = daap_command_update (data->host, data->port, login_data->session_id, login_data->request_id); dbid_list = daap_command_db_list (data->host, data->port, login_data->session_id, login_data->revision_id, login_data->request_id); if (!dbid_list) { goto init_error; } /* XXX: see XXX in the browse function above */ dbid = ((cc_item_record_t *) dbid_list->data)->dbid; /* want to request a stream, but don't read the data yet */ data->conn = daap_command_init_stream (data->host, data->port, login_data->session_id, login_data->revision_id, login_data->request_id, dbid, command, &filesize); if (! data->conn) { goto init_error; } login_data->request_id++; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE; xmms_xform_metadata_set_int (xform, metakey, filesize); xmms_xform_private_data_set (xform, data); xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "application/octet-stream", XMMS_STREAM_TYPE_END); g_slist_foreach (dbid_list, (GFunc) cc_item_record_free, NULL); g_slist_free (dbid_list); g_free (command); return TRUE; init_error: if (data) { if (data->host) g_free (data->host); g_free (data); } return FALSE; }
static gboolean xmms_faad_init (xmms_xform_t *xform) { xmms_faad_data_t *data; xmms_error_t error; NeAACDecConfigurationPtr config; gint bytes_read; gulong samplerate; guchar channels; g_return_val_if_fail (xform, FALSE); data = g_new0 (xmms_faad_data_t, 1); data->outbuf = g_string_new (NULL); data->buffer_size = FAAD_BUFFER_SIZE; xmms_xform_private_data_set (xform, data); data->decoder = NeAACDecOpen (); config = NeAACDecGetCurrentConfiguration (data->decoder); config->defObjectType = LC; config->defSampleRate = 44100; config->outputFormat = FAAD_FMT_16BIT; config->downMatrix = 0; config->dontUpSampleImplicitSBR = 0; NeAACDecSetConfiguration (data->decoder, config); switch (config->outputFormat) { case FAAD_FMT_16BIT: data->sampleformat = XMMS_SAMPLE_FORMAT_S16; break; case FAAD_FMT_24BIT: /* we don't have 24-bit format to use in xmms2 */ data->sampleformat = XMMS_SAMPLE_FORMAT_S32; break; case FAAD_FMT_32BIT: data->sampleformat = XMMS_SAMPLE_FORMAT_S32; break; case FAAD_FMT_FLOAT: data->sampleformat = XMMS_SAMPLE_FORMAT_FLOAT; break; case FAAD_FMT_DOUBLE: data->sampleformat = XMMS_SAMPLE_FORMAT_DOUBLE; break; } while (data->buffer_length < 8) { xmms_error_reset (&error); bytes_read = xmms_xform_read (xform, (gchar *) data->buffer + data->buffer_length, data->buffer_size - data->buffer_length, &error); data->buffer_length += bytes_read; if (bytes_read < 0) { xmms_log_error ("Error while trying to read data on init"); goto err; } else if (bytes_read == 0) { XMMS_DBG ("Not enough bytes to check the AAC header"); goto err; } } /* which type of file are we dealing with? */ data->filetype = FAAD_TYPE_UNKNOWN; if (xmms_xform_auxdata_has_val (xform, "decoder_config")) { data->filetype = FAAD_TYPE_MP4; } else if (!strncmp ((char *) data->buffer, "ADIF", 4)) { data->filetype = FAAD_TYPE_ADIF; } else { int i; /* ADTS mpeg file can be a stream and start in the middle of a * frame so we need to have extra loop check here */ for (i=0; i<data->buffer_length-1; i++) { if (data->buffer[i] == 0xff && (data->buffer[i+1]&0xf6) == 0xf0) { data->filetype = FAAD_TYPE_ADTS; g_memmove (data->buffer, data->buffer+i, data->buffer_length-i); data->buffer_length -= i; break; } } } if (data->filetype == FAAD_TYPE_ADTS || data->filetype == FAAD_TYPE_ADIF) { bytes_read = NeAACDecInit (data->decoder, data->buffer, data->buffer_length, &samplerate, &channels); } else if (data->filetype == FAAD_TYPE_MP4) { const guchar *tmpbuf; gsize tmpbuflen; guchar *copy; if (!xmms_xform_auxdata_get_bin (xform, "decoder_config", &tmpbuf, &tmpbuflen)) { XMMS_DBG ("AAC decoder config data found but it's wrong type! (something broken?)"); goto err; } copy = g_memdup (tmpbuf, tmpbuflen); bytes_read = NeAACDecInit2 (data->decoder, copy, tmpbuflen, &samplerate, &channels); g_free (copy); } if (bytes_read < 0) { XMMS_DBG ("Error initializing decoder library."); goto err; } /* Get mediainfo and skip the possible header */ xmms_faad_get_mediainfo (xform); g_memmove (data->buffer, data->buffer + bytes_read, data->buffer_length - bytes_read); data->buffer_length -= bytes_read; data->samplerate = samplerate; data->channels = channels; /* Because for HE AAC files some versions of libfaad return the wrong * samplerate in init, we have to do one read and let it decide the * real parameters. After changing sample parameters and format is * supported, this hack should be removed and handled in read instead. */ { gchar tmpbuf[1024]; xmms_error_reset (&error); bytes_read = xmms_faad_read (xform, tmpbuf, 1024, &error); if (bytes_read <= 0) { XMMS_DBG ("First read from faad decoder failed!"); return FALSE; } g_string_prepend_len (data->outbuf, tmpbuf, bytes_read); } xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "audio/pcm", XMMS_STREAM_TYPE_FMT_FORMAT, data->sampleformat, XMMS_STREAM_TYPE_FMT_CHANNELS, data->channels, XMMS_STREAM_TYPE_FMT_SAMPLERATE, data->samplerate, XMMS_STREAM_TYPE_END); XMMS_DBG ("AAC decoder inited successfully!"); return TRUE; err: g_string_free (data->outbuf, TRUE); g_free (data); return FALSE; }
static gboolean xmms_pls_browse (xmms_xform_t *xform, const char *url, xmms_error_t *error) { gchar buffer[XMMS_XFORM_MAX_LINE_SIZE]; gint num = -1; gchar **val; const gchar *plspath; xmms_pls_entry_t entry; g_return_val_if_fail (xform, FALSE); xmms_error_reset (error); plspath = xmms_xform_get_url (xform); if (!xmms_xform_read_line (xform, buffer, error)) { XMMS_DBG ("Error reading pls-file"); return FALSE; } /* for completeness' sake, check for the pls header here again, too * (it's already done in the magic check) */ if (g_ascii_strncasecmp (buffer, "[playlist]", 10) != 0) { XMMS_DBG ("Not a PLS file"); return FALSE; } memset (&entry, 0, sizeof (entry)); entry.num=-1; while (xmms_xform_read_line (xform, buffer, error)) { gchar *np, *ep; if (g_ascii_strncasecmp (buffer, "File", 4) == 0) { np = &buffer[4]; val = &entry.file; } else if (g_ascii_strncasecmp (buffer, "Title", 5) == 0) { np = &buffer[5]; val = &entry.title; } else { continue; } num = strtol (np, &ep, 10); if (!ep || *ep != '=') { XMMS_DBG ("Broken line '%s', skipping", buffer); continue; } ep++; /* Skip the '=' */ /* Remove leading and trailing whitespace from the value. */ g_strstrip (ep); /* Ignore empty values. */ if (!*ep) { XMMS_DBG ("Ignoring empty value in line '%s'", buffer); continue; } if (entry.num != num && entry.num != -1) { xmms_pls_add_entry (xform, plspath, &entry); } *val = g_strdup (ep); entry.num = num; } xmms_pls_add_entry (xform, plspath, &entry); return TRUE; }
static void * xmms_output_filler (void *arg) { xmms_output_t *output = (xmms_output_t *)arg; xmms_xform_t *chain = NULL; gboolean last_was_kill = FALSE; char buf[4096]; xmms_error_t err; gint ret; xmms_error_reset (&err); g_mutex_lock (output->filler_mutex); while (output->filler_state != FILLER_QUIT) { if (output->filler_state == FILLER_STOP) { if (chain) { xmms_object_unref (chain); chain = NULL; } xmms_ringbuf_set_eos (output->filler_buffer, TRUE); g_cond_wait (output->filler_state_cond, output->filler_mutex); last_was_kill = FALSE; continue; } if (output->filler_state == FILLER_KILL) { if (chain) { xmms_object_unref (chain); chain = NULL; output->filler_state = FILLER_RUN; last_was_kill = TRUE; } else { output->filler_state = FILLER_STOP; } continue; } if (output->filler_state == FILLER_SEEK) { if (!chain) { XMMS_DBG ("Seek without chain, ignoring.."); output->filler_state = FILLER_STOP; continue; } ret = xmms_xform_this_seek (chain, output->filler_seek, XMMS_XFORM_SEEK_SET, &err); if (ret == -1) { XMMS_DBG ("Seeking failed: %s", xmms_error_message_get (&err)); } else { XMMS_DBG ("Seek ok! %d", ret); output->filler_skip = output->filler_seek - ret; if (output->filler_skip < 0) { XMMS_DBG ("Seeked %d samples too far! Updating position...", -output->filler_skip); output->filler_skip = 0; output->filler_seek = ret; } xmms_ringbuf_clear (output->filler_buffer); xmms_ringbuf_hotspot_set (output->filler_buffer, seek_done, NULL, output); } output->filler_state = FILLER_RUN; } if (!chain) { xmms_medialib_entry_t entry; xmms_output_song_changed_arg_t *arg; xmms_medialib_session_t *session; g_mutex_unlock (output->filler_mutex); entry = xmms_playlist_current_entry (output->playlist); if (!entry) { XMMS_DBG ("No entry from playlist!"); output->filler_state = FILLER_STOP; g_mutex_lock (output->filler_mutex); continue; } chain = xmms_xform_chain_setup (entry, output->format_list, FALSE); if (!chain) { session = xmms_medialib_begin_write (); if (xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS) == XMMS_MEDIALIB_ENTRY_STATUS_NEW) { xmms_medialib_end (session); xmms_medialib_entry_remove (entry); } else { xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE); xmms_medialib_entry_send_update (entry); xmms_medialib_end (session); } if (!xmms_playlist_advance (output->playlist)) { XMMS_DBG ("End of playlist"); output->filler_state = FILLER_STOP; } g_mutex_lock (output->filler_mutex); continue; } arg = g_new0 (xmms_output_song_changed_arg_t, 1); arg->output = output; arg->chain = chain; arg->flush = last_was_kill; xmms_object_ref (chain); last_was_kill = FALSE; g_mutex_lock (output->filler_mutex); xmms_ringbuf_hotspot_set (output->filler_buffer, song_changed, song_changed_arg_free, arg); } xmms_ringbuf_wait_free (output->filler_buffer, sizeof (buf), output->filler_mutex); if (output->filler_state != FILLER_RUN) { XMMS_DBG ("State changed while waiting..."); continue; } g_mutex_unlock (output->filler_mutex); ret = xmms_xform_this_read (chain, buf, sizeof (buf), &err); g_mutex_lock (output->filler_mutex); if (ret > 0) { gint skip = MIN (ret, output->toskip); output->toskip -= skip; if (ret > skip) { xmms_ringbuf_write_wait (output->filler_buffer, buf + skip, ret - skip, output->filler_mutex); } } else { if (ret == -1) { /* print error */ xmms_error_reset (&err); } xmms_object_unref (chain); chain = NULL; if (!xmms_playlist_advance (output->playlist)) { XMMS_DBG ("End of playlist"); output->filler_state = FILLER_STOP; } } } g_mutex_unlock (output->filler_mutex); return NULL; }
/** * TODO: Should check for '/' in the key, and set source if found. */ static void populate_medialib (xmms_medialib_t *medialib, xmmsv_t *content) { xmms_medialib_session_t *session; xmms_medialib_entry_t entry = 0; xmmsv_list_iter_t *lit; session = xmms_medialib_session_begin (medialib); xmmsv_get_list_iter (content, &lit); while (xmmsv_list_iter_valid (lit)) { xmmsv_dict_iter_t *dit; xmms_error_t err; xmmsv_t *dict; xmms_error_reset (&err); xmmsv_list_iter_entry (lit, &dict); if (xmmsv_dict_has_key (dict, "url")) { const gchar *url; xmmsv_dict_entry_get_string (dict, "url", &url); entry = xmms_medialib_entry_new (session, url, &err); } else { gchar *url; url = g_strdup_printf ("file://%d.mp3", entry + 1); entry = xmms_medialib_entry_new (session, url, &err); g_free (url); } xmmsv_get_dict_iter (dict, &dit); while (xmmsv_dict_iter_valid (dit)) { const gchar *key, *source; gchar **parts; xmmsv_t *container; xmmsv_dict_iter_pair (dit, &key, &container); parts = g_strsplit (key, "/", 2); key = (parts[1] != NULL) ? parts[1] : key; source = (parts[1] != NULL) ? parts[0] : NULL; if (xmmsv_is_type (container, XMMSV_TYPE_STRING)) { const gchar *value; xmmsv_get_string (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_str_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_str (session, entry, key, value); } } else { gint32 value; xmmsv_get_int (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_int_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_int (session, entry, key, value); } } g_strfreev (parts); xmmsv_dict_iter_next (dit); } xmmsv_list_iter_next (lit); } xmms_medialib_session_commit (session); }
static gboolean xmms_cue_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error) { gchar line[XMMS_XFORM_MAX_LINE_SIZE]; cue_track track; gchar *p; g_return_val_if_fail (xform, FALSE); memset (&track, 0, sizeof (cue_track)); if (!xmms_xform_read_line (xform, line, error)) { xmms_error_set (error, XMMS_ERROR_INVAL, "error reading cue-file!"); return FALSE; } do { p = skip_white_space (line); if (g_ascii_strncasecmp (p, "FILE", 4) == 0) { if (track.file[0]) { add_track (xform, &track); } p = skip_to_char (p, '"'); p ++; save_to_char (p, '"', track.file); } else if (g_ascii_strncasecmp (p, "TRACK", 5) == 0) { p = skip_to_char (p, ' '); p = skip_white_space (p); p = skip_to_char (p, ' '); p = skip_white_space (p); if (g_ascii_strncasecmp (p, "AUDIO", 5) == 0) { cue_track *t = g_new0 (cue_track, 1); track.tracks = g_list_prepend (track.tracks, t); } } else if (g_ascii_strncasecmp (p, "INDEX", 5) == 0) { cue_track *t = g_list_nth_data (track.tracks, 0); if (!t) { continue; } p = skip_to_char (p, ' '); p = skip_white_space (p); p = skip_to_char (p, ' '); p = skip_white_space (p); add_index (t, p); } else if (g_ascii_strncasecmp (p, "TITLE", 5) == 0) { cue_track *t = g_list_nth_data (track.tracks, 0); p = skip_to_char (p, '"'); p ++; if (!t) { save_to_char (p, '"', track.album); } else { save_to_char (p, '"', t->title); } } else if (g_ascii_strncasecmp (p, "PERFORMER", 9) == 0) { cue_track *t = g_list_nth_data (track.tracks, 0); p = skip_to_char (p, '"'); p ++; if (!t) { save_to_char (p, '"', track.artist); } else { save_to_char (p, '"', t->artist); } } } while (xmms_xform_read_line (xform, line, error)); if (track.file[0]) { add_track (xform, &track); } xmms_error_reset (error); return TRUE; }