Bonjour à toutes et à tous.

Ceci est mon premier message posté sur Développez.net, si je n'ai pas respecté des règles élémentaires avant de poster, merci de m'en informer!

Je travaille actuellement sur projet qui tourne sous Windows et je dois effectuer un portage sous Linux. Ce projet traitant essentiellement sur le son, Alsa est au coeur de la problématique. Ainsi, je bloque depuis quelques heures déjà sur un problème qui doit être tout bête, mais dont je ne trouve pas la solution...

Je défini les paramètres de la carte son et souhaite faire afficher ces paramètres à des fins de déboguage. Plus précisément, mon problème se situe sur les fonctions :

1) snd_pcm_hw_params_set_access
Que j'utilise ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
snd_pcm_hw_params_set_access(snd_dev, params, SND_PCM_ACCESS_RW_INTERLEAVED);
Où "snd_dev" est ma carte son et "params" la stucture contenant l'espace de configuration de ma carte son. Cette fonction est censée définir quel type le type d'accès à ma carte son.

2) snd_pcm_access_name
Que j'utilise ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
snd_pcm_hw_params_get_access(params, access);
const char *s = snd_pcm_access_name(*access);
printf("access type = %s\n", s);
Où "params" est la stucture contenant l'espace de configuration de ma carte son.

Je souhaite donc faire afficher le type d'accès pour être sûr qu'il a bien été configuré.
Voici ma fonction dans son ensemble :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
void classSon::set_snd_params(int channels, int bits, int rate) {
	int rc;
	snd_pcm_hw_params_t *params;
	int exact_rate;   /* Sample rate returned by snd_pcm_hw_params_set_rate_near */ 
	int dir;          /* exact_rate == rate --> dir = 0 */
	                  /* exact_rate < rate  --> dir = -1 */
	                  /* exact_rate > rate  --> dir = 1 */
	int periods = 50;  /*valeur de base :4; Number of periods */
	snd_pcm_uframes_t periodsize = 20*22050*2/1000;/*valeur de base :8192;  Periodsize (bytes) */
 
	snd_pcm_hw_params_alloca(&params);
 
	// Initialisation des paramètres
	if (snd_pcm_hw_params_any(snd_dev, params) < 0) {
		std::cerr << "Impossible d'initialiser les paramètres." << std::endl;
	}
	// Interleaved mode
	if (snd_pcm_hw_params_set_access(snd_dev, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		std::cerr << "Impossible de configurer le type d'accès." << std::endl;
	}
 
	printf("ACCES : %i\n", (int)SND_PCM_ACCESS_RW_INTERLEAVED);
 
	// Format des échantillons : signed 16-bit little-endian
	if (snd_pcm_hw_params_set_format(snd_dev, params,SND_PCM_FORMAT_S16_LE) < 0) {
		std::cerr << "Impossible de configurer le format." << std::endl;
	}
	// Nombre de voies (mono ou stéréo)
	if (snd_pcm_hw_params_set_channels(snd_dev, params, channels) < 0) {
		std::cerr << "Impossible de configurer le nombre de voies." << std::endl;
	}
	// Fréquence. Si la fréquence exacte n est pas supportée
	// par la carte, on utilise la plus proche.
	exact_rate = rate;
	if (snd_pcm_hw_params_set_rate_near(snd_dev, params, (unsigned int*)&exact_rate, &dir) < 0) {
		std::cerr << "Impossible de configurer la fréquence." << std::endl;
	}
	if (rate != exact_rate) {
		std::cerr << "La fréquence " << rate << " n'est pas supportée, valeur utilisée : " << exact_rate << std::endl;
	}
	// Nombre de périodes
	if (snd_pcm_hw_params_set_periods(snd_dev, params, periods, 0) < 0) {
		std::cerr << "Impossible de configurer la période à " << periods << "." << std::endl;
	}
	// Taille du buffer (en frames). The resulting latency is given by
	// latency = periodsize * periods / (rate * bytes_per_frame)
	if (snd_pcm_hw_params_set_buffer_size(snd_dev, params, (periodsize * periods)>>2) < 0) {
		std::cerr << "Impossible de configurer la taille du buffer." << std::endl;
	}
	// Ecriture des paramètres sur la carte
	if ((rc = snd_pcm_hw_params(snd_dev, params)) < 0) {
		std::cerr << "Impossible de configurer la carte son : " << snd_strerror(rc) << std::endl;
	}
 
	snd_pcm_access_t *access;
 
	snd_pcm_hw_params_get_access(params, access);
	const char *s = snd_pcm_access_name(*access);
	printf("access type = %s\n", s);
}
Les dernières ligne de codes peuvent paraître étranges (déclaration de variable en fin de fonction), c'est parce qu'elles sont censées être dans une autre fonction. Je les ai mises ici pour être sûr que ce ne soit pas un problème de passage de variables entre fonctions. Enfin bref, à l'exécution, voici ce qui s'affiche :

initGlobal
initParle
initTrans
initAnalyse
finInit
ACCES : 3
access type = (null)
exitAnalyse
exitTrans
exitParle
exitGlobal
finExit
Les "init" et autres "exit" sont des infos fournies par mon main, ne dépendant pas de ce qui se passe dans cette fonction.

Je ne comprends pas pourquoi je récupère un "access type = (null)"!!!
Pour moi, je devrais récupérer soit "access type = 3" soit "access type = SND_PCM_ACCESS_RW_INTERLEAVED"...

Quelqu'un pourrait-il m'expliquer ce que je fais de mal? J'ai passé beaucoup de temps à me triturer l'esprit (seul ou avec l'ingénieur avec qui je travaille) et je/nous ne voyons pas quoi faire...

D'avance merci!