2014-01-24 61 views
3

我创建了一个连接到AUGraph的简单波形发生器。我重用了来自苹果的一些示例代码来设置AudioStreamBasicDescription这样iOS波形发生器通过AUGraph连接

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是空的,但不知道为什么。 任何帮助将不胜感激。

+0

只是巧合我在浏览器中打开了这两个选项卡:[SCWaveformView](https://github.com/rFlex/SCWaveformView)。也许别人偶然发现了你的问题,只想把一个工作波形图作为一个库;) – 2014-02-08 13:12:08

回答

0

我可以看到两个可能的错误。首先,由于@invalidname指出,以立体声录制可能不适用于iPhone等单声道设备。好吧,它可能会起作用,但如果是这样的话,您只需要返回双单声道立体声流,那么为什么要麻烦呢?你也可以配置你的数据流在单声道工作,并节省CPU的开销。

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

kAudioFormatFlagIsSignedInteger | 
kAudioFormatFlagsNativeEndian | 
kAudioFormatFlagIsPacked 

另外,不要忘记将mReserved标志设置为0,虽然可能被忽略这个标志的价值,它不会伤害到明确将其设置为0只是为了确保。

编辑:在iPhone上调试音频的另一个更为通用的提示 - 如果您正在获取失真,剪辑或其他奇怪效果,请从手机中获取数据有效载荷,然后在波形编辑器中查看录制内容。能够缩小并查看单个样本会为您提供很多关于错误的线索。要做到这一点,你需要打开“Organizer”窗口,点击你的手机,然后展开你的应用程序旁边的小箭头(在你通常会卸载它的地方)。现在你会看到一个向下的箭头,如果你点击它,Xcode会将你的应用中的数据有效载荷复制到硬盘上的某个地方。如果您将录制内容转储到磁盘,则会在此处找到解压缩的文件。从link

+0

我需要立体声,因为我为每个声道都加入了不同的频率。我可以用“AudioComponentInstance”来做到这一点,但到那时我最需要建立自己的均衡器,这可以通过AUGraph更容易完成。 – Vanya

0

我猜问题

引用是你指定一个交错格式,但随后访问该缓冲区,如果他们在你的IO回调非交错。 ioData-> mBuffers [1]无效,因为左侧和右侧的所有数据都在ioData-> mBuffers [0] .mData中交错。检查ioData-> mNumberBuffers。我的猜测是它被设置为1.另外,验证ioData-> mBuffers [0] .mNumberChannels设置为2,这将表示交错数据。

还检查了核心音频公共实用程序类来帮助设置格式的东西。使其变得如此简单。你的设置格式的代码可以减少到一行,你会更加确信它是正确的(尽管你的格式看起来设置正确 - 如果你想要的是交错的16位int):

CAStreamBasicDescription myFormat(44100.0, 2, CAStreamBasicDescription::kPCMFormatInt16, true) 

苹果使用已安装在Xcode的SDK打包这些类,但现在你需要从这里下载:https://developer.apple.com/library/mac/samplecode/CoreAudioUtilityClasses/Introduction/Intro.html

不管怎么说,它看起来像最简单的解决对你来说只是改变格式非交错。所以在你的代码中:mClientFormat.SetCanonical(2,false);

+0

我试过了,它似乎没有工作。但是,无论如何。 – Vanya