2013-02-25 50 views
3

我一直在寻找网络的答案几周没有运气。osx音频单元多通道输出

我有一个maudio profire 610多通道音频接口。 如何正确设置AudioStreamBasicDescription以使用全部8个输出通道? 目前它只适用于前2个频道。

UInt32 busCount = 3; //numberOfOutputBusses; 
AudioStreamBasicDescription outputASBD2 = { 
    .mSampleRate  = 44100, 
    .mFormatID   = kAudioFormatLinearPCM, 
    .mFormatFlags  = kAudioFormatFlagsAudioUnitCanonical, 
    .mChannelsPerFrame = busCount, 
    .mFramesPerPacket = 1, 
    .mBitsPerChannel = sizeof(Float32) * 8, 
    .mBytesPerPacket = sizeof(Float32) * busCount, 
    .mBytesPerFrame = sizeof(Float32) * busCount 
}; 

AudioUnitSetProperty(*_unit, 
            kAudioUnitProperty_StreamFormat, 
            kAudioUnitScope_Output, 
            1, 
            &outputASBD2, 
            sizeof(AudioStreamBasicDescription); 

我工作的ofxaudiounit插件对了openFrameworks: https://github.com/antimodular/ofxAudioUnit

感谢。

回答

0

规范格式是非交错的,所以每个缓冲区只有一个通道,所以.mBytesPerPacket.mBytesPerFrame应该是sizeof(Float32)。然后,你需要创建多个(busCount)缓冲区传递到AudioUnit喜欢的东西

AudioBufferList *bufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList) + (sizeof(AudioBuffer) * (busCount - 1))); 
bufferList->mNumberBuffers = busCount; 
for (int i=0; i < bufferList->mNumberBuffers; i++) { 
    bufferList->mBuffers[i].mNumberChannels = 1; 
    bufferList->mBuffers[i].mDataByteSize = BUFFER_SIZE * sizeof(float); 
    bufferList->mBuffers[i].mData = malloc(BUFFER_SIZE * sizeof(float)); 
} 
+0

感谢。我会试试这个。 与此同时,如果我使用这些其他格式标志中的任何一个,这种行为必须改变吗? kAudioFormatFlagIsSignedInteger kAudioFormatFlagsNativeEndian kAudioFormatFlagIsNonMixable 我真的不知道自己代表的是什么。 再次感谢。 – stephanschulz 2013-03-02 13:07:09

+0

kAudioFormatFlagsAudioUnitCanonical包含NativeEndian。是的,如果您使用SignedInteger,则会发生变化,因为SignedInteger似乎将所有内容都放入一个缓冲区中。我不知道IsNonMixable是什么:) – iain 2013-03-02 13:15:13

1
 UInt32 propertySize; 
    Boolean writable = false; 
    OSStatus status = AudioUnitGetPropertyInfo(*_unit, 
              kAudioOutputUnitProperty_ChannelMap, 
              kAudioUnitScope_Output, 
              0, 
              &propertySize, &writable); 
    //SignalIf_(writable == false); 
    cout<<"writable "<<&writable<<endl; 

    long nChannels = propertySize/sizeof(SInt32); 
    long* channelMapPtr = (long*)malloc(propertySize); 

    cout<<"nChannels "<<nChannels<<endl; 

    UInt32 scratch = propertySize; 
    status = AudioUnitGetProperty(*_unit, 
            kAudioOutputUnitProperty_ChannelMap, 
            kAudioUnitScope_Output, 
            0, 
            channelMapPtr, 
            &scratch); 

    // channelMapPtr[0] = 0; 
    for (long i = 0; i < nChannels; i++) 
    { 
     channelMapPtr[i] = -1; 
    } 

channelMapPtr[3] = 0; 
channelMapPtr[5] = 1; 

    OFXAU_RET_BOOL(AudioUnitSetProperty(*_unit, 
             kAudioOutputUnitProperty_ChannelMap, 
             kAudioUnitScope_Output, 
             0, 
             channelMapPtr, 
             scratch),"setting output unit's device ID"); 

    free((void *)channelMapPtr);