Bonjour, et merci par avance de votre aide.
Je souhaite jouer des notes de musique avec sfml. Pour cela, j'ai récupéré le code fourni dans le "sound" tutoriel git.
Mon probléme, et que je ne parvient pas à lire mon tableau d'échantillons entiérement. D'aprés le tuto, je suis obligé de passer par une boucle contenant une pause. Bien que normalement, la taille (=[max]) du tableau et son échantillonnage (nombre de lignes lues/seconde) devrait logiquement suffire à lire la totalité du tableau et donc durer un temps correspondant.
Le probléme de cette pause est que je ne peux bénéficier (directement) du thread "automatique" de sf::sound. Je peux bien évidement le programmer moi-même ; mais je ne comprends pas pourquoi cela ne fonctionnent pas naturellement (en plus de ne pas savoir programmer un thread).
Je vous mets ma fonction :
#include <SFML/Audio.hpp>
#include <cmath>
#include <iostream>
int play_note(std::string note = "0")
{
const double Do = 261.63*1.25;
const double Re = 293.66*1.25;
const double Mi = 329.63*1.25;
const double Fa = 349.23*1.25;
const double Sol = 391.99*1.25;
const double La = 440.00*1.25;
const double Si = 493.88*1.25;
double freq = 0;
if (note == "0") freq = 0;
if (note == "DO") freq = Do;
if (note == "RE") freq = Re;
if (note == "MI") freq = Mi;
if (note == "FA") freq = Fa;
if (note == "SOL") freq = Sol;
if (note == "LA") freq = La;
if (note == "SI") freq = Si;
const unsigned SAMPLES = 44100; //Nombre d'echantillons
const unsigned SAMPLE_RATE = 44100; //Vitesse = Nombre d'echantillons/secondes
//Soit ici, 1 secondes
const unsigned AMPLITUDE = 30000*1.75; // Amplitude max =~Volume crête
sf::Int16 raw[SAMPLES]; //Tableau de 44100 échantillons de 16bits chacun
const double TWO_PI = 6.28318;
const double increment = freq/SAMPLE_RATE;
double x = 0;
//Écriture de l'onde sonore dans chaque ligne du tableau d'échantillons
for (unsigned i = 0; i < SAMPLES; i++)
{
raw[i] = AMPLITUDE * sin(x*TWO_PI); //équation d'une onde sonore musicale
x += increment;
}
sf::SoundBuffer Buffer;
if (!Buffer.loadFromSamples(raw, SAMPLES, 1, SAMPLE_RATE))
{
std::cerr << "Loading failed!" << std::endl;
return 1;
}
Buffer.loadFromSamples(raw, SAMPLES, 1, SAMPLE_RATE);
sf::Sound sound;
sound.setBuffer(Buffer);
sound.setLoop(true);
sound.play();
int tmps = 0;
while (tmps < 40)
{
//sf::sleep(sf::milliseconds(10));
tmps++;
}
//sound.stop(); //N'a aucune influence et loop = false ou true non plus
return 0;
}
Pour clore (un temps) le sujet ; je poste ici le code fonctionnel de ma fonction. Sans passer par la création de mon propre thread. J'ai simplement pensé à regarder les exemples fourni lors de l'installation de SFML sur mon disque dur.
#include <vector>
#include <SFML/Audio.hpp>
#include <cmath>
#include <iostream>
int play_note(std::string note = "0")
{
const double Do = 261.63*1.25;
const double Re = 293.66*1.25;
const double Mi = 329.63*1.25;
const double Fa = 349.23*1.25;
const double Sol = 391.99*1.25;
const double La = 440.00*1.25;
const double Si = 493.88*1.25;
double freq = 0;
if (note == "0") freq = 0;
if (note == "DO") freq = Do;
if (note == "RE") freq = Re;
if (note == "MI") freq = Mi;
if (note == "FA") freq = Fa;
if (note == "SOL") freq = Sol;
if (note == "LA") freq = La;
if (note == "SI") freq = Si;
std::vector<sf::Int16> raw; //Tableau de n échantillons de 16bits chacun.
const unsigned SAMPLES = 1*44100; //Nombre d'echantillons
const unsigned SAMPLE_RATE = 44100; //Vitesse = Nombre d'echantillons/secondes
//Soit ici, 1 secondes
const unsigned AMPLITUDE = 30000*1.75; // Amplitude max =~Volume crête
const double TWO_PI = 6.28318;
const double increment = freq/SAMPLE_RATE;
double x = 0;
//Écriture de l'onde sonore dans chaque ligne du tableau d'échantillons
for (unsigned i = 0; i < SAMPLES; i++)
{
//équation d'une onde sonore musicale
raw.push_back(AMPLITUDE * sin(x*TWO_PI));
x += increment;
}
//Load a sound buffer from array raw
sf::SoundBuffer buffer;
if (!buffer.loadFromSamples(&raw[0], raw.size(), 1, SAMPLE_RATE))
{
std::cerr << "Loading failed!" << std::endl;
return 1;
}
// Display sound informations
std::cerr << "Note: " << note << std::endl;
std::cerr << " " << buffer.getDuration().asSeconds() << " seconds" << std::endl;
std::cerr << " " << buffer.getSampleRate() << " samples / sec" << std::endl;
std::cerr << " " << buffer.getChannelCount() << " channels" << std::endl;
// Create a sound instance and play it
sf::Sound sound(buffer);
sound.play();
// Loop while the sound is playing
while (sound.getStatus() == sf::Sound::Playing)
{
// Leave some CPU time for other processes
sf::sleep(sf::milliseconds(100));
// Display the playing position
std::cerr << "\rPlaying... " << sound.getPlayingOffset().asSeconds() << " sec";
std::cerr << std::flush;
}
std::cerr << std::endl << std::endl;
return 0;
}
Merci encore Laurent. D'autant que toutes les informations étaient clairement expliquées dans le tutoriel audio du site SFML et la solution dans les exemples donnés lors de l'installation de celles-ci.