*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/UPICNotre 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.