|
|
|
//
|
|
|
|
// AudioFile.m
|
|
|
|
// SpectogramPrototype
|
|
|
|
//
|
|
|
|
// Created by Joshua Moerman on 28/12/13.
|
|
|
|
// Copyright (c) 2013 Joshua Moerman. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "AudioFile.h"
|
|
|
|
@import AudioToolbox.ExtendedAudioFile;
|
|
|
|
|
|
|
|
@interface AudioFile (){
|
|
|
|
ExtAudioFileRef audioFile;
|
|
|
|
AudioStreamBasicDescription format;
|
|
|
|
}
|
|
|
|
- (id)initWithExtAudioFileRef:(ExtAudioFileRef) audioFile;
|
|
|
|
- (void)setupFormat;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation AudioFile
|
|
|
|
|
|
|
|
#pragma mark
|
|
|
|
#pragma mark Creation
|
|
|
|
|
|
|
|
- (id)initWithExtAudioFileRef:(ExtAudioFileRef) af{
|
|
|
|
if(self = [super init]){
|
|
|
|
audioFile = af;
|
|
|
|
[self setupFormat];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setupFormat{
|
|
|
|
format.mSampleRate = 44100.0f;
|
|
|
|
format.mFormatID = kAudioFormatLinearPCM;
|
|
|
|
format.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
|
|
|
|
format.mBytesPerPacket = 4;
|
|
|
|
format.mFramesPerPacket = 1;
|
|
|
|
format.mBytesPerFrame = 4;
|
|
|
|
format.mChannelsPerFrame = 2;
|
|
|
|
format.mBitsPerChannel = 16;
|
|
|
|
format.mReserved = 0;
|
|
|
|
|
|
|
|
UInt32 size = sizeof(format);
|
|
|
|
OSStatus err = ExtAudioFileSetProperty(audioFile, kExtAudioFileProperty_ClientDataFormat, size, &format);
|
|
|
|
assert(err == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc {
|
|
|
|
OSStatus err = ExtAudioFileDispose(audioFile);
|
|
|
|
assert(err == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (AudioFile *)audioFileFromURL:(NSURL *)url{
|
|
|
|
ExtAudioFileRef audioFile = NULL;
|
|
|
|
OSStatus err = ExtAudioFileOpenURL((__bridge CFURLRef) url, &audioFile);
|
|
|
|
assert(err == 0 && audioFile);
|
|
|
|
|
|
|
|
return [[AudioFile alloc] initWithExtAudioFileRef:audioFile];
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark
|
|
|
|
#pragma mark Usage
|
|
|
|
|
|
|
|
- (unsigned int)fillLeft:(float *)left andRight:(float *)right withNumberOfSamples:(unsigned int)nSamples {
|
|
|
|
AudioBufferList bufferList;
|
|
|
|
bufferList.mNumberBuffers = 1;
|
|
|
|
bufferList.mBuffers[0].mNumberChannels = 2;
|
|
|
|
bufferList.mBuffers[0].mDataByteSize = nSamples * format.mBytesPerFrame;
|
|
|
|
bufferList.mBuffers[0].mData = calloc(bufferList.mBuffers[0].mDataByteSize, 1);
|
|
|
|
|
|
|
|
UInt32 nFrames = nSamples;
|
|
|
|
OSStatus err = ExtAudioFileRead(audioFile, &nFrames, &bufferList);
|
|
|
|
assert(err == 0);
|
|
|
|
|
|
|
|
short * buffer = bufferList.mBuffers[0].mData;
|
|
|
|
float * leftEnd = left + nSamples;
|
|
|
|
for(unsigned int i = 0; i < nFrames; ++i){
|
|
|
|
*left++ = *buffer++ / 32768.0f;
|
|
|
|
*right++ = *buffer++ / 32768.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// assume left and right are of the same size
|
|
|
|
while(left != leftEnd){
|
|
|
|
*left++ = 0;
|
|
|
|
*right++ = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(bufferList.mBuffers[0].mData);
|
|
|
|
|
|
|
|
return nFrames;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|