ios file handling updates. restore editor window size. double-click group order toggles enabled.

This commit is contained in:
essej 2022-04-11 18:50:55 -04:00
parent 2084782a79
commit 300c89d2b2
7 changed files with 181 additions and 17 deletions

View File

@ -81,7 +81,18 @@ public:
const String getApplicationName() override { return JucePlugin_Name; }
const String getApplicationVersion() override { return JucePlugin_VersionString; }
bool moreThanOneInstanceAllowed() override { return true; }
void anotherInstanceStarted (const String&) override {}
void anotherInstanceStarted (const String& cmdline) override {
DBG("Another instance started: " << cmdline);
}
void urlOpened(const URL& url) override {
DBG("URL opened: " << url.toString(false));
if (mainWindow.get() != nullptr)
mainWindow->pluginHolder->urlOpened(url);
}
CustomLookAndFeel sonoLNF;

View File

@ -423,6 +423,14 @@ public:
}
#endif
void urlOpened(const URL& url) {
if (urlOpenedCallback)
urlOpenedCallback(url);
}
std::function<void(const URL & url)> urlOpenedCallback;
static StandalonePluginHolder* getInstance();
//==============================================================================
@ -783,6 +791,10 @@ private:
if (auto * sonoeditor = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(editor.get())) {
sonoeditor->getAudioDeviceManager = [this]() { return &owner.getDeviceManager(); };
sonoeditor->showAudioSettingsDialog = [this](Component* calloutTarget, Component* calloutParent) { owner.pluginHolder->showAudioSettingsDialog(calloutTarget, calloutParent); };
owner.pluginHolder->urlOpenedCallback = [sonoeditor](const URL& url) {
sonoeditor->urlOpened(url);
};
}
editor->addComponentListener (this);

View File

