📄 meta_decoder.cpp
字号:
#endif /* HAVE_MOD */#ifdef HAVE_TAGLIB switch (meta->format_major) {#ifdef HAVE_FLAC case FORMAT_FLAC: meta_free_flac(meta); break;#endif /* HAVE_FLAC */#ifdef HAVE_OGG_VORBIS case FORMAT_VORBIS: meta_free_oggv(meta); break;#endif /* HAVE_OGG_VORBIS */#ifdef HAVE_MPEG case FORMAT_MAD: meta_free_mpeg(meta); break;#endif /* HAVE_MPEG */#ifdef HAVE_MPC case FORMAT_MPC: meta_free_mpc(meta); break;#endif /* HAVE_MPC */ }#endif /* HAVE_TAGLIB */#ifdef HAVE_MOD mi = meta->mod_root; if(mi != NULL) { if(mi->title != NULL) { free(mi->title); } free(mi); }#endif /* HAVE_MOD */ free(meta);}#ifdef HAVE_TAGLIB/* fuction to work around buggy TagLib::ID3v2::RelativeVolumeFrame */voidread_rva2(char * raw_data, unsigned int length, char * id_str, float * voladj) { int i; char id[MAXLEN]; char str[MAXLEN]; int id_len; char * data; id[0] = '\0'; str[0] = '\0'; /* parse text string */ strncpy(id, raw_data, MAXLEN-1); id_len = strlen(id); /* skipping zero bytes */ for (i = id_len; raw_data[i] == '\0'; i++) { /* TagLib puts extra zero bytes after the end of the text, but do not count them into the frame size. */ if (i != id_len) { length++; } } length -= i; data = raw_data + i; /* now parse the binary data */ while (length >= 4) { unsigned int peak_bytes; peak_bytes = (data[3] + 7) / 8; if (4 + peak_bytes > length) break; if (data[0] == 0x01 /* MasterVolume */) { signed int voladj_fixed; double voladj_float; voladj_fixed = (data[1] << 8) | (data[2] << 0); voladj_fixed |= -(voladj_fixed & 0x8000); voladj_float = (double) voladj_fixed / 512; snprintf(id_str, MAXLEN-1, "%s", id); *voladj = voladj_float; return; } data += 4 + peak_bytes; length -= 4 + peak_bytes; } id_str[0] = '\0'; *voladj = 0.0f;}intmeta_get_rva_from_id3v2(TagLib::ID3v2::Tag * id3v2_tag, float * fval) { if (id3v2_tag == NULL) return 0; if (id3v2_tag->isEmpty()) return 0; TagLib::ID3v2::FrameList l = id3v2_tag->frameList(); std::list<TagLib::ID3v2::Frame*>::iterator i; for (i = l.begin(); i != l.end(); ++i) { TagLib::ID3v2::Frame * frame = *i; char frameID[5]; for(int j = 0; j < 4; j++) { frameID[j] = frame->frameID().data()[j]; } frameID[4] = '\0'; if (strcmp(frameID, "RVA2") == 0) { char id_str[MAXLEN]; read_rva2(frame->render().data() + 10, frame->size(), id_str, fval); } } return 0;}intmeta_get_rva_from_oxc(TagLib::Ogg::XiphComment * oxc, float * fval) { char replaygain_label[MAXLEN]; if (oxc == NULL) return 0; if (oxc->isEmpty()) return 0; switch (options.replaygain_tag_to_use) { case 0: strcpy(replaygain_label, "Replaygain_track_gain:"); break; case 1: strcpy(replaygain_label, "Replaygain_album_gain:"); break; } TagLib::Ogg::FieldListMap m = oxc->fieldListMap(); for (TagLib::Ogg::FieldListMap::Iterator i = m.begin(); i != m.end(); ++i) { for (TagLib::StringList::Iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) { char key[MAXLEN]; char val[MAXLEN]; char c; int k; for (k = 0; ((c = (*i).first.toCString(true)[k]) != '\0') && (k < MAXLEN-1); k++) { key[k] = (k == 0) ? toupper(c) : tolower(c); } key[k++] = ':'; key[k] = '\0'; for (k = 0; ((c = (*j).toCString(true)[k]) != '\0') && (k < MAXLEN-1); k++) { val[k] = c; } val[k] = '\0'; if (strcmp(key, replaygain_label) == 0) { *fval = convf(val); return 1; } } } return 0;}#endif /* HAVE_TAGLIB *//* ret: 1 if found, 0 if no RVA data *//* can be called with fval == NULL only to see if RVA is available */intmeta_get_rva(metadata * meta, float * fval) { int ret = 0; if (meta == NULL) { fprintf(stderr, "meta_get_rva(): assertion meta != NULL failed\n"); return 0; }#ifdef HAVE_TAGLIB TagLib::FLAC::File * flac_file; TagLib::Ogg::Vorbis::File * oggv_file; TagLib::MPEG::File * mpeg_file; switch (meta->format_major) {#ifdef HAVE_FLAC case FORMAT_FLAC: flac_file = reinterpret_cast<TagLib::FLAC::File *>(meta->taglib_file); ret = meta_get_rva_from_id3v2(flac_file->ID3v2Tag(), fval); if (!ret) { ret = meta_get_rva_from_oxc(flac_file->xiphComment(), fval); } break;#endif /* HAVE_FLAC */#ifdef HAVE_OGG_VORBIS case FORMAT_VORBIS: oggv_file = reinterpret_cast<TagLib::Ogg::Vorbis::File *>(meta->taglib_file); ret = meta_get_rva_from_oxc(oggv_file->tag(), fval); break;#endif /* HAVE_OGG_VORBIS */#ifdef HAVE_MPEG case FORMAT_MAD: mpeg_file = reinterpret_cast<TagLib::MPEG::File *>(meta->taglib_file); ret = meta_get_rva_from_id3v2(mpeg_file->ID3v2Tag(), fval); break;#endif /* HAVE_MPEG */ }#endif /* HAVE_TAGLIB */ return ret;}#ifdef HAVE_TAGLIBintmeta_lookup(char * str, int which, TagLib::Tag * tag) { switch (which) { case META_TITLE: if (tag->title().toCString(true)[0] != '\0') { strncpy(str, tag->title().toCString(true), MAXLEN-1); return cut_trailing_whitespace(str); } break; case META_RECORD: if (tag->album().toCString(true)[0] != '\0') { strncpy(str, tag->album().toCString(true), MAXLEN-1); return cut_trailing_whitespace(str); } break; case META_ARTIST: if (tag->artist().toCString(true)[0] != '\0') { strncpy(str, tag->artist().toCString(true), MAXLEN-1); return cut_trailing_whitespace(str); } break; case META_YEAR: if (tag->year() != 0) { snprintf(str, MAXLEN-1, "%d", tag->year()); return cut_trailing_whitespace(str); } break; case META_COMMENT: if (tag->comment().toCString(true)[0] != '\0') { strncpy(str, tag->comment().toCString(true), MAXLEN-1); return cut_trailing_whitespace(str); } break; } return 0;}#endif /* HAVE_TAGLIB */#ifdef HAVE_MODintmeta_get_title_mod(metadata * meta, char * str) { mod_info * mi; mi = meta->mod_root; if (mi != NULL) { if (str != NULL && mi->title != NULL) { strncpy(str, (char *) mi->title, MAXLEN-1); } return cut_trailing_whitespace(str); } return 0;}#endif /* HAVE_MOD */intmeta_get_title(metadata * meta, char * str) { int ret = 0; if (meta == NULL) { fprintf(stderr, "meta_get_title(): assertion meta != NULL failed\n"); return 0; }#ifdef HAVE_TAGLIB if (meta->taglib_file != NULL) { TagLib::File * file = reinterpret_cast<TagLib::File *>(meta->taglib_file); ret = meta_lookup(str, META_TITLE, file->tag()); } if (ret) return ret;#endif /* HAVE_TAGLIB */#ifdef HAVE_MOD if (meta->format_major == FORMAT_MOD) { ret = meta_get_title_mod(meta, str); }#endif /* HAVE_MOD */ return ret;}intmeta_get_record(metadata * meta, char * str) { int ret = 0; if (meta == NULL) { fprintf(stderr, "meta_get_title(): assertion meta != NULL failed\n"); return 0; }#ifdef HAVE_TAGLIB if (meta->taglib_file != NULL) { TagLib::File * file = reinterpret_cast<TagLib::File *>(meta->taglib_file); ret = meta_lookup(str, META_RECORD, file->tag()); }#endif /* HAVE_TAGLIB */ return ret;}intmeta_get_artist(metadata * meta, char * str) { int ret = 0; if (meta == NULL) { fprintf(stderr, "meta_get_title(): assertion meta != NULL failed\n"); return 0; }#ifdef HAVE_TAGLIB if (meta->taglib_file != NULL) { TagLib::File * file = reinterpret_cast<TagLib::File *>(meta->taglib_file); ret = meta_lookup(str, META_ARTIST, file->tag()); }#endif /* HAVE_TAGLIB */ return ret;}intmeta_get_year(metadata * meta, char * str) { int ret = 0; if (meta == NULL) { fprintf(stderr, "meta_get_title(): assertion meta != NULL failed\n"); return 0; }#ifdef HAVE_TAGLIB if (meta->taglib_file != NULL) { TagLib::File * file = reinterpret_cast<TagLib::File *>(meta->taglib_file); ret = meta_lookup(str, META_YEAR, file->tag()); }#endif /* HAVE_TAGLIB */ return ret;}intmeta_get_comment(metadata * meta, char * str) { int ret = 0; if (meta == NULL) { fprintf(stderr, "meta_get_title(): assertion meta != NULL failed\n"); return 0; }#ifdef HAVE_TAGLIB if (meta->taglib_file != NULL) { TagLib::File * file = reinterpret_cast<TagLib::File *>(meta->taglib_file); ret = meta_lookup(str, META_COMMENT, file->tag()); }#endif /* HAVE_TAGLIB */ return ret;}#if defined(HAVE_TAGLIB) && defined(HAVE_METAEDIT)/* Update basic metadata fields of a file. Used for mass-tagging. * Note that this method is lightweight (does not need an underlying file_decoder), * and does not need explicit filetype information either. * * Any input string may be NULL, in which case that field won't be updated. * Existing metadata not updated will be retained. * * filename should be locale encoded, fields should be UTF8. * * Return 1 if OK, < 0 else. */intmeta_update_basic(char * filename, char * title, char * artist, char * album, char * comment, char * genre, char * year, char * track) { TagLib::FileRef f(filename, false); char buf[MAXLEN]; int save = 0; if (f.isNull() || !f.tag()) { return -1; } if (f.file()->readOnly()) { return -1; } TagLib::Tag * t = f.tag(); TagLib::String str; if (title) { strncpy(buf, title, MAXLEN-1); cut_trailing_whitespace(buf); str = TagLib::String(buf, TagLib::String::UTF8); t->setTitle(str); save = 1; } if (artist) { strncpy(buf, artist, MAXLEN-1); cut_trailing_whitespace(buf); str = TagLib::String(buf, TagLib::String::UTF8); t->setArtist(str); save = 1; } if (album) { strncpy(buf, album, MAXLEN-1); cut_trailing_whitespace(buf); str = TagLib::String(buf, TagLib::String::UTF8); t->setAlbum(str); save = 1; } if (comment) { strncpy(buf, comment, MAXLEN-1); cut_trailing_whitespace(buf); str = TagLib::String(buf, TagLib::String::UTF8); t->setComment(str); save = 1; } if (genre) { strncpy(buf, genre, MAXLEN-1); cut_trailing_whitespace(buf); str = TagLib::String(buf, TagLib::String::UTF8); t->setGenre(str); save = 1; } if (year) { int i; strncpy(buf, year, MAXLEN-1); cut_trailing_whitespace(buf); if (sscanf(buf, "%d", &i) < 1) { i = 0; } if ((i < 0) || (i > 9999)) { i = 0; } t->setYear(i); save = 1; } if (track) { int i; strncpy(buf, track, MAXLEN-1); cut_trailing_whitespace(buf); if (sscanf(buf, "%d", &i) < 1) { i = 0; } if ((i < 0) || (i > 9999)) { i = 0; } t->setTrack(i); save = 1; } if (save) { f.file()->save(); } return 1;}#endif /* HAVE_TAGLIB && HAVE_METAEDIT */// vim: shiftwidth=8:tabstop=8:softtabstop=8 :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -