added offline render to plugin version. fixed file chooser cancel issue
This commit is contained in:
parent
a76068c632
commit
2fe466ec8a
18
CHANGES.md
18
CHANGES.md
@ -1,17 +1,27 @@
|
|||||||
|
|
||||||
## PaulXStretch Change History
|
## PaulXStretch Change History
|
||||||
|
|
||||||
**v1.5.3** (04-25-2022)
|
**v1.6.0** (2022-06-15)
|
||||||
|
- Added live output recording feature
|
||||||
|
- Added selection of directory for recording/capture audio files, and some format options, now defaulting to FLAC
|
||||||
|
- Added offline render feature to plugin version
|
||||||
|
- Added Binaural Beats feature (from original paulstretch)
|
||||||
|
- Added CLAP plugin support (https://github.com/free-audio/clap for info)
|
||||||
|
- Fixed an initialization bug
|
||||||
|
- Compile fix for gcc12
|
||||||
|
|
||||||
|
|
||||||
|
**v1.5.3** (2022-04-25)
|
||||||
- Fixed Mac AudioUnit validation error and potentional crash risk when using more than 8 channels.
|
- Fixed Mac AudioUnit validation error and potentional crash risk when using more than 8 channels.
|
||||||
|
|
||||||
**v1.5.2** (04-24-2022)
|
**v1.5.2** (2022-04-24)
|
||||||
- Increased maximum number of channels to 32
|
- Increased maximum number of channels to 32
|
||||||
- Optimized FFTW build to use available hardware
|
- Optimized FFTW build to use available hardware
|
||||||
- Fixed crash issue some people were seeing on older windows systems
|
- Fixed crash issue some people were seeing on older windows systems
|
||||||
- Added option (now default) to end recording automatically when chosen buffer size is reached.
|
- Added option (now default) to end recording automatically when chosen buffer size is reached.
|
||||||
- More extremely small window size tweaks
|
- More extremely small window size tweaks
|
||||||
|
|
||||||
**v1.5.1** (04-22-2022)
|
**v1.5.1** (2022-04-22)
|
||||||
- fixed passthrough when capturing
|
- fixed passthrough when capturing
|
||||||
- added declicking fades when bypassing input passthrough, playback, and recording
|
- added declicking fades when bypassing input passthrough, playback, and recording
|
||||||
- layout tweaks for extra small windows
|
- layout tweaks for extra small windows
|
||||||
@ -22,7 +32,7 @@
|
|||||||
- fixed VST3 installation issue on windows
|
- fixed VST3 installation issue on windows
|
||||||
(be sure to uninstall first, you may need to manually remove the C:\Program Files\Common Files\VST3\PaulXStretch.vst3)
|
(be sure to uninstall first, you may need to manually remove the C:\Program Files\Common Files\VST3\PaulXStretch.vst3)
|
||||||
|
|
||||||
**v1.5.0** (04-14-2022)
|
**v1.5.0** (2022-04-14)
|
||||||
- UI layout redesign to adapt to different window sizes and changed look
|
- UI layout redesign to adapt to different window sizes and changed look
|
||||||
and feel.
|
and feel.
|
||||||
- Added iOS support for standalone and AUv3
|
- Added iOS support for standalone and AUv3
|
||||||
|
15
README.md
15
README.md
@ -80,19 +80,16 @@ Copyright (C) 2006-2011 Nasca Octavian Paul, Tg. Mures, Romania
|
|||||||
# License and 3rd Party Software
|
# License and 3rd Party Software
|
||||||
|
|
||||||
Released under GNU General Public License v.3 license with App Store license
|
Released under GNU General Public License v.3 license with App Store license
|
||||||
exception. The full license text is in the LICENSE file. Paul Nasca, Xenakios and Jesse Chappell all explicitly permitted the license exception clause.
|
exception. The full license text is in the LICENSE file. Paul Nasca, Xenakios and Jesse Chappell all explicitly permitted the license exception clause. The AAX plugin and the version distributed on the iOS App Store by Sonosaurus is not built with FFTW, and the JUCE commercial license applies there.
|
||||||
|
|
||||||
|
|
||||||
It is built using JUCE 6 (slightly modified on a public fork), I'm using the very handy tool `git-subrepo` to include the source code for my forks of those software libraries in this repository.
|
It is built using JUCE 6 (slightly modified on a public fork), I'm using the very handy tool `git-subrepo` to include the source code for my forks of those software libraries in this repository.
|
||||||
FFTW is required, but statically built libraries are included in `deps` for easier building on Mac and Windows.
|
FFTW is required, but statically built libraries are included in `deps` for easier building on Mac and Windows.
|
||||||
|
|
||||||
My github forks of these that are referenced via `git-subrepo` in this repository are:
|
Dependencies that are referenced via `git-subrepo` in this repository are:
|
||||||
|
|
||||||
> https://github.com/essej/JUCE in the sono6good branch.
|
|
||||||
|
|
||||||
The version distributed on the iOS App Store by Sonosaurus is not built with FFTW, and the JUCE commercial license applies there.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- ```(deps/juce) https://github.com/essej/JUCE in the sono6good branch. ```
|
||||||
|
- ```(deps/clap-juce-extensions) https://github.com/free-audio/clap-juce-extensions in the main branch.```
|
||||||
|
- ```(deps/clap-juce-extensions/clap-libs/clap) https://github.com/free-audio/clap in the main branch.```
|
||||||
|
- ```(deps/clap-juce-extensions/clap-libs/clap-helpers) https://github.com/free-audio/clap-helpers in the main branch.```
|
||||||
|
|
||||||
|
@ -76,12 +76,9 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
|
|||||||
showSettings(true);
|
showSettings(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (JUCEApplicationBase::isStandaloneApp())
|
|
||||||
{
|
|
||||||
addAndMakeVisible(&m_render_button);
|
addAndMakeVisible(&m_render_button);
|
||||||
m_render_button.setButtonText("Render...");
|
m_render_button.setButtonText("Render...");
|
||||||
m_render_button.onClick = [this]() { showRenderDialog(); };
|
m_render_button.onClick = [this]() { showRenderDialog(); };
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
m_rewind_button = std::make_unique<DrawableButton>("rewind", DrawableButton::ButtonStyle::ImageFitted);
|
m_rewind_button = std::make_unique<DrawableButton>("rewind", DrawableButton::ButtonStyle::ImageFitted);
|
||||||
@ -730,10 +727,8 @@ void PaulstretchpluginAudioProcessorEditor::resized()
|
|||||||
|
|
||||||
topbox.items.add(FlexItem(buttw, buttonrowheight, m_import_button).withMargin(1).withFlex(1).withMaxWidth(130));
|
topbox.items.add(FlexItem(buttw, buttonrowheight, m_import_button).withMargin(1).withFlex(1).withMaxWidth(130));
|
||||||
topbox.items.add(FlexItem(buttw, buttonrowheight, m_settings_button).withMargin(1).withFlex(1).withMaxWidth(130));
|
topbox.items.add(FlexItem(buttw, buttonrowheight, m_settings_button).withMargin(1).withFlex(1).withMaxWidth(130));
|
||||||
if (JUCEApplicationBase::isStandaloneApp())
|
|
||||||
{
|
|
||||||
topbox.items.add(FlexItem(buttw, buttonrowheight, m_render_button).withMargin(1).withFlex(1).withMaxWidth(130));
|
topbox.items.add(FlexItem(buttw, buttonrowheight, m_render_button).withMargin(1).withFlex(1).withMaxWidth(130));
|
||||||
}
|
|
||||||
topbox.items.add(FlexItem(4, 4));
|
topbox.items.add(FlexItem(4, 4));
|
||||||
topbox.items.add(FlexItem(80, buttonrowheight, m_perfmeter).withMargin(1).withFlex(1).withMaxWidth(110).withMaxHeight(24).withAlignSelf(FlexItem::AlignSelf::center));
|
topbox.items.add(FlexItem(80, buttonrowheight, m_perfmeter).withMargin(1).withFlex(1).withMaxWidth(110).withMaxHeight(24).withAlignSelf(FlexItem::AlignSelf::center));
|
||||||
topbox.items.add(FlexItem(140, 26, m_info_label).withMargin(1).withFlex(2));
|
topbox.items.add(FlexItem(140, 26, m_info_label).withMargin(1).withFlex(2));
|
||||||
@ -1298,6 +1293,37 @@ void PaulstretchpluginAudioProcessorEditor::toggleFileBrowser()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PaulstretchpluginAudioProcessorEditor::showPopTip(const String & message, int timeoutMs, Component * target, int maxwidth)
|
||||||
|
{
|
||||||
|
popTip.reset(new BubbleMessageComponent());
|
||||||
|
popTip->setAllowedPlacement(BubbleComponent::above);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
if (auto * parent = target->findParentComponentOfClass<AudioProcessorEditor>()) {
|
||||||
|
parent->addChildComponent (popTip.get());
|
||||||
|
} else {
|
||||||
|
addChildComponent(popTip.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addChildComponent(popTip.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributedString text(message);
|
||||||
|
text.setJustification (Justification::centred);
|
||||||
|
text.setColour (findColour (TextButton::textColourOffId));
|
||||||
|
text.setFont(Font(12));
|
||||||
|
if (target) {
|
||||||
|
popTip->showAt(target, text, timeoutMs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Rectangle<int> topbox(getWidth()/2 - maxwidth/2, 0, maxwidth, 2);
|
||||||
|
popTip->showAt(topbox, text, timeoutMs);
|
||||||
|
}
|
||||||
|
popTip->toFront(false);
|
||||||
|
//AccessibilityHandler::postAnnouncement(message, AccessibilityHandler::AnnouncementPriority::high);
|
||||||
|
}
|
||||||
|
|
||||||
void PaulstretchpluginAudioProcessorEditor::toggleOutputRecording()
|
void PaulstretchpluginAudioProcessorEditor::toggleOutputRecording()
|
||||||
{
|
{
|
||||||
if (processor.isRecordingToFile()) {
|
if (processor.isRecordingToFile()) {
|
||||||
@ -1309,10 +1335,10 @@ void PaulstretchpluginAudioProcessorEditor::toggleOutputRecording()
|
|||||||
String filepath;
|
String filepath;
|
||||||
#if (JUCE_IOS || JUCE_ANDROID)
|
#if (JUCE_IOS || JUCE_ANDROID)
|
||||||
filepath = m_lastRecordedFile.getRelativePathFrom(File::getSpecialLocation (File::userDocumentsDirectory));
|
filepath = m_lastRecordedFile.getRelativePathFrom(File::getSpecialLocation (File::userDocumentsDirectory));
|
||||||
//showPopTip(TRANS("Finished recording to ") + filepath, 4000, mRecordingButton.get(), 130);
|
|
||||||
#else
|
#else
|
||||||
filepath = m_lastRecordedFile.getRelativePathFrom(File::getSpecialLocation (File::userHomeDirectory));
|
filepath = m_lastRecordedFile.getRelativePathFrom(File::getSpecialLocation (File::userHomeDirectory));
|
||||||
#endif
|
#endif
|
||||||
|
showPopTip(TRANS("Finished recording to ") + filepath, 4000, m_recordingButton.get(), 130);
|
||||||
|
|
||||||
m_recordingButton->setTooltip(TRANS("Last recorded file: ") + filepath);
|
m_recordingButton->setTooltip(TRANS("Last recorded file: ") + filepath);
|
||||||
|
|
||||||
@ -1373,7 +1399,7 @@ void PaulstretchpluginAudioProcessorEditor::toggleOutputRecording()
|
|||||||
else {
|
else {
|
||||||
// show error starting record
|
// show error starting record
|
||||||
String lasterr = processor.getLastErrorMessage();
|
String lasterr = processor.getLastErrorMessage();
|
||||||
//showPopTip(lasterr, 0, mRecordingButton.get());
|
showPopTip(lasterr, 0, m_recordingButton.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fileRecordingLabel->setText("", dontSendNotification);
|
m_fileRecordingLabel->setText("", dontSendNotification);
|
||||||
|
@ -564,6 +564,9 @@ private:
|
|||||||
|
|
||||||
void toggleOutputRecording();
|
void toggleOutputRecording();
|
||||||
|
|
||||||
|
void showPopTip(const String & message, int timeoutMs, Component * target, int maxwidth=100);
|
||||||
|
|
||||||
|
|
||||||
CustomLookAndFeel m_lookandfeel;
|
CustomLookAndFeel m_lookandfeel;
|
||||||
|
|
||||||
PaulstretchpluginAudioProcessor& processor;
|
PaulstretchpluginAudioProcessor& processor;
|
||||||
@ -639,6 +642,10 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<CustomTooltipWindow> tooltipWindow;
|
std::unique_ptr<CustomTooltipWindow> tooltipWindow;
|
||||||
|
|
||||||
|
// keep this down here, so it gets destroyed early
|
||||||
|
std::unique_ptr<BubbleMessageComponent> popTip;
|
||||||
|
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -284,17 +284,22 @@ void RenderSettingsComponent::buttonClicked (Button* buttonThatWasClicked)
|
|||||||
else if (buttonThatWasClicked == &buttonSelectFile)
|
else if (buttonThatWasClicked == &buttonSelectFile)
|
||||||
{
|
{
|
||||||
File lastexportfolder; // File(g_propsfile->getValue("last_export_file")).getParentDirectory();
|
File lastexportfolder; // File(g_propsfile->getValue("last_export_file")).getParentDirectory();
|
||||||
|
Component * parent = nullptr;
|
||||||
|
#if JUCE_IOS
|
||||||
|
parent = JUCEApplication::isStandaloneApp() ? nullptr : getActiveEditor();
|
||||||
|
#endif
|
||||||
|
|
||||||
m_filechooser = std::make_unique<FileChooser>("Please select audio file to render...",
|
m_filechooser = std::make_unique<FileChooser>("Please select audio file to render...",
|
||||||
lastexportfolder,
|
lastexportfolder,
|
||||||
"*.wav");
|
"*.wav", true, false, parent);
|
||||||
m_filechooser->launchAsync(FileBrowserComponent::saveMode, [this](const FileChooser &chooser) {
|
m_filechooser->launchAsync(FileBrowserComponent::saveMode, [this](const FileChooser &chooser) {
|
||||||
String newpath = chooser.getResult().getFullPathName();
|
String newpath = chooser.getResult().getFullPathName();
|
||||||
#if JUCE_IOS
|
#if JUCE_IOS
|
||||||
// not actually used here, but just in case for later
|
|
||||||
newpath = chooser.getResult().getFileName();
|
newpath = chooser.getResult().getFileName();
|
||||||
#endif
|
#endif
|
||||||
|
if (newpath.isNotEmpty()) {
|
||||||
outfileNameEditor.setText(newpath, dontSendNotification);
|
outfileNameEditor.setText(newpath, dontSendNotification);
|
||||||
|
}
|
||||||
if (newpath.isNotEmpty() && pendingRender) {
|
if (newpath.isNotEmpty() && pendingRender) {
|
||||||
buttonClicked(&buttonRender);
|
buttonClicked(&buttonRender);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user