Help! Can't work out why I can't hear anything!

Help! I am a complete newbie at this. I am following a video lecture which creates a simple app with a couple of buttons, sliders etc and also plays some white noise created by a random number function. His version (using a Mac IDE of some kind and Juce 5 I thnk) works fine - but I’m using VS2019 and Juce 6 and I can’t get it to work at all. What am I doing wrong?

This is my .h

#pragma once

#include <JuceHeader.h>

    This component lives inside our window, and this is where you should put all
    your controls and content.
class MainComponent : public juce::AudioAppComponent,
                      public juce::Button::Listener,
                      public juce::Slider::Listener
    ~MainComponent() override;

    void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;
    void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override;
    void releaseResources() override;

    void paint (juce::Graphics& g) override;
    void resized() override;

    /** implement Button::Listener */
    void buttonClicked(juce::Button*) override;

    /** implement Slider::Listener */
    void sliderValueChanged(juce::Slider *slider) override;

    // Your private member variables go here...

    juce::TextButton playButton{ "PLAY" };
    juce::TextButton stopButton{ "STOP" };
    juce::Slider volSlider;
    juce::Random rand;
    double phase;
    double dphase;


and this is my .cpp

#include "MainComponent.h"

    // Make sure you set the size of the component after
    // you add any child components.
    setSize (800, 600);

    // Some platforms require permissions to open input channels so request that here
    if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio)
        && ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio))
        juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,
                                           [&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); });
        // Specify the number of input and output channels that we want to open
        setAudioChannels (2, 2);




    // This shuts down the audio device and clears the audio source.

void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)

    phase = 0.0;
    dphase = 0.0001;


void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)

    auto* leftChan = bufferToFill.buffer->getWritePointer(0, bufferToFill.startSample);
    auto* rightChan = bufferToFill.buffer->getWritePointer(0, bufferToFill.startSample);

    for (auto i = 0; i < bufferToFill.numSamples; ++i)
        // double sample = rand.nextDouble() * 0.25;
        double sample = fmod(phase, 0.2);

        leftChan[i] = sample;
        rightChan[i] = sample;

        phase += dphase;

    // bufferToFill.clearActiveBufferRegion();

void MainComponent::releaseResources()
    // This will be called when the audio device stops, or when it is being
    // restarted due to a setting change.

    // For more details, see the help for AudioProcessor::releaseResources()

void MainComponent::paint (juce::Graphics& g)
    // (Our component is opaque, so we must completely fill the background with a solid colour)
    g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));

    // You can add your drawing code here!

void MainComponent::resized()
    // This is called when the MainContentComponent is resized.
    // If you add any child components, this is where you should
    // update their positions.


    double rowH = getHeight() / 5;
    playButton.setBounds(0, 0, getWidth(), rowH);
    stopButton.setBounds(0, rowH, getWidth(), rowH);
    volSlider.setBounds(0, rowH *2, getWidth(), rowH);


void MainComponent::buttonClicked(juce::Button* button)
    if (button == &playButton)
        DBG("Play button was clicked");
    if (button == &stopButton)
        DBG("Stop button was clicked");

void MainComponent::sliderValueChanged(juce::Slider* slider)
    if (slider == &volSlider)
        // DBG("Vol slider moved to " << slider->getValue());
        dphase = volSlider.getValue() * 0.001;

Any help greatly appreciated, thank you!

Hello, welcome to the forum!

Is the getNextAudioBlock method called at all? If it isn’t, I make the guess it’s the usual problem with AudioAppComponent where it isn’t able to initialize your audio hardware properly. You could try setAudioChannels (0, 2); instead of setAudioChannels (2, 2); in the constructor.

If the getNextAudioBlock is called, there are couple of possibilities :

  • The audio is going to some hardware output you are not currently monitoring. AudioAppComponent has no easy way to change that.
  • The audio you are generating with your function is too low in frequency to be audible (does the noise generation work, though?)
1 Like

xenakios you are a lifesaver! I changed setAudioChannels to (0,2) and it works! Thank you!