I’m trying to create a wav file with contents stored in an AudioBuffer in the pluginEditor. I dont need to stream data and write samples as the get process in the processor but rather just create a wav with what I have in that buffer.
I get an error as jassertfalse in WavAudioFormat.cpp when afw->writeFromAudioSampleBuffer(buffer, 0, buffer.getNumSamples()); is executed. The comment in WavAudioFormat.cpp says:
// if this fails, you’ve given it an output stream that can’t seek! It needs to be
// able to seek back to go back and write the header after the data has been written.
I have a unique_ptr juce::FileOutputStream fos, a ScopedPointerjuce::AudioFormatWriter afw, File file{ “path\fo.wav” }, and AudioBuffer buffer, in the pluginEditor.h .
this is what I have in the editor constructor:
formatManager.registerBasicFormats();
file.create();
fos = std::make_unique<juce::FileOutputStream>(file);
this is what I do in the editor code when I want to write the file:
fos->setPosition(0);
fos->truncate();
afw = format.createWriterFor(fos.get(),
44100.0,
(unsigned int)buffer.getNumChannels(),
16,
{},
0);
afw->writeFromAudioSampleBuffer(buffer, 0, buffer.getNumSamples());
I dont think the file gets created, and it returns false if I execute fos->openedOk() before setting the position and truncating. Is this the way to even do this? I have no clue.
my call stack if it can be of any help:
> | AAIR.exe!juce::WavAudioFormatWriter::writeHeader() Line 1400 | C++ |
---|---|---|
AAIR.exe!juce::WavAudioFormatWriter::write(const int * * data, int numSamples) Line 1360 | C++ | |
AAIR.exe!juce::AudioFormatWriter::writeFromFloatArrays(const float * const * channels, int numSourceChannels, int numSamples) Line 179 | C++ | |
AAIR.exe!juce::AudioFormatWriter::writeFromAudioSampleBuffer(const juce::AudioBuffer & source, int startSample, int numSamples) Line 195 | C++ | |
AAIR.exe!AAIRAudioProcessorEditor::changeListenerCallback(juce::ChangeBroadcaster * source) Line 520 | C++ | |
AAIR.exe!juce::ChangeBroadcaster::callListeners::__l2::(juce::ChangeListener & l) Line 87 | C++ | |
AAIR.exe!juce::ListenerList<juce::ChangeListener,juce::Array<juce::ChangeListener *,juce::DummyCriticalSection,0>>::call<void (juce::ChangeListener &)>(juce::ChangeBroadcaster::callListeners::__l2::void (juce::ChangeListener &) && callback) Line 124 | C++ | |
AAIR.exe!juce::ChangeBroadcaster::callListeners() Line 88 | C++ | |
AAIR.exe!juce::ChangeBroadcaster::ChangeBroadcasterCallback::handleAsyncUpdate() Line 100 | C++ | |
AAIR.exe!juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback() Line 35 | C++ | |
AAIR.exe!juce::InternalMessageQueue::dispatchMessage(juce::MessageManager::MessageBase * message) Line 202 | C++ | |
AAIR.exe!juce::InternalMessageQueue::dispatchMessages() Line 240 | C++ | |
AAIR.exe!juce::InternalMessageQueue::dispatchNextMessage(bool returnIfNoPendingMessages) Line 125 | C++ | |
AAIR.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 266 | C++ | |
AAIR.exe!juce::MessageManager::runDispatchLoop() Line 128 | C++ | |
AAIR.exe!juce::JUCEApplicationBase::main() Line 266 | C++ | |
AAIR.exe!WinMain(HINSTANCE__ * formal, HINSTANCE * __formal, char * __formal, int __formal) Line 47 | C++ | |
[External Code] |