Bonjour à tous.
Voila j'ai un probleme de Qtimer je pense que c'est du à une mauvaise utilisation.
Je suis en train de créer un logiciel Client/Serveur permattant d'envoyer un son au serveur et de le recevoir.

Mon problème vient du fait que lorsque je recoi les paquet du serveur je dois attendre qu'un buffer audio soit libre pour le remplir et le mettre à la suite.

Lorsque j'attends avec un bête while pas de problem ca marche mais l'IHM est freezée.
Alors Mongaulois m'a conseillé d'utiliser un QTimer ce que je vais le probleme c'est que j'ai l'impression que mon QTimer continue d'avancer au lieu de "stopper le programme".

Voila ma classe qui receptionne les données (le Qtimer est utilisé a la dernière fonction) :

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 
#include "QReception.h"
 
 
using namespace std;
 
//Constructeur 
QReception::QReception(QTcpSocket *_socket)
{
  socket=new QTcpSocket();
  socket=_socket;
  alPlay=new QOpenAl();
  tailleMessage=0;
  timer=new QTimer(this);
  connect(timer,SIGNAL(timeout()),SLOT(attenteFreeBuffer()));
}
 
//Destructeur
QReception::~QReception()
{
  delete alPlay;
  delete timer;
}
 
//Accesseur a l'objet QOpenAl
QOpenAl* QReception::getalPlay()
{
  return alPlay;
}
 
//Fonction recupérant les paquets recus
void QReception::reception()
{
 
	QDataStream stream(socket);
 
	if (tailleMessage == 0)
	{
		if(socket->bytesAvailable()<(int)sizeof(int))
			return;
		stream >> tailleMessage;
	}
 
	if (socket->bytesAvailable() < (tailleMessage)*sizeof(int))
		return;
 
	message.clear();
	k=0;
	for (int j =0 ; j<tailleMessage;j++)
	  {
	    int chiffre;
	    stream>>chiffre;
	    message.push_back(chiffre);
	    if(k>alPlay->getSampleRate())
	      {
		timer->start(50);
	      }
	    k++;
	  }	
 
}
 
 
//Fonction censée mettre en attente jusqu'a avoir la libération d'un tampon
void QReception::attenteFreeBuffer()
{
  if((alPlay->nbFreeBuffer()>0)||(alPlay->getBufferAUtiliser()<2))
    {
 
      timer->stop();
      alPlay->playSound(message);
      k=0;
      message.clear();
    }
}
et voila le code permettant de lire un son :

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "QOpenAl.h"
 
using namespace std;
 
//Constructeur 
QOpenAl::QOpenAl()
{
  if(!initOpenAl())
    {
      cout<<"impossible d'init"<<endl;
      return;
    }
 
  SampleRate=0;
  Source = new ALuint();
  alGenBuffers(2, Buffers);
  alGenSources(1, Source);
  bufferAUtiliser=0;
}
 
//Destructeur
QOpenAl::~QOpenAl()
{
  //Destruction des buffers
  alDeleteBuffers(1, &Buffers[0]);
  alDeleteBuffers(1, &Buffers[1]);
  //Destruction des sources
  alSourcei(*Source, AL_BUFFER, 0);
  alDeleteSources(1, Source);
  delete Source;
  shutdownAL();
 
}
 
//Initialise le contexte et le device
bool QOpenAl::initOpenAl()
{
 
	//Ouverture du device
	ALCdevice* Device = alcOpenDevice(NULL);
	if(!Device)
	{
		cerr<<"impossible d'ouvrir le device"<<endl;
	        return false;
	 }
	//Création contexte
	ALCcontext *Context = alcCreateContext(Device, NULL);
	if (!Context)
	{
		cerr<<"impossible d'initialiser un contexte"<<endl;
		return false;
	}
	//Activationn du contexte
	if (!alcMakeContextCurrent(Context))
		return false;
 
	return true;
}
 
