c++openal

Why is no sound being played?


I am trying to get my pi4 to play a sine wave as a test, but all I am getting is maybe static.

//g++ vc.cpp -o vc -l openal
#include <cmath>
#include <AL/al.h>
#include <AL/alc.h>
#include <iostream>
using namespace std;
const int nos = 204800;
const int freq = 44100;
const float pi = 3.14159265359;

int main(){
    if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") ==AL_TRUE)
        printf("enum supported\n");
    //to do: get the list of devices printed and choose one
    ALCdevice* Device = alcOpenDevice(NULL);
    ALCcontext* Context = alcCreateContext(Device,NULL);
    alcMakeContextCurrent(Context);
    alGetError();
    ALuint buffer;
    alGenBuffers((ALuint)1, &buffer);
    unsigned char testdata[nos];
    for(int n = 0; n < nos; n++){
        testdata[n] = 128+(char)(126*sin(2*pi*freq/10.0*n));
    }
    alBufferData(buffer, AL_FORMAT_MONO8, &testdata[0], nos, freq);
    ALuint source;
    alGenSources((ALuint)1, &source);
    alSourcei(source, AL_BUFFER, buffer);
    printf("test\n");
    alSourcePlay(source);
    ALint source_state;
    alGetSourcei(source, AL_SOURCE_STATE, &source_state);
    while (source_state == AL_PLAYING) {
        alGetSourcei(source, AL_SOURCE_STATE, &source_state);
    }
    alDeleteSources(1, &source);
    alDeleteBuffers(1, &buffer);
    Device = alcGetContextsDevice(Context);
    alcMakeContextCurrent(NULL);
    alcDestroyContext(Context);
    alcCloseDevice(Device);
    printf("done\n");
}

As stated above, I am trying to get a sine wave to play and all I am getting is maybe static.


Solution

  • In the formula amplitude * sin (2 * pi * wave_frequency * time), the time parameter must be expressed in seconds, and not in samples (because you're expressing the frequencies in Hz, samples per second).

    for(int n = 0; n < nos; n++){
            testdata[n] = 128 + (char) (127 * sin (2 * pi * freq/10.0 * (1.0 * n / freq)));
        }
    

    This will also work, because piis already a float.

            testdata[n] = 128 + (char) (127 * sin (2 * pi * freq/10.0 * n / freq));
    

    This will also work, expressing the frequency of the wave in samples per cycle, and the time in samples.

            testdata[n] = 128 + (char) (127 * sin (2 * pi / 10.0 * n));
    

    Note 1: in these examples and following your code, the sample rate is freq (44100 Hz); your wave has 10.0 samples per cycle, and it's frequency is freq/10.0 (4410 Hz). It's advisable to use a separate variable for each of these parameters, for clarity.

    Note 2: I noticed you used 126 as a multiplier, limiting the results to -126..+126 (and avoiding to exceed the 0..255 range of the 8-bit unsigned char after adding 128). I changed it to 127 (which will give us a slightly wider amplitude).