Okay, so I have gotten my code to record to the buffer and play from it. The issue I have now is when I go back to record a second time it starts playing back as it’s recording even though the play boolean is set to false
#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include "Display.h"
#include "AudioVisual.h"
//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class recorda : public AudioIODeviceCallback
{
public:
recorda (AudioThumbnail& thumbnailToUpdate)
: thumbnail(thumbnailToUpdate),
backgroundThread ("Audio Recorder Thread"),
sampleRate(0), nextSampleNum (0), activeWriter(nullptr)
{
backgroundThread.startThread();
trackOne.setSize(2, 0, false, true, false);
}
~recorda()
{
stop();
}
void startAD()
{
deviceManager.addAudioCallback(this);
deviceManager.initialise(2, 2, 0, true, "Headphones", nullptr);
}
void startRec()
{
playing=false;
startAD();
if (sampleRate > 0)
{
trackOne.clear();
}
}
void closeAD()
{
deviceManager.closeAudioDevice();
audioDeviceStopped();
std::cout<<"recording: " << recording<<std::endl;
std::cout<<"playing " << playing<<std::endl;
}
void stop()
{
recording = false;
closeAD();
}
bool playing;
bool recording;
void audioDeviceAboutToStart (AudioIODevice* device) override
{
sampleRate = device -> getCurrentSampleRate();
}
void audioDeviceStopped() override
{
sampleRate = 0;
}
//AudioIODevice, AudioDeviceManager, getCurrentSampleRate
void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels,
int numSamples) override
{
std::cout<<"recording: " << recording<<std::endl;
std::cout<<"playing " << playing<<std::endl;
int oldSampleSize = trackOne.getNumSamples();
int channelNumber = trackOne.getNumChannels();
if (recording == true)
{
trackOne.setSize( trackOne.getNumChannels(),
oldSampleSize + numSamples,
true,
true,
false);
trackOneOutput.setSize(trackOneOutput.getNumChannels(),
oldSampleSize + numSamples,
true,
true,
false);
for(int j = 0; j < channelNumber; ++j){
trackOne.copyFrom(j, oldSampleSize, inputChannelData[j], numSamples);
}
for(int i=0; i<numOutputChannels; ++i)
{
if(outputChannelData[i] != nullptr)
{
FloatVectorOperations::clear(outputChannelData[i], numSamples);
}
}
}
if(playing == true)
{
for (int i = 0; i < numOutputChannels; ++i)
{
if (outputChannelData[i] != nullptr)
{
for(int samples=0; samples<numSamples; ++samples)
{
if(position >= trackOne.getNumSamples())
{
position = 0;
}
float sample = trackOne.getSample(i, samples+position);
outputChannelData[i][samples] = sample;
//std::cout<<sample;
}
}
}
position += numSamples;
std::cout<<position<<std::endl;
}
}
int position;
private:
AudioFormatManager formatManager;
AudioThumbnail& thumbnail;
TimeSliceThread backgroundThread;
ScopedPointer<AudioFormatWriter::ThreadedWriter> threadedWriter;
ScopedPointer<AudioFormatReaderSource> currentRecordingSource;
double sampleRate;
int64 nextSampleNum;
AudioSampleBuffer trackOne, trackOneOutput, trackTwo, trackThree, trackFour;
AudioDeviceManager deviceManager;
CriticalSection writerLock;
AudioFormatWriter::ThreadedWriter* volatile activeWriter;
};
class RecordingThumb : public Component,
private ChangeListener
{
public:
RecordingThumb()
:thumbnailCache (10),
thumbnail (512, formatManager, thumbnailCache),
displayFullThumb(false)
{
formatManager.registerBasicFormats();
thumbnail.addChangeListener (this);
}
~RecordingThumb()
{
thumbnail.removeChangeListener (this);
}
AudioThumbnail& getAudioThumbnail() {return thumbnail;}
void displayFullThumbnail (bool displayFull)
{
displayFullThumb = displayFull;
repaint();
}
void paint (Graphics& g)override
{
g.fillAll (Colours::darkgrey);
g.setColour (Colours::lightgrey);
if (thumbnail.getTotalLength() > 0.0)
{
const double endTime = displayFullThumb ? thumbnail.getTotalLength() : jmax (30.0, thumbnail.getTotalLength());
Rectangle<int> thumbArea (getLocalBounds());
thumbnail.drawChannels (g, thumbArea.reduced (2), 0.0, endTime, 1.0f);
}
else
{
g.setFont(14.0f);
g.drawFittedText("(No file recorded)", getLocalBounds(), Justification::centred, 2);
}
}
private:
AudioFormatManager formatManager;
AudioThumbnailCache thumbnailCache;
AudioThumbnail thumbnail;
bool displayFullThumb;
void changeListenerCallback(ChangeBroadcaster* source) override
{
if(source == &thumbnail)
repaint();
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RecordingThumb)
};
class MainContentComponent : public AudioAppComponent,
public ChangeListener,
public Button::Listener
{
public:
//==============================================================================
MainContentComponent()
:
recorder(recordingThumb.getAudioThumbnail())
{
setOpaque(true);
addAndMakeVisible(audioVis);
addAndMakeVisible(recordingThumb);
addAndMakeVisible (&playButton);
playButton.setButtonText("Play");
playButton.addListener(this);
playButton.setColour(TextButton::buttonColourId, Colours::green);
playButton.setEnabled(true);
addAndMakeVisible(&stopButton);
stopButton.setButtonText("Stop");
stopButton.addListener(this);
stopButton.setColour(TextButton::buttonColourId, Colours::red);
stopButton.setEnabled(true);
addAndMakeVisible (recordingButton);
recordingButton.setButtonText ("Record");
recordingButton.addListener (this);
recordingButton.setColour (TextButton::buttonColourId, Colour (0xffff5c6f));
recordingButton.setColour (TextButton::textColourOnId, Colours::black);
recordingButton.setEnabled(true);
addAndMakeVisible(stopRecordingButton);
stopRecordingButton.setButtonText("Stop Recording");
stopRecordingButton.addListener (this);
stopRecordingButton.setColour (TextButton::buttonColourId, Colour(0x44444444));
stopRecordingButton.setColour(TextButton::textColourOnId, Colours::white);
addAndMakeVisible(recordingPlayButton);
recordingPlayButton.setButtonText("Play");
recordingPlayButton.addListener(this);
recordingPlayButton.setColour(TextButton::buttonColourId, Colours::green);
recordingPlayButton.setEnabled(false);
setSize (800, 600);
formatManager.registerBasicFormats();
transportSource.addChangeListener(this);
deviceManager.removeAudioCallback(&audioVis);
deviceManager.removeAudioCallback(&recorder);
// specify the number of input and output channels that we want to open
}
~MainContentComponent()
{
shutdownAudio();
deviceManager.removeAudioCallback (&recorder);
deviceManager.removeAudioCallback(&audioVis);
}
void changeListenerCallback (ChangeBroadcaster* source) override
{
}
//=======================================================================
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override
{
}
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
{
}
void releaseResources() override
{
}
//=======================================================================
void paint (Graphics& g) override
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (Colours::lightblue);
// You can add your drawing code here!
}
void resized() override
{
Rectangle<int> stuff (getLocalBounds());
//audioVis.setBounds(stuff.removeFromTop(80).reduced (8));
recordingThumb.setBounds(stuff.removeFromTop(100).removeFromRight(600).reduced(8));
recordingButton.setBounds (10, 105, (getWidth()/4) -20, 20);
stopRecordingButton.setBounds (10, 135, (getWidth()/4) -20, 20);
playButton.setBounds(10, 45, (getWidth()/4) - 20, 20);
stopButton.setBounds(10, 75, (getWidth()/4) -20, 20);
}
void startRecording()
{
recorder.playing=false;
recorder.recording=true;
recorder.startRec();
}
void stopRecording()
{
recorder.stop();
recorder.recording = false;
}
void buttonClicked (Button* button) override
{
if(button == &playButton) playButtonClicked();
if(button == &stopButton) stopButtonClicked();
if (button == &recordingButton) startRecording();
if (button == &stopRecordingButton) stopRecording();
}
void playButtonClicked()
{
setAudioChannels(2,2);
recorder.startAD();
recorder.playing=true;
recorder.recording=false;
recorder.position = 0;
}
void stopButtonClicked()
{
recorder.playing = false;
recorder.closeAD();
//recordingThumb.displayFullThumbnail(true);
}
private:
//==============================================================================
// Your private member variables go here...
AudioFormatManager formatManager;
AudioVisual audioVis;
RecordingThumb recordingThumb;
recorda recorder;
//LiveScrollingAudioDisplay liveAudioScroller;
ScopedPointer<AudioFormatReaderSource> readerSource;
AudioTransportSource transportSource;
TextButton openButton;
TextButton playButton;
TextButton stopButton;
TextButton recordingButton;
TextButton stopRecordingButton;
TextButton recordingPlayButton;
Display display;
Display display2;
Display display3;
Display display4;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
// (This function is called by the app startup code to create our main component)
Component* createMainContentComponent() { return new MainContentComponent(); }
#endif // MAINCOMPONENT_H_INCLUDED