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.
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);
samples_rendered++;
}
}
no use timer in DSP thread – very bad bad – DSP gods angry
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
gotcha.
so sample counting is definitely the way to go here
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.
perfect, thank you!