Audio Queue Services: смена устройства вывода - PullRequest
2 голосов
/ 27 августа 2010

Я провел последнюю неделю в незапланированной экскурсии в глубину звуковой системы Macintosh после того, как NSSound оказался неравным для этой задачи ... Я наконец-то получил свой файл, воспроизводящийся с помощью Audio Queue Services, и теперь есть только одна маленькая вещь Осталось сделать: переключить устройства вывода.

К сожалению, похоже, что я либо делаю что-то не так, либо UID CFStringRef устройства, который вы должны передать, не тот, который выдает Core Audio ..

В приведенном ниже фрагменте кода извлекается стандартное устройство вывода (в любом случае аудио-очередь будет воспроизводиться по умолчанию, но при этом он не будет менять устройства:

UInt32 thePropSize;
AudioDeviceID defaultAudioDevice;

OSStatus result = noErr;

// get the device list  
AudioObjectPropertyAddress thePropertyAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, 
    kAudioObjectPropertyElementMaster };

result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &thePropertyAddress, 0, NULL, &thePropSize);

result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &thePropertyAddress, 0, NULL, &thePropSize, &defaultAudioDevice);

CFStringRef theDeviceName;      

// get the device name
thePropSize = sizeof(CFStringRef);
thePropertyAddress.mSelector = kAudioObjectPropertyName;
thePropertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
thePropertyAddress.mElement = kAudioObjectPropertyElementMaster;

// get the name of the device
result = AudioObjectGetPropertyData( (AudioObjectID)defaultAudioDevice, 
                                    &thePropertyAddress, 0, NULL, &thePropSize, &theDeviceName);

// get the uid of the device
CFStringRef theDeviceUID;
thePropertyAddress.mSelector = kAudioDevicePropertyDeviceUID;
result = AudioObjectGetPropertyData( (AudioObjectID)defaultAudioDevice, 
                                    &thePropertyAddress, 0, NULL, &thePropSize, &theDeviceUID);


result = AudioQueueSetProperty( playerState.mQueue,
                                        kAudioQueueProperty_CurrentDevice,
                                        &theDeviceUID,
                                        sizeof(theDeviceUID));

Если очередь воспроизводится, я получаю сообщение об ошибке kAudioQueueErr_InvalidRunState, сообщающее, что вы не можете установить это свойство во время воспроизведения очереди. Если очередь не воспроизводится, я получаю ошибку -50.

Я что-то не так делаю с указателями? или есть где-то другое устройство uid!?

Любая помощь будет принята с благодарностью.

1 Ответ

2 голосов
/ 02 сентября 2010

Я нашел решение и выкладываю его здесь для архивов:

Apple Developer Services проверил мой код в отдельном проекте, и он сразу запустился для них просто отлично ... разница была в том, что они установили uid устройства без всех утомительных аудио-буферов и настроек громкости и т. Д. изменение uid с конца настройки очереди на сразу после создания очереди и бинго! это работает просто отлично.

Я не уверен на 100%, но я думаю, что вы просто не можете сменить устройство после установки усиления для очереди из-за некоторых ограничений аппаратного драйвера. «ошибка параметра», кажется, не совсем указывает в этом направлении, но я думаю, что ошибка «слишком поздно для изменения устройства» была бы более уместной.

...