2010-08-27 4 views
2

J'ai passé la dernière semaine à faire une excursion imprévue dans les profondeurs du système audio Macintosh après que NSSound s'est avéré être inégal à la tâche .. J'ai enfin obtenu mon fichier en jouant avec Audio Queue Services et maintenant il n'y a plus qu'une chose à faire: changer les périphériques de sortie.Services de file d'attente audio: modification du périphérique de sortie

Malheureusement, il semble que je suis soit faire quelque chose de mal ou de l'appareil UID CFStringRef que vous êtes censé passer est pas celui que Core Audio donne sur ..

Le morceau de code ci-dessous la récupère dispositif de sortie standard (auquel la file d'attente audio va jouer par défaut de toute façon, mais il refuse de changer d'appareil:

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)); 

Si la file d'attente est en cours de lecture, je reçois une erreur kAudioQueueErr_InvalidRunState, me disant que vous ne pouvez pas définir cette propriété pendant que la file d'attente est en jeu. Si la file d'attente ne joue pas, j'obtiens l'erreur de paramètre -50Je fais quelque chose de mal avec les pointeurs? ou y a-t-il un appareil différent uid quelque part?

Toute aide serait grandement appréciée.

+0

Qu'est-ce que vous essayez de faire que NSSound ne pouvait pas faire? Et qu'AudioObjectGetPropertyData a renvoyé pour la propriété DeviceUID? –

+0

La fonction de bouclage NSSound ne fonctionne pas très bien. Il insère une pause légère mais audible entre chaque répétition, ce qui dans mon contexte n'est pas acceptable. Les fluides de périphérique sur ma machine sont les suivants: "AppleHDAEngineOutput: 1B, 0,1,3: 0", "AppleHDAEngineOutput: 1B, 0,1,4: 1" « AppleHDAEngineOutput: 1B, 0,1 , 5: 2 " Cela fonctionne correctement avec [NSSound setPlaybackDeviceIdentifier:]. –

+0

Avez-vous cherché ces informations dans une application quelque part, ou les avez-vous obtenues en inspectant la valeur de retour de AudioObjectGetPropertyData? Je demande parce qu'il est possible que l'une des fonctions précédentes renvoie une erreur et non une valeur utile, ce qui est un bon moyen d'avoir des paramètres invalides à la dernière fonction. –

Répondre

2

J'ai trouvé une solution et je poste ici pour les archives:

d'Apple Developer Services testé mon code dans un projet distinct et il a couru tout simplement génial pour eux tout de suite .. la différence était qu'ils ont mis l'uid de l'appareil sans tous les tampons audio fastidieux et la configuration du volume, etc. J'ai déplacé le dispositif uid changement de la fin de la configuration de la file d'attente à immédiatement après que la file d'attente est créée et bingo! ça fonctionne très bien. Je ne suis pas sûr à 100%, mais je pense que vous ne pouvez pas changer l'appareil après avoir défini le gain pour la file d'attente en raison de certaines restrictions de pilote de matériel. "Erreur de paramètre" ne semble pas aller dans ce sens, mais je pense qu'une erreur "trop ​​tard pour changer d'appareil" serait plus appropriée.

Questions connexes