CoreAudio: получение отсчета количества устройств при подключении к Foundation на 10.6 - PullRequest
2 голосов
/ 31 августа 2010

У меня есть смешанный проект C ++ / Objective-C, который использует AudioObjectGetPropertyDataSize, чтобы подключить количество аудиоустройств (например, USB-гарнитур). Этот API, похоже, не работает при определенных условиях. Например, на 10.5 он будет работать, но на 10.6 он не будет определять, когда подключена новая USB-гарнитура.

Я сократил проблему до небольшого фрагмента кода, который воспроизводит проблему (он вызывает AudioObjectGetPropertyDataSize в цикле). Код будет работать на 10.6 (т.е. он будет обнаруживать, когда устройства подключены / отключены), когда он связан только с CoreAudio, но как только вы создадите ссылку на Foundation , он перестанет работать .

Я не понимаю, как связывание с фреймворком может нарушить код, который в противном случае работает.

Вот код (coreaudio-test.cpp):

#include <stdio.h>
#include <CoreAudio/AudioHardware.h>

int main(int argc, char **argv) {
    printf("Press <enter> to refresh device list> \n");
    while (1) {
        getchar();

        // get device count
        UInt32 dataSize = 0;
        AudioObjectPropertyAddress propertyAddress;
        propertyAddress.mSelector = kAudioHardwarePropertyDevices;
        propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal;
        propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
        OSStatus result =
            AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize);

        int count = -1;
        if (result == noErr) {
            count = dataSize / sizeof(AudioDeviceID);
        }
        printf("num devices= %d \n", count);
    }

    return 0;
}

А вот и Makefile:

LFLAGS= -framework CoreAudio

all: coreaudio-test coreaudio-test.broken

# create a test that works
coreaudio-test: coreaudio-test.cpp
    g++ -o $@ $^ $(LFLAGS)

# linking to foundation will break the test
coreaudio-test.broken: coreaudio-test.cpp
    g++ -o $@ $^ $(LFLAGS) -framework Foundation

Есть какие-нибудь мысли по поводу этого странного поведения? (Кстати, я также разместил этот вопрос в списке CoreAudio .)

Ответы [ 2 ]

2 голосов
/ 31 августа 2010

Список CoreAudio ответил на мой вопрос . Нам нужно указать CoreAudio выделить свой собственный поток диспетчеризации событий:

CFRunLoopRef theRunLoop =  NULL;
AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
AudioObjectSetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);

Я подозреваю, что когда программа связана с Foundation, CoreAudio предполагает, что основной поток действует как цикл диспетчера событий (очень часто, поскольку Objective-C обычно используется для программ с графическим интерфейсом). Когда я не связываюсь с Foundation, я думаю, он полагает, что ему нужно выделить собственный поток событий.

0 голосов
/ 31 августа 2010

Сходное поведение, которое, как и 9 лет назад, кто-то сообщил: http://lists.apple.com/archives/coreaudio-api/2001/May/msg00021.html

...