Skip to content

Commit

Permalink
Merge pull request #16 from GlobalRadio/fix_m4a_quality_new_approach
Browse files Browse the repository at this point in the history
New approach to fix m4a quality issue
  • Loading branch information
pierrepegoud authored Jan 15, 2020
2 parents 109630c + f7aa2d3 commit 0d337c9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 55 deletions.
4 changes: 2 additions & 2 deletions StreamingKit.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = "StreamingKit"
s.version = "2.4.18"
s.version = "2.4.19"
s.summary = "A fast and extensible audio streamer for iOS and OSX with support for gapless playback and custom (non-HTTP) sources."
s.homepage = "https://github.com/tumtumtum/StreamingKit/"
s.license = 'MIT'
s.author = { "Thong Nguyen" => "[email protected]" }
s.source = { :git => "https://github.com/GlobalRadio/StreamingKit.git", :tag => "guac_2.4.18"}
s.source = { :git => "https://github.com/GlobalRadio/StreamingKit.git", :tag => "guac_2.4.19"}
s.platform = :ios
s.requires_arc = true
s.source_files = 'StreamingKit/StreamingKit/*.{h,m}'
Expand Down
109 changes: 56 additions & 53 deletions StreamingKit/StreamingKit/STKAudioPlayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ @interface STKAudioPlayer()
volatile BOOL disposeWasRequested;
volatile BOOL seekToTimeWasRequested;
volatile STKAudioPlayerStopReason stopReason;

char lastFileFormat[4];
char *fileFormatM4A;
}

@property (readwrite) STKAudioPlayerInternalState internalState;
Expand Down Expand Up @@ -493,6 +496,8 @@ -(id) initWithOptions:(STKAudioPlayerOptions)optionsIn

upcomingQueue = [[NSMutableArray alloc] init];
bufferingQueue = [[NSMutableArray alloc] init];

fileFormatM4A = "fa4m";

[self resetPcmBuffers];
[self createAudioGraph];
Expand Down Expand Up @@ -801,10 +806,9 @@ -(void) handlePropertyChangeForFileStream:(AudioFileStreamID)inAudioFileStream f
}
case kAudioFileStreamProperty_FileFormat:
{
char fileFormat[4];
UInt32 fileFormatSize = sizeof(fileFormat);
UInt32 fileFormatSize = sizeof(lastFileFormat);

AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_FileFormat, &fileFormatSize, &fileFormat);
AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_FileFormat, &fileFormatSize, &lastFileFormat);

break;
}
Expand Down Expand Up @@ -852,7 +856,11 @@ -(void) handlePropertyChangeForFileStream:(AudioFileStreamID)inAudioFileStream f
entryToUpdate->packetBufferSize = packetBufferSize;
}

[self createAudioConverter:&currentlyReadingEntry->audioStreamBasicDescription];
// Delay createAudioConverter when the format is .m4a because DataFormat update happens before FormatList
// In that case the creation will happen in FormatList update
if (strcmp(fileFormatM4A, lastFileFormat) != 0) {
[self createAudioConverter:&currentlyReadingEntry->audioStreamBasicDescription];
}

pthread_mutex_unlock(&playerMutex);
}
Expand Down Expand Up @@ -881,59 +889,52 @@ -(void) handlePropertyChangeForFileStream:(AudioFileStreamID)inAudioFileStream f
}
case kAudioFileStreamProperty_FormatList:
{
Boolean outWriteable;
UInt32 formatListSize;
OSStatus err = AudioFileStreamGetPropertyInfo(inAudioFileStream, kAudioFileStreamProperty_FormatList, &formatListSize, &outWriteable);

if (err)
{
break;
}

AudioFormatListItem* formatList = malloc(formatListSize);

err = AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_FormatList, &formatListSize, formatList);

if (err)
{
free(formatList);
break;
}

