Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Sauvegarde sond et SFML  (Lu 2952 fois)

0 Membres et 2 Invités sur ce sujet

Mealya

  • Newbie
  • *
  • Messages: 3
    • Voir le profil
Sauvegarde sond et SFML
« le: Avril 01, 2014, 01:38:44 pm »
Bonjour,

Travaillant sur un gros projet annuel à la fac, l'idée est de sauvegarder un fichier son basé sur un ensemble d'arc. (l'application lit correctement la superposition des sons avec plusieurs buffers lus par des threads différents)

La méthode saveToFile marche parfaitement, néanmoins, le son lu ne possède qu'un seul son et je n'arrive pas à garder le fait que plusieurs sons soient "superposés" y a t il une solution, je bloque sur le passage de l'ensemble des buffers à un unique qui génèrerais le fichier?  ???

Merci d'avance ;)
« Modifié: Avril 01, 2014, 01:40:55 pm par Mealya »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Sauvegarde sond et SFML
« Réponse #1 le: Avril 01, 2014, 01:55:19 pm »
C'est pas très clair, tu emploies des termes un peu vagues et du coup on ne sait pas trop ce que tu veux faire exactement. Peut-être qu'un peu de code serait plus clair ;)
Laurent Gomila - SFML developer

Mealya

  • Newbie
  • *
  • Messages: 3
    • Voir le profil
Re : Sauvegarde sond et SFML
« Réponse #2 le: Avril 01, 2014, 02:20:47 pm »
*pavé incoming* (pas de balise spoil?)

soundThread::soundThread(ArcPage* arc, double cX, double cY, int vol)
{
    buff = arc->getValues();
    envl = arc->getEnveloppe()->getValues();
    freq = arc->getFrequence()->getValues();
    ampl = arc->getAmplitude()->getValues();
    form = arc->getFormeOnde()->getValues();
    coeffX = cX;
    coeffY = cY;
    volumeL = vol;
    ispause = false;
    ispauseb = false;
    isstop = false;
    is = false;
    pb = 0;
}


vector<Int16> soundThread::genererFrequenceTab2(QVector<QPointF*> tab,
                                               QVector<QPointF *> fo,
                                               QVector<QPointF *> env,
                                               QVector<QPointF *> fre,
                                               QVector<QPointF *> amp,
                                               int frequenceEchantillonage)
{
    size_t taille = floor(frequenceEchantillonage*(tab[tab.size() - 1]->x() / coeffX - tab[0]->x() / coeffX)/32);
    double dureeEnv = env[env.size() - 1]->x();
    double dureeFre = fre[fre.size() - 1]->x();
    double dureeAmp = amp[amp.size() - 1]->x();
    vector<Int16> buffer(taille);

    size_t dec = 0;
    double g = 0;
    for (int i = 0; i < tab.size() - 1; i++) {
        double f = tab.at(i)->y() * 6 / coeffY;
        size_t dureeNote = floor(frequenceEchantillonage*(tab.at(i+1)->x() / coeffX - tab.at(i)->x() / coeffX)/32);
        double secNote = (tab.at(i+1)->x() / coeffX - tab.at(i)->x() / coeffX)/32;
        double ff = 1/f;
        double dd = secNote/ff;
        double da = dureeNote/dd;

        for (size_t t = dec; (t < dec + dureeNote) && (t < taille); t++) {
            if (g >= da) {
                g -= da;
            }
            double to = floor((g * fo[fo.size()- 1]->x()) / da);
            if (to > ((double)(fo.size() - 2))) {
                to = fo.size() - 1;
            }
            double te = floor(t * dureeEnv / taille);
            if (te > ((double)(env.size() - 2))) {
                te = env.size() - 1;
            }
            double tf = floor(t * dureeFre / taille);
            if (tf > ((double)(fre.size() - 2))) {
                tf = fre.size() - 1;
            }
            tf = fre[tf]->y() * coeffY / 10.0;
            te = env[te]->y() / coeffY / 600.0;
            to = (fo[to]->y() / coeffY - 300.0) / 300.0;
            //buffer[k] = amplitude * sin(2 * M_PI * k * (tab.at(i)->y() * 6) / frequenceEchantillonage);
            buffer[t] = te * tf * to;
            g += 1;
        }

        dec = dec + dureeNote;
    }
    cout << "buff = " << buff.size() << endl;
    return buffer;
}

