Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt : 5.11.1 - Qt Creator : 4.7.0 - Qt Installer : 3.0.4 - JOM : 1.1.2 - QBS : 1.12.0

QEventLoop + QSound + QFrame

Bonjour

Je rencontre des difficultés avec une fonction essentielle pour le programme que je réalise :
QSqlQuery select("SELECT SequencesDeNoteAJouer FROM ToutesLesSequences");
while (select.next())
{
QString uneSequence = select.value(0).toString();
for (int incre = 0 ; incre < uneSequence.length() ; incre++)
{
int laNoteAJouer = uneSequence.mid(incre,1).toInt();
if (laNoteAJouer == 1)
{
frame->show();
playSound("Sons/Do.wav");
Sleep(300);
rame->hide()
}
if (laNoteAJouer == 2)
{
frame->show();
playSound("Sons/Re.wav");
Sleep(300);
frame->hide()
}
if (laNoteAJouer == 3)
{
frame->show();
playSound("Sons/Mi.wav");
Sleep(300);
frame->hide()
}
Ect………………………….
}
}
void Dialog::playSound(QString chemin)
{
QSound bells(chemin);
bells.play();
}
Le but du jeu est que l’affichage de la frame se fasse en même temps que le début du son, et que dès que le son se termine, la frame se hide(). Pour cela il tenir compte des QEventLoop (car généralement on ne voit pas du tout la frame s’afficher).
Ma question est celle-ci :
Quelle est la meilleur façon de programmer tout ceci :

- Comme ceci :
frame->show();
playSound("Sons/Do.wav");
Sleep(300);
frame->hide()
- Comme ceci :
frame->show();
playSound("Sons/Do.wav"); //de maniere synchrone, mais est ce possible ?
frame->hide()
- En utilisant les QTimer ?, mais j’aime pas trop
- En détectant d’une manière ou d’une autre la fin du son
(bool isFinished () const) ? Mais comment faire ???
Comment rajouter a cela la gestion des QEventLoop ???

Merci d'avance.