for (int i = 0; i * sizeof(AudioFormatListItem) < formatListSize; i += sizeof(AudioFormatListItem))
{
AudioStreamBasicDescription pasbd = formatList[i].mASBD;

if (pasbd.mFormatID == kAudioFormatMPEG4AAC_HE || pasbd.mFormatID == kAudioFormatMPEG4AAC_HE_V2)
{
currentlyReadingEntry->audioStreamBasicDescription = pasbd;

AudioFormatListItem afli = GetFirstPlayableAudioFormatForFile(inAudioFileStream);
currentlyReadingEntry->audioStreamBasicDescription = afli.mASBD;

break;
}
}

free(formatList);

// Calling createAudioConverter here when format is .m4a as it was delayed from DataFormat update
if (strcmp(fileFormatM4A, lastFileFormat) == 0) {
pthread_mutex_lock(&playerMutex);
[self createAudioConverter:&currentlyReadingEntry->audioStreamBasicDescription];
pthread_mutex_unlock(&playerMutex);
}

break;
}

}
}

AudioFormatListItem GetFirstPlayableAudioFormatForFile(AudioFileStreamID inFileID) {
AudioFormatListItem *formatListPtr = NULL;
AudioFormatListItem formatItem = {0};
UInt32 propertySize;

OSStatus status = noErr;

if (NULL == inFileID) return formatItem;

status = AudioFileStreamGetPropertyInfo(inFileID, kAudioFilePropertyFormatList, &propertySize, NULL);
if (noErr == status) {

// allocate memory for the format list items
formatListPtr = (AudioFormatListItem *)malloc(propertySize);
if (NULL == formatListPtr) return formatItem;

// get the list of Audio Format List Item's
status = AudioFileStreamGetProperty(inFileID, kAudioFilePropertyFormatList, &propertySize, formatListPtr);
if (noErr == status) {
// print out some helpful information
UInt32 numFormats = propertySize / sizeof(AudioFormatListItem);
printf ("This file has a %d layered data format:\n", numFormats);

UInt32 itemIndex;
UInt32 indexSize = sizeof(itemIndex);

// get the index number of the first playable format -- this index number will be for
// the highest quality layer the platform is capable of playing
status = AudioFormatGetProperty(kAudioFormatProperty_FirstPlayableFormatFromList, propertySize,
formatListPtr, &indexSize, &itemIndex);
if (noErr == status) {
printf ("Returning AudioFormatListItem at index %d.\n", itemIndex);
// copy the format item at index we want returned
formatItem = formatListPtr[itemIndex];
}
}

free(formatListPtr);
}

return formatItem;
}

-(Float64) currentTimeInFrames
{
if (audioGraph == nil)
Expand Down Expand Up @@ -1473,7 +1474,7 @@ -(void) processSeekToTime
error = AudioFileStreamSeek(audioFileStream, seekPacket, &packetAlignedByteOffset, &ioFlags);

if (!error && !(ioFlags & kAudioFileStreamSeekFlag_OffsetIsEstimated))
{
{
seekByteOffset = packetAlignedByteOffset + currentEntry->audioDataOffset;
}
}
Expand Down Expand Up @@ -1919,7 +1920,10 @@ -(void) createAudioConverter:(AudioStreamBasicDescription*)asbd

audioConverterAudioStreamBasicDescription = *asbd;

if (self->currentlyReadingEntry.dataSource.audioFileTypeHint != kAudioFileAAC_ADTSType)
BOOL additionnalCheckNeeded = (self->currentlyReadingEntry.dataSource.audioFileTypeHint != kAudioFileAAC_ADTSType)
&& (self->currentlyReadingEntry.dataSource.audioFileTypeHint != kAudioFileM4AType)
&& (self->currentlyReadingEntry.dataSource.audioFileTypeHint != kAudioFileMPEG4Type);
if (additionnalCheckNeeded)
{
status = AudioFileStreamGetPropertyInfo(audioFileStream, kAudioFileStreamProperty_MagicCookieData, &cookieSize, &writable);

Expand Down Expand Up @@ -3170,4 +3174,3 @@ -(void) setEqualizerEnabled:(BOOL)value
}

@end

0 comments on commit 0d337c9

Please sign in to comment.