//Charge Un son a partir d'un fichier
vector<ALshort> QOpenAl::loadSound(const string& Filename)
{
 
	//librairy sndfile
	//ouverture du fichier audio avec libsndfile
	SF_INFO FileInfos;
	SNDFILE* File = sf_open(Filename.c_str(), SFM_READ, &FileInfos);
	if (!File)
		cerr<<"impossible d'ouvrir le fichier"<<endl;
 
	//Lecture du nombre d'echantillon et taux echantillon
	ALsizei NbSamples = static_cast<ALsizei>(FileInfos.channels * FileInfos.frames);
	SampleRate = static_cast<ALsizei>(FileInfos.samplerate);
 
	//Lecture des echantillon audio au format 16 bits signe
	vector<ALshort> Samples(NbSamples);
	if (sf_read_short(File, &Samples[0], NbSamples)<NbSamples)
		cerr<<"Impossible"<<endl;
 
	//fermeture du fichier 
	sf_close(File);
 
	return Samples;
}
 
 
//Arrete correctement OpenAl
 
void QOpenAl::shutdownAL()
{
	//Récupération du contexte et du device
	ALCcontext* Context = alcGetCurrentContext();
	ALCdevice* Device = alcGetContextsDevice(Context);
 
	//Désactivation du contexte
	alcMakeContextCurrent(NULL);
 
	// Destruction du contexte
	alcDestroyContext (Context);
 
	//Fermeture du device
	alcCloseDevice(Device);
}
 
//Modifie le taux d'echantillonnage
void QOpenAl::setSampleRate(ALsizei _SampleRate)
{
  SampleRate=_SampleRate;
}  int tailleMessage;
 
 
//Accesseur au taux d'échantillonnage
ALsizei QOpenAl::getSampleRate()
{
  return SampleRate;
}
 
//Indique le nombre de Buffer lus
int QOpenAl::nbFreeBuffer()
{
  ALint nbBuffer;
  alGetSourcei(*Source, AL_BUFFERS_PROCESSED, &nbBuffer);
  return (int)nbBuffer;
}
 
//Recupere le buffer libre
ALuint QOpenAl::getFreeBuffer()
{
  ALuint buffer;
 
  //Si un buffer est libre on le recupere
  if(nbFreeBuffer()>0)
  {
    cout<<"bing"<<endl;
    alSourceUnqueueBuffers(*Source, 1, &buffer);
  }
  //Sinon c'est que on a pas initialisé tout les buffers
  else
  {
      buffer=Buffers[bufferAUtiliser];
      bufferAUtiliser++;
  }
 
  return buffer;
}
 
//Accesseur a numéro du buffer à utiliser
int QOpenAl::getBufferAUtiliser()
{
  return bufferAUtiliser;
}
 
//Lit la source
void QOpenAl::playSound(vector<ALshort> musique)
{
	//Recupération du buffer libre
	ALuint buffer;
	buffer=getFreeBuffer();
	//Remplissage avec les echantillons lus
 
	alBufferData(buffer,AL_FORMAT_MONO16, &musique[0],musique.size() * sizeof(ALshort),SampleRate);
 
	if (alGetError() != AL_NO_ERROR)
	  {
	    cerr<<"OpenAl error"<<endl;
	    return;
	  }
 
 
	//On attache le tampon contenant les echantillons audio a la source
	alSourceQueueBuffers(*Source, 1, &buffer);
 
	//On lit la source
	alSourcePlay(*Source);
 
}
Voila en fait quand je test le son est bien lu mais en un seul paquet comme si le QTimer au lieu d'attendre que un buffer soit libre continuait a telecharger les données à partir du serveur.

Du coup si je revoie un son celui qui était en train d'etre lu est coupé celui recu est lu et celui qui a été coupé se termine. Ce qui n'est pas l'effet souhaité.

Voila merci d'avance pour votre aide.