ALSA: débordement de tampon sur snd_pcm_writei appel
J'obtiens les erreurs de tampon lors de l'exécution d'un vieux programme, j'ai récemment ramenés de ses cendres.
Le programme des charges jusqu'à un son brut de fichier entièrement en mémoire (2100 octets de long, 525 cadres) et prépare ALSA pour la sortie (44.1 khz, 2 canaux, signé de 16 bits):
if ((err = snd_pcm_set_params(audio_handle,
SND_PCM_FORMAT_S16_LE,
SND_PCM_ACCESS_RW_INTERLEAVED,
2,
44100,
1,
sound.playback_us)) < 0) {
printf("E: Failed to prepare PCM: %s\n", snd_strerror(err));
return -1;
}
PCM état est PREPARED
avant la première lecture du son. Son joue correctement la première fois, cependant, la deuxième fois qu'il est joué, l'état est RUNNING
et un -EPIPE
("Broken pipe") est lancée par snd_pcm_writei
. La lecture de la logique:
frames = snd_pcm_writei(audio_handle,
sound.data,
write_size);
if(frames < 0) {
printf("E: %s: attempting to recover\n", snd_strerror(frames));
frames = snd_pcm_recover(audio_handle, frames, 0);
if(frames < 0) {
printf("E: snd_pcm_writei failed\n");
break;
}
} else if(frames > 0 && frames < write_size)
printf("E: Short write (expected %li, wrote %li)\n", write_size, frames);
else
printf("wrote %li frames\n", frames);
Étrangement, elle joue correctement à la troisième fois, à défaut, une fois encore, l'heure suivante. En d'autres termes, il échoue avec une -EPIPE
d'erreur à chaque fois.
Par souci de simplicité, je suis en train de jouer les sons à 1 seconde d'intervalle.
Quel est le problème avec la logique ci-dessus?
Code mis à jour pour utiliser la nouvelle API ALSA; peut être trouvé à: http://paste.ubuntu.com/7257181/
MODIFIER
Viens de découvrir que si l'on fait des tests pour un -EPIPE
état et re-prépare le PCM poignée avant de re-délivrance de la snd_pcm_writei
appel, tout est bon. Mon (nouveau) la question est donc... pourquoi?
if(frames == -EPIPE) {
snd_pcm_prepare(pcm.handle);
frames = snd_pcm_writei(pcm.handle,
sound.data, //sound.data + (offset << 1),
write_size);
}
OriginalL'auteur miguelg | 2014-04-15
Vous devez vous connecter pour publier un commentaire.
Si vous remplissez le tampon de 525 cadres (environ 12 ms), puis attendez une seconde, vous êtes garanti d'obtenir une surestimation, car il n'existe pas de données pour les autres 988 ms.
Vous pouvez utiliser
snd_pcm_drain
attendre jusqu'à ce que les données réelles a arrêté de jouer (note: typcially, l'appareil s'arrête pas jusqu'à la prochaine période de frontière).Sinon, continuer à nourrir zéro échantillons dans la mémoire tampon.
Vous n'avez pas besoin de fermer/rouvrir;
snd_pcm_prepare
suffit.OriginalL'auteur CL.