Skip to content

Commit

Permalink
Improved duration calculation - #20
Browse files Browse the repository at this point in the history
Because of #36, this does not work well with .aac files (.m4a is fine).
  • Loading branch information
Bo98 committed Sep 18, 2014
1 parent 5f7774d commit 78bee1f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
1 change: 1 addition & 0 deletions AudioStreamer/AudioStreamer.h
Expand Up @@ -245,6 +245,7 @@ struct queued_packet;
UInt64 processedPacketsSizeTotal; /* helps calculate the bit rate */
bool bitrateNotification; /* notified that the bitrate is ready */
bool isParsing; /* Are we parsing the file stream? */
UInt64 totalAudioPackets; /* Total number of audio packets expected */
}

/** @name Creating an audio stream */
Expand Down
57 changes: 52 additions & 5 deletions AudioStreamer/AudioStreamer.m
Expand Up @@ -459,13 +459,35 @@ - (BOOL) calculatedBitRate:(double*)rate {
}

- (BOOL) duration:(double*)ret {
double calculatedBitRate;
if (![self calculatedBitRate:&calculatedBitRate]) return NO;
if (calculatedBitRate == 0 || fileLength == 0) {
return NO;
if (fileLength == 0) return NO;

double packetDuration = asbd.mFramesPerPacket / asbd.mSampleRate;
if (!packetDuration) return NO;

// Method one
UInt64 packetCount;
UInt32 packetCountSize = sizeof(packetCount);
OSStatus status = AudioFileStreamGetProperty(audioFileStream,
kAudioFileStreamProperty_AudioDataPacketCount,
&packetCountSize, &packetCount);
if (status != 0) {
// Method two
packetCount = totalAudioPackets;
}

if (packetCount == 1000000)
{
// Method three
double calcBitrate;
if (![self calculatedBitRate:&calcBitrate]) return NO;
if (calcBitrate == 0) return NO;
*ret = (fileLength - dataOffset) / (calcBitrate * 0.125);
}
else
{
*ret = packetCount * asbd.mFramesPerPacket / asbd.mSampleRate;
}

*ret = (fileLength - dataOffset) / (calculatedBitRate * 0.125);
return YES;
}

Expand Down Expand Up @@ -1195,6 +1217,31 @@ - (void)handleAudioPackets:(const void*)inInputData
}

if (!audioQueue) {
OSStatus status = 0;
UInt32 ioFlags = 0;
long long byteOffset;
SInt64 lower = 0;
SInt64 upper = 1000000;
SInt64 current;
while (upper - lower > 1 || status != 0)
{
current = (upper + lower) / 2;
status = AudioFileStreamSeek(audioFileStream, current, &byteOffset, &ioFlags);
if (status == 0)
{
lower = current;
}
else
{
upper = current;
}
}
AudioFileStreamSeek(audioFileStream, 0, &byteOffset, &ioFlags);
totalAudioPackets = (UInt64)current + 1;
seekByteOffset = (UInt64)byteOffset + dataOffset;
[self closeReadStream];
[self openReadStream];

assert(!waitingOnBuffer);
[self createQueue];
}
Expand Down

0 comments on commit 78bee1f

Please sign in to comment.