I'm reimplementing some very old code that converts an AIFF file to Wave file via Carbon Quicktime APIs.
I need my implementation to run as far back as OS X 10.9, so it seems like using AVFoundation's AVAssetReader/AVAssetWriter is the way to go.
However, I need my output to be a
WAVE_FORMAT_PCM
file, but AVFoundation is outputting a WAVE_FORMAT_EXTENSIBLE
file with a SubFormat of KSDATAFORMAT_SUBTYPE_PCM
.Here is a simplified version of my code:
AVAsset* asset = [AVAsset assetWithURL:url];
AVAssetReader* reader = [AVAssetReader assetReaderWithAsset:asset error:&err];
AVAssetTrack* track = [[asset tracksWithMediaType:AVMediaTypeAudio]
objectAtIndex:0];
NSDictionary *compressionSettings = @{
AVFormatIDKey: [NSNumber numberWithUnsignedInt:kAudioFormatLinearPCM],
AVSampleRateKey: [NSNumber numberWithUnsignedInteger:44100],
AVLinearPCMBitDepthKey: [NSNumber numberWithUnsignedInt:16],
AVLinearPCMIsNonInterleavedKey: @NO,
AVLinearPCMIsFloatKey: @NO,
AVLinearPCMIsBigEndianKey: @NO,
AVNumberOfChannelsKey: [NSNumber numberWithUnsignedInteger:2]
};
AVAssetReaderOutput* readerOutput =
[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track
outputSettings:compressionSettings];
[reader addOutput:readerOutput];
AVAsset* outAsset = [AVAsset assetWithURL:outURL];
AVAssetWriter* writer = [AVAssetWriter assetWriterWithURL:outURL
fileType:AVFileTypeWAVE
error:&err];
AVAssetWriterInput* writerInput =
[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:compressionSettings];
[writer addInput:writerInput];
[writer startWriting];
[writer startSessionAtSourceTime:kCMTimeZero];
[reader startReading];
CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer];
while( sample != NULL )
{
while (TRUE) {
if ([writerInput isReadyForMoreMediaData]) {
[writerInput appendSampleBuffer:sample];
break;
}
}
CFRelease( sample );
sample = [readerOutput copyNextSampleBuffer];
}
[writer finishWritingWithCompletionHandler:^(){
NSLog(@"Done!");
}];
I've looked through the headers where
AVFileTypeWAVE
and kAudioFormatLinearPCM
are defined, and cannot find any settings that look like they would result in a WAVE_FORMAT_PCM file.Using
WAVE_FORMAT_EXTENSIBLE
is necessary if the underlying format of the file cannot be described with WAVE_FORMAT_PCM
, but I do not believe this to be the case for the audio files I am dealing with: I've written code to edit the Wave header, leaving the data
section of the file untouched, and the resulting file can be processed by my app as desired (and displays and plays back normally in other applications).If the worst comes to the worst, I can just use this Wave-header editing code in my release, but I'd prefer a cleaner solution if one exists.
Is it possible to get
AVFoundation
to write a file in the format I need, or is there some other API I can use to perform this task?