Can't get basic sinewave output

I’m following YT tutorial but there’s no output and Processing memory is climbing into gigabytes. Can someone point out what’s wrong or changed since 5.1 version.
I thought that something isn’t right with a wavetable example so I made an alternative with sin() function and got same result. Commented out is as tutorial video.

void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{
    frequency = 440;
    /*
    phase = 0;
    wtSize = 1024;
    increment = frequency * wtSize / sampleRate;
    */
    amplitude = 0.5;
    samplerate = sampleRate;
    index = 0;
    for (int i = 0; wtSize; i++)
    {
        waveTable.insert(i, std::sin(2.0 * double_Pi * i / wtSize));
    }
}
void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
    float* const leftSpeaker = bufferToFill.buffer->getWritePointer(0, bufferToFill.startSample);
    float* const rightSpeaker = bufferToFill.buffer->getWritePointer(1, bufferToFill.startSample);
    
    for (int sample = 0; sample < bufferToFill.numSamples; ++sample)
    {
        /*
        leftSpeaker[sample] = waveTable[(int)phase] * amplitude;
        rightSpeaker[sample] = waveTable[(int)phase] * amplitude;
        phase = fmod((phase + increment), wtSize);
        */
        double s = index / samplerate;
        leftSpeaker[sample] = std::sin(2.0 * double_Pi * s * frequency)  * amplitude;
        rightSpeaker[sample] = std::sin(2.0 * double_Pi * s * frequency) * amplitude;
        index += 1;
        index = fmod(index, samplerate);
    }
}

That ends up as an infinite loop in prepareToPlay and the sound will never start playing. You need to change it to for (int i = 0; i < wtSize; i++)

1 Like

OMG! I went splitting hair and bummed out for half a day.
Thank you, @Xenakios !!!. Now everything works.

And just food for thought, modern c++ emphasizes algorithms over raw loops, for reasons just like this. so, you might consider std::generate_n().

auto index {0};
std::generate_n (std::back_inserter (waveTable), wtSize, [&index] () { return sin (2.0 * double_Pi * index++ / wtSize); });
1 Like

Hmm. I see it for the first time. I copied your example in place of for loop but didn’t work. C++ docs was confusing.
Is there example of the use in context?

Oh, my code may not work, as I was assuming wavTable was something like std::vector<double>, which is what I tested that code with

1 Like

Oh, I have Array waveTable; as from that YT tutorial.

damn JUCE containers!!! lol… I’ve had other instances where I want to use an stl algorithm, but couldn’t because it was a JUCE container… so yeah, my solution won’t work… if you can switch to a vector it will work

1 Like

For some reason it doesn’t like wtSize although it’s declared in class private as double and inside prepareToPlay it’s initialized to 1024.

the enclosing-function 'this' cannot be referenced in a lambda body unless it is in the capture list;
the usage of 'MainComponent::wtSize' requires the compiler to capture 'this' but the current default capture mode does not allow it;
'wtSize' undeclared identifier;

Oh, you need to add this to the capture list

std::generate_n (std::back_inserter (waveTable), wtSize, [this, &index] () { return sin (2.0 * double_Pi * index++ / wtSize); });

The compiler was even nice enough to tell you exactly what to do! :wink:

3 Likes

Yeah, that worked! Thank you, @cpr !!!

1 Like

I suggested it because I am still working on upping my algorithm game, and this was fresh in my mind. :slight_smile:

1 Like