static void config_tag(void) { struct screen *s; struct tag *t; size_t i, n; struct conf_sec *sec, **ks, **mb; char *name, *tmp; int screenid; /* [tags] */ sec = fetch_section_first(NULL, "tags"); ks = fetch_section(sec, "tag"); n = fetch_section_count(ks); if (fetch_opt_first(sec, "1", "circular").boolean) W->flags |= WMFS_TAGCIRC; /* [mouse] */ if((mb = fetch_section(sec, "mouse"))) { config_mouse_section(&W->tmp_head.tag, mb); free(mb); } /* [tag] */ for(i = 0; i < n; ++i) { name = fetch_opt_first(ks[i], "tag", "name").str; screenid = fetch_opt_first(ks[i], "-1", "screen").num; SLIST_FOREACH(s, &W->h.screen, next) if(screenid == s->id || screenid == -1) { t = tag_new(s, name); t->statusctx = status_new_ctx(NULL, NULL); ISTRDUP(t->statusctx.status, fetch_opt_first(ks[i], "", "statusline").str); if(t->statusctx.status) status_parse(&t->statusctx); } } /* If no tag at all on a screen, add one anyway */ SLIST_FOREACH(s, &W->h.screen, next) if(TAILQ_EMPTY(&s->tags)) tag_new(s, "tag"); free(ks); }
struct tag *tag_id3_import(struct id3_tag * tag) { struct tag *ret = tag_new(); getID3Info(tag, ID3_FRAME_ARTIST, TAG_ITEM_ARTIST, ret); getID3Info(tag, ID3_FRAME_ALBUM_ARTIST, TAG_ITEM_ALBUM_ARTIST, ret); getID3Info(tag, ID3_FRAME_ALBUM_ARTIST_SORT, TAG_ITEM_ALBUM_ARTIST, ret); getID3Info(tag, ID3_FRAME_TITLE, TAG_ITEM_TITLE, ret); getID3Info(tag, ID3_FRAME_ALBUM, TAG_ITEM_ALBUM, ret); getID3Info(tag, ID3_FRAME_TRACK, TAG_ITEM_TRACK, ret); getID3Info(tag, ID3_FRAME_YEAR, TAG_ITEM_DATE, ret); getID3Info(tag, ID3_FRAME_GENRE, TAG_ITEM_GENRE, ret); getID3Info(tag, ID3_FRAME_COMPOSER, TAG_ITEM_COMPOSER, ret); getID3Info(tag, ID3_FRAME_PERFORMER, TAG_ITEM_PERFORMER, ret); getID3Info(tag, ID3_FRAME_COMMENT, TAG_ITEM_COMMENT, ret); getID3Info(tag, ID3_FRAME_DISC, TAG_ITEM_DISC, ret); tag_id3_import_musicbrainz(ret, tag); if (tag_is_empty(ret)) { tag_free(ret); ret = NULL; } return ret; }
static struct tag * oggflac_tag_dup(const char *file) { struct tag *ret = NULL; FLAC__Metadata_Iterator *it; FLAC__StreamMetadata *block; FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new(); if (!(FLAC__metadata_chain_read_ogg(chain, file))) goto out; it = FLAC__metadata_iterator_new(); FLAC__metadata_iterator_init(it, chain); ret = tag_new(); do { if (!(block = FLAC__metadata_iterator_get_block(it))) break; flac_tag_apply_metadata(ret, NULL, block); } while (FLAC__metadata_iterator_next(it)); FLAC__metadata_iterator_delete(it); if (!tag_is_defined(ret)) { tag_free(ret); ret = NULL; } out: FLAC__metadata_chain_delete(chain); return ret; }
static void xspf_text(G_GNUC_UNUSED GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, G_GNUC_UNUSED GError **error) { struct xspf_parser *parser = user_data; switch (parser->state) { case ROOT: case PLAYLIST: case TRACKLIST: break; case TRACK: if (parser->song != NULL && parser->tag != TAG_NUM_OF_ITEM_TYPES) { if (parser->song->tag == NULL) parser->song->tag = tag_new(); tag_add_item_n(parser->song->tag, parser->tag, text, text_len); } break; case LOCATION: if (parser->song == NULL) { char *uri = g_strndup(text, text_len); parser->song = song_remote_new(uri); g_free(uri); } break; } }
/** Create a new tag. * \param L The Lua VM state. * * \luastack * \lparam A table with at least a name attribute. * Optional attributes are: mwfact, ncol, nmaster and layout. * \lreturn A new tag object. */ static int luaA_tag_new(lua_State *L) { size_t len; tag_t *tag; int ncol, nmaster; const char *name, *lay; double mwfact; layout_t *layout; luaA_checktable(L, 2); if(!(name = luaA_getopt_lstring(L, 2, "name", NULL, &len))) luaL_error(L, "object tag must have a name"); mwfact = luaA_getopt_number(L, 2, "mwfact", 0.5); ncol = luaA_getopt_number(L, 2, "ncol", 1); nmaster = luaA_getopt_number(L, 2, "nmaster", 1); lay = luaA_getopt_string(L, 2, "layout", "tile"); layout = name_func_lookup(lay, LayoutList); tag = tag_new(name, len, layout, mwfact, nmaster, ncol); return luaA_tag_userdata_new(L, tag); }
static void test_syscall(void) { sc_t sc; tag_t t; char *buf; sthread_t st; t = tag_new(); buf = smalloc(t, 1024); assert(buf); sc_init(&sc); sc_mem_add(&sc, t, PROT_READ | PROT_WRITE); sc_sys_add(&sc, SYS_open); sc_sys_add(&sc, SYS_close); if (sthread_create(&st, &sc, sys_st, buf)) err(1, "sthread_create()"); if (sthread_join(st, NULL)) err(1, "sthread_join()"); if (strncmp(buf, "root", 4) != 0) errx(1, "buf is %s", buf); }
bool song_file_update_inarchive(struct song *song) { const char *suffix; const struct decoder_plugin *plugin; assert(song_is_file(song)); /* check if there's a suffix and a plugin */ suffix = uri_get_suffix(song->uri); if (suffix == NULL) return false; plugin = decoder_plugin_from_suffix(suffix, false); if (plugin == NULL) return false; if (song->tag != NULL) tag_free(song->tag); //accept every file that has music suffix //because we don't support tag reading through //input streams song->tag = tag_new(); return true; }
static int handle_end_map(void *ctx) { struct parse_data *data = (struct parse_data *) ctx; if (data->got_url > 1) { data->got_url--; return 1; } if (data->got_url == 0) return 1; /* got_url == 1, track finished, make it into a song */ data->got_url = 0; struct song *s; struct tag *t; char *u; u = g_strconcat(data->stream_url, "?client_id=", soundcloud_config.apikey, NULL); s = song_remote_new(u); g_free(u); t = tag_new(); t->time = data->duration / 1000; if (data->title != NULL) tag_add_item(t, TAG_NAME, data->title); s->tag = t; data->songs = g_slist_prepend(data->songs, s); return 1; }
struct tag *tag_id3_import(struct id3_tag * tag) { struct tag *ret = tag_new(); tag_id3_import_text(ret, tag, ID3_FRAME_ARTIST, TAG_ARTIST); tag_id3_import_text(ret, tag, ID3_FRAME_ALBUM_ARTIST, TAG_ALBUM_ARTIST); tag_id3_import_text(ret, tag, ID3_FRAME_ARTIST_SORT, TAG_ARTIST_SORT); tag_id3_import_text(ret, tag, ID3_FRAME_ALBUM_ARTIST_SORT, TAG_ALBUM_ARTIST_SORT); tag_id3_import_text(ret, tag, ID3_FRAME_TITLE, TAG_TITLE); tag_id3_import_text(ret, tag, ID3_FRAME_ALBUM, TAG_ALBUM); tag_id3_import_text(ret, tag, ID3_FRAME_TRACK, TAG_TRACK); tag_id3_import_text(ret, tag, ID3_FRAME_YEAR, TAG_DATE); tag_id3_import_text(ret, tag, ID3_FRAME_GENRE, TAG_GENRE); tag_id3_import_text(ret, tag, ID3_FRAME_COMPOSER, TAG_COMPOSER); tag_id3_import_text(ret, tag, "TPE3", TAG_PERFORMER); tag_id3_import_text(ret, tag, "TPE4", TAG_PERFORMER); tag_id3_import_comment(ret, tag, ID3_FRAME_COMMENT, TAG_COMMENT); tag_id3_import_text(ret, tag, ID3_FRAME_DISC, TAG_DISC); tag_id3_import_musicbrainz(ret, tag); tag_id3_import_ufid(ret, tag); if (tag_is_empty(ret)) { tag_free(ret); ret = NULL; } return ret; }
static struct tag * modplug_stream_tag(struct input_stream *is) { ModPlugFile *f; struct tag *ret = NULL; GByteArray *bdatas; char *title; bdatas = mod_loadfile(NULL, is); if (!bdatas) return NULL; f = ModPlug_Load(bdatas->data, bdatas->len); g_byte_array_free(bdatas, TRUE); if (f == NULL) return NULL; ret = tag_new(); ret->time = ModPlug_GetLength(f) / 1000; title = g_strdup(ModPlug_GetName(f)); if (title) tag_add_item(ret, TAG_TITLE, title); g_free(title); ModPlug_Unload(f); return ret; }
bool update_container_file(struct directory *directory, const char *name, const struct stat *st, const struct decoder_plugin *plugin) { if (plugin->container_scan == NULL) return false; db_lock(); struct directory *contdir = make_directory_if_modified(directory, name, st); if (contdir == NULL) { /* not modified */ db_unlock(); return true; } contdir->device = DEVICE_CONTAINER; db_unlock(); char *const pathname = map_directory_child_fs(directory, name); char *vtrack; unsigned int tnum = 0; while ((vtrack = plugin->container_scan(pathname, ++tnum)) != NULL) { struct song *song = song_file_new(vtrack, contdir); // shouldn't be necessary but it's there.. song->mtime = st->st_mtime; char *child_path_fs = map_directory_child_fs(contdir, vtrack); song->tag = tag_new(); decoder_plugin_scan_file(plugin, child_path_fs, &add_tag_handler, song->tag); g_free(child_path_fs); db_lock(); directory_add_song(contdir, song); db_unlock(); modified = true; g_message("added %s/%s", directory_get_path(directory), vtrack); g_free(vtrack); } g_free(pathname); if (tnum == 1) { db_lock(); delete_directory(contdir); db_unlock(); return false; } else return true; }
/** Adding a tag *\param cmd uicb_t type */ void uicb_tag_new(uicb_t cmd) { screen_get_sel(); tag_new(selscreen, (char*)cmd); return; }
void handle_tag(pTHX_ const TagTypeInfo *ptti, CtTagList *ptl, SV *name, SV *val, SV **rv) { const struct tag_tbl_ent *etbl; const char *tagstr; CtTagType tagid; CtTag *tag; assert(ptl); assert(name); if (SvROK(name)) Perl_croak(aTHX_ "Tag name must be a string, not a reference"); tagstr = SvPV_nolen(name); tagid = get_tag_id(tagstr); if (tagid == CBC_INVALID_TAG) Perl_croak(aTHX_ "Invalid tag name '%s'", tagstr); if (tagid > NUM_TAGIDS) fatal("Unknown tag type (%d) in handle_tag()", (int) tagid); etbl = &gs_TagTbl[tagid]; tag = find_tag(*ptl, tagid); if (etbl->verify) etbl->verify(aTHX_ ptti, tag, val); if (val) { TagSetRV rv; if (tag == NULL) { dTHR; dXCPT; tag = tag_new(tagid, etbl->vtbl); XCPT_TRY_START { rv = etbl->set(aTHX_ ptti, tag, val); } XCPT_TRY_END XCPT_CATCH { tag_delete(tag); XCPT_RETHROW; } insert_tag(ptl, tag); } else
struct tag * vorbis_comments_to_tag(char **comments) { struct tag *tag = tag_new(); vorbis_comments_scan(comments, &add_tag_handler, tag); if (tag_is_empty(tag)) { tag_free(tag); tag = NULL; } return tag; }
/** Create a new tag. * \param L The Lua VM state. * \luastack * \lparam A name. * \lreturn A new tag object. */ static int luaA_tag_new(lua_State *L) { size_t len; const char *name = luaL_checklstring(L, 2, &len); tag_t *tag = tag_new(globalconf.L); a_iso2utf8(name, len, &tag->name, NULL); /* to avoid error */ tag->screen = SCREEN_UNDEF; return 1; }
/* * Reads metainfo from the specified file. */ static struct tag * wavpack_tagdup(const char *fname) { WavpackContext *wpc; struct tag *tag; char error[ERRORLEN]; char *s; int size, allocated_size; wpc = WavpackOpenFileInput(fname, error, OPEN_TAGS, 0); if (wpc == NULL) { g_warning( "failed to open WavPack file \"%s\": %s\n", fname, error ); return NULL; } tag = tag_new(); tag->time = WavpackGetNumSamples(wpc); tag->time /= WavpackGetSampleRate(wpc); allocated_size = 0; s = NULL; for (unsigned i = 0; i < G_N_ELEMENTS(tagtypes); ++i) { size = WavpackGetTagItem(wpc, tagtypes[i].name, NULL, 0); if (size > 0) { ++size; /* EOS */ if (s == NULL) { s = g_malloc(size); allocated_size = size; } else if (size > allocated_size) { char *t = (char *)g_realloc(s, size); allocated_size = size; s = t; } WavpackGetTagItem(wpc, tagtypes[i].name, s, size); tag_add_item(tag, tagtypes[i].type, s); } } g_free(s); WavpackCloseFile(wpc); return tag; }
static void flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec, FLAC__uint64 t_start, FLAC__uint64 t_end) { struct decoder *decoder = data->decoder; enum decoder_command cmd; data->first_frame = t_start; while (true) { if (data->tag != NULL && !tag_is_empty(data->tag)) { cmd = decoder_tag(data->decoder, data->input_stream, data->tag); tag_free(data->tag); data->tag = tag_new(); } else cmd = decoder_get_command(decoder); if (cmd == DECODE_COMMAND_SEEK) { FLAC__uint64 seek_sample = t_start + decoder_seek_where(decoder) * data->audio_format.sample_rate; if (seek_sample >= t_start && (t_end == 0 || seek_sample <= t_end) && FLAC__stream_decoder_seek_absolute(flac_dec, seek_sample)) { data->next_frame = seek_sample; data->position = 0; decoder_command_finished(decoder); } else decoder_seek_error(decoder); } else if (cmd == DECODE_COMMAND_STOP || FLAC__stream_decoder_get_state(flac_dec) == FLAC__STREAM_DECODER_END_OF_STREAM) break; if (t_end != 0 && data->next_frame >= t_end) /* end of this sub track */ break; if (!FLAC__stream_decoder_process_single(flac_dec)) { cmd = decoder_get_command(decoder); if (cmd != DECODE_COMMAND_SEEK) break; } } if (cmd != DECODE_COMMAND_STOP) { flacPrintErroredState(FLAC__stream_decoder_get_state(flac_dec)); FLAC__stream_decoder_finish(flac_dec); } }
static struct tag * mad_decoder_stream_tag(struct input_stream *is) { struct tag *tag; int total_time; total_time = mad_decoder_total_file_time(is); if (total_time < 0) return NULL; tag = tag_new(); tag->time = total_time; return tag; }
void uicb_tag_new(Uicb cmd) { struct screen *s = W->screen; struct infobar *i; tag_new(s, (char*)cmd); s->flags |= SCREEN_TAG_UPDATE; SLIST_FOREACH(i, &s->infobars, next) infobar_elem_reinit(i); s->flags ^= SCREEN_TAG_UPDATE; }
static struct tag *mp3_tag_dup(const char *file) { struct tag *tag; int total_time; total_time = mp3_total_file_time(file); if (total_time < 0) { g_debug("Failed to get total song time from: %s", file); return NULL; } tag = tag_new(); tag->time = total_time; return tag; }
static struct tag *audiofile_tag_dup(const char *file) { struct tag *ret = NULL; int total_time = audiofile_get_duration(file); if (total_time >= 0) { ret = tag_new(); ret->time = total_time; } else { g_debug("Failed to get total song time from: %s\n", file); } return ret; }
void uicb_tag_toggle_expose(uicb_t cmd) { (void)cmd; int i, j; screen_get_sel(); for(i = 1; i <= conf.ntag[selscreen]; i++) { if(strcmp(tags[selscreen][i].name, conf.tag_expose_name) == 0) { if(clients && sel->tag) tag_set(sel->tag); tag_delete(selscreen, i); for(j = 0; j < conf.ntag[selscreen]; j++) tags[selscreen][j].request_update = True; arrange(selscreen, True); return; } } tag_new(selscreen, conf.tag_expose_name); for(i = 0; i < conf.nlayout; ++i) { if(strcmp(conf.expose_layout, conf.layout[i].type) == 0) { tags[selscreen][conf.ntag[selscreen]].layout = conf.layout[i]; } } for(i = 1; i < conf.ntag[selscreen]; ++i) { tags[selscreen][conf.ntag[selscreen]].tagad ^= TagFlag(i); } tags[selscreen][conf.ntag[selscreen]].request_update = True; arrange(selscreen, True); return; }
struct tag * tag_merge(const struct tag *base, const struct tag *add) { struct tag *ret; unsigned n; assert(base != NULL); assert(add != NULL); /* allocate new tag object */ ret = tag_new(); ret->time = add->time > 0 ? add->time : base->time; ret->num_items = base->num_items + add->num_items; ret->items = ret->num_items > 0 ? g_malloc(items_size(ret)) : NULL; g_mutex_lock(tag_pool_lock); /* copy all items from "add" */ for (unsigned i = 0; i < add->num_items; ++i) ret->items[i] = tag_pool_dup_item(add->items[i]); n = add->num_items; /* copy additional items from "base" */ for (unsigned i = 0; i < base->num_items; ++i) if (!tag_has_type(add, base->items[i]->type)) ret->items[n++] = tag_pool_dup_item(base->items[i]); g_mutex_unlock(tag_pool_lock); assert(n <= ret->num_items); if (n < ret->num_items) { /* some tags were not copied - shrink ret->items */ assert(n > 0); ret->num_items = n; ret->items = g_realloc(ret->items, items_size(ret)); } return ret; }
struct tag *tag_dup(const struct tag *tag) { struct tag *ret; if (!tag) return NULL; ret = tag_new(); ret->time = tag->time; ret->num_items = tag->num_items; ret->items = ret->num_items > 0 ? g_malloc(items_size(tag)) : NULL; g_mutex_lock(tag_pool_lock); for (unsigned i = 0; i < tag->num_items; i++) ret->items[i] = tag_pool_dup_item(tag->items[i]); g_mutex_unlock(tag_pool_lock); return ret; }
static void flac_decode_internal(struct decoder * decoder, struct input_stream *input_stream, bool is_ogg) { FLAC__StreamDecoder *flac_dec; struct flac_data data; flac_dec = flac_decoder_new(); if (flac_dec == NULL) return; flac_data_init(&data, decoder, input_stream); data.tag = tag_new(); FLAC__StreamDecoderInitStatus status = stream_init(flac_dec, &data, is_ogg); if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { flac_data_deinit(&data); FLAC__stream_decoder_delete(flac_dec); #if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7 g_warning("%s", FLAC__StreamDecoderInitStatusString[status]); #endif return; } if (!flac_decoder_initialize(&data, flac_dec, 0)) { flac_data_deinit(&data); FLAC__stream_decoder_finish(flac_dec); FLAC__stream_decoder_delete(flac_dec); return; } flac_decoder_loop(&data, flac_dec, 0, 0); flac_data_deinit(&data); FLAC__stream_decoder_finish(flac_dec); FLAC__stream_decoder_delete(flac_dec); }
static struct tag * sndfile_tag_dup(const char *path_fs) { SNDFILE *sf; SF_INFO info; struct tag *tag; const char *p; info.format = 0; sf = sf_open(path_fs, SFM_READ, &info); if (sf == NULL) return NULL; if (!audio_valid_sample_rate(info.samplerate)) { sf_close(sf); g_warning("Invalid sample rate in %s\n", path_fs); return NULL; } tag = tag_new(); tag->time = info.frames / info.samplerate; p = sf_get_string(sf, SF_STR_TITLE); if (p != NULL) tag_add_item(tag, TAG_TITLE, p); p = sf_get_string(sf, SF_STR_ARTIST); if (p != NULL) tag_add_item(tag, TAG_ARTIST, p); p = sf_get_string(sf, SF_STR_DATE); if (p != NULL) tag_add_item(tag, TAG_DATE, p); sf_close(sf); return tag; }
static void asx_text(G_GNUC_UNUSED GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, G_GNUC_UNUSED GError **error) { struct asx_parser *parser = user_data; switch (parser->state) { case ROOT: break; case ENTRY: if (parser->tag != TAG_NUM_OF_ITEM_TYPES) { if (parser->song->tag == NULL) parser->song->tag = tag_new(); tag_add_item_n(parser->song->tag, parser->tag, text, text_len); } break; } }
static void test_smalloc(void) { tag_t t = tag_new(); char *crap; sc_t sc; sthread_t st; crap = smalloc(t, 1024); strcpy(crap, "hi"); sc_init(&sc); sc_mem_add(&sc, t, PROT_READ | PROT_WRITE); if (sthread_create(&st, &sc, smalloc_st, crap)) err(1, "sthread_create()"); if (sthread_join(st, NULL)) err(1, "sthread_join()"); if (strcmp(crap, "bye") != 0) errx(1, "master crap is %s", crap); }
static void pls_parser(GKeyFile *keyfile, struct pls_playlist *playlist) { gchar *key; gchar *value; int length; GError *error = NULL; int num_entries = g_key_file_get_integer(keyfile, "playlist", "NumberOfEntries", &error); if (error) { g_debug("Invalid PLS file: '%s'", error->message); g_error_free(error); error = NULL; /* Hack to work around shoutcast failure to comform to spec */ num_entries = g_key_file_get_integer(keyfile, "playlist", "numberofentries", &error); if (error) { g_error_free(error); error = NULL; } } while (num_entries > 0) { struct song *song; key = g_strdup_printf("File%i", num_entries); value = g_key_file_get_string(keyfile, "playlist", key, &error); if(error) { g_debug("Invalid PLS entry %s: '%s'",key, error->message); g_error_free(error); g_free(key); return; } g_free(key); song = song_remote_new(value); g_free(value); key = g_strdup_printf("Title%i", num_entries); value = g_key_file_get_string(keyfile, "playlist", key, &error); g_free(key); if(error == NULL && value){ if (song->tag == NULL) song->tag = tag_new(); tag_add_item(song->tag,TAG_TITLE, value); } /* Ignore errors? Most likely value not present */ if(error) g_error_free(error); error = NULL; g_free(value); key = g_strdup_printf("Length%i", num_entries); length = g_key_file_get_integer(keyfile, "playlist", key, &error); g_free(key); if(error == NULL && length > 0){ if (song->tag == NULL) song->tag = tag_new(); song->tag->time = length; } /* Ignore errors? Most likely value not present */ if(error) g_error_free(error); error = NULL; playlist->songs = g_slist_prepend(playlist->songs, song); num_entries--; } }
static void flac_decode_internal(struct decoder * decoder, struct input_stream *input_stream, bool is_ogg) { FLAC__StreamDecoder *flac_dec; struct flac_data data; const char *err = NULL; flac_dec = flac_decoder_new(); if (flac_dec == NULL) return; flac_data_init(&data, decoder, input_stream); data.tag = tag_new(); if (is_ogg) { #if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7 FLAC__StreamDecoderInitStatus status = FLAC__stream_decoder_init_ogg_stream(flac_dec, flac_read_cb, flac_seek_cb, flac_tell_cb, flac_length_cb, flac_eof_cb, flac_write_cb, flacMetadata, flac_error_cb, (void *)&data); if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { err = "doing Ogg init()"; goto fail; } #else goto fail; #endif } else { FLAC__StreamDecoderInitStatus status = FLAC__stream_decoder_init_stream(flac_dec, flac_read_cb, flac_seek_cb, flac_tell_cb, flac_length_cb, flac_eof_cb, flac_write_cb, flacMetadata, flac_error_cb, (void *)&data); if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { err = "doing init()"; goto fail; } } if (!flac_decoder_initialize(&data, flac_dec, 0)) { flac_data_deinit(&data); FLAC__stream_decoder_delete(flac_dec); return; } flac_decoder_loop(&data, flac_dec, 0, 0); fail: flac_data_deinit(&data); FLAC__stream_decoder_delete(flac_dec); if (err) g_warning("%s\n", err); }