Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Any example of writing data continuously and Synth Sound?  (Read 4206 times)

0 Members and 1 Guest are viewing this topic.

freshtrack

  • Newbie
  • *
  • Posts: 4
    • View Profile
Any example of writing data continuously and Synth Sound?
« on: March 04, 2017, 07:54:38 am »
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.
« Last Edit: March 04, 2017, 07:59:22 am by freshtrack »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Any example of writing data continuously and Synth Sound?
« Reply #1 on: March 04, 2017, 02:23:54 pm »
As a programmer you should be able to see a concept, understand how it works on an abstract level and apply it to different code base. You already figured out that SoundStream is capable of doing exactly what you want, looking at the documentation, you already got most of the code written and explained for you, so you should be able to fill all the holes with your own code. ;)

If you get stuck somewhere, then don't hesitate to ask about the specific problem.
« Last Edit: March 04, 2017, 02:27:36 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

freshtrack

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Any example of writing data continuously and Synth Sound?
« Reply #2 on: March 04, 2017, 02:38:39 pm »
Sad thing is I am not a programmer,I know very little about C/C++ and programming thing,
If I know how to do this,I won't post this topic,right? :-\

So will you please tell me how to do this,some hint or something.
Some piece of code,or some useful example I can understand.
Because right now I really have no idea how to do it
« Last Edit: March 04, 2017, 02:43:02 pm by freshtrack »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Any example of writing data continuously and Synth Sound?
« Reply #3 on: March 04, 2017, 02:42:58 pm »
Did you read the linked documentation bit?
What do you not understand from the text and code?

We can help you understand things, if you tell us what you don't understand, but we won't got and write all the code for you.

Also, why do you pick probably one of the most complicated languages (C++) when you're just starting out? Why not start with something simpler?
And by definition, you are a "programmer" as soon as you start writing program code. ;)
« Last Edit: March 04, 2017, 02:44:32 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

freshtrack

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Any example of writing data continuously and Synth Sound?
« Reply #4 on: March 04, 2017, 02:59:46 pm »
The non stop part I think :o

1.How to add data to a SoundStream.Not load from file,but from data array or vector or something.What functioin can do this?
2.How to send these data and play.function and how?
3.Repeat Step 1 and 2 for ever

Why I am picking C++,that's just becuase I saw some video game tutorial from youtube.
And why SFML audio?because OpenAL is much more hard to understand.
And why OpenAL?because bass is not open source and free.
that's why I finally got here ;D
« Last Edit: March 04, 2017, 03:04:45 pm by freshtrack »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Any example of writing data continuously and Synth Sound?
« Reply #5 on: March 04, 2017, 03:13:21 pm »
A stream works by continuously processing some amount of data. You don't know when the stream will end, but you'll operate on a certain amount of data until there's no data left to process. The sf::Music class for example will read 1s worth of audio samples from the file in the onGetData() function.

So for your application, you'll simple have to derive from sf::SoundStream create a buffer that you can store the samples in (e.g. std::vector<sf::Uint16>) and initialize the buffers content to 0. Then you implement the onGetData() function, where you partially generate your sound waves by filling the buffer.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

freshtrack

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Any example of writing data continuously and Synth Sound?
« Reply #6 on: March 04, 2017, 04:52:19 pm »
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
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;
}
 
« Last Edit: March 04, 2017, 05:05:15 pm by freshtrack »