c++ - 通过 AUGraph 连接的 iOS 波形发生器

标签 c++ iphone objective-c core-audio audiounit

我创建了一个连接到 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 为空,但不知道为什么。 任何帮助将不胜感激。

最佳答案

我可以看到两个可能的错误。首先,正如@invalidname 所指出的,立体声录音可能不适用于 iPhone 等单声道设备。好吧,它可能会起作用,但如果它起作用了,你无论如何都会得到双单声道立体声流,所以何必呢?您不妨将您的流配置为在单声道模式下工作并节省 CPU 开销。

第二个问题可能是声音失真的来源。您的流描述格式标志应该是:

kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked

此外,不要忘记将 mReserved 标志设置为 0。虽然此标志的值可能会被忽略,但将其显式设置为 0 只是为了确保安全。

编辑:在 iPhone 上调试音频的另一个更通用的技巧——如果您遇到失真、削波或其他奇怪的效果,请从您的手机中获取数据负载并在波形编辑器中查看录音。能够缩小并查看单个样本将为您提供很多关于问题所在的线索。

为此,您需要打开“管理器”窗口,点击您的手机,然后展开您的应用程序旁边的小箭头(与您通常卸载它的位置相同)。现在您会看到一个向下的小箭头,如果您单击它,Xcode 会将数据有效负载从您的应用程序复制到硬盘驱动器上的某个位置。如果您将录音转储到磁盘,您会在此处找到提取的文件。

引用自link

关于c++ - 通过 AUGraph 连接的 iOS 波形发生器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21333055/

相关文章:

iphone - NSURL 添加参数到 fileURLWithPath 方法

iphone - 在 iPhone 上的静音模式和响铃模式之间切换

在调用析构函数之前删除的 C++ 动态成员数组

iphone - NSTimer 和非事件/ sleep 状态

objective-c - 什么时候使用 KVO?

objective-c - 在 iOS 上使用 AVAudioPlayer 需要哪些框架和导入?

objective-c - NSCombobox 选定状态未移除

c++ - 何时捕获 boost::bad lexical_cast

C++ - 将 stdout/stderr 复制到文件,同时保留控制台输出

c++ - 有没有办法让 DisableUserModeCallbackFilter 在 Windows 10 中工作?