diff --git a/flac/flacstream.cpp b/flac/flacstream.cpp index 7cc1fb9..7e1ebe7 100644 --- a/flac/flacstream.cpp +++ b/flac/flacstream.cpp @@ -99,6 +99,7 @@ void FlacStream::internalParseHeader() m_samplingFrequency = streamInfo.samplingFrequency(); m_sampleCount = streamInfo.totalSampleCount(); m_bitsPerSample = streamInfo.bitsPerSample(); + m_duration = TimeSpan::fromSeconds(static_cast(m_sampleCount) / m_samplingFrequency); } else { addNotification(NotificationType::Critical, "\"METADATA_BLOCK_STREAMINFO\" is truncated and will be ignored.", context); } diff --git a/ogg/oggstream.cpp b/ogg/oggstream.cpp index 4220314..2178649 100644 --- a/ogg/oggstream.cpp +++ b/ogg/oggstream.cpp @@ -224,6 +224,15 @@ void OggStream::internalParseHeader() m_channelCount = streamInfo.channelCount(); m_samplingFrequency = streamInfo.samplingFrequency(); m_sampleCount = streamInfo.totalSampleCount(); + if(!m_sampleCount && iterator.areAllPagesFetched()) { + const auto &pages = iterator.pages(); + const auto firstPage = find_if(pages.cbegin(), pages.cend(), pred); + const auto lastPage = find_if(pages.crbegin(), pages.crend(), pred); + if(firstPage != pages.cend() && lastPage != pages.crend()) { + m_sampleCount = lastPage->absoluteGranulePosition() - firstPage->absoluteGranulePosition(); + } + } + m_duration = TimeSpan::fromSeconds(static_cast(m_sampleCount) / m_samplingFrequency); hasIdentificationHeader = true; } else { addNotification(NotificationType::Critical, "FLAC-to-Ogg mapping header appears more then once. Oversupplied occurrence will be ignored.", context); diff --git a/tests/overall.cpp b/tests/overall.cpp index ea45067..80c66e0 100644 --- a/tests/overall.cpp +++ b/tests/overall.cpp @@ -1058,6 +1058,7 @@ void OverallTests::checkFlacTestfile1() CPPUNIT_ASSERT(track->channelCount() == 2); CPPUNIT_ASSERT(track->samplingFrequency() == 44100); CPPUNIT_ASSERT(track->bitsPerSample() == 16); + CPPUNIT_ASSERT(track->duration().minutes() == 4); } const auto tags = m_fileInfo.tags(); switch(m_tagStatus) { @@ -1099,6 +1100,7 @@ void OverallTests::checkFlacTestfile2() CPPUNIT_ASSERT(track->channelCount() == 2); CPPUNIT_ASSERT(track->samplingFrequency() == 44100); CPPUNIT_ASSERT(track->bitsPerSample() == 16); + CPPUNIT_ASSERT(track->duration().minutes() == 4); } const auto tags = m_fileInfo.tags(); switch(m_tagStatus) {