通过 AUGraph 连接的 iOS 波形发生器
Posted
技术标签:
【中文标题】通过 AUGraph 连接的 iOS 波形发生器【英文标题】:iOS waveform generator connected via AUGraph 【发布时间】:2014-01-24 12:43:33 【问题描述】:我创建了一个连接到 AUGraph 的简单波形发生器。我重用了 Apple 的一些示例代码来设置 AudiostreamBasicDescription 像这样
void SetCanonical(UInt32 nChannels, bool interleaved)
// note: leaves sample rate untouched
mFormatID = kAudioFormatLinearPCM;
int sampleSize = SizeOf32(AudioSampleType);
mFormatFlags = kAudioFormatFlagsCanonical;
mBitsPerChannel = 8 * sampleSize;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved)
mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
else
mBytesPerPacket = mBytesPerFrame = sampleSize;
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
在我的课堂上我称之为这个函数
mClientFormat.SetCanonical(2, true);
mClientFormat.mSampleRate = kSampleRate;
当采样率是
#define kSampleRate 44100.0f;
其他设置也取自示例代码
// output unit
CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple);
// iPodEQ unit
CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple);
// multichannel mixer unit
CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple);
一切正常,但问题是当我尝试到达第二个缓冲区时,我没有收到立体声并且我的回调函数失败(访问错误)
Float32 *bufferLeft = (Float32 *)ioData->mBuffers[0].mData;
Float32 *bufferRight = (Float32 *)ioData->mBuffers[1].mData;
// Generate the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
switch (generator.soundType)
case 0: //Sine
bufferLeft[frame] = sinf(thetaLeft) * amplitude;
bufferRight[frame] = sinf(thetaRight) * amplitude;
break;
所以看来我得到的是单声道而不是立体声。指针 bufferRight 为空,但不知道为什么。 任何帮助将不胜感激。
【问题讨论】:
碰巧我在浏览器中打开了这两个标签:SCWaveformView。也许其他人偶然发现了您的问题,只是想要一个工作波形图作为库;) 【参考方案1】:我可以看到两个可能的错误。首先,正如@invalidname 指出的那样,立体声录音可能不适用于 iPhone 等单声道设备。好吧,它可能会起作用,但如果确实如此,那么无论如何你都会得到双单声道立体声流,那何必呢?您不妨将流配置为以单声道工作并节省自己的 CPU 开销。
第二个问题可能是你的声音失真的来源。您的流描述格式标志应该是:
kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked
另外,不要忘记将 mReserved 标志设置为 0。虽然此标志的值可能会被忽略,但为了确保安全,将其显式设置为 0 并没有什么坏处。
编辑:在 iPhone 上调试音频的另一个更通用的技巧 - 如果您遇到失真、削波或其他奇怪的效果,请从手机中获取数据负载并在波形编辑器中查看录音。能够缩小并查看单个样本将为您提供很多关于问题所在的线索。
为此,您需要打开“管理器”窗口,点击您的手机,然后展开您的应用程序旁边的小箭头(在您通常卸载它的同一位置)。现在您将看到一个向下的箭头,如果您单击它,Xcode 会将数据有效负载从您的应用程序复制到硬盘上的某个位置。如果您要将录音转储到磁盘,您会在此处找到提取的文件。
来自link的参考
【讨论】:
我需要立体声,因为我为每个通道设置了不同的频率。我可以使用“AudioComponentInstance”来做到这一点,但到那时我很可能需要建立自己的均衡器,这可以通过 AUGraph 更轻松地完成。【参考方案2】:我猜问题是您指定的是交错格式,但随后访问缓冲区就像它们在 IO 回调中是非交错的一样。 ioData->mBuffers[1] 无效,因为左右通道的所有数据都交错在 ioData->mBuffers[0].mData 中。检查 ioData->mNumberBuffers。我的猜测是它设置为 1。另外,请验证 ioData->mBuffers[0].mNumberChannels 设置为 2,这表示交错数据。
还可以查看 Core Audio 公共实用程序类,以帮助设置格式等。让它变得容易多了。您设置格式的代码可以减少到一行,并且您会更有信心它是正确的(尽管在我看来您的格式设置正确 - 如果您想要的是交错的 16 位 int):
CAStreamBasicDescription myFormat(44100.0, 2, CAStreamBasicDescription::kPCMFormatInt16, true)
Apple 曾经将这些类打包到随 Xcode 一起安装的 SDK 中,但现在您需要在此处下载它们:https://developer.apple.com/library/mac/samplecode/CoreAudioUtilityClasses/Introduction/Intro.html
无论如何,看起来最简单的解决方法就是将格式更改为非交错。所以在你的代码中:mClientFormat.SetCanonical(2, false);
【讨论】:
我试过了,好像不行。但无论如何还是谢谢。以上是关于通过 AUGraph 连接的 iOS 波形发生器的主要内容,如果未能解决你的问题,请参考以下文章
连接节点错误 kAudioUnitErr_PropertyNotWriteable 时 AudioToolbox AUGraph 失败