So I’m trying to get my recorder to work, but for whatever reason it only creates a file that is 00:00 in length. Can someone give me any ideas what I’m doing wrong?
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include "Display.h"
#include "AudioVisual.h"
class recorda : public AudioIODeviceCallback
{
public:
recorda (AudioThumbnail& thumbnailToUpdate)
: thumbnail(thumbnailToUpdate),
backgroundThread ("Audio Recorder Thread"),
sampleRate(44100), nextSampleNum (0), activeWriter(nullptr)
{
backgroundThread.startThread();
}
~recorda()
{
stop();
}
void startRec(const File& file)
{
stop();
if (sampleRate > 0)
{
file.deleteFile();
ScopedPointer<FileOutputStream> fileStream (file.createOutputStream());
if (fileStream != nullptr)
{
WavAudioFormat wavFormat;
AudioFormatWriter* writer = wavFormat.createWriterFor (fileStream,sampleRate, 1, 16, StringPairArray(), 0);
if (writer != nullptr)
{
fileStream.release();
threadedWriter = new AudioFormatWriter::ThreadedWriter (writer, backgroundThread, 32768);
thumbnail.reset (writer ->getNumChannels(), writer->getSampleRate());
nextSampleNum = 0;
const ScopedLock sl (writerLock);
activeWriter = threadedWriter;
}
}
}
}
void stop()
{
{
const ScopedLock sl (writerLock);
activeWriter = nullptr;
}
threadedWriter = nullptr;
}
bool isRec() const
{
return activeWriter != nullptr;
}
void audioDeviceAboutToStart (AudioIODevice* device) override
{
sampleRate = device -> getCurrentSampleRate();
}
void audioDeviceStopped() override
{
sampleRate = 0;
}
void audioDeviceIOCallback (const float** inputChannelData, int /*numInputChannels*/,
float** outputChannelData, int numOutputChannels,
int numSamples) override
{
std::cerr<<"callback";
const ScopedLock sl (writerLock);
if (activeWriter != nullptr)
{
std::cerr<<"callback2";
activeWriter->write (inputChannelData, numSamples);
const AudioSampleBuffer buffer(const_cast<float**>(inputChannelData), thumbnail.getNumChannels(), numSamples);
thumbnail.addBlock (nextSampleNum, buffer, 0, numSamples);
nextSampleNum += numSamples;
}
for (int i = 0; i < numOutputChannels; ++i)
if (outputChannelData[i] != nullptr)
{
std::cerr<<"callback3";
FloatVectorOperations::clear (outputChannelData[i], numSamples);
}
}
private:
AudioThumbnail& thumbnail;
TimeSliceThread backgroundThread;
ScopedPointer<AudioFormatWriter::ThreadedWriter> threadedWriter;
double sampleRate;
int64 nextSampleNum;
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()
: //deviceManager(MainAppWindow::getSharedAudioDeviceManager()),
recorder(recordingThumb.getAudioThumbnail())
{
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);
addAndMakeVisible(display);
addAndMakeVisible(display2);
addAndMakeVisible(display3);
addAndMakeVisible(display4);
setSize (800, 600);
//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
{
//display.setBounds(200,5,500,200);
//display2.setBounds(200,150,500,200);
//display3.setBounds(200,275,500,249);
//display4.setBounds(200,400,500,200);
Rectangle<int> stuff (getLocalBounds());
//audioVis.setBounds(stuff.removeFromTop(80).reduced (8));
recordingThumb.setBounds(stuff.removeFromTop(80).reduced(8));
recordingButton.setBounds (stuff.removeFromTop (80).removeFromLeft (140).reduced (8));
}
void startRecording()
{
const File file (File::getSpecialLocation(File::userDocumentsDirectory).getNonexistentChildFile("Recording",".wav"));
recorder.startRec(file);
recordingButton.setButtonText("Stop");
recordingThumb.displayFullThumbnail(false);
}
void stopRecording()
{
recorder.stop();
recordingButton.setButtonText("Record");
recordingThumb.displayFullThumbnail(true);
}
void buttonClicked (Button* button) override
{
if (button == &recordingButton)
{
if(recorder.isRec())
{
std::cerr<<"if youz a bish don't print";
stopRecording();
}
else
startRecording();
}
}
private:
//==============================================================================
// Your private member variables go here...
AudioFormatManager formatManager;
//AudioDeviceManager& deviceManager;
AudioVisual audioVis;
RecordingThumb recordingThumb;
recorda recorder;
ScopedPointer<AudioFormatReaderSource> readerSource;
AudioTransportSource transportSource;
TextButton openButton;
TextButton playButton;
TextButton stopButton;
TextButton recordingButton;
TextButton stopRecordingButton;
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
