Joshua Moerman
11 years ago
9 changed files with 236 additions and 67 deletions
@ -0,0 +1,21 @@ |
|||||
|
//
|
||||
|
// AudioFile.h
|
||||
|
// SpectogramPrototype
|
||||
|
//
|
||||
|
// Created by Joshua Moerman on 28/12/13.
|
||||
|
// Copyright (c) 2013 Joshua Moerman. All rights reserved.
|
||||
|
//
|
||||
|
|
||||
|
#import <Foundation/Foundation.h> |
||||
|
|
||||
|
// Uses the ExtAudioFileRef from the AudioToolkit
|
||||
|
// Handles conversion to PCM and such
|
||||
|
@interface AudioFile : NSObject |
||||
|
|
||||
|
// Loads a file (and sets the right internal format)
|
||||
|
+ (AudioFile*) audioFileFromURL:(NSURL*) url; |
||||
|
|
||||
|
// Reads nSamples of data (left channel), return actual number of samples read
|
||||
|
- (unsigned int) fillArray:(float*)array withNumberOfSamples:(unsigned int)nSamples; |
||||
|
|
||||
|
@end |
@ -0,0 +1,93 @@ |
|||||
|
// |
||||
|
// 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.h> |
||||
|
|
||||
|
@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)fillArray:(float *)array 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 * end = array + nSamples; |
||||
|
for(unsigned int i = 0; i < nFrames; ++i){ |
||||
|
*array++ = *buffer++ / 32768.0; |
||||
|
// skip right channel |
||||
|
buffer++; |
||||
|
} |
||||
|
|
||||
|
while(array != end){ |
||||
|
*array++ = 0.0; |
||||
|
} |
||||
|
|
||||
|
free(bufferList.mBuffers[0].mData); |
||||
|
|
||||
|
return nFrames; |
||||
|
} |
||||
|
|
||||
|
@end |
Binary file not shown.
Reference in new issue