#import <AudioUnit/AudioUnit.h>
#import <math.h>
#import "Singer.h"
#define kOutputBus 0
#define kSampleRate 44100
//44100.0f
#define kWaveform (M_PI * 2.0f / kSampleRate)
@implementation Singer
OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
Singer *me = (Singer *)inRefCon;
static int phase = 0;
for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) {
int samples
= ioData
->mBuffers
[i
].mDataByteSize
/ sizeof(SInt16
);
SInt16 values[samples];
float waves;
for(int j = 0; j < samples; j++) {
waves = 0;
waves
+= sin(kWaveform
* 440.0f
* phase
);
waves
+= sin(kWaveform
* 659.3f
* phase
);
waves
+= sin(kWaveform
* 1760.3f
* phase
);
waves
+= sin(kWaveform
* 880.0f
* phase
);
waves *= 32500/4;// / 4; // <--------- make sure to divide by how many waves you're stacking
values[j] = (SInt16)waves;
values[j] += values[j]<<16;
phase++;
}
memcpy(ioData
->mBuffers
[i
].mData, values, samples
* sizeof(SInt16
));
}
return noErr;
}
-(id)init {
if(self = [super init]) {
[self initAudio];
}
return self;
}
-(void)initAudio {
OSStatus status;
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
AudioComponent outputComponent = AudioComponentFindNext(NULL, &desc);
status = AudioComponentInstanceNew(outputComponent, &audioUnit);
UInt32 flag = 1;
status
= AudioUnitSetProperty
(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus,
&flag,
sizeof(flag
));
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = kSampleRate;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
status
= AudioUnitSetProperty
(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus,
&audioFormat,
sizeof(audioFormat
));
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = playbackCallback;
callbackStruct.inputProcRefCon = self;
status
= AudioUnitSetProperty
(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus,
&callbackStruct,
sizeof(callbackStruct
));
status = AudioUnitInitialize(audioUnit);
}
-(void)start {
OSStatus status;
status = AudioOutputUnitStart(audioUnit);
}
-(void)stop {
OSStatus status;
status = AudioOutputUnitStop(audioUnit);
}
-(void)dealloc {
AudioUnitUninitialize(audioUnit);
[super dealloc];
}
@end