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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - disaux

Pages: [1]
1
Hello community,

I am generating a beep tone which lasts 1 second due to my specification of SAMPLES=44100. I know that I would have to set it to 44100 to get two seconds duration. However, I need to generate tones of different length so it would be useful if I could hand over the length as a parameter.

Unfortunately, SoundBuffer::loadFromSamples() needs as first paramter an const int16 array of size SAMPLES. Thus, SAMPLE is const as well and can not be altered dynamically.

Is there a way to achieve what I am trying to do?

Quote
int main() {
    playSound(2);    // should result in 88200 samples (2 seconds playback time)
    ... much code that takes ages
    return 0;
}
Quote
void playSound(int duration)
{
    const unsigned SAMPLES = 44100 * duration;    // fail
    const unsigned SAMPLE_RATE = 44100;
    const unsigned AMPLITUDE = 30000;

    sf::Int16 raw[SAMPLES];
    const double TWO_PI = 6.28318;
    const double increment = 440./44100;
    double x = 0;
    for (unsigned i = 0; i < SAMPLES; i++) {
        raw = AMPLITUDE * sin(x*TWO_PI);
        x += increment;
    }

    sf::SoundBuffer Buffer;
    if (!Buffer.loadFromSamples(raw, SAMPLES, 1, SAMPLE_RATE)) {
        std::cerr << "Loading failed!" << std::endl;
        return 1;
    }

    sf::Sound Sound;
    Sound.setBuffer(Buffer);
    Sound.play();
}

based on https://github.com/SFML/SFML/wiki/Tutorial:-Play-Sine-Wave

Cheers,
Dietmar

2
Audio / Re: Threads & "AL lib: (EE) alc_cleanup: 1 device not closed"
« on: November 10, 2015, 03:10:28 pm »
thank you for your advice, that actually helped a lot! I also realized that I don't need to sleep() because I can define the playback duration by increasing SAMPLES. Now the error message does not occur anymore (unless I force the program to stop executing by IDE). The program still crashes at the end, probably due to my usage of the audio lib, but I'll investigate that later.


3
Audio / Re: Threads & "AL lib: (EE) alc_cleanup: 1 device not closed"
« on: November 09, 2015, 10:55:52 pm »
semantically, the main thread is not exited before the sound could play. Consider that this is just an mock-up. In my real code I have something like this:

warning: pseudocode!
Quote
void main_loop()
{
    sleep(1/60 seconds);
    do_stuff();
}

// is called 60 times a second
void do_stuff()
{
    ... // building the sound object
    // play sound each 600/60=10 seconds
    if (loop_counter % 600== 0)
    {
        sound.play()
        loop_counter++;
    }
    ... // operations that will finish in <1 ms
}

I can see that the scope from which sound.play() is started, is destroyed when do_stuff() terminates. Could this be why the sound does not play if I don't put a sleep() after sound.play()?

4
Audio / Re: Threads & "AL lib: (EE) alc_cleanup: 1 device not closed"
« on: November 09, 2015, 02:19:18 pm »
Hi, thank you for your reply!

Indeed, I've read about that they are using their own thread. But that seems to apply for playing music files only...? Maybe because I'm using values from a Buffer?

When I execute Sound.play() e. g. from the main loop of my OpenGL application (or any other terminating function), it will not play the sound. Doesn't matter whether Sound.play() runs within a separate threaded function or not. If I add sf::sleep() afterwards, it will play the sound while sleeping but the program is blocked. So I've put it all into a thread.

I will try your suggestion about the thread termination time!
Edit: Actually the main thread launches bunch of other code, in real it's waiting for a user input. So it does not terminate before the thread does.

Cheers

5
Audio / Threads & "AL lib: (EE) alc_cleanup: 1 device not closed"
« on: November 09, 2015, 01:55:42 pm »
Hello community,

I'm new to programming with SFML and so far I really like this library.

I'm looking for a way to generate a beep tone with a certain frequency, which is played without blocking the rest of my program. I tried to start Sound.play() in a thread.

The problem is that it doesn't always actually play the sound and the program terminates with the message "AL lib: (EE) alc_cleanup: 1 device not closed" each time. Especially fixing the error message exceeds my understanding so I hope some of you guys have way more clue than I do :-)

Here's my code:

soundgenerator.h
Quote
#ifndef SOUNDGENERATOR_H
#define SOUNDGENERATOR_H
#include <SFML/Audio.hpp>

class SoundGenerator
{
public:
    SoundGenerator(double frequency, int amplitude, int duration);  // constructor
    void playSound();  // invokes a new thread

private:
    int duration;    // how long to play the sound
    sf::SoundBuffer buffer;     // storing the buffer as a member variable
    void playSoundThread(sf::SoundBuffer buffer);    // this fkt runs in a thread
};

#endif // SOUNDGENERATOR_H

soundgenerator.cpp
(taken from this tutorial: https://github.com/SFML/SFML/wiki/Tutorial:-Play-Sine-Wave)
Quote
#include "soundgenerator.h"
#include <SFML/Audio.hpp>
#include <cmath>
#include <thread>

// set up the parameters for the sine wave
SoundGenerator::SoundGenerator(double frequency, int amplitude, int duration)
{
    this->duration = duration;

    const unsigned SAMPLES = 44100;
    const unsigned SAMPLE_RATE = 44100;
    const unsigned AMPLITUDE = amplitude;

    sf::Int16 raw[SAMPLES];

    const double TWO_PI = 6.28318;
    const double increment = frequency/44100;
    double x = 0;
    for (unsigned j = 0; j < SAMPLES; j++) {
        raw[j] = (int)AMPLITUDE * sin(x*TWO_PI);
        x += increment;
    }

    if (!this->buffer.loadFromSamples(raw, SAMPLES, 1, SAMPLE_RATE)) {
        return;
    }
}

// here the thread is being invoked
void SoundGenerator::playSound()       
{
    std::thread t(&SoundGenerator::playSoundThread, this, this->buffer);
    t.detach();
}

// this function is put in the thread
void SoundGenerator::playSoundThread(sf::SoundBuffer buf)
{
    sf::Sound sound;
    sound.setBuffer(buf);
    sound.setLoop(true);
    sound.play();
    sf::sleep(sf::milliseconds(duration));
}

main.cpp
Quote
void main()
{
    // frequency=400 hz, amplitude=25000, duration=2000ms
    SoundGenerator* sg = new SoundGenerator(400, 25000, 2000);
    sg->playSound();

    ... going into a OpenGL loop, waiting for user input and stuff...
}

I'd be grateful for any suggestions! I'm using SFML 2.3.1 with QT 5.5 with QT Creator as IDE.

Cheers,
Dietmar

Pages: [1]
anything