【问题标题】:osx audio unit multi channel outputosx音频单元多声道输出
【发布时间】:2013-02-25 20:48:14
【问题描述】:

我已经在网上搜索了几个星期没有运气的答案。

我有一个 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);

我正在为 openframeworks 开发 ofxaudiounit 插件: https://github.com/antimodular/ofxAudioUnit

谢谢。

【问题讨论】:

    标签: macos core-audio openframeworks


    【解决方案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);
    

    【讨论】:

      【解决方案2】:

      规范格式是非交错的,所以每个缓冲区只有一个通道,所以.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));
      }
      

      【讨论】:

      • 谢谢。我会试一试。同时,如果我使用任何其他格式标志,这种方法是否必须改变? kAudioFormatFlagIsSignedInteger kAudioFormatFlagsNativeEndian kAudioFormatFlagIsNonMixable 我真的不知道它们代表什么。再次感谢。
      • kAudioFormatFlagsAudioUnitCanonical 包括 NativeEndian。是的,如果您使用 SignedInteger,它会改变,因为 SignedInteger 似乎将所有内容都放入一个缓冲区。我不知道 IsNonMixable 是干什么用的 :)
      猜你喜欢
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 2013-01-21
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多