[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: kdesupport/taglib
From: Lukáš Lalinský <lalinsky () gmail ! com>
Date: 2010-11-27 20:58:57
Message-ID: 20101127205857.DEB93AC8A3 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1201476 by lalinsky:
Fix reading of WavPack streams without a length information in the header
When the WavPack's total_samples header fiels contains -1, try to find
the final block and get the number of samples from there as
block_index + block_samples.
BUG:258016
M +2 -0 NEWS
M +1 -2 taglib/wavpack/wavpackfile.cpp
M +50 -1 taglib/wavpack/wavpackproperties.cpp
M +10 -0 taglib/wavpack/wavpackproperties.h
M +2 -0 tests/CMakeLists.txt
M +4 -2 tests/Makefile.am
AM tests/data/no_length.wv
A tests/test_wavpack.cpp [License: UNKNOWN]
--- trunk/kdesupport/taglib/NEWS #1201475:1201476
@@ -8,6 +8,8 @@
* Exposed FLAC MD5 signature of the uncompressed audio stream via
FLAC::Properties::signature(). (BUG:160172)
* Added function ByteVector::toHex() for hex-encoding of byte vectors.
+ * WavPack reader now tries to get the audio length by finding the final
+ block, if the header doesn't have the information. (BUG:258016)
TagLib 1.6.3 (Apr 17, 2010)
===========================
--- trunk/kdesupport/taglib/taglib/wavpack/wavpackfile.cpp #1201475:1201476
@@ -230,8 +230,7 @@
if(readProperties) {
seek(0);
- d->properties = new Properties(readBlock(WavPack::HeaderSize),
- length() - d->APESize);
+ d->properties = new Properties(this, length() - d->APESize);
}
}
--- trunk/kdesupport/taglib/taglib/wavpack/wavpackproperties.cpp #1201475:1201476
@@ -48,7 +48,8 @@
sampleRate(0),
channels(0),
version(0),
- bitsPerSample(0) {}
+ bitsPerSample(0),
+ file(0) {}
ByteVector data;
long streamLength;
@@ -59,6 +60,7 @@
int channels;
int version;
int bitsPerSample;
+ File *file;
};
////////////////////////////////////////////////////////////////////////////////
@@ -71,6 +73,14 @@
read();
}
+WavPack::Properties::Properties(File *file, long streamLength, ReadStyle style) : AudioProperties(style)
+{
+ ByteVector data = file->readBlock(32);
+ d = new PropertiesPrivate(data, streamLength, style);
+ d->file = file;
+ read();
+}
+
WavPack::Properties::~Properties()
{
delete d;
@@ -122,12 +132,19 @@
#define SRATE_LSB 23
#define SRATE_MASK (0xfL << SRATE_LSB)
+#define MIN_STREAM_VERS 0x402
+#define MAX_STREAM_VERS 0x410
+
+#define FINAL_BLOCK 0x1000
+
void WavPack::Properties::read()
{
if(!d->data.startsWith("wvpk"))
return;
d->version = d->data.mid(8, 2).toShort(false);
+ if(d->version < MIN_STREAM_VERS || d->version > MAX_STREAM_VERS)
+ return;
unsigned int flags = d->data.mid(24, 4).toUInt(false);
d->bitsPerSample = ((flags & BYTES_STORED) + 1) * 8 -
@@ -137,10 +154,42 @@
unsigned int samples = d->data.mid(12, 4).toUInt(false);
if (samples == ~0u) {
+ if(d->file && d->style != Fast) {
+ samples = seekFinalIndex();
+ }
+ else {
samples = 0;
}
+ }
d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0;
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
}
+unsigned int WavPack::Properties::seekFinalIndex()
+{
+ ByteVector blockID("wvpk", 4);
+
+ long offset = d->streamLength;
+ while(offset > 0) {
+ offset = d->file->rfind(blockID, offset);
+ if(offset == -1)
+ return 0;
+ d->file->seek(offset);
+ ByteVector data = d->file->readBlock(32);
+ if(data.size() != 32)
+ return 0;
+ int version = data.mid(8, 2).toShort(false);
+ if(version < MIN_STREAM_VERS || version > MAX_STREAM_VERS)
+ continue;
+ unsigned int flags = data.mid(24, 4).toUInt(false);
+ if(!(flags & FINAL_BLOCK))
+ return 0;
+ unsigned int blockIndex = data.mid(16, 4).toUInt(false);
+ unsigned int blockSamples = data.mid(20, 4).toUInt(false);
+ return blockIndex + blockSamples;
+ }
+
+ return 0;
+}
+
--- trunk/kdesupport/taglib/taglib/wavpack/wavpackproperties.h #1201475:1201476
@@ -54,10 +54,19 @@
/*!
* Create an instance of WavPack::Properties with the data read from the
* ByteVector \a data.
+ *
+ * \deprecated This constructor will be dropped in favor of the one below
+ * in a future version.
*/
Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
/*!
+ * Create an instance of WavPack::Properties.
+ */
+ // BIC: merge with the above constructor
+ Properties(File *file, long streamLength, ReadStyle style = Average);
+
+ /*!
* Destroys this WavPack::Properties instance.
*/
virtual ~Properties();
@@ -84,6 +93,7 @@
Properties &operator=(const Properties &);
void read();
+ unsigned int seekFinalIndex();
class PropertiesPrivate;
PropertiesPrivate *d;
--- trunk/kdesupport/taglib/tests/CMakeLists.txt #1201475:1201476
@@ -18,6 +18,7 @@
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/flac
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/flac
+ ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/wavpack
)
SET(test_runner_SRCS
@@ -42,6 +43,7 @@
test_ape.cpp
test_apetag.cpp
test_wav.cpp
+ test_wavpack.cpp
)
IF(WITH_MP4)
SET(test_runner_SRCS ${test_runner_SRCS}
--- trunk/kdesupport/taglib/tests/Makefile.am #1201475:1201476
@@ -12,7 +12,8 @@
-I$(top_srcdir)/taglib/flac \
-I$(top_srcdir)/taglib/riff \
-I$(top_srcdir)/taglib/riff/aiff \
- -I$(top_srcdir)/taglib/mpeg/id3v2/frames
+ -I$(top_srcdir)/taglib/mpeg/id3v2/frames \
+ -I$(top_srcdir)/taglib/wavpack
test_runner_SOURCES = \
main.cpp \
@@ -32,7 +33,8 @@
test_aiff.cpp \
test_ogg.cpp \
test_oggflac.cpp \
- test_flac.cpp
+ test_flac.cpp \
+ test_wavpack.cpp
if build_tests
TESTS = test_runner
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic