/* 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
+ * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 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
* 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.
+ * 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.,
+ * with this program; if not, write to the Free Software Foundation, Inc.,
*/
+#include "plugin.h"
+
#include <stdlib.h>
+#include <string.h> /* for strlen() */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdarg.h>
+#include <inttypes.h>
#include <gtk/gtk.h>
#include "FLAC/metadata.h"
#include "charset.h"
#include "configure.h"
-#include "plugin_common/vorbiscomment.h"
-#include "plugin_common/locale_hack.h"
+#include "plugin_common/replaygain.h"
+#include "plugin_common/tags.h"
+#include "locale_hack.h"
static GtkWidget *window = NULL;
static GList *genre_list = NULL;
static GtkWidget *filename_entry, *tag_frame;
static GtkWidget *title_entry, *artist_entry, *album_entry, *date_entry, *tracknum_entry, *comment_entry;
+static GtkWidget *replaygain_reference, *replaygain_track_gain, *replaygain_album_gain, *replaygain_track_peak, *replaygain_album_peak;
static GtkWidget *genre_combo;
static GtkWidget *flac_samplerate, *flac_channels, *flac_bits_per_sample, *flac_blocksize, *flac_filesize, *flac_samples, *flac_bitrate;
static gchar *current_filename = NULL;
-static FLAC_Plugin__CanonicalTag *canonical_tag = NULL;
+static FLAC__StreamMetadata *tags_ = NULL;
static const gchar *vorbis_genres[] =
{
N_("Anime"), N_("JPop"), N_("Synthpop")
};
-static void local__safe_free(void *object)
-{
- if(0 != object)
- free(object);
-}
-
static void label_set_text(GtkWidget * label, char *str, ...)
{
va_list args;
g_free(tempstr);
}
-static void set_entry_tag(GtkEntry * entry, gchar * tag)
+static void set_entry_tag(GtkEntry * entry, const char * utf8)
{
- char *text;
-
- if(tag) {
+ if(utf8) {
if(flac_cfg.title.convert_char_set) {
- text = convert_from_file_to_user(tag);
+ char *text = convert_from_utf8_to_user(utf8);
gtk_entry_set_text(entry, text);
free(text);
}
else
- gtk_entry_set_text(entry, tag);
+ gtk_entry_set_text(entry, utf8);
}
else
gtk_entry_set_text(entry, "");
}
-static char *get_entry_tag(GtkEntry * entry)
+static void get_entry_tag(GtkEntry * entry, const char *name)
{
gchar *text;
+ char *utf8;
text = gtk_entry_get_text(entry);
if (!text || strlen(text) == 0)
- return 0;
+ return;
if(flac_cfg.title.convert_char_set)
- return convert_from_user_to_file(text);
+ utf8 = convert_from_user_to_utf8(text);
else
- return strdup(text);
+ utf8 = text;
+
+ FLAC_plugin__tags_add_tag_utf8(tags_, name, utf8, /*separator=*/0);
+
+ if(flac_cfg.title.convert_char_set)
+ free(utf8);
}
-static void show_tag()
+static void show_tag(void)
{
- set_entry_tag(GTK_ENTRY(title_entry), canonical_tag->title);
- set_entry_tag(GTK_ENTRY(artist_entry), canonical_tag->composer);
- set_entry_tag(GTK_ENTRY(album_entry), canonical_tag->album);
- set_entry_tag(GTK_ENTRY(date_entry), canonical_tag->year_recorded);
- set_entry_tag(GTK_ENTRY(tracknum_entry), canonical_tag->track_number);
- set_entry_tag(GTK_ENTRY(comment_entry), canonical_tag->comment);
- set_entry_tag(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), canonical_tag->genre);
+ set_entry_tag(GTK_ENTRY(title_entry) , FLAC_plugin__tags_get_tag_utf8(tags_, "TITLE"));
+ set_entry_tag(GTK_ENTRY(artist_entry) , FLAC_plugin__tags_get_tag_utf8(tags_, "ARTIST"));
+ set_entry_tag(GTK_ENTRY(album_entry) , FLAC_plugin__tags_get_tag_utf8(tags_, "ALBUM"));
+ set_entry_tag(GTK_ENTRY(date_entry) , FLAC_plugin__tags_get_tag_utf8(tags_, "DATE"));
+ set_entry_tag(GTK_ENTRY(tracknum_entry) , FLAC_plugin__tags_get_tag_utf8(tags_, "TRACKNUMBER"));
+ set_entry_tag(GTK_ENTRY(comment_entry) , FLAC_plugin__tags_get_tag_utf8(tags_, "DESCRIPTION"));
+ set_entry_tag(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), FLAC_plugin__tags_get_tag_utf8(tags_, "GENRE"));
}
static void save_tag(GtkWidget * w, gpointer data)
(void)w;
(void)data;
- local__safe_free(canonical_tag->title);
- local__safe_free(canonical_tag->composer);
- local__safe_free(canonical_tag->album);
- local__safe_free(canonical_tag->year_recorded);
- local__safe_free(canonical_tag->track_number);
- local__safe_free(canonical_tag->comment);
- local__safe_free(canonical_tag->genre);
- canonical_tag->title = get_entry_tag(GTK_ENTRY(title_entry));
- canonical_tag->composer = get_entry_tag(GTK_ENTRY(artist_entry));
- canonical_tag->album = get_entry_tag(GTK_ENTRY(album_entry));
- canonical_tag->year_recorded = get_entry_tag(GTK_ENTRY(date_entry));
- canonical_tag->track_number = get_entry_tag(GTK_ENTRY(tracknum_entry));
- canonical_tag->comment = get_entry_tag(GTK_ENTRY(comment_entry));
- canonical_tag->genre = get_entry_tag(GTK_ENTRY(GTK_COMBO(genre_combo)->entry));
-
- FLAC_plugin__vorbiscomment_set(current_filename, canonical_tag);
+ FLAC_plugin__tags_delete_tag(tags_, "TITLE");
+ FLAC_plugin__tags_delete_tag(tags_, "ARTIST");
+ FLAC_plugin__tags_delete_tag(tags_, "ALBUM");
+ FLAC_plugin__tags_delete_tag(tags_, "DATE");
+ FLAC_plugin__tags_delete_tag(tags_, "TRACKNUMBER");
+ FLAC_plugin__tags_delete_tag(tags_, "DESCRIPTION");
+ FLAC_plugin__tags_delete_tag(tags_, "GENRE");
+
+ get_entry_tag(GTK_ENTRY(title_entry) , "TITLE");
+ get_entry_tag(GTK_ENTRY(artist_entry) , "ARTIST");
+ get_entry_tag(GTK_ENTRY(album_entry) , "ALBUM");
+ get_entry_tag(GTK_ENTRY(date_entry) , "DATE");
+ get_entry_tag(GTK_ENTRY(tracknum_entry) , "TRACKNUMBER");
+ get_entry_tag(GTK_ENTRY(comment_entry) , "DESCRIPTION");
+ get_entry_tag(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), "GENRE");
+
+ FLAC_plugin__tags_set(current_filename, tags_);
gtk_widget_destroy(window);
}
{
(void)w;
(void)data;
-
- local__safe_free(canonical_tag->title);
- local__safe_free(canonical_tag->composer);
- local__safe_free(canonical_tag->album);
- local__safe_free(canonical_tag->year_recorded);
- local__safe_free(canonical_tag->track_number);
- local__safe_free(canonical_tag->comment);
- local__safe_free(canonical_tag->genre);
-
- canonical_tag->title = canonical_tag->composer = canonical_tag->album = canonical_tag->year_recorded = canonical_tag->track_number = canonical_tag->comment = canonical_tag->genre = 0;
-
- FLAC_plugin__vorbiscomment_set(current_filename, canonical_tag);
+
+ FLAC_plugin__tags_delete_tag(tags_, "TITLE");
+ FLAC_plugin__tags_delete_tag(tags_, "ARTIST");
+ FLAC_plugin__tags_delete_tag(tags_, "ALBUM");
+ FLAC_plugin__tags_delete_tag(tags_, "DATE");
+ FLAC_plugin__tags_delete_tag(tags_, "TRACKNUMBER");
+ FLAC_plugin__tags_delete_tag(tags_, "DESCRIPTION");
+ FLAC_plugin__tags_delete_tag(tags_, "GENRE");
+
+ FLAC_plugin__tags_set(current_filename, tags_);
gtk_widget_destroy(window);
}
-static void show_file_info()
+static void show_file_info(void)
{
FLAC__StreamMetadata streaminfo;
struct stat _stat;
label_set_text(flac_blocksize, _("Blocksize: variable\n min/max: %d/%d"), streaminfo.data.stream_info.min_blocksize, streaminfo.data.stream_info.max_blocksize);
if (streaminfo.data.stream_info.total_samples)
- label_set_text(flac_samples, _("Samples: %llu\nLength: %d:%.2d"),
+ label_set_text(flac_samples, _("Samples: %" PRIu64 "\nLength: %d:%.2d"),
streaminfo.data.stream_info.total_samples,
(int)(streaminfo.data.stream_info.total_samples / streaminfo.data.stream_info.sample_rate / 60),
(int)(streaminfo.data.stream_info.total_samples / streaminfo.data.stream_info.sample_rate % 60));
if(!stat(current_filename, &_stat) && S_ISREG(_stat.st_mode)) {
- label_set_text(flac_filesize, _("Filesize: %ld B"), _stat.st_size);
+ label_set_text(flac_filesize, _("Filesize: %zd B"), _stat.st_size);
if (streaminfo.data.stream_info.total_samples)
label_set_text(flac_bitrate, _("Avg. bitrate: %.1f kb/s\nCompression ratio: %.1f%%"),
8.0 * (float)(_stat.st_size) / (1000.0 * (float)streaminfo.data.stream_info.total_samples / (float)streaminfo.data.stream_info.sample_rate),
}
}
+static void show_replaygain(void)
+{
+ /* known limitation: If only one of gain and peak is set, neither will be shown. This is true for
+ * both track and album replaygain tags. Written so it will be easy to fix, with some trouble. */
+
+ gtk_label_set_text(GTK_LABEL(replaygain_reference), "");
+ gtk_label_set_text(GTK_LABEL(replaygain_track_gain), "");
+ gtk_label_set_text(GTK_LABEL(replaygain_album_gain), "");
+ gtk_label_set_text(GTK_LABEL(replaygain_track_peak), "");
+ gtk_label_set_text(GTK_LABEL(replaygain_album_peak), "");
+
+ double reference, track_gain, track_peak, album_gain, album_peak;
+ FLAC__bool reference_set, track_gain_set, track_peak_set, album_gain_set, album_peak_set;
+
+ if(!FLAC_plugin__replaygain_get_from_file(
+ current_filename,
+ &reference, &reference_set,
+ &track_gain, &track_gain_set,
+ &album_gain, &album_gain_set,
+ &track_peak, &track_peak_set,
+ &album_peak, &album_peak_set
+ ))
+ return;
+
+ if(reference_set)
+ label_set_text(replaygain_reference, _("ReplayGain Reference Loudness: %2.1f dB"), reference);
+ if(track_gain_set)
+ label_set_text(replaygain_track_gain, _("ReplayGain Track Gain: %+2.2f dB"), track_gain);
+ if(album_gain_set)
+ label_set_text(replaygain_album_gain, _("ReplayGain Album Gain: %+2.2f dB"), album_gain);
+ if(track_peak_set)
+ label_set_text(replaygain_track_peak, _("ReplayGain Track Peak: %1.8f"), track_peak);
+ if(album_peak_set)
+ label_set_text(replaygain_album_peak, _("ReplayGain Album Peak: %1.8f"), album_peak);
+}
+
void FLAC_XMMS__file_info_box(char *filename)
{
unsigned i;
gtk_label_set_justify(GTK_LABEL(flac_bitrate), GTK_JUSTIFY_LEFT);
gtk_box_pack_start(GTK_BOX(flac_box), flac_bitrate, FALSE, FALSE, 0);
+ replaygain_reference = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(replaygain_reference), 0, 0);
+ gtk_label_set_justify(GTK_LABEL(replaygain_reference), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start(GTK_BOX(flac_box), replaygain_reference, FALSE, FALSE, 0);
+
+ replaygain_track_gain = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(replaygain_track_gain), 0, 0);
+ gtk_label_set_justify(GTK_LABEL(replaygain_track_gain), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start(GTK_BOX(flac_box), replaygain_track_gain, FALSE, FALSE, 0);
+
+ replaygain_album_gain = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(replaygain_album_gain), 0, 0);
+ gtk_label_set_justify(GTK_LABEL(replaygain_album_gain), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start(GTK_BOX(flac_box), replaygain_album_gain, FALSE, FALSE, 0);
+
+ replaygain_track_peak = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(replaygain_track_peak), 0, 0);
+ gtk_label_set_justify(GTK_LABEL(replaygain_track_peak), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start(GTK_BOX(flac_box), replaygain_track_peak, FALSE, FALSE, 0);
+
+ replaygain_album_peak = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(replaygain_album_peak), 0, 0);
+ gtk_label_set_justify(GTK_LABEL(replaygain_album_peak), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start(GTK_BOX(flac_box), replaygain_album_peak, FALSE, FALSE, 0);
+
gtk_widget_show_all(window);
}
gtk_entry_set_text(GTK_ENTRY(filename_entry), filename);
gtk_editable_set_position(GTK_EDITABLE(filename_entry), -1);
- if(canonical_tag)
- FLAC_plugin__canonical_tag_clear(canonical_tag);
- else
- canonical_tag = FLAC_plugin__canonical_tag_new();
+ if(tags_)
+ FLAC_plugin__tags_destroy(&tags_);
- FLAC_plugin__vorbiscomment_get(current_filename, canonical_tag);
+ FLAC_plugin__tags_get(current_filename, &tags_);
show_tag();
show_file_info();
+ show_replaygain();
gtk_widget_set_sensitive(tag_frame, TRUE);
}