void soundThread::stop() {
    sync.lock();
    isstop = true;
    sync.unlock();
    pauseCond.wakeAll();
}

void soundThread::resume() {
    sync.lock();
    ispause = false;
    ispauseb = true;
    pb = 0;
    sync.unlock();
    pauseCond.wakeAll();
}

void soundThread::pause() {
    sync.lock();
    ispause = true;
    ispauseb = false;
    sync.unlock();
}

void soundThread::volume(int v) {
    sync.lock();
    isVolume = true;
    volumeL = v;
    sync.unlock();
}

void soundThread::run()
{
     vector<Int16> buf;
     sf::SoundBuffer tabBuffer;

     buf = genererFrequenceTab2(buff, form, envl, freq, ampl, 44100);

     if (!tabBuffer.loadFromSamples(buf.data(), buf.size(), 1, 44100))
     {
        // cout << "test" << endl;
     }
     tabSound.setBuffer(tabBuffer);
     tabSound.setVolume(volumeL);
     tabSound.play();
     while (((tabSound.getStatus() == sf::Sound::Playing)
            || (tabSound.getStatus() == sf::Sound::Paused))
            && !is)
     {
         sync.lock();
         if (ispause) {
             tabSound.pause();
             pauseCond.wait(&sync); // in this place, your thread will stop to execute until someone calls resume
         }
         if (ispauseb) {
             if (pb == 0) {
                tabSound.play();
                pb = 1;
             }
         }
         if (isVolume) {
               tabSound.setVolume(volumeL);
               isVolume = false;
         }
         if (isstop) {
             is = true;
         }
         sync.unlock();
         sf::sleep(sf::milliseconds(100));
         //ne rien faire
     }
     tabSound.stop();
     buf.clear();
}
 

Le logiciel sur lequel on travail est une mise à jour de celui ci : http://fr.wikipedia.org/wiki/UPIC
Notre classe qui génère un son pour l'application.

Donc en gros on a une liste d'arc, la liste d'arc, chaque arc contient des points, que l'on met en relation avec amplitude, forme d'onde,...

L'idée c'est de sauvegarder ce son sous format audio. Or actuellement on travaille sur un buffer pour chaque arc. Ce qui est compliqué d'arriver à un seul qui prend en compte tout cela avec saveToFile.

Ici deux arc :



EDIT : Actuellement la seule méthode que j'ai trouvée et de faire une moyenne des Y pour chaque coordonnée X, ce qui ne donne pas ce que l'on attend car donne un son plat notamment comme sur l'image ci dessus.
« Modifié: Avril 01, 2014, 02:26:10 pm par Mealya »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Sauvegarde sond et SFML
« Réponse #3 le: Avril 01, 2014, 02:30:06 pm »
Ah, ok je vois. Tu veux fusionner plusieurs sf::SoundBuffer en un seul, en superposant leurs contenus.

Il y a un sujet qui est tombé récemment à ce propos sur le forum anglais, tu peux y jeter un oeil. La solution à ce problème est assez standard, tu devrais pouvoir trouver l'algorithme avec ton ami Google. Si je me souviens bien, ça parle de renormalisation. A priori ça ne devrait pas être plus compliqué que de faire la somme de tous les Y pour chaque X, puis de diviser par le Y maximum (le max sur la totalité du son) pour revenir dans la plage valide.

Note que ça n'a rien à voir avec SFML, là c'est juste un problème d'algorithme audio :P
« Modifié: Avril 01, 2014, 02:33:41 pm par Laurent »
Laurent Gomila - SFML developer

Mealya

  • Newbie
  • *
  • Messages: 3
    • Voir le profil
Re : Sauvegarde sond et SFML
« Réponse #4 le: Avril 01, 2014, 02:32:22 pm »
Oki ça marche merci de l'info :)

Je tiendrais au courant du résultat sur le topic