# HG changeset patch # User chainsaw # Date 1161478921 25200 # Node ID a19f24790f3c89edeab5680633d6c8479fdd55c2 # Parent 63bde7ca7ad05f7d27cbfbc9329fe5281c3b8729 [svn] It compiles now. diff -r 63bde7ca7ad0 -r a19f24790f3c ChangeLog --- a/ChangeLog Sat Oct 21 09:21:12 2006 -0700 +++ b/ChangeLog Sat Oct 21 18:02:01 2006 -0700 @@ -1,3 +1,12 @@ +2006-10-21 16:21:12 +0000 Tony Vroon + revision [192] + First attempt at porting our FLAC plugin to API 1.1.3 (completely incompatible, as usual!). Needs more work and a version-sensitize FLAC checker. + trunk/src/flac/Makefile.lite | 39 --- + trunk/src/flac/fileinfo.c | 71 +++++ + trunk/src/flac/plugin.c | 517 +++++++++++++++---------------------------- + 3 files changed, 255 insertions(+), 372 deletions(-) + + 2006-10-20 07:59:45 +0000 Yoshiki Yazawa revision [190] - xspf now uses url encoding for location entry. diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/grabbag/replaygain.h --- a/src/flac/grabbag/replaygain.h Sat Oct 21 09:21:12 2006 -0700 +++ b/src/flac/grabbag/replaygain.h Sat Oct 21 18:02:01 2006 -0700 @@ -1,5 +1,5 @@ /* grabbag - Convenience lib for various routines common to several tools - * Copyright (C) 2002,2003,2004,2005 Josh Coalson + * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -35,6 +35,12 @@ extern const unsigned GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED; +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS; /* = "REPLAYGAIN_REFERENCE_LOUDNESS" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN; /* = "REPLAYGAIN_TRACK_GAIN" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK; /* = "REPLAYGAIN_TRACK_PEAK" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN; /* = "REPLAYGAIN_ALBUM_GAIN" */ +extern const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK; /* = "REPLAYGAIN_ALBUM_PEAK" */ + FLAC__bool grabbag__replaygain_is_valid_sample_frequency(unsigned sample_frequency); FLAC__bool grabbag__replaygain_init(unsigned sample_frequency); @@ -48,13 +54,15 @@ /* These three functions return an error string on error, or NULL if successful */ const char *grabbag__replaygain_analyze_file(const char *filename, float *title_gain, float *title_peak); const char *grabbag__replaygain_store_to_vorbiscomment(FLAC__StreamMetadata *block, float album_gain, float album_peak, float title_gain, float title_peak); +const char *grabbag__replaygain_store_to_vorbiscomment_reference(FLAC__StreamMetadata *block); const char *grabbag__replaygain_store_to_vorbiscomment_album(FLAC__StreamMetadata *block, float album_gain, float album_peak); const char *grabbag__replaygain_store_to_vorbiscomment_title(FLAC__StreamMetadata *block, float title_gain, float title_peak); const char *grabbag__replaygain_store_to_file(const char *filename, float album_gain, float album_peak, float title_gain, float title_peak, FLAC__bool preserve_modtime); +const char *grabbag__replaygain_store_to_file_reference(const char *filename, FLAC__bool preserve_modtime); const char *grabbag__replaygain_store_to_file_album(const char *filename, float album_gain, float album_peak, FLAC__bool preserve_modtime); const char *grabbag__replaygain_store_to_file_title(const char *filename, float title_gain, float title_peak, FLAC__bool preserve_modtime); -FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, double *gain, double *peak); +FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *reference, double *gain, double *peak); double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping); #ifdef __cplusplus diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/plugin.c --- a/src/flac/plugin.c Sat Oct 21 09:21:12 2006 -0700 +++ b/src/flac/plugin.c Sat Oct 21 18:02:01 2006 -0700 @@ -88,7 +88,7 @@ static void *play_loop_(void *arg); -static FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder); +static FLAC__bool safe_decoder_init_(char *filename, FLAC__StreamDecoder *decoder); static void safe_decoder_finish_(FLAC__StreamDecoder *decoder); static void safe_decoder_delete_(FLAC__StreamDecoder *decoder); @@ -186,6 +186,7 @@ { ConfigDb *db; FLAC__uint32 test = 1; + gchar *tmp; is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true; @@ -572,7 +573,7 @@ return 0; /* to silence the compiler warning about not returning a value */ } -FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder) +FLAC__bool safe_decoder_init_(char *filename, FLAC__StreamDecoder *decoder) { if(decoder == 0) return false; diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/plugin_common/Makefile --- a/src/flac/plugin_common/Makefile Sat Oct 21 09:21:12 2006 -0700 +++ b/src/flac/plugin_common/Makefile Sat Oct 21 18:02:01 2006 -0700 @@ -11,12 +11,14 @@ defs.h \ dither.h \ locale_hack.h \ - tags.h + tags.h \ + replaygain.h SOURCES = \ charset.c \ dither.c \ - tags.c + tags.c \ + replaygain.c OBJECTS = ${SOURCES:.c=.o} diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/plugin_common/Makefile.lite --- a/src/flac/plugin_common/Makefile.lite Sat Oct 21 09:21:12 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -# plugin_common - Routines common to several plugins -# Copyright (C) 2002,2003,2004,2005 Josh Coalson -# -# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# -# GNU makefile -# - -topdir = ../.. - -LIB_NAME = libplugin_common -INCLUDES = -I$(topdir)/include -I$(HOME)/local/include -I$(ICONV_INCLUDE_DIR) -DEFINES = - -SRCS_C = \ - charset.c \ - dither.c \ - tags.c - -include $(topdir)/build/lib.mk - -# DO NOT DELETE THIS LINE -- make depend depends on it. diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/plugin_common/README --- a/src/flac/plugin_common/README Sat Oct 21 09:21:12 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -This directory contains a convenience library of routines that are -common to the plugins. diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/plugin_common/plugin_common_static.dsp --- a/src/flac/plugin_common/plugin_common_static.dsp Sat Oct 21 09:21:12 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -# Microsoft Developer Studio Project File - Name="plugin_common_static" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=plugin_common_static - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "plugin_common_static.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "plugin_common_static.mak" CFG="plugin_common_static - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "plugin_common_static - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "plugin_common_static - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "plugin_common" -# PROP Scc_LocalPath "..\.." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "plugin_common_static - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\..\obj\release\lib" -# PROP Intermediate_Dir "Release_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MD /W3 /WX /GX /Ox /Og /Oi /Os /Op /I ".\include" /I "..\..\include" /D "FLAC__NO_DLL" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /nodefaultlib - -!ELSEIF "$(CFG)" == "plugin_common_static - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\..\obj\debug\lib" -# PROP Intermediate_Dir "Debug_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".\include" /I "..\..\include" /D "FLAC__NO_DLL" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /nodefaultlib - -!ENDIF - -# Begin Target - -# Name "plugin_common_static - Win32 Release" -# Name "plugin_common_static - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp" -# Begin Source File - -SOURCE=.\charset.c -# End Source File -# Begin Source File - -SOURCE=.\dither.c -# End Source File -# Begin Source File - -SOURCE=.\tags.c -# End Source File -# End Group -# Begin Group "Public Header Files" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\all.h -# End Source File -# Begin Source File - -SOURCE=.\charset.h -# End Source File -# Begin Source File - -SOURCE=.\dither.h -# End Source File -# Begin Source File - -SOURCE=.\locale_hack.h -# End Source File -# Begin Source File - -SOURCE=.\tags.h -# End Source File -# End Group -# End Target -# End Project diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/plugin_common/replaygain.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/flac/plugin_common/replaygain.c Sat Oct 21 18:02:01 2006 -0700 @@ -0,0 +1,62 @@ +/* plugin_common - Routines common to several plugins + * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson + * Copyright (C) 2003 Philip Jägenstedt + * + * 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. + */ + +#if HAVE_CONFIG_H +# include +#endif + +#include "replaygain.h" +#include "FLAC/ordinals.h" +#include "FLAC/metadata.h" +#include "grabbag.h" + +void FLAC_plugin__replaygain_get_from_file(const char *filename, + double *reference, FLAC__bool *reference_set, + double *track_gain, FLAC__bool *track_gain_set, + double *album_gain, FLAC__bool *album_gain_set, + double *track_peak, FLAC__bool *track_peak_set, + double *album_peak, FLAC__bool *album_peak_set) +{ + FLAC__Metadata_SimpleIterator *iterator = FLAC__metadata_simple_iterator_new(); + + *track_gain_set = *album_gain_set = *track_peak_set = *album_peak_set = false; + + if(0 != iterator) { + if(FLAC__metadata_simple_iterator_init(iterator, filename, /*read_only=*/true, /*preserve_file_stats=*/true)) { + FLAC__bool got_vorbis_comments = false; + do { + if(FLAC__metadata_simple_iterator_get_block_type(iterator) == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + FLAC__StreamMetadata *block = FLAC__metadata_simple_iterator_get_block(iterator); + if(0 != block) { + if(grabbag__replaygain_load_from_vorbiscomment(block, /*album_mode=*/false, /*strict=*/true, reference, track_gain, track_peak)) { + *reference_set = *track_gain_set = *track_peak_set = true; + } + if(grabbag__replaygain_load_from_vorbiscomment(block, /*album_mode=*/true, /*strict=*/true, reference, album_gain, album_peak)) { + *reference_set = *album_gain_set = *album_peak_set = true; + } + FLAC__metadata_object_delete(block); + got_vorbis_comments = true; + } + } + } while (!got_vorbis_comments && FLAC__metadata_simple_iterator_next(iterator)); + } + FLAC__metadata_simple_iterator_delete(iterator); + } + return; +} diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/plugin_common/replaygain.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/flac/plugin_common/replaygain.h Sat Oct 21 18:02:01 2006 -0700 @@ -0,0 +1,32 @@ +/* plugin_common - Routines common to several plugins + * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson + * Copyright (C) 2003 Philip Jägenstedt + * + * 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__PLUGIN_COMMON__REPLAYGAIN_H +#define FLAC__PLUGIN_COMMON__REPLAYGAIN_H + +#include "FLAC/ordinals.h" + +void FLAC_plugin__replaygain_get_from_file(const char *filename, + double *reference, FLAC__bool *reference_set, + double *track_gain, FLAC__bool *track_gain_set, + double *album_gain, FLAC__bool *album_gain_set, + double *track_peak, FLAC__bool *track_peak_set, + double *album_peak, FLAC__bool *album_peak_set); + +#endif diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/replaygain.c --- a/src/flac/replaygain.c Sat Oct 21 09:21:12 2006 -0700 +++ b/src/flac/replaygain.c Sat Oct 21 18:02:01 2006 -0700 @@ -1,5 +1,5 @@ /* grabbag - Convenience lib for various routines common to several tools - * Copyright (C) 2002,2003,2004,2005 Josh Coalson + * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,11 +16,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#if HAVE_CONFIG_H +# include +#endif + #include "grabbag.h" #include "replaygain_analysis.h" #include "FLAC/assert.h" -#include "FLAC/file_decoder.h" #include "FLAC/metadata.h" +#include "FLAC/stream_decoder.h" #include #include #include @@ -41,23 +45,27 @@ #endif #define local_max(a,b) ((a)>(b)?(a):(b)) -static const FLAC__byte *tag_title_gain_ = (FLAC__byte*)"REPLAYGAIN_TRACK_GAIN"; -static const FLAC__byte *tag_title_peak_ = (FLAC__byte*)"REPLAYGAIN_TRACK_PEAK"; -static const FLAC__byte *tag_album_gain_ = (FLAC__byte*)"REPLAYGAIN_ALBUM_GAIN"; -static const FLAC__byte *tag_album_peak_ = (FLAC__byte*)"REPLAYGAIN_ALBUM_PEAK"; +static const char *reference_format_ = "%s=%2.1f dB"; +static const char *gain_format_ = "%s=%+2.2f dB"; static const char *peak_format_ = "%s=%1.8f"; -static const char *gain_format_ = "%s=%+2.2f dB"; static double album_peak_, title_peak_; -const unsigned GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED = 148; +const unsigned GRABBAG__REPLAYGAIN_MAX_TAG_SPACE_REQUIRED = 190; /* + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 29 + 1 + 8 + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12 + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 10 + FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8 + 21 + 1 + 12 */ +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS = (const FLAC__byte * const)"REPLAYGAIN_REFERENCE_LOUDNESS"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN = (const FLAC__byte * const)"REPLAYGAIN_TRACK_GAIN"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK = (const FLAC__byte * const)"REPLAYGAIN_TRACK_PEAK"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_GAIN"; +const FLAC__byte * const GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK = (const FLAC__byte * const)"REPLAYGAIN_ALBUM_PEAK"; + static FLAC__bool get_file_stats_(const char *filename, struct stat *stats) { @@ -82,8 +90,8 @@ FLAC__ASSERT(0 != block); FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + FLAC__ASSERT(0 != format); FLAC__ASSERT(0 != name); - FLAC__ASSERT(0 != value); buffer[sizeof(buffer)-1] = '\0'; /* @@ -266,7 +274,7 @@ FLAC__bool error; } DecoderInstance; -static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) +static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { DecoderInstance *instance = (DecoderInstance*)client_data; const unsigned bits_per_sample = frame->header.bits_per_sample; @@ -295,7 +303,7 @@ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } -static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) +static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { DecoderInstance *instance = (DecoderInstance*)client_data; @@ -318,7 +326,7 @@ } } -static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) +static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { DecoderInstance *instance = (DecoderInstance*)client_data; @@ -330,7 +338,7 @@ const char *grabbag__replaygain_analyze_file(const char *filename, float *title_gain, float *title_peak) { DecoderInstance instance; - FLAC__FileDecoder *decoder = FLAC__file_decoder_new(); + FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); if(0 == decoder) return "memory allocation error"; @@ -338,27 +346,21 @@ instance.error = false; /* It does these three by default but lets be explicit: */ - FLAC__file_decoder_set_md5_checking(decoder, false); - FLAC__file_decoder_set_metadata_ignore_all(decoder); - FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); + FLAC__stream_decoder_set_md5_checking(decoder, false); + FLAC__stream_decoder_set_metadata_ignore_all(decoder); + FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); - FLAC__file_decoder_set_filename(decoder, filename); - FLAC__file_decoder_set_write_callback(decoder, write_callback_); - FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_); - FLAC__file_decoder_set_error_callback(decoder, error_callback_); - FLAC__file_decoder_set_client_data(decoder, &instance); - - if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) { - FLAC__file_decoder_delete(decoder); + if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &instance) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { + FLAC__stream_decoder_delete(decoder); return "initializing decoder"; } - if(!FLAC__file_decoder_process_until_end_of_file(decoder) || instance.error) { - FLAC__file_decoder_delete(decoder); + if(!FLAC__stream_decoder_process_until_end_of_stream(decoder) || instance.error) { + FLAC__stream_decoder_delete(decoder); return "decoding file"; } - FLAC__file_decoder_delete(decoder); + FLAC__stream_decoder_delete(decoder); grabbag__replaygain_get_title(title_gain, title_peak); @@ -369,6 +371,9 @@ { const char *error; + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block))) + return error; + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_title(block, title_gain, title_peak))) return error; @@ -378,20 +383,34 @@ return 0; } +const char *grabbag__replaygain_store_to_vorbiscomment_reference(FLAC__StreamMetadata *block) +{ + FLAC__ASSERT(0 != block); + FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); + + if(FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS) < 0) + return "memory allocation error"; + + if(!append_tag_(block, reference_format_, GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS, ReplayGainReferenceLoudness)) + return "memory allocation error"; + + return 0; +} + const char *grabbag__replaygain_store_to_vorbiscomment_album(FLAC__StreamMetadata *block, float album_gain, float album_peak) { FLAC__ASSERT(0 != block); FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); if( - FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)tag_album_gain_) < 0 || - FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)tag_album_peak_) < 0 + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN) < 0 || + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK) < 0 ) return "memory allocation error"; if( - !append_tag_(block, peak_format_, tag_album_peak_, album_peak) || - !append_tag_(block, gain_format_, tag_album_gain_, album_gain) + !append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN, album_gain) || + !append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK, album_peak) ) return "memory allocation error"; @@ -404,14 +423,14 @@ FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); if( - FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)tag_title_gain_) < 0 || - FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)tag_title_peak_) < 0 + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN) < 0 || + FLAC__metadata_object_vorbiscomment_remove_entries_matching(block, (const char *)GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK) < 0 ) return "memory allocation error"; if( - !append_tag_(block, peak_format_, tag_title_peak_, title_peak) || - !append_tag_(block, gain_format_, tag_title_gain_, title_gain) + !append_tag_(block, gain_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN, title_gain) || + !append_tag_(block, peak_format_, GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK, title_peak) ) return "memory allocation error"; @@ -515,6 +534,26 @@ return 0; } +const char *grabbag__replaygain_store_to_file_reference(const char *filename, FLAC__bool preserve_modtime) +{ + FLAC__Metadata_Chain *chain; + FLAC__StreamMetadata *block; + const char *error; + + if(0 != (error = store_to_file_pre_(filename, &chain, &block))) + return error; + + if(0 != (error = grabbag__replaygain_store_to_vorbiscomment_reference(block))) { + FLAC__metadata_chain_delete(chain); + return error; + } + + if(0 != (error = store_to_file_post_(filename, chain, preserve_modtime))) + return error; + + return 0; +} + const char *grabbag__replaygain_store_to_file_album(const char *filename, float album_gain, float album_peak, FLAC__bool preserve_modtime) { FLAC__Metadata_Chain *chain; @@ -570,7 +609,7 @@ return false; q++; memset(s, 0, sizeof(s)-1); - strncpy(s, q, local_min(sizeof(s)-1, (size_t)(entry->length - (q-p)))); + strncpy(s, q, local_min(sizeof(s)-1, entry->length - (q-p))); v = strtod(s, &end); if(end == s) @@ -580,22 +619,33 @@ return true; } -FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, double *gain, double *peak) +FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *reference, double *gain, double *peak) { - int gain_offset, peak_offset; + int reference_offset, gain_offset, peak_offset; FLAC__ASSERT(0 != block); + FLAC__ASSERT(0 != reference); + FLAC__ASSERT(0 != gain); + FLAC__ASSERT(0 != peak); FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); - if(0 > (gain_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? tag_album_gain_ : tag_title_gain_)))) - return false; - if(0 > (peak_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? tag_album_peak_ : tag_title_peak_)))) - return false; + /* Default to current level until overridden by a detected tag; this + * will always be true until we change replaygain_analysis.c + */ + *reference = ReplayGainReferenceLoudness; + + if(0 <= (reference_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS))) + (void)parse_double_(block->data.vorbis_comment.comments + reference_offset, reference); + + if(0 > (gain_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN : GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN)))) + return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); + if(0 > (peak_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK : GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK)))) + return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); if(!parse_double_(block->data.vorbis_comment.comments + gain_offset, gain)) - return false; + return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); if(!parse_double_(block->data.vorbis_comment.comments + peak_offset, peak)) - return false; + return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); return true; } diff -r 63bde7ca7ad0 -r a19f24790f3c src/flac/replaygain_analysis.h --- a/src/flac/replaygain_analysis.h Sat Oct 21 09:21:12 2006 -0700 +++ b/src/flac/replaygain_analysis.h Sat Oct 21 18:02:01 2006 -0700 @@ -43,6 +43,7 @@ #endif typedef float Float_t; /* Type used for filtering */ +extern Float_t ReplayGainReferenceLoudness; /* in dB SPL, currently == 89.0 */ int InitGainAnalysis ( long samplefreq ); int AnalyzeSamples ( const Float_t* left_samples, const Float_t* right_samples, size_t num_samples, int num_channels );