diff --git a/taglib/flac/flacproperties.cpp b/taglib/flac/flacproperties.cpp index d36d26ec..8bdc5d8d 100644 --- a/taglib/flac/flacproperties.cpp +++ b/taglib/flac/flacproperties.cpp @@ -42,7 +42,8 @@ public: bitrate(0), sampleRate(0), sampleWidth(0), - channels(0) {} + channels(0), + sampleFrames(0) {} ByteVector data; long streamLength; @@ -52,6 +53,7 @@ public: int sampleRate; int sampleWidth; int channels; + unsigned long long sampleFrames; ByteVector signature; }; @@ -101,6 +103,11 @@ int FLAC::Properties::channels() const return d->channels; } +unsigned long long FLAC::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + ByteVector FLAC::Properties::signature() const { return d->signature; @@ -132,6 +139,8 @@ void FLAC::Properties::read() pos += 3; uint flags = d->data.mid(pos, 4).toUInt(true); + pos += 4; + d->sampleRate = flags >> 12; d->channels = ((flags >> 9) & 7) + 1; d->sampleWidth = ((flags >> 4) & 31) + 1; @@ -139,12 +148,14 @@ void FLAC::Properties::read() // The last 4 bits are the most significant 4 bits for the 36 bit // stream length in samples. (Audio files measured in days) - uint highLength =d->sampleRate > 0 ? (((flags & 0xf) << 28) / d->sampleRate) << 4 : 0; + unsigned long long hi = flags & 0xf; + unsigned long long lo = d->data.mid(pos, 4).toUInt(true); pos += 4; - d->length = d->sampleRate > 0 ? - (d->data.mid(pos, 4).toUInt(true)) / d->sampleRate + highLength : 0; - pos += 4; + d->sampleFrames = (hi << 32) | lo; + + if(d->sampleRate > 0) + d->length = int(d->sampleFrames / d->sampleRate); // Uncompressed bitrate: diff --git a/taglib/flac/flacproperties.h b/taglib/flac/flacproperties.h index a8a02e7c..c1458981 100644 --- a/taglib/flac/flacproperties.h +++ b/taglib/flac/flacproperties.h @@ -77,6 +77,11 @@ namespace TagLib { */ int sampleWidth() const; + /*! + * Return the number of sample frames + */ + unsigned long long sampleFrames() const; + /*! * Returns the MD5 signature of the uncompressed audio stream as read * from the stream info header header. diff --git a/taglib/mpeg/id3v1/id3v1tag.cpp b/taglib/mpeg/id3v1/id3v1tag.cpp index 4a1d69b2..94d533ae 100644 --- a/taglib/mpeg/id3v1/id3v1tag.cpp +++ b/taglib/mpeg/id3v1/id3v1tag.cpp @@ -51,12 +51,17 @@ public: static const StringHandler *stringHandler; }; -const ID3v1::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = new StringHandler; +static const StringHandler defaultStringHandler; +const ID3v1::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = &defaultStringHandler; //////////////////////////////////////////////////////////////////////////////// // StringHandler implementation //////////////////////////////////////////////////////////////////////////////// +StringHandler::StringHandler() +{ +} + String ID3v1::StringHandler::parse(const ByteVector &data) const { return String(data, String::Latin1).stripWhiteSpace(); @@ -189,7 +194,9 @@ void ID3v1::Tag::setTrack(uint i) void ID3v1::Tag::setStringHandler(const StringHandler *handler) { - delete TagPrivate::stringHandler; + if(TagPrivate::stringHandler != &defaultStringHandler) + delete TagPrivate::stringHandler; + TagPrivate::stringHandler = handler; } diff --git a/taglib/mpeg/id3v1/id3v1tag.h b/taglib/mpeg/id3v1/id3v1tag.h index fad485e5..a90ac531 100644 --- a/taglib/mpeg/id3v1/id3v1tag.h +++ b/taglib/mpeg/id3v1/id3v1tag.h @@ -62,6 +62,7 @@ namespace TagLib { TAGLIB_IGNORE_MISSING_DESTRUCTOR public: // BIC: Add virtual destructor. + StringHandler(); /*! * Decode a string from \a data. The default implementation assumes that diff --git a/taglib/riff/wav/wavproperties.cpp b/taglib/riff/wav/wavproperties.cpp index c8b7fd6b..f0453968 100644 --- a/taglib/riff/wav/wavproperties.cpp +++ b/taglib/riff/wav/wavproperties.cpp @@ -125,5 +125,5 @@ void RIFF::WAV::Properties::read(const ByteVector &data) d->length = byteRate > 0 ? d->streamLength / byteRate : 0; if(d->channels > 0 && d->sampleWidth > 0) - d->sampleFrames = d->streamLength / (d->channels * (d->sampleWidth / 8)); + d->sampleFrames = d->streamLength / (d->channels * ((d->sampleWidth + 7) / 8)); } diff --git a/taglib/trueaudio/trueaudioproperties.cpp b/taglib/trueaudio/trueaudioproperties.cpp index 5b1bf12d..1e4e87d3 100644 --- a/taglib/trueaudio/trueaudioproperties.cpp +++ b/taglib/trueaudio/trueaudioproperties.cpp @@ -48,7 +48,8 @@ public: bitrate(0), sampleRate(0), channels(0), - bitsPerSample(0) {} + bitsPerSample(0), + sampleFrames(0) {} ByteVector data; long streamLength; @@ -59,6 +60,7 @@ public: int sampleRate; int channels; int bitsPerSample; + uint sampleFrames; }; //////////////////////////////////////////////////////////////////////////////// @@ -101,6 +103,11 @@ int TrueAudio::Properties::channels() const return d->channels; } +uint TrueAudio::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + int TrueAudio::Properties::ttaVersion() const { return d->version; @@ -118,19 +125,26 @@ void TrueAudio::Properties::read() int pos = 3; d->version = d->data[pos] - '0'; - pos += 1 + 2; + pos += 1; - d->channels = d->data.mid(pos, 2).toShort(false); - pos += 2; + // According to http://en.true-audio.com/TTA_Lossless_Audio_Codec_-_Format_Description + // TTA2 headers are in development, and have a different format + if(1 == d->version) { + // Skip the audio format + pos += 2; - d->bitsPerSample = d->data.mid(pos, 2).toShort(false); - pos += 2; + d->channels = d->data.mid(pos, 2).toShort(false); + pos += 2; - d->sampleRate = d->data.mid(pos, 4).toUInt(false); - pos += 4; + d->bitsPerSample = d->data.mid(pos, 2).toShort(false); + pos += 2; - unsigned long samples = d->data.mid(pos, 4).toUInt(false); - d->length = samples / d->sampleRate; + d->sampleRate = d->data.mid(pos, 4).toUInt(false); + pos += 4; - d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; + d->sampleFrames = d->data.mid(pos, 4).toUInt(false); + d->length = d->sampleFrames / d->sampleRate; + + d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; + } } diff --git a/taglib/trueaudio/trueaudioproperties.h b/taglib/trueaudio/trueaudioproperties.h index f66fd2e9..126b6788 100644 --- a/taglib/trueaudio/trueaudioproperties.h +++ b/taglib/trueaudio/trueaudioproperties.h @@ -73,6 +73,11 @@ namespace TagLib { */ int bitsPerSample() const; + /*! + * Returns the total number of sample frames + */ + uint sampleFrames() const; + /*! * Returns the major version number. */