Skip to content

Commit

Permalink
Calculate bitrate for ALAC files without it (taglib#961)
Browse files Browse the repository at this point in the history
If the "alac" atom of an MP4 file has a zero bitrate, it is calculated.
  • Loading branch information
ufleisch committed Dec 8, 2020
1 parent 91b00b1 commit d0d22be
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions taglib/mp4/mp4properties.cpp
Expand Up @@ -31,6 +31,27 @@

using namespace TagLib;

namespace
{
// Calculate the total bytes used by audio data, used to calculate the bitrate
long long calculateMdatLength(const MP4::AtomList &list)
{
long long totalLength = 0;
for(MP4::AtomList::ConstIterator it = list.begin(); it != list.end(); ++it) {
long length = (*it)->length;
if(length == 0)
return 0; // for safety, see checkValid() in mp4file.cpp

if((*it)->name == "mdat")
totalLength += length;

totalLength += calculateMdatLength((*it)->children);
}

return totalLength;
}
}

class MP4::Properties::PropertiesPrivate
{
public:
Expand Down Expand Up @@ -224,6 +245,13 @@ MP4::Properties::read(File *file, Atoms *atoms)
d->channels = data.at(73);
d->bitrate = static_cast<int>(data.toUInt(80U) / 1000.0 + 0.5);
d->sampleRate = data.toUInt(84U);

if(d->bitrate == 0 && d->length > 0) {
// There are files which do not contain a nominal bitrate, e.g. those
// generated by refalac64.exe. Calculate the bitrate from the audio
// data size (mdat atoms) and the duration.
d->bitrate = (calculateMdatLength(atoms->atoms) * 8) / d->length;
}
}
}

Expand Down

0 comments on commit d0d22be

Please sign in to comment.