I’m trying to record some audio with a class derived from AudioIODeviceCallback. I’m using the AudioRecordingDemo as a template, but the recording doesn’t works. I’m playing some PureData patches too (that works fine). Maybe could someone say me is still missing? I’m posting here only a part of the code, the classes are big. I tested it on OSX, Windows and Linux with both aiff and wav formats, without results.
AudioRecorder::AudioRecorder() {
backgroundThread.startThread();
}
AudioRecorder::~AudioRecorder() {
if(isRecording())
stopRecording();
closePdResources();
threadedWriter.reset();
}
void AudioRecorder::startRecording(const juce::File &file) {
stopRecording();
if (sampleRate > 0) {
file.deleteFile();
std::unique_ptr<juce::FileOutputStream> fileStream (file.createOutputStream());
if (fileStream.get() != nullptr) {
#if JUCE_MAC
juce::AiffAudioFormat aiffFormat;
auto* writer = aiffFormat.createWriterFor (fileStream.get(), sampleRate, 1, bitDepth, {}, 0);
#else
juce::WavAudioFormat wavFormat;
auto* writer = wavFormat.createWriterFor (fileStream.get(), sampleRate, 1, bitDepth, {}, 0);
#endif
if (writer != nullptr) {
fileStream.release();
threadedWriter.reset (new juce::AudioFormatWriter::ThreadedWriter (writer, backgroundThread, 32768));
const juce::ScopedLock sl (writerLock);
activeWriter = threadedWriter.get();
}
}
}
}
void AudioRecorder::stopRecording() {
{
const juce::ScopedLock sl (writerLock);
activeWriter = nullptr;
}
threadedWriter.reset();
}
bool AudioRecorder::isRecording() const {
return activeWriter.load() != nullptr;
}
void AudioRecorder::audioDeviceAboutToStart(juce::AudioIODevice *device) {
sampleRate = device->getCurrentSampleRate();
initPd(sampleRate); //There is no problem here, that works fine
}
void AudioRecorder::audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) {
if(!isRecording()) {
fillPdOutput(outputChannelData, numOutputChannels, numSamples);
}
else {
const juce::ScopedLock sl (writerLock);
if (activeWriter.load() != nullptr ) {
wrote = activeWriter.load()->write (inputChannelData, numSamples);
}
fillPdOutput(outputChannelData, numOutputChannels, numSamples); //fillPdOutput works fine, it refers to some stuff with Pure Data
}
}
and in the Main Component class:
in Component constructor:
formatManager.registerBasicFormats();
audioDeviceManager.initialise (1, 2, nullptr, true, {}, nullptr);
…more stuff
void MainComponent::initializeAudioResources() {
recorder = std::make_shared<AudioRecorder>();
audioDeviceManager.addAudioCallback(recorder.get());
isAudioInitialized = true;
}
void MainComponent::releaseAudioResources() {
audioDeviceManager.removeAudioCallback(recorder.get());
recorder.reset();
isAudioInitialized = false;
}
void MainComponent::startMicrophoneRecording() {
isMicrophoneRecord = true;
auto parentDir = juce::File::getSpecialLocation(juce::File::userDocumentsDirectory);
#if JUCE_MAC
lastRecording = parentDir.getNonexistentChildFile ("MyRecord", ".aiff");
#else
lastRecording = parentDir.getNonexistentChildFile("MyRecord", ".wav");
#endif
recorder->startRecording(lastRecording);
startMetronome(); //this methode works
}
void MainComponent::stopMicrophoneRecording() {
recorder->stopRecording();
lastRecording = juce::File();
stopMetronome();
releaseAudioResources();
}
