(newb) Let button generate audio for n seconds

I would like to press a button and generate a chord by playing saw waves for a duration of 1 second after button press.
Would anyone be willing to give me pointers on how to go about this? I followed the synth tutorial but am not sure how cease the audio output in relation to the button press.

1 Like

you could only output a specified number of samples – use the sampleRate to calculate how many samples 1 second is

or you could maybe use a timer callback to automatically stop playback after a certain number of callbacks? (or just 1 if your timer rate is 1000 ms)

auto desired_time_seconds = 1
auto desired_time_samples = desired_time_seconds * getSampleRate()
int samples_rendered = 0;
float phase = 0.f;
float desired_frequency = 440.f;

button->onClick = [this]() {
    processor.samples_rendered = 0;

processBlock {
...inside sample loop

    if (samples_render < desired_time_samples) {
          float output = sin(phase * 2 * PI);

          phase += desired_frequency / getSampleRate();

          if (phase > 1) {
            phase -= 1;

        buffer.set_sample(channe, sample_index, output);
1 Like

no use timer in DSP thread – very bad bad – DSP gods angry

1 Like

well, you could use a timer in the message thread to call a function in the Processor, right?

Your example code above looks great, just saying, theoretically…

Yeah I think the timers aren’t guaranteed to be accurate in any capacity though, I really only ever use them to call repaint continuously on graphics

1 Like


so sample counting is definitely the way to go here :slightly_smiling_face:

Thank you so much for the response.
I feel I’ve tried just about everything and can’t get sound to come out. I have this running as a synth, as opposed to a plugin on the mixer. Does that prevent you from being able to output audio in a channel/sample loop in the process block?
Just to make sure my sin wave calc wasn’t wrong I just tried generating noise, my exact code is this:

void CCAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels  = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();

    for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear (i, 0, buffer.getNumSamples());

    for (int channel = 0; channel < totalNumInputChannels; ++channel)
        float* channelData = buffer.getWritePointer(channel);
        for (int sample=0;sample<buffer.getNumSamples(); ++sample)
                channelData[sample] = random.nextFloat() * 0.25f - 0.125f;

If your plugin is an instrument, the totalNumInputChannels will likely be 0 and your loops are never executed. Try totalNumOutputChannels instead.

1 Like

perfect, thank you!