2016-08-02 2 views
2

Je continue d'envoyer des données à IAudioClient (GetBufferSize/GetCurrentPadding/GetBuffer/ReleaseBuffer), mais je veux savoir quand le périphérique audio a fini de lire les dernières données que j'ai envoyées. Je ne veux pas supposer que le lecteur s'est arrêté juste parce que j'ai envoyé la dernière partie de données à l'appareil: il pourrait encore jouer les données mises en mémoire tampon.IAudioClient - Recevoir une notification à la fin de la lecture?

J'ai essayé d'utiliser IAudioClock/IAudioClock2 pour vérifier la position du tampon matériel, mais il reste le même à partir du moment où j'envoie le dernier segment.

Je ne vois pas aussi rien de pertinent dans les interfaces IMMNotificationClient et IAudioSessionNotification ...

Qu'est-ce que je manque?

Merci! IMMNotificationClient et IAudioSessionNotification ne vont pas vous aider, ils sont pour détecter de nouveaux périphériques/nouvelles sessions d'application respectivement.

Répondre

1

Autant que je sache, il n'y a rien dans WASAPI qui envoie explicitement un événement lorsque le dernier échantillon est consommé par le périphérique (mode exclusif) ou le moteur audio (mode partagé). Un truc que j'ai utilisé dans le passé (mais avec DirectSound, mais qui devrait fonctionner aussi bien avec WASAPI) est de vérifier en continu l'espace disponible dans le tampon audio (pour WASAPI, en utilisant GetCurrentPadding). Après avoir envoyé le dernier échantillon, enregistrez immédiatement le remplissage actuel, disons qu'il s'agit de N trames. Ensuite, continuez d'écrire des zéros sur AudioClient jusqu'à ce que N images aient été traitées (comme indiqué par IAudioClock (2), ou juste guestimate en utilisant un timer), puis arrêtez le flux. Que cela fonctionne sur un flux exclusif en mode événementiel est un problème de qualité du pilote; le pilote peut choisir de signaler la "vraie" position de lecture ou la traiter simplement en morceaux de taille de mémoire tampon complète.

+0

IAudioClock :: GetPosition/etc renvoie toujours la même valeur, que l'audio soit en cours de lecture ou non. Je peux utiliser IAudioMeterInformation.GetPeakValue et vérifier si la valeur retournée == 0. Cela semble fonctionner dans mon cas (l'audio est un enregistrement de microphone avec au moins un peu de bruit ambiant), mais je ne l'aime pas vraiment comme générique solution - on peut certainement avoir des périodes de silence dans le flux audio. –

+0

AudioClock devrait retourner des positions en augmentation continue tant que vous n'arrêtez pas le flux. Vous avez un exemple de code qui reproduit le problème? –

+0

Rien que je peux poster - J'ai une application Delphi qui diffuse les données (fonctionne bien), et tout en streaming, j'ai un feu de minuterie toutes les 50ms (juste un test) et appelez AudioClock :: GetPosition. Les deux valeurs renvoyées sont consignées. Ils restent les mêmes à tout moment et ne diffèrent que lorsque je réinitialise l'appareil. –