new to SFML 2.4.2,and I did'nt find some good example about how to do this.
I found some topic about soundstream without full coding.
and some example from github like this.
https://github.com/slallement/SoundSynth
It works but not the way I want.
The note seems to be data fixed length and add to the buffer and can not continuous write data to the buffer.
What I need is something like bass audio library.
http://www.un4seen.com/
they have a very good example called synth.
some code like below
stream=BASS_StreamCreate(info.freq,2,0,(STREAMPROC*)WriteStream,0); // create a stream (stereo for effects)
BASS_ChannelPlay(stream,FALSE); // start it
DWORD CALLBACK WriteStream(HSTREAM handle, short *buffer, DWORD length, void *user)
{
int k,c,s;
float omega;
memset(buffer,0,length);
for (k=0;k<KEYS;k++) {
if (!vol[k]) continue;
omega=2*M_PI*pow(2.0,(k+3)/12.0)*440.0/info.freq;
for (c=0;c<length/sizeof(short);c+=2) {
s=buffer[c]+sin(pos[k])*vol[k];
if (s>32767) s=32767;
else if (s<-32768) s=-32768;
buffer[c+1]=buffer[c]=s; // left and right channels are the same
pos[k]+=omega;
if (vol[k]<MAXVOL) {
vol[k]-=DECAY;
if (vol[k]<=0) { // faded-out
vol[k]=0;
break;
}
}
}
pos[k]=fmod(pos[k],2*M_PI);
}
return length;
}
All the work is in this thread called WriteStream
in the function,you just write and wave formular like sine wave,It just keep producing sound.
and according to the vol array outside,you can control which freq sound to play if your key is down.
What I need it how to write such a non stop, keep writing thread,to fill buffer and playing for ever.
OK,I'm trying to modify MyStream and bass synth example,not quite I want.
MyStream example from here
http://www.sfml-dev.org/tutorials/2.4/audio-streams.php (http://www.sfml-dev.org/tutorials/2.4/audio-streams.php)
the sound I suppose is sine wave non stop.
but the result is sine wave with some break pop sound and the volume vibe.What's wrong?Get pretty confused.
#include <SFML/Audio.hpp>
#include <vector>
#define MAXVOL (0.22*32768)
#define DECAY (MAXVOL/4000)
#define KEYS 1
#define M_PI 3.14159265358979323846
float vol[KEYS] = { 0 }, pos[KEYS];
int sampleRate = 44100;
int numChannel = 2;
int bfSize = sampleRate * numChannel;
class MyStream : public sf::SoundStream
{
public:
void SetBufSize(int sz, int numChannel, int sampleRate)
{
m_samples.resize(sz, 0);
m_currentSample = 0;
initialize(numChannel, sampleRate);
}
private:
virtual bool onGetData(Chunk& data)
{
static const int samplesToStream = bfSize;
data.samples = &m_samples[m_currentSample];
vol[0] = MAXVOL;
if (m_currentSample + samplesToStream <= m_samples.size())
{
int k, c, s;
float omega;
for (k = 0; k < KEYS; k++)
{
omega = 2 * M_PI*pow(2.0, (k + 3) / 12.0)*440.0 / sampleRate;
for (c = 0; c < samplesToStream / sizeof(short); c += numChannel)
{
s = m_samples[c] + sin(pos[k])*vol[k];
if (s > 32767) s = 32767;
else if (s < -32768) s = -32768;
m_samples[c + 1] = m_samples[c] = s;
pos[k] += omega;
}
pos[k] = fmod(pos[k], 2 * M_PI);
}
data.sampleCount = sampleRate;
m_currentSample = 0;
return true;
}
else
{
//won't run here
data.sampleCount = m_samples.size() - m_currentSample;
m_currentSample = m_samples.size();
return false;
}
}
//won't run here
virtual void onSeek(sf::Time timeOffset)
{
m_currentSample = static_cast<std::size_t>(timeOffset.asSeconds() * getSampleRate() * getChannelCount());
}
std::vector<sf::Int16> m_samples;
std::size_t m_currentSample;
};
int main()
{
MyStream stream;
stream.SetBufSize(bfSize, numChannel, sampleRate);
stream.play();
//won't stop in this example
while (stream.getStatus() == MyStream::Playing)
sf::sleep(sf::seconds(1));
return 0;
}