Daisuke Shimamura's id3 v1/v2 + i18n patches
This commit is contained in:
parent
d8ab3468fa
commit
412fa3b7a2
43
configure.in
43
configure.in
@ -104,6 +104,49 @@ AM_CONDITIONAL(FLaC__HAS_XMMS, test x$XMMS_INPUT_PLUGIN_DIR != x)
|
||||
|
||||
SHARE_LIBS='$(top_builddir)/src/share/libutf8.a $(top_builddir)/src/share/libgetopt.a'
|
||||
|
||||
dnl check for i18n(internationalization)
|
||||
AM_WITH_NLS
|
||||
AM_ICONV
|
||||
AM_LANGINFO_CODESET
|
||||
|
||||
dnl check id3lib librairies
|
||||
LIBS_save_blah_blah_blah=$LIBS
|
||||
LIBS=""
|
||||
AC_SEARCH_LIBS(ID3Tag_Link,"id3" "id3 -lstdc++" "id3 -lz" "id3 -lz -lstdc++",
|
||||
[have_id3lib=yes],
|
||||
[AC_MSG_WARN([id3lib not found - ID3v2 will not be supported, internal function support only id3v1])])
|
||||
AM_CONDITIONAL(FLaC__HAS_ID3LIB, [test x$have_id3lib = xyes])
|
||||
if test x$have_id3lib = xyes ; then
|
||||
AC_DEFINE(FLAC__HAS_ID3LIB)
|
||||
ID3LIBS=$LIBS
|
||||
fi
|
||||
AC_SUBST(ID3LIBS)
|
||||
|
||||
dnl expected version for cross compiling
|
||||
ID3LIB_MAJOR=3
|
||||
ID3LIB_MINOR=8
|
||||
ID3LIB_PATCH=0
|
||||
|
||||
AC_MSG_CHECKING(for id3lib version)
|
||||
AC_TRY_RUN([
|
||||
#include <id3.h>
|
||||
#include <stdio.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
FILE *output;
|
||||
output=fopen("conftest.id3","w");
|
||||
fprintf(output,"ID3LIB_MAJOR=%d\nID3LIB_MINOR=%d\nID3LIB_PATCH=%d\n",ID3LIB_MAJOR_VERSION,ID3LIB_MINOR_VERSION,ID3LIB_PATCH_VERSION);
|
||||
fclose(output);
|
||||
exit(0);
|
||||
}
|
||||
], . conftest.id3; echo "${ID3LIB_MAJOR}.${ID3LIB_MINOR}.${ID3LIB_PATCH}", AC_MSG_WARN(could not determine id3lib version),[echo $ac_n "cross compiling; assuming ${ID3LIB_MAJOR}.${ID3LIB_MINOR}.${ID3LIB_PATCH} $ac_c"])
|
||||
AC_DEFINE_UNQUOTED(ID3LIB_MAJOR, $ID3LIB_MAJOR)
|
||||
AC_DEFINE_UNQUOTED(ID3LIB_MINOR, $ID3LIB_MINOR)
|
||||
AC_DEFINE_UNQUOTED(ID3LIB_PATCH, $ID3LIB_PATCH)
|
||||
|
||||
LIBS=$LIBS_save_blah_blah_blah
|
||||
|
||||
AC_CHECK_PROGS(NASM, nasm)
|
||||
AM_CONDITIONAL(FLaC__HAS_NASM, test -n "$NASM")
|
||||
if test -n "$NASM" ; then
|
||||
|
@ -20,15 +20,26 @@
|
||||
#
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.lite
|
||||
Makefile.lite \
|
||||
id3_tag.c
|
||||
|
||||
CFLAGS = @CFLAGS@ @XMMS_CFLAGS@
|
||||
xmmsinputplugindir = @XMMS_INPUT_PLUGIN_DIR@
|
||||
|
||||
# Don't build a static library
|
||||
LIBTOOL = $(top_builddir)/libtool-disable-static
|
||||
|
||||
xmmsinputplugin_LTLIBRARIES = libxmms-flac.la
|
||||
libxmms_flac_la_SOURCES = plugin.c
|
||||
|
||||
plugin_sources = plugin.c wrap_id3.c configure.c charset.c
|
||||
id3v2_sources = id3_tag.c
|
||||
|
||||
if FLaC__HAS_ID3LIB
|
||||
libxmms_flac_la_SOURCES = $(plugin_sources) $(id3v2_sources)
|
||||
else
|
||||
libxmms_flac_la_SOURCES = $(plugin_sources)
|
||||
endif
|
||||
|
||||
# work around the bug in libtool where its relinking fails with a different DESTDIR
|
||||
# for libtool bug info see:
|
||||
# http://mail.gnu.org/pipermail/bug-libtool/2002-February/003018.html
|
||||
@ -37,5 +48,5 @@ libxmms_flac_la_SOURCES = plugin.c
|
||||
# for fix info see:
|
||||
# http://lists.freshrpms.net/pipermail/rpm-list/2002-April/000746.html
|
||||
# the workaround is the extra '-L$(top_builddir)/src/libFLAC/.libs'
|
||||
libxmms_flac_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -L$(top_builddir)/src/libFLAC/.libs @XMMS_LIBS@
|
||||
libxmms_flac_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -L$(top_builddir)/src/libFLAC/.libs @XMMS_LIBS@ @ID3LIBS@
|
||||
libxmms_flac_la_LDFLAGS = -module -avoid-version
|
||||
|
@ -24,7 +24,11 @@ INCLUDES = $(shell xmms-config --cflags) -I./include -I../../include
|
||||
LIBS = ../../obj/lib/libFLAC.a
|
||||
|
||||
OBJS = \
|
||||
plugin.o
|
||||
plugin.o \
|
||||
configure.o \
|
||||
wrap_id3.o \
|
||||
charset.o
|
||||
|
||||
|
||||
include ../../build/lib.mk
|
||||
|
||||
|
306
src/plugin_xmms/charset.c
Normal file
306
src/plugin_xmms/charset.c
Normal file
@ -0,0 +1,306 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Almost from charset.c
|
||||
* EasyTAG - Tag editor for MP3 and OGG files
|
||||
* Copyright (C) 1999-2001 Håvard Kvålen <havardk@xmms.org>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LANGINFO_CODESET
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "charset.h"
|
||||
#include "mylocale.h"
|
||||
#include "configure.h"
|
||||
|
||||
|
||||
/****************
|
||||
* Declarations *
|
||||
****************/
|
||||
|
||||
#define CHARSET_TRANS_ARRAY_LEN ( sizeof(charset_trans_array) / sizeof((charset_trans_array)[0]) )
|
||||
const CharsetInfo charset_trans_array[] = {
|
||||
{N_("Arabic (IBM-864)"), "IBM864" },
|
||||
{N_("Arabic (ISO-8859-6)"), "ISO-8859-6" },
|
||||
{N_("Arabic (Windows-1256)"), "windows-1256" },
|
||||
{N_("Baltic (ISO-8859-13)"), "ISO-8859-13" },
|
||||
{N_("Baltic (ISO-8859-4)"), "ISO-8859-4" },
|
||||
{N_("Baltic (Windows-1257)"), "windows-1257" },
|
||||
{N_("Celtic (ISO-8859-14)"), "ISO-8859-14" },
|
||||
{N_("Central European (IBM-852)"), "IBM852" },
|
||||
{N_("Central European (ISO-8859-2)"), "ISO-8859-2" },
|
||||
{N_("Central European (Windows-1250)"), "windows-1250" },
|
||||
{N_("Chinese Simplified (GB18030)"), "gb18030" },
|
||||
{N_("Chinese Simplified (GB2312)"), "GB2312" },
|
||||
{N_("Chinese Traditional (Big5)"), "Big5" },
|
||||
{N_("Chinese Traditional (Big5-HKSCS)"), "Big5-HKSCS" },
|
||||
{N_("Cyrillic (IBM-855)"), "IBM855" },
|
||||
{N_("Cyrillic (ISO-8859-5)"), "ISO-8859-5" },
|
||||
{N_("Cyrillic (ISO-IR-111)"), "ISO-IR-111" },
|
||||
{N_("Cyrillic (KOI8-R)"), "KOI8-R" },
|
||||
{N_("Cyrillic (Windows-1251)"), "windows-1251" },
|
||||
{N_("Cyrillic/Russian (CP-866)"), "IBM866" },
|
||||
{N_("Cyrillic/Ukrainian (KOI8-U)"), "KOI8-U" },
|
||||
{N_("English (US-ASCII)"), "us-ascii" },
|
||||
{N_("Greek (ISO-8859-7)"), "ISO-8859-7" },
|
||||
{N_("Greek (Windows-1253)"), "windows-1253" },
|
||||
{N_("Hebrew (IBM-862)"), "IBM862" },
|
||||
{N_("Hebrew (Windows-1255)"), "windows-1255" },
|
||||
{N_("Japanese (EUC-JP)"), "EUC-JP" },
|
||||
{N_("Japanese (ISO-2022-JP)"), "ISO-2022-JP" },
|
||||
{N_("Japanese (Shift_JIS)"), "Shift_JIS" },
|
||||
{N_("Korean (EUC-KR)"), "EUC-KR" },
|
||||
{N_("Nordic (ISO-8859-10)"), "ISO-8859-10" },
|
||||
{N_("South European (ISO-8859-3)"), "ISO-8859-3" },
|
||||
{N_("Thai (TIS-620)"), "TIS-620" },
|
||||
{N_("Turkish (IBM-857)"), "IBM857" },
|
||||
{N_("Turkish (ISO-8859-9)"), "ISO-8859-9" },
|
||||
{N_("Turkish (Windows-1254)"), "windows-1254" },
|
||||
{N_("Unicode (UTF-7)"), "UTF-7" },
|
||||
{N_("Unicode (UTF-8)"), "UTF-8" },
|
||||
{N_("Unicode (UTF-16BE)"), "UTF-16BE" },
|
||||
{N_("Unicode (UTF-16LE)"), "UTF-16LE" },
|
||||
{N_("Unicode (UTF-32BE)"), "UTF-32BE" },
|
||||
{N_("Unicode (UTF-32LE)"), "UTF-32LE" },
|
||||
{N_("Vietnamese (VISCII)"), "VISCII" },
|
||||
{N_("Vietnamese (Windows-1258)"), "windows-1258" },
|
||||
{N_("Visual Hebrew (ISO-8859-8)"), "ISO-8859-8" },
|
||||
{N_("Western (IBM-850)"), "IBM850" },
|
||||
{N_("Western (ISO-8859-1)"), "ISO-8859-1" },
|
||||
{N_("Western (ISO-8859-15)"), "ISO-8859-15" },
|
||||
{N_("Western (Windows-1252)"), "windows-1252" }
|
||||
|
||||
/*
|
||||
* From this point, character sets aren't supported by iconv
|
||||
*/
|
||||
/* {N_("Arabic (IBM-864-I)"), "IBM864i" },
|
||||
{N_("Arabic (ISO-8859-6-E)"), "ISO-8859-6-E" },
|
||||
{N_("Arabic (ISO-8859-6-I)"), "ISO-8859-6-I" },
|
||||
{N_("Arabic (MacArabic)"), "x-mac-arabic" },
|
||||
{N_("Armenian (ARMSCII-8)"), "armscii-8" },
|
||||
{N_("Central European (MacCE)"), "x-mac-ce" },
|
||||
{N_("Chinese Simplified (GBK)"), "x-gbk" },
|
||||
{N_("Chinese Simplified (HZ)"), "HZ-GB-2312" },
|
||||
{N_("Chinese Traditional (EUC-TW)"), "x-euc-tw" },
|
||||
{N_("Croatian (MacCroatian)"), "x-mac-croatian" },
|
||||
{N_("Cyrillic (MacCyrillic)"), "x-mac-cyrillic" },
|
||||
{N_("Cyrillic/Ukrainian (MacUkrainian)"), "x-mac-ukrainian" },
|
||||
{N_("Farsi (MacFarsi)"), "x-mac-farsi"},
|
||||
{N_("Greek (MacGreek)"), "x-mac-greek" },
|
||||
{N_("Gujarati (MacGujarati)"), "x-mac-gujarati" },
|
||||
{N_("Gurmukhi (MacGurmukhi)"), "x-mac-gurmukhi" },
|
||||
{N_("Hebrew (ISO-8859-8-E)"), "ISO-8859-8-E" },
|
||||
{N_("Hebrew (ISO-8859-8-I)"), "ISO-8859-8-I" },
|
||||
{N_("Hebrew (MacHebrew)"), "x-mac-hebrew" },
|
||||
{N_("Hindi (MacDevanagari)"), "x-mac-devanagari" },
|
||||
{N_("Icelandic (MacIcelandic)"), "x-mac-icelandic" },
|
||||
{N_("Korean (JOHAB)"), "x-johab" },
|
||||
{N_("Korean (UHC)"), "x-windows-949" },
|
||||
{N_("Romanian (MacRomanian)"), "x-mac-romanian" },
|
||||
{N_("Turkish (MacTurkish)"), "x-mac-turkish" },
|
||||
{N_("User Defined"), "x-user-defined" },
|
||||
{N_("Vietnamese (TCVN)"), "x-viet-tcvn5712" },
|
||||
{N_("Vietnamese (VPS)"), "x-viet-vps" },
|
||||
{N_("Western (MacRoman)"), "x-mac-roman" },
|
||||
// charsets whithout posibly translatable names
|
||||
{"T61.8bit", "T61.8bit" },
|
||||
{"x-imap4-modified-utf7", "x-imap4-modified-utf7"},
|
||||
{"x-u-escaped", "x-u-escaped" },
|
||||
{"windows-936", "windows-936" }
|
||||
*/
|
||||
};
|
||||
|
||||
/*************
|
||||
* Functions *
|
||||
*************/
|
||||
|
||||
char* get_current_charset (void)
|
||||
{
|
||||
char *charset = getenv("CHARSET");
|
||||
|
||||
#ifdef HAVE_LANGINFO_CODESET
|
||||
if (!charset)
|
||||
charset = nl_langinfo(CODESET);
|
||||
#endif
|
||||
if (!charset)
|
||||
charset = "ISO-8859-1";
|
||||
|
||||
return charset;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
static char* convert_string (const char *string, char *from, char *to)
|
||||
{
|
||||
size_t outleft, outsize, length;
|
||||
iconv_t cd;
|
||||
char *out, *outptr;
|
||||
const char *input = string;
|
||||
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
length = strlen(string);
|
||||
|
||||
/* g_message("converting %s from %s to %s", string, from, to); */
|
||||
if ((cd = iconv_open(to, from)) == (iconv_t)-1)
|
||||
{
|
||||
g_warning("convert_string(): Conversion not supported. Charsets: %s -> %s", from, to);
|
||||
return g_strdup(string);
|
||||
}
|
||||
|
||||
/* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */
|
||||
/* + 1 for nul in case len == 1 */
|
||||
outsize = ((length + 3) & ~3) + 1;
|
||||
out = g_malloc(outsize);
|
||||
outleft = outsize - 1;
|
||||
outptr = out;
|
||||
|
||||
retry:
|
||||
if (iconv(cd, &input, &length, &outptr, &outleft) == -1)
|
||||
{
|
||||
int used;
|
||||
switch (errno)
|
||||
{
|
||||
case E2BIG:
|
||||
used = outptr - out;
|
||||
outsize = (outsize - 1) * 2 + 1;
|
||||
out = g_realloc(out, outsize);
|
||||
outptr = out + used;
|
||||
outleft = outsize - 1 - used;
|
||||
goto retry;
|
||||
case EINVAL:
|
||||
break;
|
||||
case EILSEQ:
|
||||
/* Invalid sequence, try to get the
|
||||
rest of the string */
|
||||
input++;
|
||||
length = strlen(input);
|
||||
goto retry;
|
||||
default:
|
||||
g_warning("convert_string(): Conversion failed. Inputstring: %s; Error: %s", string, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
*outptr = '\0';
|
||||
|
||||
iconv_close(cd);
|
||||
return out;
|
||||
}
|
||||
#else
|
||||
static char* convert_string (const char *string, char *from, char *to)
|
||||
{
|
||||
if (!string)
|
||||
return NULL;
|
||||
return g_strdup(string);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Commons conversion functions
|
||||
*/
|
||||
char* convert_from_file_to_user (const char *string)
|
||||
{
|
||||
char *file_charset = flac_cfg.file_char_set;
|
||||
char *user_charset = flac_cfg.user_char_set;
|
||||
|
||||
return convert_string(string,file_charset,user_charset);
|
||||
}
|
||||
|
||||
char* convert_from_user_to_file (const char *string)
|
||||
{
|
||||
char *file_charset = flac_cfg.file_char_set;
|
||||
char *user_charset = flac_cfg.user_char_set;
|
||||
|
||||
return convert_string(string,user_charset,file_charset);
|
||||
}
|
||||
|
||||
|
||||
GList *Charset_Create_List (void)
|
||||
{
|
||||
GList *list = NULL;
|
||||
guint i;
|
||||
|
||||
for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
|
||||
list = g_list_append(list,_(charset_trans_array[i].charset_title));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return charset_name from charset_title
|
||||
*/
|
||||
gchar *Charset_Get_Name_From_Title (gchar *charset_title)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (charset_title)
|
||||
for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
|
||||
if ( strcasecmp(_(charset_title),_(charset_trans_array[i].charset_title)) == 0 )
|
||||
return charset_trans_array[i].charset_name;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return charset_title from charset_name
|
||||
*/
|
||||
gchar *Charset_Get_Title_From_Name (gchar *charset_name)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (charset_name)
|
||||
for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
|
||||
if ( strcasecmp(charset_name,charset_trans_array[i].charset_name) == 0 )
|
||||
return _(charset_trans_array[i].charset_title);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test if the conversion is supported between two character sets ('from' and 'to)
|
||||
*/
|
||||
#ifdef HAVE_ICONV
|
||||
gboolean test_conversion_charset (char *from, char *to)
|
||||
{
|
||||
iconv_t cd;
|
||||
|
||||
if ((cd=iconv_open(to,from)) == (iconv_t)-1)
|
||||
{
|
||||
/* Conversion not supported */
|
||||
return FALSE;
|
||||
}
|
||||
iconv_close(cd);
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
gboolean test_conversion_charset (char *from, char *to)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
57
src/plugin_xmms/charset.h
Normal file
57
src/plugin_xmms/charset.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Almost from charset.h - 2001/12/04
|
||||
* EasyTAG - Tag editor for MP3 and OGG files
|
||||
* Copyright (C) 1999-2001 H蛆ard Kv虱en <havardk@xmms.org>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CHARSET_H__
|
||||
#define __CHARSET_H__
|
||||
|
||||
|
||||
/***************
|
||||
* Declaration *
|
||||
***************/
|
||||
|
||||
typedef struct {
|
||||
gchar *charset_title;
|
||||
gchar *charset_name;
|
||||
} CharsetInfo;
|
||||
|
||||
/* translated charset titles */
|
||||
extern const CharsetInfo charset_trans_array[];
|
||||
|
||||
/**************
|
||||
* Prototypes *
|
||||
**************/
|
||||
|
||||
gchar* get_current_charset (void);
|
||||
|
||||
gchar* convert_from_file_to_user (const gchar *string);
|
||||
gchar* convert_from_user_to_file (const gchar *string);
|
||||
|
||||
GList *Charset_Create_List (void);
|
||||
gchar *Charset_Get_Name_From_Title (gchar *charset_title);
|
||||
gchar *Charset_Get_Title_From_Name (gchar *charset_name);
|
||||
|
||||
gboolean test_conversion_charset (char *from, char *to);
|
||||
|
||||
|
||||
#endif /* __CHARSET_H__ */
|
||||
|
258
src/plugin_xmms/configure.c
Normal file
258
src/plugin_xmms/configure.c
Normal file
@ -0,0 +1,258 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Based on mpg123 plugin
|
||||
* and prefs.c - 2000/05/06
|
||||
* EasyTAG - Tag editor for MP3 and OGG files
|
||||
* Copyright (C) 2000-2002 Jerome Couderc <j.couderc@ifrance.com>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <xmms/configfile.h>
|
||||
#include <xmms/dirbrowser.h>
|
||||
#include <xmms/titlestring.h>
|
||||
#include <xmms/util.h>
|
||||
#include <xmms/plugin.h>
|
||||
|
||||
#include "mylocale.h"
|
||||
#include "charset.h"
|
||||
#include "configure.h"
|
||||
|
||||
/*
|
||||
* Initialize Global Valueable
|
||||
*/
|
||||
flac_config_t flac_cfg = {
|
||||
FALSE,
|
||||
NULL,
|
||||
FALSE,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static GtkWidget *flac_configurewin = NULL;
|
||||
static GtkWidget *vbox, *notebook;
|
||||
|
||||
static GtkWidget *title_tag_override, *title_tag_box, *title_tag_entry, *title_desc;
|
||||
static GtkWidget *convert_char_set, *fileCharacterSetEntry, *userCharacterSetEntry;
|
||||
|
||||
static gchar *gtk_entry_get_text_1 (GtkWidget *widget);
|
||||
static void flac_configurewin_ok(GtkWidget * widget, gpointer data);
|
||||
static void configure_destroy(GtkWidget * w, gpointer data);
|
||||
static void title_tag_override_cb(GtkWidget * w, gpointer data);
|
||||
static void convert_char_set_cb(GtkWidget * w, gpointer data);
|
||||
|
||||
static void flac_configurewin_ok(GtkWidget * widget, gpointer data)
|
||||
{
|
||||
ConfigFile *cfg;
|
||||
gchar *filename;
|
||||
|
||||
g_free(flac_cfg.tag_format);
|
||||
flac_cfg.tag_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_tag_entry)));
|
||||
flac_cfg.file_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(fileCharacterSetEntry));
|
||||
flac_cfg.user_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(userCharacterSetEntry));
|
||||
|
||||
filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
|
||||
cfg = xmms_cfg_open_file(filename);
|
||||
if (!cfg)
|
||||
cfg = xmms_cfg_new();
|
||||
xmms_cfg_write_boolean(cfg, "flac", "tag_override", flac_cfg.tag_override);
|
||||
xmms_cfg_write_string(cfg, "flac", "tag_format", flac_cfg.tag_format);
|
||||
xmms_cfg_write_boolean(cfg, "flac", "convert_char_set", flac_cfg.convert_char_set);
|
||||
xmms_cfg_write_string(cfg, "flac", "file_char_set", flac_cfg.file_char_set);
|
||||
xmms_cfg_write_string(cfg, "flac", "user_char_set", flac_cfg.user_char_set);
|
||||
xmms_cfg_write_file(cfg, filename);
|
||||
xmms_cfg_free(cfg);
|
||||
g_free(filename);
|
||||
gtk_widget_destroy(flac_configurewin);
|
||||
}
|
||||
|
||||
static void configure_destroy(GtkWidget * w, gpointer data)
|
||||
{
|
||||
}
|
||||
|
||||
static void title_tag_override_cb(GtkWidget * w, gpointer data)
|
||||
{
|
||||
flac_cfg.tag_override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_tag_override));
|
||||
|
||||
gtk_widget_set_sensitive(title_tag_box, flac_cfg.tag_override);
|
||||
gtk_widget_set_sensitive(title_desc, flac_cfg.tag_override);
|
||||
|
||||
}
|
||||
|
||||
static void convert_char_set_cb(GtkWidget * w, gpointer data)
|
||||
{
|
||||
flac_cfg.convert_char_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(convert_char_set));
|
||||
|
||||
gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.convert_char_set);
|
||||
gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.convert_char_set);
|
||||
}
|
||||
|
||||
void FLAC_XMMS__configure(void)
|
||||
{
|
||||
GtkWidget *title_frame, *title_tag_vbox, *title_tag_label;
|
||||
GtkWidget *label, *hbox;
|
||||
GtkWidget *bbox, *ok, *cancel;
|
||||
GList *list;
|
||||
|
||||
if (flac_configurewin != NULL) {
|
||||
gdk_window_raise(flac_configurewin->window);
|
||||
return;
|
||||
}
|
||||
flac_configurewin = gtk_window_new(GTK_WINDOW_DIALOG);
|
||||
gtk_signal_connect(GTK_OBJECT(flac_configurewin), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &flac_configurewin);
|
||||
gtk_signal_connect(GTK_OBJECT(flac_configurewin), "destroy", GTK_SIGNAL_FUNC(configure_destroy), &flac_configurewin);
|
||||
gtk_window_set_title(GTK_WINDOW(flac_configurewin), _("Flac Configuration"));
|
||||
gtk_window_set_policy(GTK_WINDOW(flac_configurewin), FALSE, FALSE, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(flac_configurewin), 10);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 10);
|
||||
gtk_container_add(GTK_CONTAINER(flac_configurewin), vbox);
|
||||
|
||||
notebook = gtk_notebook_new();
|
||||
gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
|
||||
|
||||
/* Title config.. */
|
||||
|
||||
title_frame = gtk_frame_new(_("ID3 Tags:"));
|
||||
gtk_container_border_width(GTK_CONTAINER(title_frame), 5);
|
||||
|
||||
title_tag_vbox = gtk_vbox_new(FALSE, 10);
|
||||
gtk_container_border_width(GTK_CONTAINER(title_tag_vbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(title_frame), title_tag_vbox);
|
||||
|
||||
/* Convert Char Set */
|
||||
|
||||
convert_char_set = gtk_check_button_new_with_label(_("Convert Character Set"));
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(convert_char_set), flac_cfg.convert_char_set);
|
||||
gtk_signal_connect(GTK_OBJECT(convert_char_set), "clicked", convert_char_set_cb, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(title_tag_vbox), convert_char_set, FALSE, FALSE, 0);
|
||||
// Combo boxes...
|
||||
hbox = gtk_hbox_new(FALSE,4);
|
||||
gtk_container_add(GTK_CONTAINER(title_tag_vbox),hbox);
|
||||
label = gtk_label_new(_("Convert character set from :"));
|
||||
gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
|
||||
fileCharacterSetEntry = gtk_combo_new();
|
||||
gtk_box_pack_start(GTK_BOX(hbox),fileCharacterSetEntry,TRUE,TRUE,0);
|
||||
|
||||
label = gtk_label_new (_("to :"));
|
||||
gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
|
||||
userCharacterSetEntry = gtk_combo_new();
|
||||
gtk_box_pack_start(GTK_BOX(hbox),userCharacterSetEntry,TRUE,TRUE,0);
|
||||
|
||||
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(fileCharacterSetEntry)->entry),FALSE);
|
||||
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(userCharacterSetEntry)->entry),FALSE);
|
||||
gtk_combo_set_value_in_list(GTK_COMBO(fileCharacterSetEntry),TRUE,FALSE);
|
||||
gtk_combo_set_value_in_list(GTK_COMBO(userCharacterSetEntry),TRUE,FALSE);
|
||||
|
||||
list = Charset_Create_List();
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(fileCharacterSetEntry),list);
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(userCharacterSetEntry),list);
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(fileCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.file_char_set));
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(userCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.user_char_set));
|
||||
gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.convert_char_set);
|
||||
gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.convert_char_set);
|
||||
|
||||
/* Override Tagging Format */
|
||||
|
||||
title_tag_override = gtk_check_button_new_with_label(_("Override generic titles"));
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(title_tag_override), flac_cfg.tag_override);
|
||||
gtk_signal_connect(GTK_OBJECT(title_tag_override), "clicked", title_tag_override_cb, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_tag_override, FALSE, FALSE, 0);
|
||||
|
||||
title_tag_box = gtk_hbox_new(FALSE, 5);
|
||||
gtk_widget_set_sensitive(title_tag_box, flac_cfg.tag_override);
|
||||
gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_tag_box, FALSE, FALSE, 0);
|
||||
|
||||
title_tag_label = gtk_label_new(_("Title format:"));
|
||||
gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_label, FALSE, FALSE, 0);
|
||||
|
||||
title_tag_entry = gtk_entry_new();
|
||||
gtk_entry_set_text(GTK_ENTRY(title_tag_entry), flac_cfg.tag_format);
|
||||
gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_entry, TRUE, TRUE, 0);
|
||||
|
||||
title_desc = xmms_titlestring_descriptions("pafFetnygc", 2);
|
||||
gtk_widget_set_sensitive(title_desc, flac_cfg.tag_override);
|
||||
gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_desc, FALSE, FALSE, 0);
|
||||
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title")));
|
||||
|
||||
/* Buttons */
|
||||
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
|
||||
|
||||
ok = gtk_button_new_with_label(_("Ok"));
|
||||
gtk_signal_connect(GTK_OBJECT(ok), "clicked", GTK_SIGNAL_FUNC(flac_configurewin_ok), NULL);
|
||||
GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok);
|
||||
|
||||
cancel = gtk_button_new_with_label(_("Cancel"));
|
||||
gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(flac_configurewin));
|
||||
GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
|
||||
|
||||
gtk_widget_show_all(flac_configurewin);
|
||||
}
|
||||
|
||||
void FLAC_XMMS__aboutbox()
|
||||
{
|
||||
static GtkWidget *about_window;
|
||||
|
||||
if (about_window)
|
||||
gdk_window_raise(about_window->window);
|
||||
|
||||
about_window = xmms_show_message(
|
||||
_("About Flac Plugin"),
|
||||
_("Flac Plugin by Josh Coalson\n"
|
||||
"contributions by\n"
|
||||
"......\n"
|
||||
"......\n"
|
||||
"and\n"
|
||||
"Daisuke Shimamura\n"
|
||||
"Visit http://flac.sourceforge.net/"),
|
||||
_("Ok"), FALSE, NULL, NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(about_window), "destroy",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroyed),
|
||||
&about_window);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get text of an Entry or a ComboBox
|
||||
*/
|
||||
static gchar *gtk_entry_get_text_1 (GtkWidget *widget)
|
||||
{
|
||||
if (GTK_IS_COMBO(widget))
|
||||
{
|
||||
return gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(widget)->entry));
|
||||
}else if (GTK_IS_ENTRY(widget))
|
||||
{
|
||||
return gtk_entry_get_text(GTK_ENTRY(widget));
|
||||
}else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
42
src/plugin_xmms/configure.h
Normal file
42
src/plugin_xmms/configure.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Based on mpg123 plugin
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIGURE_H__
|
||||
#define __CONFIGURE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct {
|
||||
gboolean tag_override;
|
||||
gchar *tag_format;
|
||||
gboolean convert_char_set;
|
||||
gchar *file_char_set;
|
||||
gchar *user_char_set;
|
||||
} flac_config_t;
|
||||
|
||||
extern flac_config_t flac_cfg;
|
||||
|
||||
extern void FLAC_XMMS__configure(void);
|
||||
extern void FLAC_XMMS__aboutbox();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
325
src/plugin_xmms/fileinfo.c
Normal file
325
src/plugin_xmms/fileinfo.c
Normal file
@ -0,0 +1,325 @@
|
||||
/* XMMS - Cross-platform multimedia player
|
||||
* Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
|
||||
* Copyright (C) 1999,2000 Håvard Kvålen
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include "FLAC/all.h"
|
||||
#include "id3_tag.h"
|
||||
#include "configure.h"
|
||||
|
||||
gboolean get_file_info(char *filename, flac_file_info_struct *tmp_file_info)
|
||||
{
|
||||
FLAC__StreamMetadata streaminfo;
|
||||
|
||||
if(0 == filename)
|
||||
filename = "";
|
||||
|
||||
if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tmp_file_info->sample_rate = streaminfo.data.stream_info.sample_rate;
|
||||
tmp_file_info->channels = streaminfo.data.stream_info.channels;
|
||||
tmp_file_info->bits_per_sample = streaminfo.data.stream_info.bits_per_sample;
|
||||
tmp_file_info->total_samples = streaminfo.data.stream_info.total_samples;
|
||||
|
||||
tmp_file_info->length_in_msec = streaminfo.data.stream_info.total_samples * 10 / (streaminfo.data.stream_info.sample_rate / 100);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *filename_entry, *id3_frame;
|
||||
static GtkWidget *title_entry, *artist_entry, *album_entry, *year_entry, *tracknum_entry, *comment_entry;
|
||||
static GtkWidget *genre_combo;
|
||||
static GtkWidget *flac_level, *flac_bitrate, *flac_samplerate, *flac_flags;
|
||||
static GtkWidget *flac_fileinfo, *flac_genre;
|
||||
|
||||
static gchar *current_filename = NULL;
|
||||
|
||||
extern gchar *flac_filename;
|
||||
extern gint flac_bitrate, flac_frequency, flac_layer, flac_lsf, flac_mode;
|
||||
extern gboolean flac_stereo, flac_flac25;
|
||||
|
||||
#define MAX_STR_LEN 100
|
||||
|
||||
static void set_entry_tag(GtkEntry * entry, gchar * tag, gint length)
|
||||
{
|
||||
gint stripped_len;
|
||||
gchar *text;
|
||||
|
||||
stripped_len = flac_strip_spaces(tag, length);
|
||||
text = g_strdup_printf("%-*.*s", stripped_len, stripped_len, tag);
|
||||
gtk_entry_set_text(entry, text);
|
||||
g_free(text);
|
||||
}
|
||||
|
||||
static void get_entry_tag(GtkEntry * entry, gchar * tag, gint length)
|
||||
{
|
||||
gchar *text;
|
||||
|
||||
text = gtk_entry_get_text(entry);
|
||||
memset(tag, ' ', length);
|
||||
memcpy(tag, text, strlen(text) > length ? length : strlen(text));
|
||||
}
|
||||
|
||||
static gint genre_comp_func(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return strcasecmp(a, b);
|
||||
}
|
||||
|
||||
static gchar* channel_mode_name(int mode)
|
||||
{
|
||||
static const gchar *channel_mode[] =
|
||||
{N_("Mono"), N_("Stereo")};
|
||||
if (mode < 1 || mode > 2)
|
||||
return "";
|
||||
return gettext(channel_mode[mode]);
|
||||
}
|
||||
|
||||
void FLAC_XMMS__file_info_box(char *filename)
|
||||
{
|
||||
gint i;
|
||||
FILE *fh;
|
||||
gchar *tmp, *title;
|
||||
|
||||
gboolean rc;
|
||||
|
||||
#ifdef FLAC__HAS_ID3LIB
|
||||
File_Tag tag;
|
||||
Initialize_File_Tag_Item (&tag);
|
||||
rc = Id3tag_Read_File_Tag (filename, &tag);
|
||||
#else
|
||||
id3v2_struct tag;
|
||||
memset(&tag, 0, sizeof(tag));
|
||||
rc = get_id3v1_tag_as_v2_(filename, &tag);
|
||||
#endif
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *vbox, *hbox, *left_vbox, *table;
|
||||
GtkWidget *flac_frame, *flac_box;
|
||||
GtkWidget *label, *filename_hbox;
|
||||
GtkWidget *bbox, *save, *remove_id3, *cancel;
|
||||
|
||||
window = gtk_window_new(GTK_WINDOW_DIALOG);
|
||||
gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
|
||||
gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 10);
|
||||
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||
|
||||
filename_hbox = gtk_hbox_new(FALSE, 5);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), filename_hbox, FALSE, TRUE, 0);
|
||||
|
||||
label = gtk_label_new(_("Filename:"));
|
||||
gtk_box_pack_start(GTK_BOX(filename_hbox), label, FALSE, TRUE, 0);
|
||||
filename_entry = gtk_entry_new();
|
||||
gtk_editable_set_editable(GTK_EDITABLE(filename_entry), FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(filename_hbox), filename_entry, TRUE, TRUE, 0);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 10);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
|
||||
|
||||
left_vbox = gtk_vbox_new(FALSE, 10);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), left_vbox, FALSE, FALSE, 0);
|
||||
|
||||
id3_frame = gtk_frame_new(_("ID3 Tag:"));
|
||||
gtk_box_pack_start(GTK_BOX(left_vbox), id3_frame, FALSE, FALSE, 0);
|
||||
|
||||
table = gtk_table_new(5, 5, FALSE);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
|
||||
gtk_container_add(GTK_CONTAINER(id3_frame), table);
|
||||
|
||||
label = gtk_label_new(_("Title:"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5);
|
||||
|
||||
title_entry = gtk_entry_new_with_max_length(30);
|
||||
gtk_table_attach(GTK_TABLE(table), title_entry, 1, 4, 0, 1, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
|
||||
|
||||
label = gtk_label_new(_("Artist:"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5);
|
||||
|
||||
artist_entry = gtk_entry_new_with_max_length(30);
|
||||
gtk_table_attach(GTK_TABLE(table), artist_entry, 1, 4, 1, 2, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
|
||||
|
||||
label = gtk_label_new(_("Album:"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 5);
|
||||
|
||||
album_entry = gtk_entry_new_with_max_length(30);
|
||||
gtk_table_attach(GTK_TABLE(table), album_entry, 1, 4, 2, 3, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
|
||||
|
||||
label = gtk_label_new(_("Comment:"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 5, 5);
|
||||
|
||||
comment_entry = gtk_entry_new_with_max_length(30);
|
||||
gtk_table_attach(GTK_TABLE(table), comment_entry, 1, 4, 3, 4, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
|
||||
|
||||
label = gtk_label_new(_("Year:"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 5, 5);
|
||||
|
||||
year_entry = gtk_entry_new_with_max_length(4);
|
||||
gtk_widget_set_usize(year_entry, 40, -1);
|
||||
gtk_table_attach(GTK_TABLE(table), year_entry, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
|
||||
|
||||
label = gtk_label_new(_("Track number:"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 2, 3, 4, 5, GTK_FILL, GTK_FILL, 5, 5);
|
||||
|
||||
tracknum_entry = gtk_entry_new_with_max_length(3);
|
||||
gtk_widget_set_usize(tracknum_entry, 40, -1);
|
||||
gtk_table_attach(GTK_TABLE(table), tracknum_entry, 3, 4, 4, 5, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
|
||||
|
||||
label = gtk_label_new(_("Genre:"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 5, 5);
|
||||
|
||||
genre_combo = gtk_combo_new();
|
||||
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), FALSE);
|
||||
if (!genre_list)
|
||||
{
|
||||
for (i = 0; i < GENRE_MAX; i++)
|
||||
genre_list = g_list_prepend(genre_list, (char *) flac_id3_genres[i]);
|
||||
genre_list = g_list_prepend(genre_list, "");
|
||||
genre_list = g_list_sort(genre_list, genre_comp_func);
|
||||
}
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(genre_combo), genre_list);
|
||||
|
||||
gtk_table_attach(GTK_TABLE(table), genre_combo, 1, 4, 5, 6, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
|
||||
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_box_pack_start(GTK_BOX(left_vbox), bbox, FALSE, FALSE, 0);
|
||||
|
||||
save = gtk_button_new_with_label(_("Save"));
|
||||
gtk_signal_connect(GTK_OBJECT(save), "clicked", GTK_SIGNAL_FUNC(save_cb), NULL);
|
||||
GTK_WIDGET_SET_FLAGS(save, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX(bbox), save, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(save);
|
||||
|
||||
remove_id3 = gtk_button_new_with_label(_("Remove ID3"));
|
||||
gtk_signal_connect(GTK_OBJECT(remove_id3), "clicked", GTK_SIGNAL_FUNC(remove_id3_cb), NULL);
|
||||
GTK_WIDGET_SET_FLAGS(remove_id3, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX(bbox), remove_id3, TRUE, TRUE, 0);
|
||||
|
||||
cancel = gtk_button_new_with_label(_("Cancel"));
|
||||
gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window));
|
||||
GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
|
||||
|
||||
flac_frame = gtk_frame_new(_("FLAC Info:"));
|
||||
gtk_box_pack_start(GTK_BOX(hbox), flac_frame, FALSE, FALSE, 0);
|
||||
|
||||
flac_box = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(flac_frame), flac_box);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(flac_box), 10);
|
||||
gtk_box_set_spacing(GTK_BOX(flac_box), 0);
|
||||
|
||||
flac_level = gtk_label_new("");
|
||||
gtk_widget_set_usize(flac_level, 120, -2);
|
||||
gtk_misc_set_alignment(GTK_MISC(flac_level), 0, 0);
|
||||
gtk_box_pack_start(GTK_BOX(flac_box), flac_level, FALSE, FALSE, 0);
|
||||
|
||||
flac_bitrate = gtk_label_new("");
|
||||
gtk_misc_set_alignment(GTK_MISC(flac_bitrate), 0, 0);
|
||||
gtk_label_set_justify(GTK_LABEL(flac_bitrate), GTK_JUSTIFY_LEFT);
|
||||
gtk_box_pack_start(GTK_BOX(flac_box), flac_bitrate, FALSE, FALSE, 0);
|
||||
|
||||
flac_samplerate = gtk_label_new("");
|
||||
gtk_misc_set_alignment(GTK_MISC(flac_samplerate), 0, 0);
|
||||
gtk_box_pack_start(GTK_BOX(flac_box), flac_samplerate, FALSE, FALSE, 0);
|
||||
|
||||
flac_flags = gtk_label_new("");
|
||||
gtk_misc_set_alignment(GTK_MISC(flac_flags), 0, 0);
|
||||
gtk_label_set_justify(GTK_LABEL(flac_flags), GTK_JUSTIFY_LEFT);
|
||||
gtk_box_pack_start(GTK_BOX(flac_box), flac_flags, FALSE, FALSE, 0);
|
||||
|
||||
flac_fileinfo = gtk_label_new("");
|
||||
gtk_misc_set_alignment(GTK_MISC(flac_fileinfo), 0, 0);
|
||||
gtk_label_set_justify(GTK_LABEL(flac_fileinfo), GTK_JUSTIFY_LEFT);
|
||||
gtk_box_pack_start(GTK_BOX(flac_box), flac_fileinfo, FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all(window);
|
||||
}
|
||||
|
||||
if (current_filename)
|
||||
g_free(current_filename);
|
||||
current_filename = g_strdup(filename);
|
||||
|
||||
title = g_strdup_printf(_("File Info - %s"), g_basename(filename));
|
||||
gtk_window_set_title(GTK_WINDOW(window), title);
|
||||
g_free(title);
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(filename_entry), filename);
|
||||
gtk_editable_set_position(GTK_EDITABLE(filename_entry), -1);
|
||||
|
||||
if (tag.title != NULL && strlen(tag.title) > 0)
|
||||
{
|
||||
gtk_entry_set_text(GTK_ENTRY(title_entry), tag.title);
|
||||
}
|
||||
else
|
||||
{
|
||||
title = g_strdup(g_basename(filename));
|
||||
if ((tmp = strrchr(title, '.')) != NULL)
|
||||
*tmp = '\0';
|
||||
gtk_entry_set_text(GTK_ENTRY(title_entry), title);
|
||||
g_free(title);
|
||||
}
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(artist_entry), tag.artist);
|
||||
gtk_entry_set_text(GTK_ENTRY(album_entry), tag.album);
|
||||
gtk_entry_set_text(GTK_ENTRY(year_entry), tag.year);
|
||||
gtk_entry_set_text(GTK_ENTRY(tracknum_entry), tag.track);
|
||||
gtk_entry_set_text(GTK_ENTRY(comment_entry), tag.comment);
|
||||
gtk_entry_set_text(GTK_ENTRY(genre_entry), tag.genre);
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(flac_level), "");
|
||||
gtk_label_set_text(GTK_LABEL(flac_bitrate), "");
|
||||
gtk_label_set_text(GTK_LABEL(flac_samplerate), "");
|
||||
gtk_label_set_text(GTK_LABEL(flac_flags), "");
|
||||
gtk_label_set_text(GTK_LABEL(flac_fileinfo), "");
|
||||
|
||||
if (!strncasecmp(filename, "http://", 7))
|
||||
{
|
||||
file_info_http(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive(id3_frame, TRUE);
|
||||
|
||||
label_set_text(flac_bitrate, _("Bits/Samples: %d"), tmp_file_info->bits_per_sample);
|
||||
/* tmp_file_info->length_in_msec */
|
||||
|
||||
label_set_text(flac_samplerate, _("Samplerate: %ld Hz"), tmp_file_info->sample_rate);
|
||||
label_set_text(flac_channel, _("Channel: %s"), channel_mode_name(tmp_file_info->channel);
|
||||
#if 0
|
||||
label_set_text(flac_fileinfo, _("%d frames\nFilesize: %lu B"), num_frames, ftell(fh));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
187
src/plugin_xmms/genres.h
Normal file
187
src/plugin_xmms/genres.h
Normal file
@ -0,0 +1,187 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Based on genres.h - EasyTAG - Jerome Couderc 2000/05/29
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GENRES_H__
|
||||
#define __GENRES_H__
|
||||
|
||||
|
||||
/* GENRE_MAX is the last genre number that can be used */
|
||||
#define GENRE_MAX ( sizeof(id3_genres)/sizeof(id3_genres[0]) - 1 )
|
||||
#define ID3_INVALID_GENRE 255
|
||||
|
||||
|
||||
/*
|
||||
* Do not sort genres!!
|
||||
* Last Update: 2000/04/30
|
||||
*/
|
||||
static char *id3_genres[] =
|
||||
{
|
||||
"Blues", /* 0 */
|
||||
"Classic Rock",
|
||||
"Country",
|
||||
"Dance",
|
||||
"Disco",
|
||||
"Funk", /* 5 */
|
||||
"Grunge",
|
||||
"Hip-Hop",
|
||||
"Jazz",
|
||||
"Metal",
|
||||
"New Age", /* 10 */
|
||||
"Oldies",
|
||||
"Other",
|
||||
"Pop",
|
||||
"R&B",
|
||||
"Rap", /* 15 */
|
||||
"Reggae",
|
||||
"Rock",
|
||||
"Techno",
|
||||
"Industrial",
|
||||
"Alternative", /* 20 */
|
||||
"Ska",
|
||||
"Death Metal",
|
||||
"Pranks",
|
||||
"Soundtrack",
|
||||
"Euro-Techno", /* 25 */
|
||||
"Ambient",
|
||||
"Trip-Hop",
|
||||
"Vocal",
|
||||
"Jazz+Funk",
|
||||
"Fusion", /* 30 */
|
||||
"Trance",
|
||||
"Classical",
|
||||
"Instrumental",
|
||||
"Acid",
|
||||
"House", /* 35 */
|
||||
"Game",
|
||||
"Sound Clip",
|
||||
"Gospel",
|
||||
"Noise",
|
||||
"Altern Rock", /* 40 */
|
||||
"Bass",
|
||||
"Soul",
|
||||
"Punk",
|
||||
"Space",
|
||||
"Meditative", /* 45 */
|
||||
"Instrumental Pop",
|
||||
"Instrumental Rock",
|
||||
"Ethnic",
|
||||
"Gothic",
|
||||
"Darkwave", /* 50 */
|
||||
"Techno-Industrial",
|
||||
"Electronic",
|
||||
"Pop-Folk",
|
||||
"Eurodance",
|
||||
"Dream", /* 55 */
|
||||
"Southern Rock",
|
||||
"Comedy",
|
||||
"Cult",
|
||||
"Gangsta",
|
||||
"Top 40", /* 60 */
|
||||
"Christian Rap",
|
||||
"Pop/Funk",
|
||||
"Jungle",
|
||||
"Native American",
|
||||
"Cabaret", /* 65 */
|
||||
"New Wave",
|
||||
"Psychadelic",
|
||||
"Rave",
|
||||
"Showtunes",
|
||||
"Trailer", /* 70 */
|
||||
"Lo-Fi",
|
||||
"Tribal",
|
||||
"Acid Punk",
|
||||
"Acid Jazz",
|
||||
"Polka", /* 75 */
|
||||
"Retro",
|
||||
"Musical",
|
||||
"Rock & Roll",
|
||||
"Hard Rock",
|
||||
"Folk", /* 80 */
|
||||
"Folk/Rock",
|
||||
"National Folk",
|
||||
"Fast Fusion",
|
||||
"Swing",
|
||||
"Bebob", /* 85 */
|
||||
"Latin",
|
||||
"Revival",
|
||||
"Celtic",
|
||||
"Bluegrass",
|
||||
"Avantgarde", /* 90 */
|
||||
"Gothic Rock",
|
||||
"Progressive Rock",
|
||||
"Psychedelic Rock",
|
||||
"Symphonic Rock",
|
||||
"Slow Rock", /* 95 */
|
||||
"Big Band",
|
||||
"Chorus",
|
||||
"Easy Listening",
|
||||
"Acoustic",
|
||||
"Humour", /* 100 */
|
||||
"Speech",
|
||||
"Chanson",
|
||||
"Opera",
|
||||
"Chamber Music",
|
||||
"Sonata", /* 105 */
|
||||
"Symphony",
|
||||
"Booty Bass",
|
||||
"Primus",
|
||||
"Porn Groove",
|
||||
"Satire", /* 110 */
|
||||
"Slow Jam",
|
||||
"Club",
|
||||
"Tango",
|
||||
"Samba",
|
||||
"Folklore", /* 115 */
|
||||
"Ballad",
|
||||
"Power Ballad",
|
||||
"Rhythmic Soul",
|
||||
"Freestyle",
|
||||
"Duet", /* 120 */
|
||||
"Punk Rock",
|
||||
"Drum Solo",
|
||||
"A Capella",
|
||||
"Euro-House",
|
||||
"Dance Hall", /* 125 */
|
||||
"Goa",
|
||||
"Drum & Bass",
|
||||
"Club-House",
|
||||
"Hardcore",
|
||||
"Terror", /* 130 */
|
||||
"Indie",
|
||||
"BritPop",
|
||||
"Negerpunk",
|
||||
"Polsk Punk",
|
||||
"Beat", /* 135 */
|
||||
"Christian Gangsta Rap",
|
||||
"Heavy Metal",
|
||||
"Black Metal",
|
||||
"Crossover",
|
||||
"Contemporary Christian",/* 140 */
|
||||
"Christian Rock",
|
||||
"Merengue",
|
||||
"Salsa",
|
||||
"Thrash Metal",
|
||||
"Anime", /* 145 */
|
||||
"JPop",
|
||||
"Synthpop"
|
||||
};
|
||||
|
||||
#endif /* __GENRES_H__ */
|
508
src/plugin_xmms/id3_tag.c
Normal file
508
src/plugin_xmms/id3_tag.c
Normal file
@ -0,0 +1,508 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Almost from id3_tag.c - 2001/02/16
|
||||
* EasyTAG - Tag editor for MP3 and OGG files
|
||||
* Copyright (C) 2001-2002 Jerome Couderc <j.couderc@ifrance.com>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <id3.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "configure.h"
|
||||
#include "genres.h"
|
||||
#include "charset.h"
|
||||
#include "mylocale.h"
|
||||
#include "id3_tag.h"
|
||||
|
||||
/****************
|
||||
* Declarations *
|
||||
****************/
|
||||
#define ID3V2_MAX_STRING_LEN 4096
|
||||
#define NUMBER_TRACK_FORMATED 1
|
||||
|
||||
/**************
|
||||
* Prototypes *
|
||||
**************/
|
||||
static size_t ID3Tag_Link_1 (ID3Tag *id3tag, const char *filename);
|
||||
static size_t ID3Field_GetASCII_1 (const ID3Field *field, char *buffer, size_t maxChars, index_t itemNum);
|
||||
|
||||
static gchar *Id3tag_Genre_To_String (unsigned char genre_code);
|
||||
static void Strip_String (gchar *string);
|
||||
|
||||
/*************
|
||||
* Functions *
|
||||
*************/
|
||||
/*
|
||||
* Read id3v1.x / id3v2 tag and load data into the File_Tag structure using id3lib functions.
|
||||
* Returns TRUE on success, else FALSE.
|
||||
* If a tag entry exists (ex: title), we allocate memory, else value stays to NULL
|
||||
*/
|
||||
gboolean Id3tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
|
||||
{
|
||||
FILE *file;
|
||||
ID3Tag *id3_tag = NULL; /* Tag defined by the id3lib */
|
||||
gchar *string, *string1, *string2;
|
||||
gboolean USE_CHARACTER_SET_TRANSLATION;
|
||||
|
||||
USE_CHARACTER_SET_TRANSLATION = flac_cfg.convert_char_set;
|
||||
|
||||
if (!filename || !FileTag)
|
||||
return FALSE;
|
||||
|
||||
if ( (file=fopen(filename,"r"))==NULL )
|
||||
{
|
||||
g_print(_("ERROR while opening file: '%s' (%s).\n\a"),filename,g_strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
fclose(file); // We close it cause id3lib opens/closes file itself
|
||||
|
||||
|
||||
/* Get data from tag */
|
||||
if ( (id3_tag = ID3Tag_New()) )
|
||||
{
|
||||
ID3Frame *id3_frame;
|
||||
ID3Field *id3_field;
|
||||
luint frm_size;
|
||||
luint num_chars;
|
||||
guint field_num = 0; // First field
|
||||
|
||||
/* Link the file to the tag */
|
||||
frm_size = ID3Tag_Link_1(id3_tag,filename);
|
||||
|
||||
string = g_malloc(ID3V2_MAX_STRING_LEN+1);
|
||||
|
||||
/*********
|
||||
* Title *
|
||||
*********/
|
||||
if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_TITLE)) )
|
||||
{
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
|
||||
{
|
||||
// Note: if 'num_chars' is equal to 0, then the field is empty or corrupted!
|
||||
if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
|
||||
&& string != NULL )
|
||||
{
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(string);
|
||||
Strip_String(string1);
|
||||
FileTag->title = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
Strip_String(string);
|
||||
FileTag->title = g_strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********
|
||||
* Artist *
|
||||
**********/
|
||||
if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_LEADARTIST)) )
|
||||
{
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
|
||||
{
|
||||
if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
|
||||
&& string != NULL )
|
||||
{
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(string);
|
||||
Strip_String(string1);
|
||||
FileTag->artist = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
Strip_String(string);
|
||||
FileTag->artist = g_strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
* Album *
|
||||
*********/
|
||||
if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_ALBUM)) )
|
||||
{
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
|
||||
{
|
||||
if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
|
||||
&& string != NULL )
|
||||
{
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(string);
|
||||
Strip_String(string1);
|
||||
FileTag->album = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
Strip_String(string);
|
||||
FileTag->album = g_strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********
|
||||
* Year *
|
||||
********/
|
||||
if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_YEAR)) )
|
||||
{
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
|
||||
{
|
||||
if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
|
||||
&& string != NULL )
|
||||
{
|
||||
gchar *tmp_str;
|
||||
|
||||
Strip_String(string);
|
||||
|
||||
/* Fix for id3lib 3.7.x: if the id3v1.x tag was filled with spaces
|
||||
* instead of zeroes, then the year field contains garbages! */
|
||||
tmp_str = string;
|
||||
while (isdigit(*tmp_str)) tmp_str++;
|
||||
*tmp_str = 0;
|
||||
/* End of fix for id3lib 3.7.x */
|
||||
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(string);
|
||||
Strip_String(string1);
|
||||
FileTag->year = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
Strip_String(string);
|
||||
FileTag->year = g_strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
* Track and Total Track *
|
||||
*************************/
|
||||
if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_TRACKNUM)) )
|
||||
{
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
|
||||
{
|
||||
if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
|
||||
&& string != NULL )
|
||||
{
|
||||
|
||||
Strip_String(string);
|
||||
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(string);
|
||||
string2 = strchr(string1,'/');
|
||||
if (NUMBER_TRACK_FORMATED)
|
||||
{
|
||||
if (string2)
|
||||
{
|
||||
FileTag->track_total = g_strdup_printf("%.2d",atoi(string2+1)); // Just to have numbers like this : '01', '05', '12', ...
|
||||
*string2 = '\0';
|
||||
}
|
||||
FileTag->track = g_strdup_printf("%.2d",atoi(string1)); // Just to have numbers like this : '01', '05', '12', ...
|
||||
}else
|
||||
{
|
||||
if (string2)
|
||||
{
|
||||
FileTag->track_total = g_strdup(string2+1);
|
||||
*string2 = '\0';
|
||||
}
|
||||
FileTag->track = g_strdup(string1);
|
||||
}
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
string2 = strchr(string,'/');
|
||||
if (NUMBER_TRACK_FORMATED)
|
||||
{
|
||||
if (string2)
|
||||
{
|
||||
FileTag->track_total = g_strdup_printf("%.2d",atoi(string2+1)); // Just to have numbers like this : '01', '05', '12', ...
|
||||
*string2 = '\0';
|
||||
}
|
||||
FileTag->track = g_strdup_printf("%.2d",atoi(string)); // Just to have numbers like this : '01', '05', '12', ...
|
||||
}else
|
||||
{
|
||||
if (string2)
|
||||
{
|
||||
FileTag->track_total = g_strdup(string2+1);
|
||||
*string2 = '\0';
|
||||
}
|
||||
FileTag->track = g_strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
* Genre *
|
||||
*********/
|
||||
if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_CONTENTTYPE)) )
|
||||
{
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
|
||||
{
|
||||
/*
|
||||
* We manipulate only the name of the genre
|
||||
*/
|
||||
if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
|
||||
&& string != NULL )
|
||||
{
|
||||
gchar *tmp;
|
||||
|
||||
Strip_String(string);
|
||||
|
||||
if ( (string[0]=='(') && (tmp=strchr(string,')')) && (strlen((tmp+1))>0) )
|
||||
{
|
||||
|
||||
/* Convert a genre written as '(3)Dance' into 'Dance' */
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(tmp+1);
|
||||
FileTag->genre = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
FileTag->genre = g_strdup(tmp+1);
|
||||
}
|
||||
|
||||
}else if ( (string[0]=='(') && (tmp=strchr(string,')')) )
|
||||
{
|
||||
|
||||
/* Convert a genre written as '(3)' into 'Dance' */
|
||||
*tmp = 0;
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(Id3tag_Genre_To_String(atoi(string+1)));
|
||||
FileTag->genre = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
FileTag->genre = g_strdup(Id3tag_Genre_To_String(atoi(string+1)));
|
||||
}
|
||||
|
||||
}else
|
||||
{
|
||||
|
||||
/* Genre is already written as 'Dance' */
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(string);
|
||||
FileTag->genre = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
FileTag->genre = g_strdup(string);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********
|
||||
* Comment *
|
||||
***********/
|
||||
if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_COMMENT)) )
|
||||
{
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
|
||||
{
|
||||
if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
|
||||
&& string != NULL )
|
||||
{
|
||||
if (USE_CHARACTER_SET_TRANSLATION)
|
||||
{
|
||||
string1 = convert_from_file_to_user(string);
|
||||
Strip_String(string1);
|
||||
FileTag->comment = g_strdup(string1);
|
||||
g_free(string1);
|
||||
}else
|
||||
{
|
||||
Strip_String(string);
|
||||
FileTag->comment = g_strdup(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_DESCRIPTION)) )
|
||||
{
|
||||
gchar *comment1 = g_malloc0(MAX_STRING_LEN+1);
|
||||
num_chars = ID3Field_GetASCII(id3_field,comment1,MAX_STRING_LEN,Item_Num);
|
||||
g_free(comment1);
|
||||
}
|
||||
if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_LANGUAGE)) )
|
||||
{
|
||||
gchar *comment2 = g_malloc0(MAX_STRING_LEN+1);
|
||||
num_chars = ID3Field_GetASCII(id3_field,comment2,MAX_STRING_LEN,Item_Num);
|
||||
g_free(comment2);
|
||||
}*/
|
||||
}
|
||||
g_free(string);
|
||||
|
||||
/* Free allocated data */
|
||||
ID3Tag_Delete(id3_tag);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void Initialize_File_Tag_Item (File_Tag *FileTag)
|
||||
{
|
||||
if (FileTag)
|
||||
{
|
||||
FileTag->key = 0;
|
||||
FileTag->saved = FALSE;
|
||||
FileTag->title = NULL;
|
||||
FileTag->artist = NULL;
|
||||
FileTag->album = NULL;
|
||||
FileTag->track = NULL;
|
||||
FileTag->track_total = NULL;
|
||||
FileTag->year = NULL;
|
||||
FileTag->genre = NULL;
|
||||
FileTag->comment = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees a File_Tag item.
|
||||
*/
|
||||
gboolean Free_File_Tag_Item (File_Tag *FileTag)
|
||||
{
|
||||
if (!FileTag) return FALSE;
|
||||
|
||||
if (FileTag->title) g_free(FileTag->title);
|
||||
if (FileTag->artist) g_free(FileTag->artist);
|
||||
if (FileTag->album) g_free(FileTag->album);
|
||||
if (FileTag->year) g_free(FileTag->year);
|
||||
if (FileTag->track) g_free(FileTag->track);
|
||||
if (FileTag->track_total) g_free(FileTag->track_total);
|
||||
if (FileTag->genre) g_free(FileTag->genre);
|
||||
if (FileTag->comment) g_free(FileTag->comment);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the name of a genre code if found
|
||||
* Three states for genre code :
|
||||
* - defined (0 to GENRE_MAX)
|
||||
* - undefined/unknown (GENRE_MAX+1 to ID3_INVALID_GENRE-1)
|
||||
* - invalid (>ID3_INVALID_GENRE)
|
||||
*/
|
||||
static gchar *Id3tag_Genre_To_String (unsigned char genre_code)
|
||||
{
|
||||
if (genre_code>=ID3_INVALID_GENRE) /* empty */
|
||||
return "";
|
||||
else if (genre_code>GENRE_MAX) /* unknown tag */
|
||||
return "Unknown";
|
||||
else /* known tag */
|
||||
return id3_genres[genre_code];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* As the ID3Tag_Link function of id3lib-3.8.0pre2 returns the ID3v1 tags
|
||||
* when a file has both ID3v1 and ID3v2 tags, we first try to explicitely
|
||||
* get the ID3v2 tags with ID3Tag_LinkWithFlags and, if we cannot get them,
|
||||
* fall back to the ID3v1 tags.
|
||||
* (Written by Holger Schemel).
|
||||
*/
|
||||
static size_t ID3Tag_Link_1 (ID3Tag *id3tag, const char *filename)
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
# if ( (ID3LIB_MAJOR >= 3) && (ID3LIB_MINOR >= 8) )
|
||||
/* First, try to get the ID3v2 tags */
|
||||
offset = ID3Tag_LinkWithFlags(id3tag,filename,ID3TT_ID3V2);
|
||||
if (offset == 0)
|
||||
{
|
||||
/* No ID3v2 tags available => try to get the ID3v1 tags */
|
||||
offset = ID3Tag_LinkWithFlags(id3tag,filename,ID3TT_ID3V1);
|
||||
}
|
||||
# else
|
||||
/* Function 'ID3Tag_LinkWithFlags' is not defined up to id3lib-.3.7.13 */
|
||||
offset = ID3Tag_Link(id3tag,filename);
|
||||
# endif
|
||||
//g_print("ID3 TAG SIZE: %d\t%s\n",offset,g_basename(filename));
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* As the ID3Field_GetASCII function differs with the version of id3lib, we must redefine it.
|
||||
*/
|
||||
static size_t ID3Field_GetASCII_1(const ID3Field *field, char *buffer, size_t maxChars, index_t itemNum)
|
||||
{
|
||||
|
||||
/* Defined by id3lib: ID3LIB_MAJOR_VERSION, ID3LIB_MINOR_VERSION, ID3LIB_PATCH_VERSION
|
||||
* Defined by autoconf: ID3LIB_MAJOR, ID3LIB_MINOR, ID3LIB_PATCH
|
||||
*
|
||||
* <= 3.7.12 : first item num is 1 for ID3Field_GetASCII
|
||||
* = 3.7.13 : first item num is 0 for ID3Field_GetASCII
|
||||
* >= 3.8.0 : doesn't need item num for ID3Field_GetASCII
|
||||
*/
|
||||
//g_print("id3lib version: %d.%d.%d\n",ID3LIB_MAJOR,ID3LIB_MINOR,ID3LIB_PATCH);
|
||||
# if (ID3LIB_MAJOR >= 3)
|
||||
// (>= 3.x.x)
|
||||
# if (ID3LIB_MINOR <= 7)
|
||||
// (3.0.0 to 3.7.x)
|
||||
# if (ID3LIB_PATCH >= 13)
|
||||
// (>= 3.7.13)
|
||||
return ID3Field_GetASCII(field,buffer,maxChars,itemNum);
|
||||
# else
|
||||
return ID3Field_GetASCII(field,buffer,maxChars,itemNum+1);
|
||||
# endif
|
||||
# else
|
||||
// (>= to 3.8.0)
|
||||
//return ID3Field_GetASCII(field,buffer,maxChars);
|
||||
return ID3Field_GetASCIIItem(field,buffer,maxChars,itemNum);
|
||||
# endif
|
||||
# else
|
||||
// Not tested (< 3.x.x)
|
||||
return ID3Field_GetASCII(field,buffer,maxChars,itemNum+1);
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete spaces at the end and the beginning of the string
|
||||
*/
|
||||
static void Strip_String (gchar *string)
|
||||
{
|
||||
if (!string) return;
|
||||
string = g_strstrip(string);
|
||||
}
|
||||
|
67
src/plugin_xmms/id3_tag.h
Normal file
67
src/plugin_xmms/id3_tag.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Based on id3_tag.h - 2001/02/16
|
||||
* et_core.h - 2001/10/21
|
||||
* EasyTAG - Tag editor for MP3 and OGG files
|
||||
* Copyright (C) 2001-2002 Jerome Couderc <j.couderc@ifrance.com>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ID3TAG_H__
|
||||
#define __ID3TAG_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/***************
|
||||
* Declaration *
|
||||
***************/
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Description of each item of the TagList list
|
||||
*/
|
||||
typedef struct _File_Tag File_Tag;
|
||||
struct _File_Tag
|
||||
{
|
||||
gulong key; /* Incremented value */
|
||||
gboolean saved; /* Set to TRUE if this tag had been saved */
|
||||
gchar *title; /* Title of track */
|
||||
gchar *artist; /* Artist name */
|
||||
gchar *album; /* Album name */
|
||||
gchar *year; /* Year of track */
|
||||
gchar *track; /* Position of track in the album */
|
||||
gchar *track_total; /* The number of tracks for the album (ex: 12/20) */
|
||||
gchar *genre; /* Genre of song */
|
||||
gchar *comment; /* Comment */
|
||||
};
|
||||
|
||||
/**************
|
||||
* Prototypes *
|
||||
**************/
|
||||
void Initialize_File_Tag_Item (File_Tag *FileTag);
|
||||
gboolean Free_File_Tag_Item (File_Tag *FileTag);
|
||||
gboolean Id3tag_Read_File_Tag (gchar *filename, File_Tag *FileTag);
|
||||
|
||||
#endif /* __ID3TAG_H__ */
|
55
src/plugin_xmms/mylocale.h
Normal file
55
src/plugin_xmms/mylocale.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
*
|
||||
* locale.h - 2000/05/05 13:10 Jerome Couderc
|
||||
* EasyTAG - Tag editor for MP3 and OGG files
|
||||
* Copyright (C) 1999-2001 H蛆ard Kv虱en <havardk@xmms.org>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Gettext support for EasyTAG
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __MY_LOCALE_H__
|
||||
#define __MY_LOCALE_H__
|
||||
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
/*
|
||||
* Standard gettext macros.
|
||||
*/
|
||||
#ifdef ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) gettext (String)
|
||||
# ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
# else
|
||||
# define N_(String) (String)
|
||||
# endif
|
||||
#else
|
||||
# define textdomain(String) (String)
|
||||
# define gettext(String) (String)
|
||||
# define dgettext(Domain,Message) (Message)
|
||||
# define dcgettext(Domain,Message,Type) (Message)
|
||||
# define bindtextdomain(Domain,Directory) (Domain)
|
||||
# define _(String) (String)
|
||||
# define N_(String) (String)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __MY_LOCALE_H__ */
|
@ -22,27 +22,25 @@
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "xmms/plugin.h"
|
||||
#include "xmms/util.h"
|
||||
#include <xmms/plugin.h>
|
||||
#include <xmms/util.h>
|
||||
#include <xmms/configfile.h>
|
||||
#include <xmms/titlestring.h>
|
||||
|
||||
#ifdef HAVE_LANGINFO_CODESET
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "FLAC/all.h"
|
||||
#include "configure.h"
|
||||
#include "wrap_id3.h"
|
||||
#include "charset.h"
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#define min(x,y) ((x)<(y)?(x):(y))
|
||||
|
||||
typedef struct {
|
||||
FLAC__byte raw[128];
|
||||
char title[31];
|
||||
char artist[31];
|
||||
char album[31];
|
||||
char comment[31];
|
||||
unsigned year;
|
||||
unsigned track; /* may be 0 if v1 (not v1.1) tag */
|
||||
unsigned genre;
|
||||
char description[1024]; /* the formatted description passed to xmms */
|
||||
} id3v1_struct;
|
||||
|
||||
typedef struct {
|
||||
FLAC__bool abort_flag;
|
||||
FLAC__bool is_playing;
|
||||
@ -67,7 +65,6 @@ static int FLAC_XMMS__get_time();
|
||||
static void FLAC_XMMS__cleanup();
|
||||
static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length);
|
||||
|
||||
static FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag);
|
||||
static void *play_loop_(void *arg);
|
||||
static FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder);
|
||||
static void safe_decoder_finish_(FLAC__FileDecoder *decoder);
|
||||
@ -76,15 +73,14 @@ static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *d
|
||||
static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
|
||||
static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
|
||||
|
||||
|
||||
InputPlugin flac_ip =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
"FLAC Player v" FLAC__VERSION_STRING,
|
||||
FLAC_XMMS__init,
|
||||
NULL,
|
||||
NULL,
|
||||
FLAC_XMMS__aboutbox,
|
||||
FLAC_XMMS__configure,
|
||||
FLAC_XMMS__is_our_file,
|
||||
NULL,
|
||||
FLAC_XMMS__play_file,
|
||||
@ -101,7 +97,7 @@ InputPlugin flac_ip =
|
||||
NULL,
|
||||
NULL,
|
||||
FLAC_XMMS__get_song_info,
|
||||
NULL, /* file_info_box */
|
||||
NULL, /* file_info_box */
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -122,6 +118,30 @@ InputPlugin *get_iplugin_info()
|
||||
|
||||
void FLAC_XMMS__init()
|
||||
{
|
||||
ConfigFile *cfg;
|
||||
|
||||
flac_cfg.tag_override = FALSE;
|
||||
g_free(flac_cfg.tag_format);
|
||||
flac_cfg.convert_char_set = FALSE;
|
||||
|
||||
cfg = xmms_cfg_open_default_file();
|
||||
xmms_cfg_read_boolean(cfg, "flac", "tag_override", &flac_cfg.tag_override);
|
||||
if (!xmms_cfg_read_string(cfg, "flac", "tag_format",
|
||||
&flac_cfg.tag_format))
|
||||
flac_cfg.tag_format = g_strdup("%p - %t");
|
||||
|
||||
xmms_cfg_read_boolean(cfg, "flac", "convert_char_set", &flac_cfg.convert_char_set);
|
||||
if (!xmms_cfg_read_string(cfg, "flac", "file_char_set",
|
||||
&flac_cfg.file_char_set))
|
||||
{
|
||||
flac_cfg.file_char_set = get_current_charset();
|
||||
}
|
||||
if (!xmms_cfg_read_string(cfg, "flac", "user_char_set",
|
||||
&flac_cfg.user_char_set))
|
||||
{
|
||||
flac_cfg.user_char_set = get_current_charset();
|
||||
}
|
||||
|
||||
decoder_ = FLAC__file_decoder_new();
|
||||
}
|
||||
|
||||
@ -139,7 +159,7 @@ int FLAC_XMMS__is_our_file(char *filename)
|
||||
void FLAC_XMMS__play_file(char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
id3v1_struct tag;
|
||||
gchar *ret;
|
||||
|
||||
reservoir_samples_ = 0;
|
||||
audio_error_ = false;
|
||||
@ -166,8 +186,10 @@ void FLAC_XMMS__play_file(char *filename)
|
||||
return;
|
||||
}
|
||||
|
||||
(void)get_id3v1_tag_(filename, &tag);
|
||||
flac_ip.set_info(tag.description, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
|
||||
ret = flac_format_song_title(filename);
|
||||
flac_ip.set_info(ret, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
|
||||
|
||||
g_free(ret);
|
||||
|
||||
file_info_.seek_to_in_sec = -1;
|
||||
file_info_.play_thread_open = true;
|
||||
@ -219,7 +241,6 @@ void FLAC_XMMS__cleanup()
|
||||
|
||||
void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
|
||||
{
|
||||
id3v1_struct tag;
|
||||
FLAC__StreamMetadata streaminfo;
|
||||
|
||||
if(0 == filename)
|
||||
@ -238,9 +259,7 @@ void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
|
||||
}
|
||||
|
||||
if(title) {
|
||||
(void)get_id3v1_tag_(filename, &tag);
|
||||
*title = g_malloc(strlen(tag.description)+1);
|
||||
strcpy(*title, tag.description);
|
||||
*title = flac_format_song_title(filename);
|
||||
}
|
||||
if(length_in_msec)
|
||||
*length_in_msec = streaminfo.data.stream_info.total_samples * 10 / (streaminfo.data.stream_info.sample_rate / 100);
|
||||
@ -250,52 +269,6 @@ void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
|
||||
* local routines
|
||||
**********************************************************************/
|
||||
|
||||
FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag)
|
||||
{
|
||||
const char *temp;
|
||||
FILE *f = fopen(filename, "rb");
|
||||
memset(tag, 0, sizeof(id3v1_struct));
|
||||
|
||||
/* set the title and description to the filename by default */
|
||||
temp = strrchr(filename, '/');
|
||||
if(!temp)
|
||||
temp = filename;
|
||||
else
|
||||
temp++;
|
||||
strcpy(tag->description, temp);
|
||||
*strrchr(tag->description, '.') = '\0';
|
||||
strncpy(tag->title, tag->description, 30); tag->title[30] = '\0';
|
||||
|
||||
if(0 == f)
|
||||
return false;
|
||||
if(-1 == fseek(f, -128, SEEK_END)) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
if(fread(tag->raw, 1, 128, f) < 128) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
fclose(f);
|
||||
if(strncmp(tag->raw, "TAG", 3))
|
||||
return false;
|
||||
else {
|
||||
char year_str[5];
|
||||
|
||||
memcpy(tag->title, tag->raw+3, 30);
|
||||
memcpy(tag->artist, tag->raw+33, 30);
|
||||
memcpy(tag->album, tag->raw+63, 30);
|
||||
memcpy(year_str, tag->raw+93, 4); year_str[4] = '\0'; tag->year = atoi(year_str);
|
||||
memcpy(tag->comment, tag->raw+97, 30);
|
||||
tag->genre = (unsigned)((FLAC__byte)tag->raw[127]);
|
||||
tag->track = (unsigned)((FLAC__byte)tag->raw[126]);
|
||||
|
||||
sprintf(tag->description, "%s - %s", tag->artist, tag->title);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void *play_loop_(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
@ -463,3 +436,4 @@ void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorS
|
||||
if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
|
||||
file_info->abort_flag = true;
|
||||
}
|
||||
|
||||
|
272
src/plugin_xmms/wrap_id3.c
Normal file
272
src/plugin_xmms/wrap_id3.c
Normal file
@ -0,0 +1,272 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2000,2001,2002 Josh Coalson
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* Based on FLAC plugin.c and mpg123 plugin
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
#include <xmms/plugin.h>
|
||||
#include <xmms/util.h>
|
||||
#include <xmms/configfile.h>
|
||||
#include <xmms/titlestring.h>
|
||||
|
||||
#include "mylocale.h"
|
||||
#include "configure.h"
|
||||
|
||||
#ifdef FLAC__HAS_ID3LIB
|
||||
#include <id3.h>
|
||||
#include "id3_tag.h"
|
||||
|
||||
#else
|
||||
#include "charset.h"
|
||||
#include "genres.h"
|
||||
|
||||
typedef struct id3v1tag_t {
|
||||
char tag[3]; /* always "TAG": defines ID3v1 tag 128 bytes before EOF */
|
||||
char title[30];
|
||||
char artist[30];
|
||||
char album[30];
|
||||
char year[4];
|
||||
union {
|
||||
struct {
|
||||
char comment[30];
|
||||
} v1_0;
|
||||
struct {
|
||||
char comment[28];
|
||||
char __zero;
|
||||
unsigned char track;
|
||||
} v1_1;
|
||||
} u;
|
||||
unsigned char genre;
|
||||
} id3v1_struct;
|
||||
|
||||
typedef struct id3tag_t {
|
||||
char title[64];
|
||||
char artist[64];
|
||||
char album[64];
|
||||
char comment[256];
|
||||
char genre[256];
|
||||
char year[16];
|
||||
char track[16];
|
||||
} id3v2_struct;
|
||||
|
||||
static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *tag);
|
||||
static void flac_id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2);
|
||||
static const char *flac_get_id3_genre(unsigned char genre_code);
|
||||
#endif /* FLAC__HAS_ID3LIB */
|
||||
|
||||
static gchar *extname(const char *filename);
|
||||
static char* flac_getstr(char* str);
|
||||
static int flac_getnum(char* str);
|
||||
|
||||
/*
|
||||
* Function flac_format_song_title (tag, filename)
|
||||
*
|
||||
* Create song title according to `tag' and/or `filename' and
|
||||
* return it. The title must be subsequently freed using g_free().
|
||||
*
|
||||
*/
|
||||
gchar *flac_format_song_title(gchar * filename)
|
||||
{
|
||||
gchar *ret = NULL;
|
||||
TitleInput *input = NULL;
|
||||
gboolean rc;
|
||||
|
||||
#ifdef FLAC__HAS_ID3LIB
|
||||
File_Tag tag;
|
||||
Initialize_File_Tag_Item (&tag);
|
||||
rc = Id3tag_Read_File_Tag (filename, &tag);
|
||||
#else
|
||||
id3v2_struct tag;
|
||||
memset(&tag, 0, sizeof(tag));
|
||||
rc = get_id3v1_tag_as_v2_(filename, &tag);
|
||||
#endif
|
||||
XMMS_NEW_TITLEINPUT(input);
|
||||
|
||||
if (rc)
|
||||
{
|
||||
input->performer = flac_getstr(tag.artist);
|
||||
input->album_name = flac_getstr(tag.album);
|
||||
input->track_name = flac_getstr(tag.title);
|
||||
input->track_number = flac_getnum(tag.track);
|
||||
input->year = flac_getnum(tag.year);
|
||||
input->genre = flac_getstr(tag.genre);
|
||||
input->comment = flac_getstr(tag.comment);
|
||||
}
|
||||
input->file_name = g_basename(filename);
|
||||
input->file_path = filename;
|
||||
input->file_ext = extname(filename);
|
||||
ret = xmms_get_titlestring(flac_cfg.tag_override ?
|
||||
flac_cfg.tag_format :
|
||||
xmms_get_gentitle_format(), input);
|
||||
g_free(input);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
/*
|
||||
* Format according to filename.
|
||||
*/
|
||||
ret = g_strdup(g_basename(filename));
|
||||
if (extname(ret) != NULL)
|
||||
*(extname(ret) - 1) = '\0'; /* removes period */
|
||||
}
|
||||
|
||||
#ifdef FLAC__HAS_ID3LIB
|
||||
Free_File_Tag_Item (&tag);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function extname (filename)
|
||||
*
|
||||
* Return pointer within filename to its extenstion, or NULL if
|
||||
* filename has no extension.
|
||||
*
|
||||
*/
|
||||
static gchar *extname(const char *filename)
|
||||
{
|
||||
gchar *ext = strrchr(filename, '.');
|
||||
|
||||
if (ext != NULL)
|
||||
++ext;
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
static char* flac_getstr(char* str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
return str;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int flac_getnum(char* str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
return atoi(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FLAC__HAS_ID3LIB
|
||||
/*
|
||||
* Function get_idv2_tag_(filename, ID3v2tag)
|
||||
*
|
||||
* Get ID3v2 tag from file.
|
||||
*
|
||||
*/
|
||||
static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *id3v2tag)
|
||||
{
|
||||
FILE *file;
|
||||
id3v1_struct id3v1tag;
|
||||
|
||||
memset(id3v2tag, 0, sizeof(id3v2_struct));
|
||||
|
||||
if ((file = fopen(filename, "rb")) != 0)
|
||||
{
|
||||
if ((fseek(file, -1 * sizeof (id3v1tag), SEEK_END) == 0) &&
|
||||
(fread(&id3v1tag, 1, sizeof (id3v1tag), file) == sizeof (id3v1tag)) &&
|
||||
(strncmp(id3v1tag.tag, "TAG", 3) == 0))
|
||||
{
|
||||
flac_id3v1_to_id3v2(&id3v1tag, id3v2tag);
|
||||
|
||||
if (flac_cfg.convert_char_set)
|
||||
{
|
||||
gchar *string;
|
||||
|
||||
string = convert_from_file_to_user(id3v2tag->title);
|
||||
strcpy(id3v2tag->title, string);
|
||||
g_free(string);
|
||||
|
||||
string = convert_from_file_to_user(id3v2tag->artist);
|
||||
strcpy(id3v2tag->artist, string);
|
||||
g_free(string);
|
||||
|
||||
string = convert_from_file_to_user(id3v2tag->album);
|
||||
strcpy(id3v2tag->album, string);
|
||||
g_free(string);
|
||||
|
||||
string = convert_from_file_to_user(id3v2tag->comment);
|
||||
strcpy(id3v2tag->comment, string);
|
||||
g_free(string);
|
||||
|
||||
string = convert_from_file_to_user(id3v2tag->genre);
|
||||
strcpy(id3v2tag->genre, string);
|
||||
g_free(string);
|
||||
|
||||
string = convert_from_file_to_user(id3v2tag->year);
|
||||
strcpy(id3v2tag->year, string);
|
||||
g_free(string);
|
||||
|
||||
string = convert_from_file_to_user(id3v2tag->track);
|
||||
strcpy(id3v2tag->track, string);
|
||||
g_free(string);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function flac_id3v1_to_id3v2 (v1, v2)
|
||||
*
|
||||
* Convert ID3v1 tag `v1' to ID3v2 tag `v2'.
|
||||
*
|
||||
*/
|
||||
static void flac_id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2)
|
||||
{
|
||||
memset(v2,0,sizeof(id3v2_struct));
|
||||
strncpy(v2->title, v1->title, 30);
|
||||
strncpy(v2->artist, v1->artist, 30);
|
||||
strncpy(v2->album, v1->album, 30);
|
||||
strncpy(v2->comment, v1->u.v1_0.comment, 30);
|
||||
strncpy(v2->genre, flac_get_id3_genre(v1->genre), sizeof (v2->genre));
|
||||
strncpy(v2->year, v1->year, 4);
|
||||
|
||||
/* Check for v1.1 tags. */
|
||||
if (v1->u.v1_1.__zero == 0)
|
||||
sprintf(v2->track, "%d", v1->u.v1_1.track);
|
||||
else
|
||||
strcpy(v2->track, "0");
|
||||
|
||||
g_strstrip(v2->title);
|
||||
g_strstrip(v2->artist);
|
||||
g_strstrip(v2->album);
|
||||
g_strstrip(v2->comment);
|
||||
g_strstrip(v2->genre);
|
||||
g_strstrip(v2->year);
|
||||
g_strstrip(v2->track);
|
||||
}
|
||||
|
||||
static const char *flac_get_id3_genre(unsigned char genre_code)
|
||||
{
|
||||
if (genre_code < GENRE_MAX)
|
||||
return gettext(id3_genres[genre_code]);
|
||||
|
||||
return "";
|
||||
}
|
||||
#endif /* ifndef FLAC__HAS_ID3LIB */
|
24
src/plugin_xmms/wrap_id3.h
Normal file
24
src/plugin_xmms/wrap_id3.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* libxmms-flac - XMMS FLAC input plugin
|
||||
* Copyright (C) 2002 Daisuke Shimamura
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __FLAC_ID3_H__
|
||||
#define __FLAC_ID3_H__
|
||||
|
||||
gchar *flac_format_song_title(gchar * filename);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user