diff --git a/Source/PS_Source/StretchSource.cpp b/Source/PS_Source/StretchSource.cpp index 3c5f13a..90dcc60 100644 --- a/Source/PS_Source/StretchSource.cpp +++ b/Source/PS_Source/StretchSource.cpp @@ -611,6 +611,13 @@ double StretchAudioSource::getInfileLengthSeconds() return (double)m_inputfile->info.nsamples / m_inputfile->info.samplerate; } +double StretchAudioSource::getInfileSamplerate() +{ + if (m_inputfile == nullptr) + return 0.0; + return m_inputfile->info.samplerate; +} + void StretchAudioSource::setRate(double rate) { if (rate == m_playrate) diff --git a/Source/PS_Source/StretchSource.h b/Source/PS_Source/StretchSource.h index aab20d6..13bb45d 100644 --- a/Source/PS_Source/StretchSource.h +++ b/Source/PS_Source/StretchSource.h @@ -56,6 +56,7 @@ public: double getInfilePositionPercent(); double getInfilePositionSeconds(); double getInfileLengthSeconds(); + double getInfileSamplerate(); void setRate(double rate); double getRate() { diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index ab2262f..c9cba4c 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -526,24 +526,43 @@ void PaulstretchpluginAudioProcessor::saveCaptureBuffer() m_threadpool->addJob(task); } -String PaulstretchpluginAudioProcessor::offlineRender(File outputfile) +String PaulstretchpluginAudioProcessor::offlineRender(OfflineRenderParams renderpars) { - File outputfiletouse = outputfile.getNonexistentSibling(); - ValueTree state = getStateTree(false, false); + File outputfiletouse = renderpars.outputfile.getNonexistentSibling(); + ValueTree state{ getStateTree(false, false) }; auto processor = std::make_shared(); + processor->setStateFromTree(state); - int blocksize = 2048; + double outsr{ renderpars.outsr }; + if (outsr < 10.0) + outsr = processor->getStretchSource()->getInfileSamplerate(); + Logger::writeToLog(outputfiletouse.getFullPathName() + " " + String(outsr) + " " + String(renderpars.outputformat)); + return {}; + int blocksize{ 2048 }; int numoutchans = *processor->getIntParameter(cpi_num_outchans); - processor->prepareToPlay(44100.0, blocksize); + processor->prepareToPlay(renderpars.outsr, blocksize); + double t0 = *processor->getFloatParameter(cpi_soundstart); double t1 = *processor->getFloatParameter(cpi_soundend); sanitizeTimeRange(t0, t1); - double outsr = processor->getSampleRateChecked(); + WavAudioFormat wavformat; FileOutputStream* outstream = outputfiletouse.createOutputStream(); if (outstream == nullptr) return "Could not create output file"; - auto writer = wavformat.createWriterFor(outstream, getSampleRateChecked(), numoutchans, 32, StringPairArray(), 0); + int oformattouse{ 16 }; + bool clipoutput{ false }; + if (renderpars.outputformat == 1) + oformattouse = 24; + if (renderpars.outputformat == 2) + oformattouse = 32; + if (renderpars.outputformat == 3) + { + oformattouse = 32; + clipoutput = true; + } + auto writer = wavformat.createWriterFor(outstream, getSampleRateChecked(), numoutchans, + oformattouse, StringPairArray(), 0); if (writer == nullptr) { delete outstream; diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 3f925a7..015b5af 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -120,6 +120,19 @@ public: class PaulstretchpluginAudioProcessorEditor; +struct OfflineRenderParams +{ + OfflineRenderParams(File ofile, double osr, int oformat, double omaxdur, int onumloops, CallOutBox* ocb=nullptr) : + outputfile(ofile), outsr(osr), outputformat(oformat), maxoutdur(omaxdur), numloops(onumloops), cbox(ocb) + {} + File outputfile; + double outsr = 44100.0; + double maxoutdur = 3600.0; + int numloops = 1; + int outputformat = 0; // 0=16 bit pcm, 1=24 bit pcm, 2=32 bit float, 3=32 bit float clipped + CallOutBox* cbox = nullptr; +}; + class PaulstretchpluginAudioProcessor : public AudioProcessor, public MultiTimer, public VSTCallbackHandler, public AudioProcessorParameter::Listener { @@ -201,7 +214,7 @@ public: bool m_load_file_with_state = true; ValueTree getStateTree(bool ignoreoptions, bool ignorefile); void setStateFromTree(ValueTree tree); - String offlineRender(File outputfile); + String offlineRender(OfflineRenderParams renderpars); std::atomic m_offline_render_state{ -1 }; std::atomic m_offline_render_cancel_requested{ false }; std::atomic m_capture_save_state{ 0 }; diff --git a/Source/RenderSettingsComponent.cpp b/Source/RenderSettingsComponent.cpp index f21478b..10b2a79 100644 --- a/Source/RenderSettingsComponent.cpp +++ b/Source/RenderSettingsComponent.cpp @@ -81,13 +81,13 @@ RenderSettingsComponent::RenderSettingsComponent (PaulstretchpluginAudioProcesso setSize (600, 400); comboBoxSamplerate.setSelectedId(1); comboBoxBitDepth.setSelectedId(3); - String lastexportfile = ""; // g_propsfile->getValue("last_export_file"); + String lastexportfile = m_proc->m_propsfile->m_props_file->getValue(ID_lastrenderpath); auto sep = File::getSeparatorChar(); File temp(lastexportfile); if (temp.getParentDirectory().exists()) outfileNameEditor.setText(lastexportfile, dontSendNotification); else - outfileNameEditor.setText(File::getSpecialLocation(File::userDocumentsDirectory).getFullPathName()+sep+"untitled.wav", + outfileNameEditor.setText(File::getSpecialLocation(File::userDocumentsDirectory).getFullPathName()+sep+"pxsrender.wav", dontSendNotification); numLoopsEditor.setVisible(m_proc->getStretchSource()->isLoopingEnabled()); label3.setVisible(m_proc->getStretchSource()->isLoopingEnabled()); @@ -158,22 +158,25 @@ void RenderSettingsComponent::buttonClicked (Button* buttonThatWasClicked) outfile = File(outfileNameEditor.getText()); if (outfile.getParentDirectory().exists()==false) return; - int64_t numLoops = 0; + int numLoops = 0; if (numLoopsEditor.isVisible()) numLoops = numLoopsEditor.getText().getLargeIntValue(); - numLoops = jlimit(0, 1000000, numLoops); + numLoops = jlimit(0, 1000000, numLoops); int sampleRate = comboBoxSamplerate.getSelectedId(); if (sampleRate == 1) sampleRate = 0; double maxrenderlen = m_editorMaxOutDuration.getText().getDoubleValue()*3600.0; maxrenderlen = jlimit(1.0, 1000000.0, maxrenderlen); - m_proc->offlineRender(File(outfileNameEditor.getText())); - //m_main->renderToFile(File(outfileNameEditor.getText()),numLoops, - // comboBoxBitDepth.getSelectedId()-1,sampleRate,m_toggleFloatClip.getToggleState(),maxrenderlen); - auto pardlg = dynamic_cast(getParentComponent()); + int oformat = comboBoxBitDepth.getSelectedId() - 1; + if (oformat == 2 && m_toggleFloatClip.getToggleState()) + oformat = 3; + OfflineRenderParams renderpars{ File(outfileNameEditor.getText()),(double)comboBoxSamplerate.getSelectedId(), + oformat,maxrenderlen,numLoops }; + m_proc->m_propsfile->m_props_file->setValue(ID_lastrenderpath, outfileNameEditor.getText()); + m_proc->offlineRender(renderpars); + if (auto pardlg = dynamic_cast(getParentComponent()); pardlg!=nullptr) { - if (pardlg != nullptr) - pardlg->exitModalState(1); + pardlg->exitModalState(1); } return; } diff --git a/Source/RenderSettingsComponent.h b/Source/RenderSettingsComponent.h index 3513488..18d8fdd 100644 --- a/Source/RenderSettingsComponent.h +++ b/Source/RenderSettingsComponent.h @@ -51,6 +51,7 @@ private: Label m_labelMaxOutDuration; TextEditor m_editorMaxOutDuration; ToggleButton m_toggleFloatClip; + String ID_lastrenderpath{ "lastrenderpath" }; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RenderSettingsComponent) };