Distorted Sine Wave


#1

Hi all, first post! :slight_smile:

Anyways, I began working with JUCE recently (and have come back to C++ after a good few years). Following on from the sine synth tutorial, I decided to make the wave in stereo and try out some processing on the audi output. The problem with the code below is that the output is distorted and not a clean sine wave. I believe the problem is to do with the same wave not being written to both the left and write channel and so the waves are not smooth sines, however I cannot think of a fix.

Sorry for the n00b question, any suggestions?

for (int channel = 0; channel < bufferToFill.buffer->getNumChannels(); ++channel)
        {
            // Get a pointer to the start sample in the buffer for this audio output channel
            float* const buffer = bufferToFill.buffer->getWritePointer (channel, bufferToFill.startSample);
    
            // Fill the required number of samples with values generated from the sine formula
            for (int sample = 0; sample < bufferToFill.numSamples; ++sample)
            {
                const float currentSample = (float) std::sin (currentAngle);
                currentAngle += changeOfAngle;
                buffer[sample] = currentSample * 0.125;
            }
        }

void updateChangeOfAngle()
{
    //double frequencyValue = MidiMessage::getMidiNoteInHertz(frequencySlider.getValue());
    const double cyclesPerSample = MidiMessage::getMidiNoteInHertz(69 + frequencySlider.getValue()) / currentSampleRate;
    changeOfAngle = 2 * double_Pi * cyclesPerSample;
}

#2

add a DBG() statement when the outer for() loop starts and look at the value of currentSample and currentAngle before the inner loop is executed.


#3

Debugging shows what I thought was correct in that the values created from the inner for loop continue over so there is a big chunk of sine wave missing from each channel. I think the problem is something along the lines of How would I store the point at which the previous channels calculations got to and read that value to continue from?


#4

You’re doubling up on incrementing the counter (currentAngle). Simple fix is to flip the order of the nested loops, IE

for (int sample = 0; sample < bufferToFill.numSamples; ++sample)
{
    const float currentSample = (float) std::sin (currentAngle);
    currentAngle += changeOfAngle;

    for (int channel = 0; channel < bufferToFill.buffer->getNumChannels(); ++channel)
         bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample)[sample] = currentSample;
}

#5

Thank you ever so much!
Knew it was a simple fix, just didn’t know how to go about it. Wrapping my head around the basics of audio/ MIDI processing still