【发布时间】:2012-09-03 09:34:36
【问题描述】:
周末,我在学习如何在 iOS 上编写音频合成程序时遇到了障碍。我已经在 iOS 上开发了几年,但我只是进入音频合成方面。现在,我只是在编写演示应用程序来帮助我学习这些概念。我目前已经能够在音频单元的播放渲染器中构建和堆叠正弦波而没有问题。但是,我想了解渲染器中发生了什么,这样我就可以在每个左右通道中渲染 2 个单独的正弦波。目前,我假设在我的初始音频部分中我需要进行以下更改:
发件人:
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。但是,在回调中使用交错格式是不寻常的——通常该格式是操作系统的规范格式。 -
谢谢。实际上,我只是在几分钟前才弄清楚这一切。不过,正如你所说,它是交错的。我必须弄清楚如何循环通过回调以在不同的 L&R 通道中呈现正弦波。不过感谢您的帮助!
-
你好 jwkerr,我希望我能说服你发布你的渲染函数。我一直试图让立体渲染工作一段时间,但不能完全理解。谢谢
-
你好@jwkerr。你能告诉我如何设置AudioStreamBasicDescription吗?我也想得到立体声正弦波!
标签: objective-c ios audio core-audio audiounit