在上週末我碰到了一個絆腳石,學習如何在iOS上編寫音頻合成。我在iOS上開發了好幾年,但我只是進入音頻合成方面。現在,我只是編寫演示程序來幫助我學習這些概念。我目前已經能夠在沒有問題的音頻單元的播放渲染器中構建和堆疊正弦波。但是,我想了解渲染器中發生了什麼,所以我可以在每個左右聲道中渲染2個獨立的正弦波。目前,我認爲在我的初始化音頻部分,我需要做以下修改:iOS音頻單元 - 創建立體聲正弦波
來源:
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;
要:
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
//44100.0f
#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;
//NSLog(@"switch");
}
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; // <--------- make sure to divide by how many waves you're stacking
values[j] = (SInt16)waves;
values[j] += values[j]<<16;
phase++;
phase1++;
}
memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16));
}
return noErr;
}
在此先感謝您的幫助!
如果格式是交錯的(就像你的ASBD所建議的那樣),那麼樣本將在一個緩衝區左右交替變化:'LRLRLRLR'。然而,在回調中使用交織格式通常是不尋常的 - 通常格式是操作系統的規範格式。 – sbooth
謝謝。其實我只是在幾分鐘前就把它全部弄清楚了。儘管如此,它是交錯的。我必須弄清楚如何循環回調才能在不同的L&R通道中渲染正弦波。感謝您的幫助! – jwkerr
你好jwkerr,我希望我能說說你發佈你的渲染函數。我一直試圖讓立體渲染工作一段時間,並不能完全得到它。謝謝 – VaporwareWolf