thestk / rtaudio

A set of C++ classes that provide a common API for realtime audio input/output across Linux (native ALSA, JACK, PulseAudio and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound, ASIO, and WASAPI) operating systems.
Other
1.49k stars 317 forks source link

Incorrect implementation of the amplitude when calculating the output signal #418

Open UQMark opened 7 months ago

UQMark commented 7 months ago

I'm not entirely sure if the problem lies with the library itself, but I just couldn't find another explanation. So... I have a basic for loop in which the audio output stream is formed based on the wave table and the parameters of the ADSR envelope.

int callbackFunction(void* outputBuffer, void* inputBuffer, unsigned int bufferFrames,
    double streamTime, RtAudioStreamStatus status, void* oscillatorParam)
{
    double* buffer = (double*)outputBuffer;
    struct Oscillator* oscillator = (struct Oscillator*)oscillatorParam;

    for (unsigned int i = 0; i < bufferFrames; i++)
    {
        float out = 0.0;

        if (midiManager.isActive())
        {
            if (midiManager.keyPressed)
            {
                adsr.triggerAttack();
                midiManager.keyPressed = false;
            }

            if (midiManager.keyReleased)
            {
                adsr.triggerRelease();
                midiManager.keyReleased = false;
            }

            midiManager.active = false;
        } 

        oscillator->volume = adsr.process();
        std::cout << "volume value: " << oscillator->volume << std::endl;
        out = filter.process(oscillator->process()) * oscillator->volume;

        buffer[i] = out;
    }

    return 0;
}

In the range of amplitude from 0.25 to 1.0, the resulting volume sounds exactly the same. Initially, I assumed that the problem lay in the implementation of ADSR, since when setting sustain= 0.25, the amplitude remained at the maximum level (that is, the final phase of the attack). Then I decided to remove the process function call and implemented the modulation using a knob controller. The problem has not disappeared, but I noticed that the variable oscillator->volume (as opposed to the actual volume) changes according to the parameters of the envelope (as it should be). This may mean that the problem is still in the implementation of the library itself. If this behavior had occurred as a result of an incorrectly formed wave table during the initialization of the oscillators, then even with the key held down, I would certainly have noticed a malfunction. In addition, the only block of code where an amplitude change can occur is precisely the for loop inside the callback function.