📄 meta_decoder.cpp
字号:
/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: meta_decoder.cpp,v 1.17 2006/10/02 17:50:27 peterszilagyi Exp $*/#include <config.h>#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <assert.h>#include <gtk/gtk.h>#ifdef HAVE_MOD#include <libmodplug/modplug.h>#endif /* HAVE_MOD */#ifdef HAVE_TAGLIB#include <tag.h>#include <id3v1tag.h>#include <id3v2tag.h>#include <apetag.h>#include <xiphcomment.h>#include <fileref.h>#include <mpegfile.h>#include <mpcfile.h>#include <flacfile.h>#include <vorbisfile.h>#endif /* HAVE_TAGLIB */#include "common.h"#include "core.h"#include "i18n.h"#include "options.h"#include "decoder/file_decoder.h"#include "meta_decoder.h"#ifdef HAVE_MOD#include "decoder/dec_mod.h"extern char * valid_extensions_mod[];#endif /* HAVE_MOD */#define META_TITLE 1#define META_RECORD 2#define META_ARTIST 3#define META_YEAR 4#define META_COMMENT 5extern options_t options;intcut_trailing_whitespace(char * str) { int i = strlen(str) - 1; while (i >= 0) { if ((str[i] == ' ') || (str[i] == '\t')) { str[i] = '\0'; } else { break; } --i; } return ((i >= 0) ? 1 : 0);}#ifdef HAVE_MODvoidmod_name_filter(char *str) { char buffer[MAXLEN]; int n, k, f, len; strncpy(buffer, str, MAXLEN-1); k = f = n = 0; len = strlen(buffer); while (buffer[n] == ' ' || buffer[n] == '\t' || buffer[n] == '_' || buffer[n] == '.') { n++; } for(; n < len; n++) { if (isprint(buffer[n])) { if (buffer[n] == '_' || buffer[n] == '.') { buffer[n] = ' '; } str[k++] = buffer[n]; f = 1; } } if (f) { str[k] = '\0'; }}voidmod_filename_filter(char *str, char **valid_extensions) { char buffer[MAXLEN]; char *pos; int i; strncpy(buffer, str, MAXLEN-1); if ((pos = strrchr(buffer, '/')) != NULL) { pos++; i = 0; while(pos[i]) { str[i] = pos[i]; i++; } str[i] = '\0'; } if ((pos = strrchr(str, '.')) != NULL) { if (strcasecmp(pos+1, "gz") == 0 || strcasecmp (pos+1, "bz2") == 0) { *pos = '\0'; } } if ((pos = strrchr(str, '.')) != NULL) { i = 0; while (valid_extensions[i] != NULL) { if (strcasecmp(pos+1, valid_extensions[i]) == 0) { *pos = '\0'; } ++i; } } strncpy(buffer, str, MAXLEN-1); if ((pos = strchr(buffer, '.')) != NULL) { *pos = '\0'; i = 0; while (valid_extensions[i] != NULL) { if (strcasecmp(buffer, valid_extensions[i]) == 0) { *pos++; i = 0; while(pos[i] != '\0') { str[i] = pos[i]; i++; } str[i] = '\0'; break; } ++i; } }}#endif /* HAVE_MOD *//* fills in descr based on frameID, ret 1 if found, 0 else */intlookup_id3v2_textframe(char * frameID, char * descr) { static struct { char const * frameID; char const * descr; } const info[] = { { "TALB", _("Album") }, { "TBPM", _("Beats per minute") }, { "TCOM", _("Composer") }, { "TCON", _("Content type") }, { "TCOP", _("Copyright") }, { "TDEN", _("Encoding time") }, { "TDLY", _("Playlist delay") }, { "TDOR", _("Original release time") }, { "TDRC", _("Recording time") }, { "TDRL", _("Release time") }, { "TDTG", _("Tagging time") }, { "TENC", _("Encoded by") }, { "TEXT", _("Lyricist") }, { "TFLT", _("File type") }, { "TIPL", _("Involved people") }, { "TIT1", _("Content group") }, { "TIT2", _("Title") }, { "TIT3", _("Subtitle") }, { "TKEY", _("Initial key") }, { "TLAN", _("Language") }, { "TLEN", _("Length (ms)") }, { "TMCL", _("Musician credits") }, { "TMED", _("Media type") }, { "TMOO", _("Mood") }, { "TOAL", _("Original album") }, { "TOFN", _("Original filename") }, { "TOLY", _("Original lyricist") }, { "TOPE", _("Original artist") }, { "TOWN", _("Owner/licensee") }, { "TPE1", _("Artist") }, { "TPE2", _("Orchestra") }, { "TPE3", _("Conductor") }, { "TPE4", _("Interpreted/remixed") }, { "TPOS", _("Part of set") }, { "TPRO", _("Produced") }, { "TPUB", _("Publisher") }, { "TRCK", _("Track number") }, { "TRSN", _("Radio station name") }, { "TRSO", _("Radio station owner") }, { "TSOA", _("Album sort order") }, { "TSOP", _("Artist sort order") }, { "TSOT", _("Title sort order") }, { "TSRC", _("ISRC") }, { "TSSE", _("Encoding settings") }, { "TSST", _("Set subtitle") }, { NULL, NULL } }; for (int i = 0; info[i].frameID != NULL; i++) { if (strcmp(info[i].frameID, frameID) == 0) { strncpy(descr, info[i].descr, MAXLEN-1); return 1; } } return 0;}#ifdef HAVE_MODmod_info *modinfo_new(void) { mod_info * new_tag = NULL; if ((new_tag = (mod_info *)malloc(sizeof(mod_info))) == NULL) { fprintf(stderr, "meta_decoder.c/modinfo_new(): malloc error\n"); return NULL; } new_tag->title = NULL; new_tag->active = 0; return new_tag;}#endif /* HAVE_MOD */metadata *meta_new(void) { metadata * new_tag = NULL; if ((new_tag = (metadata *)malloc(sizeof(metadata))) == NULL) { fprintf(stderr, "meta_decoder.c/meta_new(): malloc error\n"); return NULL; }#ifdef HAVE_TAGLIB new_tag->taglib_file = NULL;#endif /* HAVE_TAGLIB */#ifdef HAVE_MOD new_tag->mod_root = modinfo_new();#endif /* HAVE_MOD */ return new_tag;}#ifdef HAVE_MODvoidappend_mod(metadata * meta, mod_info * mod) { if (meta == NULL) { fprintf(stderr, "append_mod(): assertion meta != NULL failed\n"); return; } if (meta->mod_root == NULL) { fprintf(stderr, "append_mod(): assertion meta->mod_root != NULL failed\n"); return; } meta->mod_root = mod;}#endif /* HAVE_MOD */#ifdef HAVE_TAGLIB#ifdef HAVE_FLACvoid *meta_read_flac(char * file) { TagLib::FLAC::File * taglib_flac_file = new TagLib::FLAC::File(file, false); return reinterpret_cast<void *>(taglib_flac_file);}#endif /* HAVE_FLAC */#ifdef HAVE_OGG_VORBISvoid *meta_read_oggv(char * file) { TagLib::Ogg::Vorbis::File * taglib_oggv_file = new TagLib::Ogg::Vorbis::File(file, false); return reinterpret_cast<void *>(taglib_oggv_file);}#endif /* HAVE_OGG_VORBIS */#ifdef HAVE_MPEGvoid *meta_read_mpeg(char * file) { TagLib::MPEG::File * taglib_mpeg_file = new TagLib::MPEG::File(file, false); return reinterpret_cast<void *>(taglib_mpeg_file);}#endif /* HAVE_MPEG */#ifdef HAVE_MPCvoid *meta_read_mpc(char * file) { TagLib::MPC::File * taglib_mpc_file = new TagLib::MPC::File(file, false); return reinterpret_cast<void *>(taglib_mpc_file);}#endif /* HAVE_MPC */#endif /* HAVE_TAGLIB *//* ret: 1 if successful, 0 if error */intmeta_read(metadata * meta, char * file) { file_decoder_t * fdec = NULL; if ((fdec = file_decoder_new()) == NULL) { fprintf(stderr, "meta_read(): error: file_decoder_new() returned NULL\n"); file_decoder_delete(fdec); return 0; } if (file_decoder_open(fdec, file)) { fprintf(stderr, "file_decoder_open() failed on %s\n", file); file_decoder_delete(fdec); return 0; } meta->format_major = fdec->fileinfo.format_major; meta->format_minor = fdec->fileinfo.format_minor; meta->total_samples = fdec->fileinfo.total_samples; meta->sample_rate = fdec->fileinfo.sample_rate; meta->is_mono = fdec->fileinfo.is_mono; meta->bps = fdec->fileinfo.bps;#ifdef HAVE_TAGLIB switch (meta->format_major) {#ifdef HAVE_FLAC case FORMAT_FLAC: meta->taglib_file = meta_read_flac(file); break;#endif /* HAVE_FLAC */#ifdef HAVE_OGG_VORBIS case FORMAT_VORBIS: meta->taglib_file = meta_read_oggv(file); break;#endif /* HAVE_OGG_VORBIS */#ifdef HAVE_MPEG case FORMAT_MAD: meta->taglib_file = meta_read_mpeg(file); break;#endif /* HAVE_MPEG */#ifdef HAVE_MPC case FORMAT_MPC: meta->taglib_file = meta_read_mpc(file); break;#endif /* HAVE_MPC */ }#endif /* HAVE_TAGLIB */#ifdef HAVE_MOD if (fdec->file_lib == MOD_LIB) { decoder_t * dec = (decoder_t *)(fdec->pdec); mod_pdata_t * pd = (mod_pdata_t *)dec->pdata; mod_info * mi = modinfo_new(); mi->title = strdup(ModPlug_GetName(pd->mpf)); mod_name_filter(mi->title); if (!strlen(mi->title)) { free(mi->title); mi->title = strdup(file); mod_filename_filter(mi->title, valid_extensions_mod); mod_name_filter(mi->title); } mi->active = 1;#ifdef HAVE_MOD_INFO mi->type = ModPlug_GetModuleType(pd->mpf); mi->samples = ModPlug_NumSamples(pd->mpf); mi->instruments = ModPlug_NumInstruments(pd->mpf); mi->patterns = ModPlug_NumPatterns(pd->mpf); mi->channels = ModPlug_NumChannels(pd->mpf);#endif /* HAVE_MOD_INFO */ append_mod(meta, mi); }#endif /* HAVE_MOD */ file_decoder_close(fdec); file_decoder_delete(fdec); return 1;}#ifdef HAVE_TAGLIB#ifdef HAVE_FLACvoidmeta_free_flac(metadata * meta) { TagLib::FLAC::File * taglib_flac_file = reinterpret_cast<TagLib::FLAC::File *>(meta->taglib_file); taglib_flac_file->~File();}#endif /* HAVE_FLAC */#ifdef HAVE_OGG_VORBISvoidmeta_free_oggv(metadata * meta) { TagLib::Ogg::Vorbis::File * taglib_oggv_file = reinterpret_cast<TagLib::Ogg::Vorbis::File *>(meta->taglib_file); taglib_oggv_file->~File();}#endif /* HAVE_OGG_VORBIS */#ifdef HAVE_MPEGvoidmeta_free_mpeg(metadata * meta) { TagLib::MPEG::File * taglib_mpeg_file = reinterpret_cast<TagLib::MPEG::File *>(meta->taglib_file); taglib_mpeg_file->~File();}#endif /* HAVE_MPEG */#ifdef HAVE_MPCvoidmeta_free_mpc(metadata * meta) { TagLib::MPC::File * taglib_mpc_file = reinterpret_cast<TagLib::MPC::File *>(meta->taglib_file); taglib_mpc_file->~File();}#endif /* HAVE_MPC */#endif /* HAVE_TAGLIB */voidmeta_free(metadata * meta) {#ifdef HAVE_MOD mod_info * mi;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -