gpt4 book ai didi

macos - 如何启用/禁用聚合 CoreAudio 设备的输入或输出 channel ?

转载 作者:行者123 更新时间:2023-12-04 07:37:11 25 4
gpt4 key购买 nike

我已经彻底阅读了这个线程中的问题和答案: How to exclude input or output channels from an aggregate CoreAudio device?

它似乎缺少有关解决方案的信息:我创建了一个包含多个音频设备的聚合设备。当调用核心音频以接收流的数量(使用 kAudioDevicePropertyStreams)时,返回值始终为 1。我还尝试了 CoreAudio 实用程序类中的实现:CAHALAudioDevice::GetIOProcStreamUsage。我仍然看不到如何访问子流并按照此处所述禁用/启用它们。需要做什么来实现子流的禁用/启用?

编辑

这里有CAHALAudioDevice::GetIOProcStreamUsage供引用:

void    CAHALAudioDevice::GetIOProcStreamUsage(AudioDeviceIOProcID 
inIOProcID, bool inIsInput, bool* outStreamUsage) const
{
// make an AudioHardwareIOProcStreamUsage the right size
UInt32 theNumberStreams = GetNumberStreams(inIsInput);
UInt32 theSize = SizeOf32(void*) + SizeOf32(UInt32) + (theNumberStreams * SizeOf32(UInt32));
CAAutoFree<AudioHardwareIOProcStreamUsage> theStreamUsage(theSize);

// set it up
theStreamUsage->mIOProc = reinterpret_cast<void*>(inIOProcID);
theStreamUsage->mNumberStreams = theNumberStreams;

// get the property
CAPropertyAddress theAddress(kAudioDevicePropertyIOProcStreamUsage, inIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput);
GetPropertyData(theAddress, 0, NULL, theSize, theStreamUsage);

// fill out the return value
for(UInt32 theIndex = 0; theIndex < theNumberStreams; ++theIndex)
{
outStreamUsage[theIndex] = (theStreamUsage->mStreamIsOn[theIndex] != 0);
}
}

最佳答案

作为引用,这是我的程序使用的函数来完成 linked question 中描述的结果。 :

// Tell CoreAudio which input (or output) streams we actually want to use in our device
// @param devID the CoreAudio audio device ID of the aggregate device to modify
// @param ioProc the rendering callback-function (as was passed to AudioDeviceCreateIOProcID()'s second argument)
// @param scope either kAudioObjectPropertyScopeInput or kAudioObjectPropertyScopeOutput depending on which type of channels we want to modify
// @param numValidChannels how many audio channels in the aggregate device we want to actually use
// @param rightJustify if true, we want to use the last (numValidChannels) in the device; if false we want to use the first (numValidChannels) in the device
// @returns 0 on success or -1 on error
// @note this function doesn't change the layout of the audio-sample data in the audio-render callback; rather it causes some channels of audio in the callback to become zero'd out/unused.
int SetProcStreamUsage(AudioDeviceID devID, void * ioProc, AudioObjectPropertyScope scope, int numValidChannels, bool rightJustify)
{
const AudioObjectPropertyAddress sizesAddress =
{
kAudioDevicePropertyStreamConfiguration,
scope,
kAudioObjectPropertyElementMaster
};
Uint32 streamSizesDataSize = 0;
OSStatus err = AudioObjectGetPropertyDataSize(devID, &sizesAddress, 0, NULL, &streamSizesDataSize);
if (err != noErr)
{
printf("SetProcStreamUsage(%u,%i,%i): AudioObjectGetPropertyDataSize(kAudioDevicePropertyStreamConfiguration) failed!\n", (unsigned int) devID, scope, rightJustify);
return -1; // ("AudioObjectGetPropertyDataSize(kAudioDevicePropertyStreamConfiguration) failed");
}

const AudioObjectPropertyAddress usageAddress =
{
kAudioDevicePropertyIOProcStreamUsage,
scope,
kAudioObjectPropertyElementMaster
};

Uint32 streamUsageDataSize = 0;
err = AudioObjectGetPropertyDataSize(devID, &usageAddress, 0, NULL, &streamUsageDataSize);
if (err != noErr)
{
printf("SetProcStreamUsage(%u,%i,%i): AudioObjectGetPropertyDataSize(kAudioDevicePropertyIOProcStreamUsage) failed!\n", (unsigned int) devID, scope, rightJustify);
return -1; // ("AudioObjectGetPropertyDataSize(kAudioDevicePropertyIOProcStreamUsage) failed");
}

AudioBufferList * bufList = (AudioBufferList*) malloc(streamSizesDataSize); // using malloc() because the object-size is variable
if (bufList)
{
int ret;

err = AudioObjectGetPropertyData(devID, &sizesAddress, 0, NULL, &streamSizesDataSize, bufList);
if (err == noErr)
{
AudioHardwareIOProcStreamUsage * streamUsage = (AudioHardwareIOProcStreamUsage *) malloc(streamUsageDataSize); // using malloc() because the object-size is variable
if (streamUsage)
{
streamUsage->mIOProc = ioProc;
err = AudioObjectGetPropertyData(devID, &usageAddress, 0, NULL, &streamUsageDataSize, streamUsage);
if (err == noErr)
{
if (bufList->mNumberBuffers == streamUsage->mNumberStreams)
{
Int32 numChannelsLeft = numValidChannels;
if (rightJustify)
{
// We only want streams corresponding to the last (N) channels to be enabled
for (Int32 i=streamUsage->mNumberStreams-1; i>=0; i--)
{
streamUsage->mStreamIsOn[i] = (numChannelsLeft > 0);
numChannelsLeft -= bufList->mBuffers[i].mNumberChannels;
}
}
else
{
// We only want streams corresponding to the first (N) channels to be enabled
for (Uint32 i=0; i<streamUsage->mNumberStreams; i++)
{
streamUsage->mStreamIsOn[i] = (numChannelsLeft > 0);
numChannelsLeft -= bufList->mBuffers[i].mNumberChannels;
}
}

// Now set the stream-usage per our update, above
err = AudioObjectSetPropertyData(devID, &usageAddress, 0, NULL, streamUsageDataSize, streamUsage);
if (err != noErr)
{
printf("SetProcStreamUsage(%u,%i,%i): AudioObjectSetPropertyData(kAudioDevicePropertyIOProcStreamUsage) failed!\n", (unsigned int) devID, scope, rightJustify);
ret = -1; // ("AudioObjectSetPropertyData(kAudioDevicePropertyIOProcStreamUsage) failed");
}
}
else
{
printf("SetProcStreamUsage(%u,%i,%i): #Buffers (%u) doesn't match #Streams (%u)!\n", (unsigned int) devID, scope, rightJustify, bufList->mNumberBuffers, streamUsage->mNumberStreams);
ret = -1;
}
}
else
{
printf("SetProcStreamUsage(%u,%i,%i): AudioObjectSetPropertyData(kAudioDevicePropertyIOProcStreamUsage) failed!\n", (unsigned int) devID, scope, rightJustify);
ret = -1; // ("AudioObjectGetPropertyData(kAudioDevicePropertyIOProcStreamUsage) failed");
}

free(streamUsage);
}
else ret = -1; // out of memory?
}
else
{
printf("SetProcStreamUsage(%u,%i,%i): AudioObjectGetPropertyData(kAudioDevicePropertyStreamConfiguration) failed!\n", (unsigned int) devID, scope, rightJustify);
ret = -1; // ("AudioObjectGetPropertyData(kAudioDevicePropertyStreamConfiguration) failed");
}

free(bufList);
return ret;
}
else return -1; // out of memory?
}

关于macos - 如何启用/禁用聚合 CoreAudio 设备的输入或输出 channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67670847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com