C++ 通过螺旋图连接的iOS波形发生器

C++ 通过螺旋图连接的iOS波形发生器,c++,iphone,objective-c,core-audio,audiounit,C++,Iphone,Objective C,Core Audio,Audiounit,我已经创建了一个简单的波形发生器,它连接到一个螺旋图。我重用了苹果公司的一些示例代码来设置AudioStreamBasicDescription,如下所示 void SetCanonical(UInt32 nChannels, bool interleaved) // note: leaves sample rate untouched { mFormatID = kAudioFormatLinearPCM; int sampleSize = Siz

我已经创建了一个简单的波形发生器,它连接到一个螺旋图。我重用了苹果公司的一些示例代码来设置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;
Float32*bufferLeft=(Float32*)ioData->mBuffers[0].mData;
Float32*bufferRight=(Float32*)ioData->mBuffers[1].mData;
//生成样本
对于(UInt32 frame=0;frame
看来我是用单声道而不是立体声。右边的指针是空的,但不知道为什么。
任何帮助都将不胜感激。

我可以看到两个可能的错误。首先,正如@invalidname所指出的,立体声录音在单声道设备(如iPhone)上可能不起作用。好吧,它可能起作用,但如果起作用,您只会返回双单声道立体声流,那么为什么要麻烦呢?您不妨将流配置为w在mono中工作,节省CPU开销

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

kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked
另外,不要忘记将mReserved标志设置为0。虽然此标志的值可能会被忽略,但为了确保安全,将其显式设置为0并没有什么坏处

编辑:在iPhone上调试音频的另一个更一般的技巧——如果你得到失真、剪辑或其他奇怪的效果,从手机中抓取数据负载,在波形编辑器中查看录音。能够缩小并查看单个样本将为你提供很多关于出错原因的线索

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


引用自

我猜问题在于,您指定的是交错格式,但访问缓冲区时,就好像它们在IO回调中是非交错的一样。ioData->mBuffers[1]无效,因为所有数据,包括左通道和右通道,都在ioData->mBuffers[0]中交错.mData。检查ioData->mNumberBuffers。我猜它被设置为1。另外,请验证ioData->mBuffers[0]。mNumberChannels被设置为2,这将指示交错数据

此外,还可以查看核心音频公用事业类,以帮助设置格式。这样做非常简单。设置格式的代码可以减少到一行,您将更有信心它是正确的(尽管对我来说,您的格式看起来设置正确-如果您想要的是交错16位整数):

苹果曾经将这些类打包到随Xcode安装的SDK中,但现在您需要在此处下载它们:


无论如何,看起来最简单的修复方法就是将格式更改为非交错格式

巧合的是,我在浏览器中打开了这两个选项卡:。可能其他人偶然发现了你的问题,只是想要一个可用的波形图作为库;)我需要立体声,因为我为每个频道设置了不同的频率。我可以使用“AudioComponentInstance”来实现这一点,但到那时我最有可能需要建立我自己的均衡器,这可以通过AUGraph更容易地完成。我尝试了,但它似乎不起作用。但无论如何,thanx。
CAStreamBasicDescription myFormat(44100.0, 2, CAStreamBasicDescription::kPCMFormatInt16, true)