Réponses

  • Je sais que c'est presque la même question que Bearnaise mais je ne voulais pas compliquer sa situation ...
  • November 2006 modifié
    tu devrais jetter un oeil du cote des QMutex peut etre ?

    Ludo


    -- edit --
    pour rendre synchone playSound utilise :
    PlaySound("fichier.wav", GetModuleHandle(NULL), SND_FILENAME|SND_ASYNC );

    --/edit --


    -- edit 2 --
    Oublie les QMutex, j'avais lu un peu vite ton explication -> rien a voir

    -- /edit --
  • Ok pour Playsound ...
    Ca me pose juste un nouveau probleme, de conversion cette fois ci (WCHAR)
    J'ai essayé ca : PlaySound(((chemin).latin1()), NULL, SND_APPLICATION);
    =>QString have no member named latin1()

    Mais merci, ca fait déja avancer le probleme
  • November 2006 modifié
    Je crois que c'est : QString::toLatin1();
    mais dans ton cas ne te fais pas ch***
    utilise :
    PlaySound(chemin.data(), NULL, SND_APPLICATION);
    Ludo

    -- edit --
    Je note qu'au passage tu a corrige mon erreur dans les arguments de PlaySound ;)
    -- /edit --
  • Salut,

    Le support son de Qt est extrêmement limité comme tu peux le voir, tout particulièrement sous windows :(
    La solution que Ludo suggère te retirera le support multi-plateforme puisque tu t'appuieras sur l'api win32.

    Je te conseille plutôt de te tourner vers quelque chose de multi plateforme et dédié: ça peut être sdl ou openal par exemple. A priori, faudrait peut-être l'utiliser dans un thread à part, et lorsque le thread se termine, tu envoies un signal soundFinished() par exemple.
  • November 2006 modifié
    IrmatDen said:
    Salut,

    Le support son de Qt est extrêmement limité comme tu peux le voir, tout particulièrement sous windows :(
    La solution que Ludo suggère te retirera le support multi-plateforme puisque tu t'appuieras sur l'api win32.

    Je te conseille plutôt de te tourner vers quelque chose de multi plateforme et dédié: ça peut être sdl ou openal par exemple. A priori, faudrait peut-être l'utiliser dans un thread à part, et lorsque le thread se termine, tu envoies un signal soundFinished() par exemple.
    Tout a fait juste et meme +1
    avec une petite correction :
    Je n'ai jamais suggere d'utiliser Playsound, Ya l'avait deja utilise des le depart.

    Apres il faut connaitre le contexte de Ya,
    - si c'est le dev d'outils internes/perso et dont tu sais pertinement que tu seras toujours sous win32 , c'est peut etre une perte de temps d'apprendre a utiliser sdl ou openal (oui je sais c'est pas complique ;) mais faut les compiler etc ... Et tout ca "juste" pour jouer un son.

    - dans les autres cas : alors oui il faut bannir Playsound et se tourner vers un truc un peu moins "bricolage" (<- ne pas prendre mal ce terme ;) )

    Ludo
  • PlaySound(chemin).data(), NULL, SND_APPLICATION);

    me donne : Impossible de convertir QChar to WCHAR

    Je vais aussi regarde les threads, ca devrait regler mes problemes d'affichages ...
  • Ya said:
    PlaySound(chemin).data(), NULL, SND_APPLICATION);

    me donne : Impossible de convertir QChar to WCHAR

    Je vais aussi regarde les threads, ca devrait regler mes problemes d'affichages ...
    En fait ca depend de ton compilo et des options, un truc correct pourrait etre (pas compile-> donc pas teste ;))
    wchar_t *array=new wchar_t [chemin.lenght()+1];
    chemin.toWCharArray (array ) ;
    PlaySound(array, NULL, SND_APPLICATION);
    delete []array;
    Ludo
  • Il y a aussi fdmod comme librairie audio, disponibe sur plein de platforme et tres performante ( et surtout peu de ressource systeme utilisé ) d'apres certain temoignages.

    Si tu veux que tes sons via QSound soient joué instentanement, il faut les bufferisé a l'avance :

    QSound doNote( "do.wav" );
    QSound reNote( "re.wev" );

    et quand tu en as besoin les apelé :

    doNote.play();
    reNote.play();

    une possibilité de ta play sound pourrait etre :

    void playSound( const QSound& s, QFrame* f, int t = 300 )
    {
    if ( f )
    f.show();
    s.play();
    if ( f )
    {
    QTimer::singleShot( t, f, SLOT( hide() ) );
    while ( f->isVisible() )
    QApplication::processEvents();
    }
    }

    P@sNox,
  • pour le wchar, essayes string.toAscii().constData();


    P@sNox,
  • Ca ne marche pas non plus :
    int QString::toWCharArray(array*) is private
    error within this context

    J'utilise MinGW pourtant ...
  • Ya said:
    Ca ne marche pas non plus :
    int QString::toWCharArray(array*) is private
    error within this context

    J'utilise MinGW pourtant ...
    Tu dois avoir un probleme ailleurs car toWCharArray est public (du moins dans la doc QT 4.2)

    sinon tu peux essayer un truc plus simple :
    PlaySound(chemin.toStdWString ().c_str(), NULL, SND_APPLICATION);
  • lud42fr said:
    Je n'ai jamais suggere d'utiliser Playsound, Ya l'avait deja utilise des le depart.
    Ya" said:
    void Dialog::playSound(QString chemin)
    {
    QSound bells(chemin);
    bells.play();
    }
    Non, playSound était une fonction perso (au nom trompeur il est vrai ;))

    Sinon, pour l'histoire de conversion en WCHAR, tu peux tester ça:
    PlaySound(_T(chemin.data()), NULL, SND_APPLICATION);
    La macro _T étant définie dans (fichier d'include 100% windows).
  • Non, playSound était une fonction perso (au nom trompeur il est vrai ;))
    Effectivement, j'ai lu trop vite le code :rolleyes:
    Maintenant que je sais ca, c'est vraiment une erreur de ma part d'avoir oriente Ya su PlaySound de M$.

    Encore desole

    Ludo
  • Merci a tous, vous etez géniaux ...
    Tout marche Nickel !!!
  • Tu as opté pour quelle solution alors au final?
  • La tienne principalement ;) avec le QTimer et je me tâte a approfondir FMOD car ni QSound ni PlaySound(chemin.toStdWString ().c_str(), NULL, SND_APPLICATION); ne me satisfont. Je croyais pouvoir arriver (naïvement sans doute) a jouer plusieurs sons en même temps avec playsound (car il faut que j’arrive a simuler des accords) mais …

    Une nouvelle aventure pour moi, qui a déjà bien du mal avec Qt, et qui sans ce forum, n’arriverai a rien ;) (sans dec, merci … merci milles fois)
  • FMODex (FMOD en C++, ce dernier n'étant plus maintenu) contient ce qu'il faut pour faire du midi si besoin est. Sinon, pour jouer plusieurs sons en simultané proprement, il te faudra une lib dédiée quelle qu'elle soit.
Connectez-vous ou Inscrivez-vous pour répondre.