Over the weekend, I hit a stumbling block while learning how to program audio synthesis on iOS. I have been developing on iOS for several years, but I'm just getting into the aspect of audio synthesis. Right now, I'm just programming demos to help me learn concepts. Currently, I can create and add sine waves in the playback player for audio devices without any problems. But I want to understand what is happening in the renderer, so I can display two separate sine waves in each left and right channels. I currently assume that in the sound initialization section I will need to make the following changes:
From:
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;
To:
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = kSampleRate;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 4;
audioFormat.mBytesPerFrame = 4;
. , . , . , , - , , . memcpy mBuffers [0] mbuffers [1], . ( , ).
#define kOutputBus 0
#define kSampleRate 44100
#define kWaveform (M_PI * 2.0f / kSampleRate)
OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
HomeViewController *me = (HomeViewController *)inRefCon;
static int phase = 1;
static int phase1 = 1;
for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) {
int samples = ioData->mBuffers[i].mDataByteSize / sizeof(SInt16);
SInt16 values[samples];
float waves;
float volume=.5;
float wave1;
for(int j = 0; j < samples; j++) {
waves = 0;
wave1 = 0;
MyManager *sharedManager = [MyManager sharedManager];
wave1 = sin(kWaveform * sharedManager.globalFr1 * phase1)*sharedManager.globalVol1;
if (0.000001f > wave1) {
[me setFr1:sharedManager.globalFr1];
phase1 = 0;
}
waves += wave1;
waves += sin(kWaveform * sharedManager.globalFr2 * phase)*sharedManager.globalVol2;
waves += sin(kWaveform * sharedManager.globalFr3 * phase)*sharedManager.globalVol3;
waves += sin(kWaveform * sharedManager.globalFr4 * phase)*sharedManager.globalVol4;
waves += sin(kWaveform * sharedManager.globalFr5 * phase)*sharedManager.globalVol5;
waves += sin(kWaveform * sharedManager.globalFr6 * phase)*sharedManager.globalVol6;
waves += sin(kWaveform * sharedManager.globalFr7 * phase)*sharedManager.globalVol7;
waves += sin(kWaveform * sharedManager.globalFr8 * phase)*sharedManager.globalVol8;
waves += sin(kWaveform * sharedManager.globalFr9 * phase)*sharedManager.globalVol9;
waves *= 32767 / 9;
values[j] = (SInt16)waves;
values[j] += values[j]<<16;
phase++;
phase1++;
}
memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16));
}
return noErr;
}
!