@ -77,7 +77,11 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
addAndMakeVisible(&m_perfmeter);
addAndMakeVisible(&m_import_button);
m_import_button.setButtonText("Show browser");
#if JUCE_IOS
m_import_button.setButtonText("Load Audio...");
#else
m_import_button.setButtonText("Show browser");
#endif
m_import_button.onClick = [this]()
{
toggleFileBrowser();
@ -169,7 +173,13 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
m_stretchgroup = std::make_unique<ParameterGroupComponent>("", -1, &processor, false);
m_stretchgroup->setBackgroundColor(Colour(0xff332244));
m_stretchgroup->addParameterComponent(m_parcomps[cpi_stretchamount].get());
if (*processor.getBoolParameter(cpi_bypass_stretch)) {
m_stretchgroup->addParameterComponent(m_parcomps[cpi_dryplayrate].get());
removeChildComponent(m_parcomps[cpi_stretchamount].get());
} else {
m_stretchgroup->addParameterComponent(m_parcomps[cpi_stretchamount].get());
removeChildComponent(m_parcomps[cpi_dryplayrate].get());
}
m_stretchgroup->addParameterComponent(m_parcomps[cpi_fftsize].get());
addAndMakeVisible(m_stretchgroup.get());
@ -282,6 +292,15 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
m_spec_order_ed.ModuleSelectedCallback = [this](int id)
{
auto nowtime = Time::getMillisecondCounterHiRes() * 1e-3;
if (m_lastspec_select_group == id && nowtime < m_lastspec_select_time + 0.5) {
// double click toggles enabled
setSpectrumProcGroupEnabled(id, !isSpectrumProcGroupEnabled(id));
}
m_lastspec_select_group = id;
m_lastspec_select_time = nowtime;
if (id == FreeFilterGroup) {
if (isSpectrumProcGroupEnabled(id)) {
m_wavefilter_tab.setCurrentTabIndex(2);
@ -367,14 +386,18 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
//m_wavefilter_tab.addTab("Spectrum", Colours::white, &m_sonogram, false);
addAndMakeVisible(&m_wavefilter_tab);
setSize (1200, 320+14*25);
auto defbounds = processor.getLastPluginBounds();
setSize (defbounds.getWidth(), defbounds.getHeight());
startTimer(1, 100);
startTimer(2, 1000);
startTimer(3, 200);
m_wavecomponent.startTimer(100);
setResizeLimits(320, 570, 40000, 4000);
setResizeLimits(320, 430, 40000, 4000);
setResizable(true, !JUCEApplicationBase::isStandaloneApp());
@ -401,6 +424,19 @@ bool PaulstretchpluginAudioProcessorEditor::isSpectrumProcGroupEnabled(int group
return false;
}
void PaulstretchpluginAudioProcessorEditor::setSpectrumProcGroupEnabled(int groupid, bool enabled)
{
auto order = processor.getStretchSource()->getSpectrumProcessOrder();
for (int i=0; i < order.size(); ++i) {
if (order[i].m_index == groupid) {
*(order[i].m_enabled) = enabled; //->setValueNotifyingHost(enabled ? 1.0f : 0.0f);
return;
}
}
return;
}
void PaulstretchpluginAudioProcessorEditor::showRenderDialog()
{
@ -510,6 +546,10 @@ void PaulstretchpluginAudioProcessorEditor::resized()
minh = 40;
#endif
DBG("Resized: " << getWidth() << " " << getHeight());
processor.setLastPluginBounds(getLocalBounds());
FlexBox mainbox;
mainbox.flexDirection = FlexBox::Direction::column;
@ -653,6 +693,7 @@ void PaulstretchpluginAudioProcessorEditor::resized()
#if JUCE_IOS
tabminh = 234;
orderminh = 44;
#endif
int totminh = vpminh + orderminh + tabminh + topboxh + toggleh + volh + stretchH;
@ -798,9 +839,17 @@ void PaulstretchpluginAudioProcessorEditor::timerCallback(int id)
processor.m_free_filter_envelope->updateMinMaxValues();
m_free_filter_component.repaint();
m_spec_order_ed.repaint();
m_parcomps[cpi_dryplayrate]->setVisible(*processor.getBoolParameter(cpi_bypass_stretch));
m_parcomps[cpi_stretchamount]->setVisible(!(*processor.getBoolParameter(cpi_bypass_stretch)));
//if (m_wavefilter_tab.getCurrentTabIndex() != processor.m_cur_tab_index)
if (*processor.getBoolParameter(cpi_bypass_stretch)) {
m_stretchgroup->replaceParameterComponent(m_parcomps[cpi_stretchamount].get(), m_parcomps[cpi_dryplayrate].get());
} else {
m_stretchgroup->replaceParameterComponent(m_parcomps[cpi_dryplayrate].get(), m_parcomps[cpi_stretchamount].get());
}
//m_parcomps[cpi_dryplayrate]->setVisible(*processor.getBoolParameter(cpi_bypass_stretch));
//m_parcomps[cpi_stretchamount]->setVisible(!*processor.getBoolParameter(cpi_bypass_stretch));
//if (m_wavefilter_tab.getCurrentTabIndex() != processor.m_cur_tab_index)
// m_wavefilter_tab.setCurrentTabIndex(processor.m_cur_tab_index, false);
}
}
@ -827,6 +876,24 @@ void PaulstretchpluginAudioProcessorEditor::filesDropped(const StringArray & fil
}
}
void PaulstretchpluginAudioProcessorEditor::urlOpened(const URL& url)
{
DBG("Got URL: " << url.toString(false));
std::unique_ptr<InputStream> wi (url.createInputStream (false));
if (wi != nullptr)
{
File file = url.getLocalFile();
DBG("Attempting to load after input stream create: " << file.getFullPathName());
processor.setAudioFile(file);
} else {
File file = url.getLocalFile();
DBG("Attempting to load after no input stream create: " << file.getFullPathName());
processor.setAudioFile(file);
}
toFront(true);
}
bool PaulstretchpluginAudioProcessorEditor::keyPressed(const KeyPress & press)
{
std::function<bool(void)> action;
@ -901,7 +968,7 @@ void PaulstretchpluginAudioProcessorEditor::showAbout()
"GPL licensed source code for this plugin at : https://bitbucket.org/xenakios/paulstretchplugin/overview\n";
if (host.type != juce::PluginHostType::UnknownHost) {
text += "Running in : "+host.getHostDescription()+"\n";
text += String("Running in : ") + host.getHostDescription()+ String("\n");
}
content->setJustificationType(Justification::centred);
@ -927,17 +994,54 @@ void PaulstretchpluginAudioProcessorEditor::showAbout()
void PaulstretchpluginAudioProcessorEditor::toggleFileBrowser()
{
if (m_filechooser == nullptr)
#if JUCE_IOS
String curropendir = processor.m_propsfile->m_props_file->getValue("importfilefolder",
File::getSpecialLocation(File::userDocumentsDirectory).getFullPathName());
Component * parent = JUCEApplication::isStandaloneApp() ? nullptr : this;
fileChooser.reset(new FileChooser("Choose an audio file to open...",
curropendir,
"*.wav;*.mp3;*.m4a;*.aif;*.aiff;*.caf;*.ogg;*.flac",
true, false, parent));
fileChooser->launchAsync (FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles,
[this] (const FileChooser& chooser)
{
auto results = chooser.getURLResults();
if (results.size() > 0)
{
auto url = results.getReference (0);
std::unique_ptr<InputStream> wi (url.createInputStream (false));
if (wi != nullptr)
{
File file = url.getLocalFile();
DBG("Attempting to load from: " << file.getFullPathName());
//curropendir = file.getParentDirectory();
processor.setAudioFile(file);
processor.m_propsfile->m_props_file->setValue("importfilefolder", file.getParentDirectory().getFullPathName());
}
}
});
#else
if (m_filechooser == nullptr)
{
m_filechooser = std::make_unique<MyFileBrowserComponent>(processor);
addChildComponent(m_filechooser.get());
}
m_filechooser->setBounds(0, 26, getWidth()/2, getHeight() - 75);
m_filechooser->setBounds(0, m_import_button.getBottom(), getWidth()/2, getHeight() - 75);
m_filechooser->setVisible(!m_filechooser->isVisible());
if (m_filechooser->isVisible())
m_import_button.setButtonText("Hide browser");
else
m_import_button.setButtonText("Show browser");
#endif
}
WaveformComponent::WaveformComponent(AudioFormatManager* afm, AudioThumbnail* thumb, StretchAudioSource* sas)
@ -2035,6 +2139,21 @@ void ParameterGroupComponent::addParameterComponent(ParameterComponent * pcomp)
}
}
void ParameterGroupComponent::replaceParameterComponent(ParameterComponent * oldcomp, ParameterComponent * newcomp)
{
for (int i = 0; i < m_parcomps.size(); ++i)
{
if (m_parcomps[i] == oldcomp) {
removeChildComponent(oldcomp);
addAndMakeVisible(newcomp);
m_parcomps[i] = newcomp;
resized();
break;
}
}
}
int ParameterGroupComponent::doLayout(Rectangle<int> bounds)
{
int titlew = m_namelabel ? 100 : m_enableButton ? 40 : 0;
@ -2142,11 +2261,11 @@ MyFileBrowserComponent::MyFileBrowserComponent(PaulstretchpluginAudioProcessor &
String initiallocfn = m_proc.m_propsfile->m_props_file->getValue("importfilefolder",
File::getSpecialLocation(File::userHomeDirectory).getFullPathName());
File initialloc(initiallocfn);
m_fbcomp = std::make_unique<FileBrowserComponent>(1 | 4,
m_fbcomp = std::make_unique<FileBrowserComponent>(FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles,
initialloc, &m_filefilter, nullptr);
m_fbcomp->addListener(this);
addAndMakeVisible(m_fbcomp.get());
setLookAndFeel(&m_filebwlookandfeel);
//setLookAndFeel(&m_filebwlookandfeel);
}
MyFileBrowserComponent::~MyFileBrowserComponent()
@ -2161,7 +2280,7 @@ void MyFileBrowserComponent::resized()
void MyFileBrowserComponent::paint(Graphics & g)
{
g.fillAll(Colours::black.withAlpha(0.8f));
g.fillAll(Colours::black.withAlpha(0.9f));
}
void MyFileBrowserComponent::selectionChanged()

View File

@ -115,6 +115,7 @@ public:
//void addParameterComponent(std::unique_ptr<ParameterComponent> pcomp);
void addParameterComponent(ParameterComponent * pcomp);
void replaceParameterComponent(ParameterComponent * oldcomp, ParameterComponent * newcomp);
void updateParameterComponents();
@ -524,12 +525,15 @@ public:
//SimpleFFTComponent m_sonogram;
String m_last_err;
void urlOpened(const URL& url);
std::function<AudioDeviceManager*()> getAudioDeviceManager;
std::function<void(Component*,Component*)> showAudioSettingsDialog;
private:
bool isSpectrumProcGroupEnabled(int groupid);
void setSpectrumProcGroupEnabled(int groupid, bool enabled);
CustomLookAndFeel m_lookandfeel;
@ -551,6 +555,8 @@ private:
TextButton m_rewind_button;
Label m_info_label;
SpectralChainEditor m_spec_order_ed;
double m_lastspec_select_time = 0.0;
int m_lastspec_select_group = -1;
void showSettingsMenu();
@ -566,6 +572,7 @@ private:
std::vector<int> m_capturelens{ 2,5,10,30,60,120 };
std::unique_ptr<MyFileBrowserComponent> m_filechooser;
std::unique_ptr<FileChooser> fileChooser;
WildcardFileFilter m_filefilter;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessorEditor)

View File

@ -290,6 +290,10 @@ ValueTree PaulstretchpluginAudioProcessor::getStateTree(bool ignoreoptions, bool
storeToTreeProperties(paramtree, nullptr, "waveviewrange", m_wave_view_range);
ValueTree freefilterstate = m_free_filter_envelope->saveState(Identifier("freefilter_envelope"));
paramtree.addChild(freefilterstate, -1, nullptr);
storeToTreeProperties(paramtree, nullptr, "pluginwidth", mPluginWindowWidth);
storeToTreeProperties(paramtree, nullptr, "pluginheight", mPluginWindowHeight);
return paramtree;
}
@ -306,6 +310,9 @@ void PaulstretchpluginAudioProcessor::setStateFromTree(ValueTree tree)
"capturewhenhostrunning", m_capture_when_host_plays,"mutewhilecapturing",m_mute_while_capturing,
"savecapturedaudio",m_save_captured_audio, "muteprocwhilecapturing",m_mute_processed_while_capturing);
getFromTreeProperties(tree, "tabaindex", m_cur_tab_index);
getFromTreeProperties(tree, "pluginwidth", mPluginWindowWidth);
getFromTreeProperties(tree, "pluginheight", mPluginWindowHeight);
if (tree.hasProperty("numspectralstagesb"))
{
std::vector<SpectrumProcess> old_order = m_stretch_source->getSpectrumProcessOrder();

View File

@ -174,6 +174,7 @@ public:
void parameterValueChanged(int parameterIndex, float newValue) override;
void parameterGestureChanged(int parameterIndex, bool gestureIsStarting) override;
//==============================================================================
void getStateInformation (MemoryBlock& destData) override;
void setStateInformation (const void* data, int sizeInBytes) override;
@ -189,6 +190,10 @@ public:
{
return dynamic_cast<AudioParameterBool*>(getParameters()[index]);
}
void setLastPluginBounds(juce::Rectangle<int> bounds) { mPluginWindowWidth = bounds.getWidth(); mPluginWindowHeight = bounds.getHeight();}
juce::Rectangle<int> getLastPluginBounds() const { return juce::Rectangle<int>(0,0,mPluginWindowWidth, mPluginWindowHeight); }
void setDirty();
void setRecordingEnabled(bool b);
bool isRecordingEnabled() { return m_is_recording; }
@ -269,6 +274,8 @@ private:
double m_last_in_pos = 0.0;
std::vector<int> m_bufamounts{ 4096,8192,16384,32768,65536,262144 };
ProcessParameters m_ppar;
int mPluginWindowWidth = 870;
int mPluginWindowHeight = 770;
void setFFTSize(double size);
void startplay(Range<double> playrange, int numoutchans, int maxBlockSize, String& err);

View File

@ -69,7 +69,8 @@
microphonePermissionNeeded="1" iosBackgroundAudio="1" buildNumber="100"
iosScreenOrientation="UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight,UIInterfaceOrientationPortrait,UIInterfaceOrientationPortraitUpsideDown"
iPadScreenOrientation="UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight,UIInterfaceOrientationPortrait,UIInterfaceOrientationPortraitUpsideDown"
UIStatusBarHidden="0" UIRequiresFullScreen="0" customPList="&lt;plist version=&quot;1.0&quot;&gt;&#10;&lt;dict&gt;&#10;&#10;&#10;&lt;key&gt;ITSAppUsesNonExemptEncryption&lt;/key&gt;&#10;&#9;&lt;false/&gt;&#10;&#10;&lt;key&gt;UIStatusBarHidden&lt;/key&gt;&#10;&#9;&lt;false/&gt;&#10;&#9;&lt;key&gt;UIStatusBarStyle&lt;/key&gt;&#10;&#9;&lt;string&gt;UIStatusBarStyleLightContent&lt;/string&gt;&#10;&#10;&lt;key&gt;UIViewControllerBasedStatusBarAppearance&lt;/key&gt;&#10;&lt;false/&gt;&#10;&#10;&#10;&lt;key&gt;NSLocalNetworkUsageDescription&lt;/key&gt;&#10;&#9;&lt;string&gt;DrumJamPad uses networking to communicate with other local services&lt;/string&gt;&#10;&#10;&lt;/dict&gt;&#10;&lt;/plist&gt;">
UIStatusBarHidden="0" UIRequiresFullScreen="0" customPList="&lt;plist version=&quot;1.0&quot;&gt;&#10;&lt;dict&gt;&#10;&#10;&#10;&lt;key&gt;ITSAppUsesNonExemptEncryption&lt;/key&gt;&#10;&#9;&lt;false/&gt;&#10;&#10;&lt;key&gt;UIStatusBarHidden&lt;/key&gt;&#10;&#9;&lt;false/&gt;&#10;&#9;&lt;key&gt;UIStatusBarStyle&lt;/key&gt;&#10;&#9;&lt;string&gt;UIStatusBarStyleLightContent&lt;/string&gt;&#10;&#10;&lt;key&gt;UIViewControllerBasedStatusBarAppearance&lt;/key&gt;&#10;&lt;false/&gt;&#10;&#10;&#10;&lt;key&gt;NSLocalNetworkUsageDescription&lt;/key&gt;&#10;&#9;&lt;string&gt;DrumJamPad uses networking to communicate with other local services&lt;/string&gt;&#10;&#10;&lt;key&gt;CFBundleDocumentTypes&lt;/key&gt;&#10;&#9;&lt;array&gt;&#10;&#9;&#9;&lt;dict&gt;&#10;&#9;&#9;&#9;&lt;key&gt;CFBundleTypeIconFiles&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;array/&gt;&#10;&#9;&#9;&#9;&lt;key&gt;CFBundleTypeName&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;string&gt;Audio File&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;key&gt;CFBundleTypeRole&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;string&gt;Viewer&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;key&gt;LSHandlerRank&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;string&gt;Owner&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;key&gt;LSItemContentTypes&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;array&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;com.microsoft.waveform-audio&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;public.aiff-audio&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;com.apple.coreaudio-format&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;public.mpeg-4-audio&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;public.mp3&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;/array&gt;&#10;&#9;&#9;&lt;/dict&gt;&#10;&#9;&#9;&lt;/array&gt;&#10;&#10;&lt;/dict&gt;&#10;&lt;/plist&gt;"
UIFileSharingEnabled="1" UISupportsDocumentBrowser="1">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug" headerPath="Source/PS_Source&#10;Source/WDL&#10;${HOME}/iosstatic/include"
libraryPath="${HOME}/iosstatic/lib&#10;"/>