Re: [flac-dev] Encoder example for 24-bit files
pcm[i] = (FLAC__int32)buffer[3*i+2]; pcm[i] = 8; pcm[i] |= (FLAC__int32)buffer[3*i+1]; pcm[i] = 8; pcm[i] |= (FLAC__int32)buffer[3*i]; (I might be mistaken but) I think you should realize the 24 bit sample has a sign bit in the last of the bytes. Casting the FLAC__byte from the buffer to FLAC__int32 will not trat the sign bit as such leading to huge, incorrect values (and in a quick tes, to an encoding error). So you should change the cast in the first line to a FLAC__int8. The casts in the next lines aren't needed at all I think. I was writing up an example for you and came up with the following (this is extremely ugly and ineffecient, but should accept 24, 16, or any other bits-per-sample): size_t i; for (i = 0; i need*channels; ++i) { pcm[i] = 0; size_t s; for (s = 0; s (bps / 8 - 1); ++s) pcm[i] |= buffer[(bps / 8) * i + s] (8 * s); pcm[i] |= (FLAC__int8)buffer[(bps / 8) * i + s] (8 * s); } ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [flac-dev] exhaustive-model-search issue results in multi-gigabyte FLAC file
Some more possibly interesting information: 1. With me, both flac 1.2.1 and 1.3.0 fail to produce a flac file at all. They both end with: snippet6.wav: 35% complete, ratio=0,781 snippet6.wav: ERROR during encoding state = FLAC__STREAM_ENCODER_FRAMING_ERROR This is after my entire RAM is filled up (could that be the reason? my swap remains nearly unused though). 2. Flake has no problems with the file, but the file turns into 16 bit when doing that. The resulting flac file can be decoded and encoded by flac without issues. ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[flac-dev] New C++ file encode example
Ok, so I ended up creating 2 versions of this, I hope the attachments aren't too big. The first one is what I mentioned earlier, pretty much a line-for-line translation of the original example. The c++-style casts made the (already ugly) lines with casts even uglier by the way... The difference in the second version is that the metadata objects are no longer heap-allocated. This is more in line with the concept of RAII, and removes the need to keep setting and checking the 'ok' bool, which in the first version needs to be done from the moment the metadata[] is created. The only downside is that users following this example would need to remember to make sure the metadata objects are kept in scope for the duration of encoding. On the other hand, they no longer have to remember to delete all the objects at every point the program returns. Bas encode_example_ver1.patch Description: Binary data main_ver2.cpp Description: Binary data main_ver1.cpp Description: Binary data encode_example_ver2.patch Description: Binary data ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [flac-dev] New C++ file encode example
Full source of the second version. The difference in the second version is that the metadata objects are no longer heap-allocated. This is more in line with the concept of RAII, and removes the need to keep setting and checking the 'ok' bool, which in the first version needs to be done from the moment the metadata[] is created. The only downside is that users following this example would need to remember to make sure the metadata objects are kept in scope for the duration of encoding. On the other hand, they no longer have to remember to delete all the objects at every point the program returns. main_ver2.cpp Description: Binary data ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [flac-dev] New C++ file encode example
And a patch for the 2nd version. encode_example_ver2.patch Description: Binary data ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [flac-dev] Patch for Metadata::Padding
Yes of course. What I had in mind, was to create VorbisComment::append_comment(char const *field_name, char const *field_value) functions, without the need for an Entry object. And similar for insert_comment, replace_comment and others. The idea coming from uses as in the file encode example code, where the Entry object is really not used by itself. The easy way to implement this would be to just create the Entry object in the new function and then call the old function with the Entry object. But I thought this was inefficient and didn't improve on just typing 'append_comment(FLAC::Metadata::VorbisComment::Entry(ARTIST, Justin Bieber))', except it would be a shorter line. The efficient way, when a user controlled Entry object isn't necessary, would really bypass creating the Entry object altogether and copy the char * directly into the underlying FLAC__StreamMetadata struct. But looking at the code (which I did a while ago, so I forgot the details) it would require either duplicating a lot of code or splitting the existing code into some separate functions so the relevant parts can be used by both versions of the append_comment(). It all just seems too much trouble for what it's worth. Bas - Original Message - From: Martin Leese martin.le...@stanfordalumni.org To: flac-dev@xiph.org Cc: Sent: Tuesday, September 11, 2012 9:25 PM Subject: Re: [flac-dev] Patch for Metadata::Padding Bastiaan Timmer wrote: ... In a previous message I mentioned writing some more convenience functions, but on closer inspection they would either be inefficient or very difficult to implement. Could you briefly list these, in case somebody else wants to have a go. Many thanks, Martin -- Martin J Leese E-mail: martin.leese stanfordalumni.org Web: http://members.tripod.com/martin_leese/ ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[flac-dev] Patch for Metadata::Padding
Hi! Attached is a tiny patch adding a convenience function to create a Metadata::Padding object with a certain size in one statement. In a previous message I mentioned writing some more convenience functions, but on closer inspection they would either be inefficient or very difficult to implement. I have also nearly finished converting the cpp file-encode example to use the C++ api, and will upload that later today or tomorrow. I have also changed the non-FLAC related code to be more C++ like (C++ streams for IO, no c style casts, no global vars), but let me know if this is not wanted. Other than that, the new example is just a line-for-line translation into c++. Also, the patch will probably be big (maybe bigger than the raw file), and hard to read. Should I send a patch or just the the file? thanks, Bas metadata_padding.patch Description: Binary data ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[flac-dev] Quick patch to fix FLAC_metadata_object api
A missing '/endcode' tag in include/FLAC/metadata.h causes the FLAC__bool FLAC__metadata_object_cuesheet_set_track() method to not appear in the docs, and the next method (insert_track) to get the documentation of set_track. It also creates a broken link to set_track in the FLAC++ docs. Attached is a tiny patch to fix this. I was actually working on some other (small) patches, but this cropped up and now I'm going to be late for work, so those will have to wait for another day... Basdiff --git a/include/FLAC/metadata.h b/include/FLAC/metadata.h index c98f74d..53b32f9 100644 --- a/include/FLAC/metadata.h +++ b/include/FLAC/metadata.h @@ -1986,7 +1986,7 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMet *\code object-type == FLAC__METADATA_TYPE_CUESHEET \endcode *\code track_num object-data.cue_sheet.num_tracks \endcode *\code (track-indices != NULL track-num_indices 0) || - * (track-indices == NULL track-num_indices == 0) + * (track-indices == NULL track-num_indices == 0) \endcode * \retval FLAC__bool *\c false if \a copy is \c true and malloc() fails, else \c true. */ ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[flac-dev] [PATCH] Add missing functions to VorbisComment class + a few other things
Attached is a patch that adds 5 missing FLAC__metadata_object_vorbiscomment_* functions to the VorbisComment class. In my previous message I stated 8 functions were missing, but on closer inspection, 3 of those belong in the VorbisComment::Entry class, and 2 of them already have equivalent functions in there. The last one (FLAC__metadata_object_vorbiscomment_entry_matches()) does not, but I have not done that one (yet). Looking at the FLAC__metadata_object_cuesheet_* FLAC__metadata_object_picture_* functions, it looks like the corresponding FLAC++ classes are already complete. Maybe some functions are missing from CueSheet::Track. If nobody objects, I will take a look later this week. Also, I've noticed that on my system, flac will not compile with --enable-debug, because some functions that use 'PRId64' get compiled in, but no included header defines 'PRId64'. I have not written a patch because I'm not sure whether this is just my weird system (fairly standard Fedora installation) or all gcc users or all *NIX users. However, should a fix be necessary: PRId64 is defined in inttypes.h which can be included in line 43 of src/libFLAC/lpo.c (after the '#if defined DEBUG') to solve this on my system. Lastly, the reason I tried to compile with debug was some invalid read sizes reported by valgrind when creating a VorbisComment::Entry. The invalid read is reported in set_field_name() at line 653 (src/libFLAC++/metadata.cpp), where strlen() is used on the newly created char *field_name_. I could not see anything wrong with the code though, and strangely enough just calling printf on the field_name_ 1 line before the strlen() removes all valgrind errors. So I'm not sure what's going on, but it's probably a bug in valgrind, maybe somebody on this list knows? Bas Timmer add_vorbiscomment_members.patch Description: Binary data ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [flac-dev] [PATCH] Add missing functions to VorbisComment class + a few other things
While you are at it, can you check/fix the following warning ? metadata.cpp:812:98: warning: narrowing conversion of 'strlen(((const char*)string))' from 'size_t {aka long unsigned int}' to 'FLAC__uint32 {aka unsigned int}' inside { } is ill-formed in C++11 [-Wnarrowing] Thanks ! Yeah sure! I don't get that error because I'm on a 32 bit OS by the way. The message makes it pretty clear you are compiling on 64 bit, so the size_t returned by strlen is 64 bits, but FLAC__StreamMetadata_VorbisComment_Entry expects a FLAC__uint32 (which is obviously 32 bits), so gcc warns/errors that the size_t might not fit. I can think of two solutions: 1. Make the FLAC__StreamMetadata_VorbisComment_Entry struct's 'length' member a FLAC__uint64. 2. static_cast the return value of strlen to 32 bits... I'd say option 2 is easiest, as I don't know what else will be affected by changing the size of FLAC__StreamMetadata_VorbisComment_Entry. The only problem with option 2 would be if the vendor string ever gets larger than ~4.3 billion characters, but I don't think vorbis comments support values that large anyway. Anyway, here's a patch that casts to FLAC__uint32, Note I have the offending code on a very different line number (current git I think), so this patch may not apply cleanly. But it's a one-liner anyway (a one-worder actually), so you could just read it and apply it manually... Also, I don't know if such a cast is considered an expensive operation, but in that case it might be possible to first check the size of size_t (during preprocessing) to see if it is larger than 32 bits. The cast is unnecessary if it is not. Bas narrowing_patch Description: Binary data ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[flac-dev] [PATCH] Add missing functions to SeekTable class
The attached patch adds the missing FLAC__metadata_object_seektable_*() functions from FLAC's metadata object methods (FLAC/metadata.h) to FLAC++'s SeekTable class. Of the 11 functions in the C API, only 4 are currently in the C++ API, this patch adds the missing 7. If this patch is ok, VorbisComment will be next. A quick look tells me only 5 out of 13 FLAC__metadata_object_vorbiscomment*() functions from FLAC/metadata.h exist in FLAC++'s VorbisComment class. Bas Timmerdiff --git a/include/FLAC++/metadata.h b/include/FLAC++/metadata.h index c23af91..94eb6fc 100644 --- a/include/FLAC++/metadata.h +++ b/include/FLAC++/metadata.h @@ -502,6 +502,9 @@ namespace FLAC { unsigned get_num_points() const; ::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const; + //! See FLAC__metadata_object_seektable_resize_points() + bool resize_points(unsigned new_num_points); + //! See FLAC__metadata_object_seektable_set_point() void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint point); @@ -513,6 +516,24 @@ namespace FLAC { //! See FLAC__metadata_object_seektable_is_legal() bool is_legal() const; + + //! See FLAC__metadata_object_seektable_template_append_placeholders() + bool template_append_placeholders(unsigned num); + + //! See FLAC__metadata_object_seektable_template_append_point() + bool template_append_point(FLAC__uint64 sample_number); + + //! See FLAC__metadata_object_seektable_template_append_points() + bool template_append_points(FLAC__uint64 sample_numbers[], unsigned num); + + //! See FLAC__metadata_object_seektable_template_append_spaced_points() + bool template_append_spaced_points(unsigned num, FLAC__uint64 total_samples); + + //! See FLAC__metadata_object_seektable_template_append_spaced_points_by_samples() + bool template_append_spaced_points_by_samples(unsigned samples, FLAC__uint64 total_samples); + + //! See FLAC__metadata_object_seektable_template_sort() + bool template_sort(bool compact); }; /** VORBIS_COMMENT metadata block. diff --git a/src/libFLAC++/metadata.cpp b/src/libFLAC++/metadata.cpp index 3c9f657..0870d02 100644 --- a/src/libFLAC++/metadata.cpp +++ b/src/libFLAC++/metadata.cpp @@ -438,6 +438,12 @@ namespace FLAC { return object_-data.seek_table.points[index]; } + bool SeekTable::resize_points(unsigned new_num_points) + { + FLAC__ASSERT(is_valid()); + return (bool)::FLAC__metadata_object_seektable_resize_points(object_, new_num_points); + } + void SeekTable::set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint point) { FLAC__ASSERT(is_valid()); @@ -465,6 +471,42 @@ namespace FLAC { return (bool)::FLAC__metadata_object_seektable_is_legal(object_); } + bool SeekTable::template_append_placeholders(unsigned num) + { + FLAC__ASSERT(is_valid()); + return (bool)::FLAC__metadata_object_seektable_template_append_placeholders(object_, num); + } + + bool SeekTable::template_append_point(FLAC__uint64 sample_number) + { + FLAC__ASSERT(is_valid()); + return (bool)::FLAC__metadata_object_seektable_template_append_point(object_, sample_number); + } + + bool SeekTable::template_append_points(FLAC__uint64 sample_numbers[], unsigned num) + { + FLAC__ASSERT(is_valid()); + return (bool)::FLAC__metadata_object_seektable_template_append_points(object_, sample_numbers, num); + } + + bool SeekTable::template_append_spaced_points(unsigned num, FLAC__uint64 total_samples) + { + FLAC__ASSERT(is_valid()); + return (bool)::FLAC__metadata_object_seektable_template_append_spaced_points(object_, num, total_samples); + } + + bool SeekTable::template_append_spaced_points_by_samples(unsigned samples, FLAC__uint64 total_samples) + { + FLAC__ASSERT(is_valid()); + return (bool)::FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(object_, samples, total_samples); + } + + bool SeekTable::template_sort(bool compact) + { + FLAC__ASSERT(is_valid()); + return (bool)::FLAC__metadata_object_seektable_template_sort(object_, compact); + } + // // VorbisComment::Entry ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [flac-dev] Writing seektable using libFLAC++
Well, I have to apologize, we can disregard the most important part of my previous mail. The code mentioned in that one does in fact work fine when compiled against current git. I had only compiled against current (but old) stable release when I wrote that, which suffered from a bug (commit 1649c4ab3c08d95fb1056d73d8809fa77d4976dc). And I can, indeed, get rid of the C API calls altogether like this: d_md = new FLAC::Metadata::Prototype *[d_metadatasize]; d_md[d_metadatasize - 1] = new FLAC::Metadata::SeekTable; for (int i = 0; i numseekpoints; ++i) reinterpret_castFLAC::Metadata::Seektable *(d_md[0])-insert_point(i, {i * spacing, 0, 0}); It would, however, still be more natural (and sometimes more efficient) to be able to call 'Seektable::resize_points()' and 'Seektable::set_point()' (as is done in FLAC__metadata_object_seektable_template_append_spaced_points_by_samples()), or even to call 'template_append_spaced_points_by_samples()' directly on the Seektable object so we can write somethign like the following: d_md = new FLAC::Metadata::Prototype *[d_metadatasize]; d_md[d_metadatasize - 1] = new FLAC::Metadata::SeekTable; reinterpret_castFLAC::Metadata::Seektable *(d_md[0])-template_append_spaced_points_by_samples(samples, total_samples); Which would be more or less identical to how it's done in the C API. I am still willing to create those functions in libFLAC++, but I would like to hear if there's any chance they'll make it in (assuming they are written correctly and working). Maybe there is some reason only a few functions from FLAC/metadata.h are currently reproduced in the C++ API... thanks, Bas Timmer ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[flac-dev] Writing seektable using libFLAC++
Hi! I've been using a little C++ program I've written to encode flac files. The program does this in the usual way (I think), by inheriting a class from FLAC::Encoder::File, and passing it chunks of raw samples through process_interleaved()... Anyway, the program works beautifully, and I've now decided to try and add some metadata to the encoded flacs. Eventually, there will be vorbis comments, but right now I'm just trying to add a seektable. From some code examples I've managed to get it working using the libFLAC C API like this: FLAC__StreamMetadata *md[1]; md[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE); // THIS LEAKS FLAC__metadata_object_seektable_template_append_spaced_points(md[0], 13, d_bytestotal / 4); FLAC__metadata_object_seektable_template_sort(md[0], true); set_metadata(md, 1); Now, I have several questions: 1. Most importantly: How can I get this to work with the libFLAC++ API? Do I not _need_ the template-methods, and are they not missing from the C++ API? I've also tried getting just half the metadata code from the C++ API and using the C API for the template-functions, like this: FLAC::Metadata::Prototype *md[1]; FLAC__StreamMetadata *seektable = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE); FLAC__metadata_object_seektable_template_append_spaced_points(seektable, 13, d_bytestotal / 4); FLAC__metadata_object_seektable_template_sort(seektable, true); md[0] = new FLAC::Metadata::SeekTable(seektable); set_metadata(md, 1); But that does not seem to work. Checking md[0]-type(), and md[0]-is_valid() and md[0]-is_legal() all return expected values, but the resulting flac has no seektable, but instead a 0-length metadata block of type 56 (UNKNOWN). So what am I doing wrong? And can I get rid of the C API calls altogether? Also, as you can see I'm arbitrarily creating 13 seekpoints, this is just for testing. But what is a good amount of seekpoints, how does the official flac binary determine a default? 2. I noticed while reading the source that all FLAC::Metadata::Prototype child classes have default constructors, that seem to do what you'd expect. They are not mentioned in the API docs (for example: http://flac.sourceforge.net/api/classFLAC_1_1Metadata_1_1SeekTable.html). Can this be considered a bug? 3. Assuming the FLAC__metadata_object_seektable_template_* functions are necessary for creating a proper seektable, and that these functions don't exist in the C++ API, would it be appreciated if I wrote some wrappers for these functions as members of the FLAC::Metadata::Seektable class? I'm assuming these functions would just be one-liners, so I should be capable and willing to do that. The same goes for all other FLAC__metadata_object_* functions not already wrapped in the appropriate FLAC::Metadata::Prototype children. Sorry for the long message... but thanks for reading! bepaald ___ flac-dev mailing list flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [Flac-dev] Git branch with compiling fixes for win32
Well the memory leak I mentioned in my previous message for one. But there are plenty more listed here: http://sourceforge.net/tracker/?atid=113478group_id=13478func=browse and here: http://sourceforge.net/tracker/?atid=313478group_id=13478func=browse Admittedly I haven't read all of those, maybe some are invalid or actually feature requests, but surely some more actual, valid bugs are listed there as well. So I would be happy if (after 2 years) someone would take care of a couple of open reports. At least those where users have already submitted patches to fix them (after reviewing the patch of course). --- On Sat, 11/19/11, Brian Willoughby bri...@sounds.wa.com wrote: From: Brian Willoughby bri...@sounds.wa.com Subject: Re: [Flac-dev] Git branch with compiling fixes for win32 To: Bastiaan Timmer basjetim...@yahoo.com Cc: flac-dev@xiph.org Date: Saturday, November 19, 2011, 4:48 AM What bugs? On Nov 18, 2011, at 04:16, Bastiaan Timmer wrote: It's good to see some updates to the FLAC project after so much time! Will there be any timeline for a bugfix-release? ___ Flac-dev mailing list Flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [Flac-dev] Git branch with compiling fixes for win32
Well, I have been away a couple of days, so I don't know if I'm in time, but I reported a memory leak and submitted a patch a couple of months ago. It would be nice if it can make it in. I first reported the leak here: http://lists.xiph.org/pipermail/flac-dev/2011-August/003002.html And the patch is here: http://sourceforge.net/tracker/?func=detailaid=3390048group_id=13478atid=313478 And there are plenty more patches on the sourceforge tracker if you want to apply more. (But I obviously haven't checked them all and what they are supposed to fix.) It's good to see some updates to the FLAC project after so much time! Will there be any timeline for a bugfix-release? thanks, Bas Timmer --- On Wed, 11/9/11, Erik de Castro Lopo mle...@mega-nerd.com wrote: From: Erik de Castro Lopo mle...@mega-nerd.com Subject: Re: [Flac-dev] Git branch with compiling fixes for win32 To: flac-dev@xiph.org Date: Wednesday, November 9, 2011, 10:58 PM Sven-Hendrik Haase wrote: Si señor: http://code.entropywave.com/git/flac.git Ok, there are about 6 commits there. Over the weekend I'll have a look at them and if they're fine, I'll push them to the Xiph Git repo. If anyone else has Flac patches that they would like to see commited to the Xiph Git repo, now would be a good time to speak up. Cheers, Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Flac-dev mailing list Flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev ___ Flac-dev mailing list Flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
Re: [Flac-dev] Feed decoder from c++ std::stream
Well, unless somebody has a brilliant idea, I am giving up on this. I don't see how I can do what I wanted to. The slightly hacky way I thought would work, was by guaranteeing the read_callback could read at least enough data to make process_single() return (ie the buffer should contain at least 1 frame or block). But it seems that even when the maximum frame size is known, that can never be guaranteed (probably due to sync errors). The only solution I can think of is an API change such as proposed here: http://sourceforge.net/tracker/?func=detailaid=2922254group_id=13478atid=363478 In the meantime, my program will have slightly limited FLAC capabilities and use a separate code path when flac decoding is requested. PS.: What is the status of the project by the way? I know FLAC is very widely supported, and I generally really like the library and the format, but the current version is old, and if I'm not mistaken the CVS hasn;t been touched in years. Please tell me the project isn't dead. ___ Flac-dev mailing list Flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[Flac-dev] Memory leak
During my current dealings with the FLAC library I think I discovered a memory leak. After an encoder stream has finish()'ed, I believe you are supposed to use it again by calling init(). However, when verification is enabled, the init() routine will create a new stream decoder (to verify the data) without deleting (or reusing) the existing one. A small program demonstrating this is pasted here: $ cat main.cc #include cstdlib #include string #include iostream #include FLAC++/encoder.h class FlacWriter : public FLAC::Encoder::File { public: inline bool dataStart(std::string const filename); inline bool dataUpdate(char const *const data, int len); inline bool dataFinish(); }; inline bool FlacWriter::dataStart(std::string const filename) { if (set_verify(true) init(filename) == FLAC__STREAM_ENCODER_INIT_STATUS_OK) return true; return false; } inline bool FlacWriter::dataUpdate(char const *const data, int len) { return true; // handle data here and call process(_interleaved) } inline bool FlacWriter::dataFinish() { if (!finish()) return false; return true; } int main(int argc, char *argv[]) { int numencodes = argc 1 ? atoi(argv[1]) : 2; if (!numencodes) numencodes = 2; FlacWriter fw; for (int i = 0; i numencodes; ++i) { if (!fw.dataStart(filname.flac)) { std::cout Failed init! std::endl; return 1; } while (true) // normally read audio data here in blocks, and update FlacWriter { if (!fw.dataUpdate(audio data read from file, 26)) { std::cout Failed update! std::endl; return 1; } break; } if (!fw.dataFinish()) { std::cout Failed finish! std::endl; return 1; } } return 0; } As can be seen from valgrind output, when the encoder is not reused after finish(), no leaks occur: $ g++ -Wall -O3 main.cc -lFLAC++ $ valgrind --leak-check=full ./a.out 1 ==30494== Memcheck, a memory error detector ==30494== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==30494== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==30494== Command: ./a.out 1 ==30494== ==30494== ==30494== HEAP SUMMARY: ==30494== in use at exit: 0 bytes in 0 blocks ==30494== total heap usage: 28 allocs, 28 frees, 144,168 bytes allocated ==30494== ==30494== All heap blocks were freed -- no leaks are possible ==30494== ==30494== For counts of detected and suppressed errors, rerun with: -v ==30494== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 20 from 8) However for each time init() is called again on the encoder, a constant amount of bytes are not deleted: $ valgrind --leak-check=full ./a.out 2 ==30495== Memcheck, a memory error detector ==30495== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==30495== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==30495== Command: ./a.out 2 ==30495== ==30495== ==30495== HEAP SUMMARY: ==30495== in use at exit: 6,772 bytes in 5 blocks ==30495== total heap usage: 52 allocs, 47 frees, 275,712 bytes allocated ==30495== ==30495== 6,772 (8 direct, 6,764 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5 ==30495==at 0x400522F: calloc (vg_replace_malloc.c:418) ==30495==by 0x4068847: FLAC__stream_decoder_new (stream_decoder.c:284) ==30495==by 0x4074911: init_stream_internal_ (stream_encoder.c:1007) ==30495==by 0x4075A98: init_FILE_internal_ (stream_encoder.c:1221) ==30495==by 0x401EE65: FLAC::Encoder::File::init(char const*) (stream_encoder.cpp:459) ==30495==by 0x401E9FC: FLAC::Encoder::File::init(std::string const) (stream_encoder.cpp:464) ==30495==by 0x804A300: main (in /home/svandijk/programming/FLACLEAK/a.out) ==30495== ==30495== LEAK SUMMARY: ==30495==definitely lost: 8 bytes in 1 blocks ==30495==indirectly lost: 6,764 bytes in 4 blocks ==30495== possibly lost: 0 bytes in 0 blocks ==30495==still reachable: 0 bytes in 0 blocks ==30495== suppressed: 0 bytes in 0 blocks ==30495== ==30495== For counts of detected and suppressed errors, rerun with: -v ==30495== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 20 from 8) In this example I used FLAC::Encoder::File, but the same thing happens with FLAC::Encoder::Stream and, from reading the source, with the C API, as long as one does not call FLAC__stream_encoder_delete() and FLAC__stream_encoder_new() between finish()'ing and init()'ing a stream. The fix will have to be in init_stream_internal_() in src/libFLAC/stream_encoder.c:1007 (in libFLAC-1.2.1), where it should checked whether encoder-private_-verify.decoder == NULL before calling FLAC__stream_decoder_new(). If a decoder is already set (from a previous call to init(), it should first be deleted or (preferably) reused. Alternatively, the verification decoder can be deleted when finish() is called on the encoder that contains it. Workarounds are to not reuse
Re: [Flac-dev] Memory leak
After some more testing, and reading the source, the finish() is indeed called on the verification decoder when its container encoder is finished. This correctly leaves the decoder in the FLAC__STREAM_DECODER_UNINITIALIZED state, ready to be reinitialized (or return an error). So, all that needs to be done is check for NULL when the encoder is initialized and not call FLAC__stream_decoder_new() when a decoder is already allocated. I have submitted a patch on the flac tracker here: https://sourceforge.net/tracker/?func=detailaid=3390048group_id=13478atid=313478 thanks, Bas Timmer ___ Flac-dev mailing list Flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev
[Flac-dev] Feed decoder from c++ std::stream
Hi! I am working on an application that reads audio data from files, and runs it through some user defined filters. The filters basically all derive from some base filter and have methods start(), update() and finish(). The start routine performs any initialization required by the filter, and finish() does the clean up. In between, I simply read the file piece by piece into a buffer using std::ifstream.read(buffer, bufsize), and then call the filters update function with the buffer and the number of bytes read. In this fashion I have implemented a WAV reader, WAV writer, MD5 summer, AccurateRip checker and a FLAC encoder and hope to implement MP3 and Vorbis encoders and any number of audio filters (gain/compression/etc). However, at the moment I'm stuck trying to write a FLAC decoder. It seems that the FLAC::Decoder module is incompatible with this approach as it insists on taking control of the data it receives through its read callback. Is this correct? Does anyone see any obvious way to do this? I have only come up with one (slightly hacky) way to do this, but it requires to know the maximum frame size of the input file, which as I understand it, need not be set in the STREAMINFO, and has no theoretical maximum. So it works now, because I read the input file in 1MB chunks, and I have not come across a file with larger frames, but it is not guaranteed. Any ideas? I hope that was somewhat clear, I'm finding it difficult to explain. Let me know if you need more clarification or some example code. thanks, Bas Timmer ___ Flac-dev mailing list Flac-dev@xiph.org http://lists.xiph.org/mailman/listinfo/flac-dev