diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e06248..5a08736 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,9 +36,9 @@ endif() # `project()` command. `project()` sets up some helpful variables that describe source/binary # directories, and the current project version. This is a standard CMake command. -project(PaulXStretch VERSION 1.5.0) +project(PaulXStretch VERSION 1.5.1) -set(BUILDVERSION 107) +set(BUILDVERSION 108) # If you've installed JUCE somehow (via a package manager, or directly using the CMake install diff --git a/LICENSE b/LICENSE index f93cc48..ea73e79 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,18 @@ + +GPL Section 7 Exception +As a special exception to the terms and conditions of the +GNU General Public License Version 3 (the "GPL") shown below: + +As additional permission under section 7, you are allowed to distribute +the software through an app store, even if that store has restrictive +terms and conditions that are incompatible with the GPL, provided that +the source is also available under the GPL with or without this permission +through a channel without those restrictive terms and conditions. + +Paul Nasca, Xenakios and Jesse Chappell all explicitly permitted this +license exception clause. + + GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/LICENSE_EXCEPTION b/LICENSE_EXCEPTION deleted file mode 100644 index 1c34542..0000000 --- a/LICENSE_EXCEPTION +++ /dev/null @@ -1,11 +0,0 @@ - -GPL Section 7 Exception -As a special exception to the terms and conditions of the -GNU General Public License Version 3 (the "GPL"): - -As additional permission under section 7, you are allowed to distribute -the software through an app store, even if that store has restrictive -terms and conditions that are incompatible with the GPL, provided that -the source is also available under the GPL with or without this permission -through a channel without those restrictive terms and conditions. - diff --git a/README.md b/README.md index f349173..7826c80 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,8 @@ Copyright (C) 2006-2011 Nasca Octavian Paul, Tg. Mures, Romania # License and 3rd Party Software Released under GNU General Public License v.3 license with App Store license -exception. The full license text is in the LICENSE and LICENSE_EXCEPTION files. +exception. The full license text is in the LICENSE and LICENSE_EXCEPTION files. Paul Nasca, Xenakios and Jesse Chappell all explicitly permitted the license exception clause. + 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. @@ -89,6 +90,7 @@ My github forks of these that are referenced via `git-subrepo` in this repositor > 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. diff --git a/Source/CustomLookAndFeel.cpp b/Source/CustomLookAndFeel.cpp index d6cef14..3d2e8ac 100644 --- a/Source/CustomLookAndFeel.cpp +++ b/Source/CustomLookAndFeel.cpp @@ -63,6 +63,7 @@ CustomLookAndFeel::CustomLookAndFeel() setColour (Slider::rotarySliderFillColourId, Colour::fromFloatRGBA(0.5, 0.4, 0.6, 0.9)); setColour (TabbedButtonBar::tabOutlineColourId, Colour::fromFloatRGBA(0.3, 0.3, 0.3, 0.6)); + setColour (TabbedComponent::outlineColourId, Colour::fromFloatRGBA(0.2, 0.2, 0.2, 0.5)); @@ -662,7 +663,7 @@ void CustomLookAndFeel::drawFileBrowserRow (Graphics& g, int width, int height, g.setColour (fileListComp != nullptr ? fileListComp->findColour (DirectoryContentsDisplayComponent::textColourId) : findColour (DirectoryContentsDisplayComponent::textColourId)); - g.setFont (myFont.withHeight(height * 0.5f)); + g.setFont (myFont.withHeight(height * 0.6f)); if (width > 450 && ! isDirectory) { @@ -673,7 +674,7 @@ void CustomLookAndFeel::drawFileBrowserRow (Graphics& g, int width, int height, x, 0, sizeX - x, height, Justification::centredLeft, 1); - g.setFont (myFont.withHeight(height * 0.5f)); + g.setFont (myFont.withHeight(height * 0.6f)); g.setColour (Colours::darkgrey); if (! isDirectory) diff --git a/Source/CustomStandaloneFilterApp.cpp b/Source/CustomStandaloneFilterApp.cpp index 9955b8b..101ebb0 100644 --- a/Source/CustomStandaloneFilterApp.cpp +++ b/Source/CustomStandaloneFilterApp.cpp @@ -1,28 +1,4 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. - - JUCE is an open source library subject to commercial or open-source - licensing. - - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). - - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy - - Or: You may also use this code under the terms of the GPL v3 (see - www.gnu.org/licenses). - - JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER - EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE - DISCLAIMED. - - ============================================================================== -*/ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception #include "../JuceLibraryCode/JuceHeader.h" diff --git a/Source/CustomStandaloneFilterWindow.h b/Source/CustomStandaloneFilterWindow.h index 535c0ef..863e73f 100644 --- a/Source/CustomStandaloneFilterWindow.h +++ b/Source/CustomStandaloneFilterWindow.h @@ -1,28 +1,4 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. - - JUCE is an open source library subject to commercial or open-source - licensing. - - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). - - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy - - Or: You may also use this code under the terms of the GPL v3 (see - www.gnu.org/licenses). - - JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER - EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE - DISCLAIMED. - - ============================================================================== -*/ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception //#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client //extern juce::AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (juce::AudioProcessor::WrapperType type); @@ -271,11 +247,19 @@ public: updateMinAndMax ((int) defaultConfig.numOuts, minNumOutputs, maxNumOutputs); } - if (auto* bus = processor->getBus (true, 0)) + if (auto* bus = processor->getBus (true, 0)) { updateMinAndMax (bus->getDefaultLayout().size(), minNumInputs, maxNumInputs); + if (bus->isNumberOfChannelsSupported(1)) { + updateMinAndMax (1, minNumInputs, maxNumInputs); + } + } - if (auto* bus = processor->getBus (false, 0)) + if (auto* bus = processor->getBus (false, 0)) { updateMinAndMax (bus->getDefaultLayout().size(), minNumOutputs, maxNumOutputs); + if (bus->isNumberOfChannelsSupported(1)) { + updateMinAndMax (1, minNumOutputs, maxNumOutputs); + } + } minNumInputs = jmin (minNumInputs, maxNumInputs); minNumOutputs = jmin (minNumOutputs, maxNumOutputs); @@ -465,9 +449,9 @@ private: deviceSelector (deviceManagerToUse, minAudioInputChannels, maxAudioInputChannels, minAudioOutputChannels, maxAudioOutputChannels, - true, + true, // show midi (pluginHolder.processor.get() != nullptr && pluginHolder.processor->producesMidi()), - true, false), + false, false), shouldMuteLabel ("Feedback Loop:", "Feedback Loop:"), shouldMuteButton ("Mute audio input") { diff --git a/Source/PS_Source/Input/AInputS.h b/Source/PS_Source/Input/AInputS.h index 4d3067a..e56e5e9 100644 --- a/Source/PS_Source/Input/AInputS.h +++ b/Source/PS_Source/Input/AInputS.h @@ -1,20 +1,6 @@ -/* - Copyright (C) 2006-2011 Nasca Octavian Paul - Author: Nasca Octavian Paul - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2006-2011 Nasca Octavian Paul +// Author: Nasca Octavian Paul #pragma once diff --git a/Source/PS_Source/Input/InputS.h b/Source/PS_Source/Input/InputS.h index 9e486a3..c8c47af 100644 --- a/Source/PS_Source/Input/InputS.h +++ b/Source/PS_Source/Input/InputS.h @@ -1,20 +1,7 @@ -/* - Copyright (C) 2006-2011 Nasca Octavian Paul - Author: Nasca Octavian Paul +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2006-2011 Nasca Octavian Paul +// Author: Nasca Octavian Paul - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #pragma once diff --git a/Source/PS_Source/StretchSource.cpp b/Source/PS_Source/StretchSource.cpp index 56b7c8e..4107460 100644 --- a/Source/PS_Source/StretchSource.cpp +++ b/Source/PS_Source/StretchSource.cpp @@ -1,19 +1,6 @@ -/* - -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2022 Jesse Chappell #include "StretchSource.h" diff --git a/Source/PS_Source/StretchSource.h b/Source/PS_Source/StretchSource.h index 9044079..74f3c23 100644 --- a/Source/PS_Source/StretchSource.h +++ b/Source/PS_Source/StretchSource.h @@ -1,20 +1,6 @@ -/* - -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ - +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2022 Jesse Chappell #pragma once diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 7dd4586..2230830 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -1,20 +1,6 @@ -/* - -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ - +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell #include "PluginProcessor.h" #include "PluginEditor.h" @@ -84,7 +70,7 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau { return jmap(x, 0.0, 1.0, -48.0, 12.0); }; - int tabdepth = 24; + int tabdepth = 26; #if JUCE_IOS tabdepth = 36; @@ -209,6 +195,7 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau std::unique_ptr pauseimg(Drawable::createFromImageData(BinaryData::pause_icon_svg, BinaryData::pause_icon_svgSize)); pausebut->setImages(pauseimg.get(), nullptr, nullptr, nullptr, playimg.get()); pausebut->setColour(DrawableButton::backgroundColourId, Colour::fromFloatRGBA(0.1f, 0.5f, 0.1f, 0.55f)); + pausebut->setTooltip("Play / Pause"); } if (auto * loopbut = m_parcomps[cpi_looping_enabled]->getDrawableButton()) { @@ -469,7 +456,7 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau }; m_wave_container->addAndMakeVisible(&m_wavecomponent); - auto tabbgcol = Colour(0xff444444); + auto tabbgcol = Colour(0xff303030); m_wavefilter_tab.addTab("Waveform", tabbgcol, m_wave_container, true); m_wavefilter_tab.addTab("Ratio mixer", tabbgcol, &m_ratiomixeditor, false); @@ -873,9 +860,6 @@ void PaulstretchpluginAudioProcessorEditor::resized() mainbox.items.add(FlexItem(6, 2)); - mainbox.items.add(FlexItem(minw, topboxh, topbox).withMargin(margin).withFlex(0)); - - mainbox.items.add(FlexItem(minw, toggleh, togglesbox).withMargin(margin).withFlex(0)); auto reparentIfNecessary = [] (Component * comp, Component *newparent) { @@ -899,6 +883,7 @@ void PaulstretchpluginAudioProcessorEditor::resized() int totminh = vpminh + orderminh + tabminh + topboxh + toggleh + volh + stretchH + 18; int shortthresh = vpminh + orderminh + tabminh + topboxh + toggleh; + int veryshortthresh = tabminh + topboxh + toggleh; if (getHeight() < totminh) { // not enough vertical space, put the top items in the scrollable viewport @@ -916,19 +901,41 @@ void PaulstretchpluginAudioProcessorEditor::resized() if (getHeight() < shortthresh) { // really not much space, put group scroll in a new tab if (m_wavefilter_tab.getNumTabs() <= 3) { - m_wavefilter_tab.addTab("Controls", Colour(0xff555555), m_groupviewport.get(), false); + m_wavefilter_tab.addTab("Controls", Colour(0xff333333), m_groupviewport.get(), false); m_wavefilter_tab.setCurrentTabIndex(3); } + if (getHeight() < veryshortthresh) { + + reparentItemsIfNecessary(topbox, m_groupcontainer.get()); + reparentItemsIfNecessary(togglesbox, m_groupcontainer.get()); + + groupsbox.items.insert(0, FlexItem(minw, toggleh, togglesbox).withMargin(groupmargin).withFlex(0)); + groupsbox.items.insert(0, FlexItem(minw, topboxh, topbox).withMargin(groupmargin).withFlex(0)); + + useh += toggleh + topboxh + groupmargin*4; + } + else { + reparentItemsIfNecessary(topbox, this); + reparentItemsIfNecessary(togglesbox, this); + + mainbox.items.add(FlexItem(minw, topboxh, topbox).withMargin(margin).withFlex(0)); + mainbox.items.add(FlexItem(minw, toggleh, togglesbox).withMargin(margin).withFlex(0)); + + } + reparentIfNecessary(&m_spec_order_ed, m_groupcontainer.get()); groupsbox.items.add(FlexItem(minw, orderminh, m_spec_order_ed).withMargin(2)); + useh += orderminh + 4; m_shortMode = true; } else { reparentIfNecessary(&m_spec_order_ed, this); + reparentItemsIfNecessary(topbox, this); + reparentItemsIfNecessary(togglesbox, this); if (m_wavefilter_tab.getNumTabs() > 3) { // bring it back @@ -940,6 +947,10 @@ void PaulstretchpluginAudioProcessorEditor::resized() addAndMakeVisible(m_groupviewport.get()); } m_shortMode = false; + + mainbox.items.add(FlexItem(minw, topboxh, topbox).withMargin(margin).withFlex(0)); + mainbox.items.add(FlexItem(minw, toggleh, togglesbox).withMargin(margin).withFlex(0)); + } @@ -960,11 +971,13 @@ void PaulstretchpluginAudioProcessorEditor::resized() reparentIfNecessary(m_groupviewport.get(), this); reparentIfNecessary(&m_spec_order_ed, this); reparentIfNecessary(m_stretchgroup.get(), this); - //reparentItemsIfNecessary(togglesbox, this); reparentItemsIfNecessary(volbox, this); + reparentItemsIfNecessary(topbox, this); + reparentItemsIfNecessary(togglesbox, this); + mainbox.items.add(FlexItem(minw, topboxh, topbox).withMargin(margin).withFlex(0)); + mainbox.items.add(FlexItem(minw, toggleh, togglesbox).withMargin(margin).withFlex(0)); - //mainbox.items.add(FlexItem(minw, toggleh, togglesbox).withMargin(margin).withFlex(0)); mainbox.items.add(FlexItem(minw, volh, volbox).withMargin(margin).withFlex(0)); mainbox.items.add(FlexItem(6, 3)); mainbox.items.add(FlexItem(minw, stretchH, *m_stretchgroup).withMargin(margin).withFlex(0)); @@ -1016,6 +1029,12 @@ void PaulstretchpluginAudioProcessorEditor::resized() m_zs.setBounds(m_wave_container->getX(), m_wavecomponent.getBottom(), m_wave_container->getWidth(), zscrollh); //m_wavecomponent.setBounds(1, m_spec_order_ed.getBottom()+1, getWidth()-2, remain_h/5*4); + if (m_filechooser && m_filechooser->isVisible()) { + auto importbounds = getLocalArea(nullptr, m_import_button.getScreenBounds()); + m_filechooser->setBounds(0, importbounds.getBottom(), getWidth()/2, getHeight() - 75); + m_filechooser->toFront(false); + } + if (m_shortMode) { m_groupcontainer->repaint(); } @@ -1317,7 +1336,8 @@ void PaulstretchpluginAudioProcessorEditor::toggleFileBrowser() m_filechooser = std::make_unique(processor); addChildComponent(m_filechooser.get()); } - m_filechooser->setBounds(0, m_import_button.getBottom(), getWidth()/2, getHeight() - 75); + auto bounds = getLocalArea(nullptr, m_import_button.getScreenBounds()); + m_filechooser->setBounds(0, bounds.getBottom(), getWidth()/2, getHeight() - 75); m_filechooser->setVisible(!m_filechooser->isVisible()); if (m_filechooser->isVisible()) m_import_button.setButtonText("Hide browser"); @@ -1667,6 +1687,14 @@ void WaveformComponent::mouseWheelMove(const MouseEvent & e, const MouseWheelDet double t0 = normt - newScale * xratio; double t1 = normt + newScale * (1.0 - xratio); + if (abs(wd.deltaX) > 0.0) { + auto deltax = 0.15f * wd.deltaX; + double old_len = t1 - t0; + t0 = (jlimit(0.0, 1.0 - old_len, t0 + deltax)); + t1 = (jlimit(old_len, t0 + old_len, t1 + deltax)); + } + + t0 = jlimit(0.0,1.0, t0); t1 = jlimit(0.0,1.0, t1); @@ -2310,7 +2338,17 @@ void PerfMeterComponent::timerCallback() void zoom_scrollbar::mouseDown(const MouseEvent &e) { + auto ha = get_hot_area(e.x, e.y); m_drag_start_x = e.x; + + m_handle_off_x = 0; + + if (ha == ha_left_edge) { + m_handle_off_x = e.x - m_therange.getStart() * getWidth(); + } + else if (ha == ha_right_edge) { + m_handle_off_x = e.x - m_therange.getEnd() * getWidth(); + } } void zoom_scrollbar::mouseDoubleClick (const MouseEvent&) @@ -2341,21 +2379,19 @@ void zoom_scrollbar::mouseMove(const MouseEvent &e) void zoom_scrollbar::mouseDrag(const MouseEvent &e) { - if (m_hot_area == ha_none) - return; if (m_hot_area == ha_left_edge) { - double new_left_edge = 1.0 / getWidth()*e.x; + double new_left_edge = 1.0 / getWidth()*(e.x - m_handle_off_x); m_therange.setStart(jlimit(0.0, m_therange.getEnd() - 0.01, new_left_edge)); repaint(); } - if (m_hot_area == ha_right_edge) + else if (m_hot_area == ha_right_edge) { - double new_right_edge = 1.0 / getWidth()*e.x; + double new_right_edge = 1.0 / getWidth()*(e.x - m_handle_off_x); m_therange.setEnd(jlimit(m_therange.getStart() + 0.01, 1.0, new_right_edge)); repaint(); } - if (m_hot_area == ha_handle) + else if (m_hot_area == ha_handle || m_hot_area == ha_none) { double delta = 1.0 / getWidth()*(e.x - m_drag_start_x); //double old_start = m_start; @@ -2370,6 +2406,21 @@ void zoom_scrollbar::mouseDrag(const MouseEvent &e) RangeChanged(m_therange); } +void zoom_scrollbar::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wd) +{ + float delta = -0.1f * wd.deltaY; + + double old_len = m_therange.getLength(); + m_therange.setStart(jlimit(0.0, 1.0 - old_len, m_therange.getStart() + delta)); + m_therange.setEnd(jlimit(old_len, m_therange.getStart() + old_len, m_therange.getEnd() + delta)); + + repaint(); + + if (RangeChanged) + RangeChanged(m_therange); +} + + void zoom_scrollbar::mouseEnter(const MouseEvent & event) { m_hot_area = get_hot_area(event.x, event.y); @@ -2384,16 +2435,42 @@ void zoom_scrollbar::mouseExit(const MouseEvent &) void zoom_scrollbar::paint(Graphics &g) { - g.setColour(Colours::darkgrey); + int radius = 16; +#if JUCE_IOS + radius *= 2; +#endif + + Colour basecolor = Colours::darkgrey; + g.setColour(basecolor); + + Colour barcolor = Colours::grey; + g.fillRect(0, 0, getWidth(), getHeight()); int x0 = (int)(getWidth()*m_therange.getStart()); int x1 = (int)(getWidth()*m_therange.getEnd()); - if (m_hot_area != ha_none) - g.setColour(Colours::white.withAlpha(0.8f)); - else g.setColour(Colours::grey); - //g.fillRect(x0, 0, x1 - x0, getHeight()); + if (m_hot_area == ha_handle) + barcolor = barcolor.brighter(0.5f); //Colours::white.withAlpha(0.8f); + + g.setColour(barcolor); + + //g.fillRect(x0, 0, x1 - x0, getHeight()); g.fillRoundedRectangle(x0, 0, x1 - x0, getHeight(), 8.0f); + // edge handles + + Colour handlecol = barcolor.brighter(); + if (m_hot_area == ha_left_edge) + g.setColour(handlecol.brighter()); + else g.setColour(handlecol); + + g.fillRoundedRectangle(x0, 0, radius, getHeight(), 8.0f); + + if (m_hot_area == ha_right_edge) + g.setColour(handlecol.brighter()); + else g.setColour(handlecol); + + g.fillRoundedRectangle(x1 - radius, 0, radius, getHeight(), 8.0f); + } void zoom_scrollbar::setRange(Range rng, bool docallback) @@ -2408,7 +2485,7 @@ void zoom_scrollbar::setRange(Range rng, bool docallback) zoom_scrollbar::hot_area zoom_scrollbar::get_hot_area(int x, int) { - int radius = 10; + int radius = 16; #if JUCE_IOS radius *= 2; #endif diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 94993d8..fdc51eb 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -1,19 +1,6 @@ -/* - -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell #pragma once @@ -41,6 +28,7 @@ public: void mouseEnter(const MouseEvent &event) override; void mouseExit(const MouseEvent &event) override; void mouseDoubleClick (const MouseEvent&) override; + void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wd) override; void paint(Graphics &g) override; std::function)> RangeChanged; @@ -52,6 +40,7 @@ private: hot_area m_hot_area = ha_none; hot_area get_hot_area(int x, int y); int m_drag_start_x = 0; + int m_handle_off_x = 0; }; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 9a2e58b..2ffc284 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -1,19 +1,7 @@ -/* +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ #include "PluginProcessor.h" #include "PluginEditor.h" @@ -61,11 +49,19 @@ inline AudioParameterFloat* make_floatpar(String id, String name, float minv, fl return new AudioParameterFloat(id, name, NormalisableRange(minv, maxv, step, skew), defv); } +#if JUCE_IOS +#define ALTBUS_ACTIVE true +#else +#define ALTBUS_ACTIVE false +#endif + //============================================================================== PaulstretchpluginAudioProcessor::PaulstretchpluginAudioProcessor(bool is_stand_alone_offline) - : AudioProcessor(PaulstretchpluginAudioProcessor::BusesProperties().withInput("Main In", AudioChannelSet::stereo(), true).withOutput ("Main Out", AudioChannelSet::stereo(), true)), + : AudioProcessor(PaulstretchpluginAudioProcessor::BusesProperties().withInput("Main In", AudioChannelSet::stereo(), true).withOutput ("Main Out", AudioChannelSet::stereo(), true).withInput ("Aux 1 In", AudioChannelSet::stereo(), ALTBUS_ACTIVE).withInput ("Aux 2 In", AudioChannelSet::stereo(), ALTBUS_ACTIVE).withInput ("Aux 3 In", AudioChannelSet::stereo(), ALTBUS_ACTIVE).withOutput ("Aux 1 Out", AudioChannelSet::stereo(), ALTBUS_ACTIVE).withOutput ("Aux 2 Out", AudioChannelSet::stereo(), ALTBUS_ACTIVE).withOutput ("Aux 3 Out", AudioChannelSet::stereo(), ALTBUS_ACTIVE)), m_bufferingthread("pspluginprebufferthread"), m_is_stand_alone_offline(is_stand_alone_offline) { + DBG("Attempt proc const"); + m_filechoose_callback = [this](const FileChooser& chooser) { URL resu = chooser.getURLResult(); @@ -91,13 +87,18 @@ m_bufferingthread("pspluginprebufferthread"), m_is_stand_alone_offline(is_stand_ m_free_filter_envelope->AddNode({ 0.0,0.75 }); m_free_filter_envelope->AddNode({ 1.0,0.75 }); m_free_filter_envelope->set_reset_nodes(m_free_filter_envelope->get_all_nodes()); + + DBG("recbuffer"); + m_recbuffer.setSize(2, 48000); m_recbuffer.clear(); if (m_afm->getNumKnownFormats()==0) m_afm->registerBasicFormats(); if (m_is_stand_alone_offline == false) m_thumb = std::make_unique(512, *m_afm, *m_thumbcache); - + + DBG("making bool pars"); + m_sm_enab_pars[0] = new AudioParameterBool("enab_specmodule0", "Enable harmonics", false); m_sm_enab_pars[1] = new AudioParameterBool("enab_specmodule1", "Enable tonal vs noise", false); m_sm_enab_pars[2] = new AudioParameterBool("enab_specmodule2", "Enable frequency shift", true); @@ -108,12 +109,17 @@ m_bufferingthread("pspluginprebufferthread"), m_is_stand_alone_offline(is_stand_ m_sm_enab_pars[7] = new AudioParameterBool("enab_specmodule7", "Enable free filter", true); m_sm_enab_pars[8] = new AudioParameterBool("enab_specmodule8", "Enable compressor", false); + DBG("making stretch source"); m_stretch_source = std::make_unique(2, m_afm,m_sm_enab_pars); m_stretch_source->setOnsetDetection(0.0); m_stretch_source->setLoopingEnabled(true); m_stretch_source->setFFTWindowingType(1); + + DBG("About to add parameters"); + + addParameter(make_floatpar("mainvolume0", "Main volume", -24.0, 12.0, -3.0, 0.1, 1.0)); addParameter(make_floatpar("stretchamount0", "Stretch amount", 0.1, 1024.0, 2.0, 0.1, 0.25)); addParameter(make_floatpar("fftsize0", "FFT size", 0.0, 1.0, 0.7, 0.01, 1.0)); @@ -216,11 +222,12 @@ m_bufferingthread("pspluginprebufferthread"), m_is_stand_alone_offline(is_stand_ if (!m_is_stand_alone_offline) { setPreBufferAmount(2); - startTimer(1, 50); + startTimer(1, 40); } m_show_technical_info = m_propsfile->m_props_file->getBoolValue("showtechnicalinfo", false); - + + DBG("Constructed PS plugin"); } PaulstretchpluginAudioProcessor::~PaulstretchpluginAudioProcessor() @@ -764,7 +771,7 @@ void PaulstretchpluginAudioProcessor::prepareToPlay(double sampleRate, int sampl m_adsr.setSampleRate(sampleRate); m_cur_sr = sampleRate; m_curmaxblocksize = samplesPerBlock; - m_input_buffer.setSize(getMainBusNumInputChannels(), samplesPerBlock); + m_input_buffer.setSize(getTotalNumInputChannels(), samplesPerBlock); *getBoolParameter(cpi_rewind) = false; m_lastrewind = false; int numoutchans = *m_outchansparam; @@ -794,6 +801,8 @@ void PaulstretchpluginAudioProcessor::prepareToPlay(double sampleRate, int sampl { m_buffering_source->prepareToPlay(samplesPerBlock, getSampleRateChecked()); } + + m_standalone = juce::PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone; } void PaulstretchpluginAudioProcessor::releaseResources() @@ -808,10 +817,14 @@ bool PaulstretchpluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& ignoreUnused (layouts); return true; #else + + // support anything + return true; + // This is the place where you check if the layout is supported. // In this template code we only support mono or stereo. - if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono() - && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo()) + if ( /* layouts.getMainOutputChannelSet() != AudioChannelSet::mono() && */ + layouts.getMainOutputChannelSet() != AudioChannelSet::stereo()) return false; // This checks if the input layout matches the output layout @@ -825,21 +838,42 @@ bool PaulstretchpluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& } #endif -void copyAudioBufferWrappingPosition(const AudioBuffer& src, AudioBuffer& dest, int destbufpos, int maxdestpos) +static void copyAudioBufferWrappingPosition(const AudioBuffer& src, int numSamples, AudioBuffer& dest, int destbufpos, int maxdestpos, float fademode) { + int useNumSamples = jmin(numSamples, src.getNumSamples()); + for (int i = 0; i < dest.getNumChannels(); ++i) { int channel_to_copy = i % src.getNumChannels(); - if (destbufpos + src.getNumSamples() > maxdestpos) + if (destbufpos + useNumSamples > maxdestpos) { - int wrappos = (destbufpos + src.getNumSamples()) % maxdestpos; - int partial_len = src.getNumSamples() - wrappos; - dest.copyFrom(channel_to_copy, destbufpos, src, channel_to_copy, 0, partial_len); - dest.copyFrom(channel_to_copy, partial_len, src, channel_to_copy, 0, wrappos); + int wrappos = (destbufpos + useNumSamples) % maxdestpos; + int partial_len = useNumSamples - wrappos; + + if (fademode == 0.0f) { + dest.copyFrom(i, destbufpos, src, channel_to_copy, 0, partial_len); + dest.copyFrom(i, partial_len, src, channel_to_copy, 0, wrappos); + } else { + //DBG("recfade wrap: " << fademode); + if (fademode > 0.0f) { + // fade in + dest.copyFromWithRamp(i, destbufpos, src.getReadPointer(channel_to_copy), partial_len, fademode > 0.0f ? 0.0f : 1.0f, fademode > 0.0f ? 1.0f : 0.0f); + dest.copyFrom(i, partial_len, src, channel_to_copy, 0, wrappos); + } else { + // fade out + dest.copyFrom(i, destbufpos, src, channel_to_copy, 0, partial_len); + dest.copyFromWithRamp(i, partial_len, src.getReadPointer(channel_to_copy), wrappos, fademode > 0.0f ? 0.0f : 1.0f, fademode > 0.0f ? 1.0f : 0.0f); + } + } } else { - dest.copyFrom(channel_to_copy, destbufpos, src, channel_to_copy, 0, src.getNumSamples()); + if (fademode == 0.0f) { + dest.copyFrom(i, destbufpos, src, channel_to_copy, 0, useNumSamples); + } else { + //DBG("recfade: " << fademode); + dest.copyFromWithRamp(i, destbufpos, src.getReadPointer(channel_to_copy), useNumSamples, fademode > 0.0f ? 0.0f : 1.0f, fademode > 0.0f ? 1.0f : 0.0f); + } } } } @@ -856,44 +890,110 @@ void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, M ScopedLock locker(m_cs); const int totalNumInputChannels = getTotalNumInputChannels(); const int totalNumOutputChannels = getTotalNumOutputChannels(); - AudioPlayHead* phead = getPlayHead(); + bool passthruEnabled = getParameter(cpi_passthrough) > 0.5f; + + AudioPlayHead* phead = getPlayHead(); + bool seektostart = false; if (phead != nullptr) { phead->getCurrentPosition(m_playposinfo); + + if (m_playposinfo.isPlaying && m_playposinfo.ppqPosition == 0.0 || m_playposinfo.timeInSamples == 0) { + seektostart = true; + } } - else + else { m_playposinfo.isPlaying = false; + } + ScopedNoDenormals noDenormals; double srtemp = getSampleRate(); if (srtemp != m_cur_sr) m_cur_sr = srtemp; m_prebufsmoother.setSlope(0.9, srtemp / buffer.getNumSamples()); m_smoothed_prebuffer_ready = m_prebufsmoother.process(m_buffering_source->getPercentReady()); - + + if (buffer.getNumSamples() > m_input_buffer.getNumSamples()) { + // just in case + m_input_buffer.setSize(totalNumInputChannels, buffer.getNumSamples(), false, false, true); + } + + for (int i = 0; i < totalNumInputChannels; ++i) m_input_buffer.copyFrom(i, 0, buffer, i, 0, buffer.getNumSamples()); for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i) buffer.clear (i, 0, buffer.getNumSamples()); + + float fadepassthru = 0.0f; + if (!passthruEnabled) { + if (m_lastpassthru != passthruEnabled) { + // ramp it down + fadepassthru = -1.0f; + for (int i = 0; i < totalNumInputChannels; ++i) + buffer.applyGainRamp(i, 0, buffer.getNumSamples(), 1.0f, 0.0f); + } + else { + for (int i = 0; i < totalNumInputChannels; ++i) + buffer.clear (i, 0, buffer.getNumSamples()); + } + } + else if (passthruEnabled != m_lastpassthru) { + // ramp it up + fadepassthru = 1.0f; + for (int i = 0; i < totalNumInputChannels; ++i) + buffer.applyGainRamp(i, 0, buffer.getNumSamples(), 0.0f, 1.0f); + } + + m_lastpassthru = passthruEnabled; + + float recfade = 0.0f; + if (m_is_recording != m_is_recording_pending) { + recfade = m_is_recording_pending ? 1.0f : -1.0f; + m_is_recording = m_is_recording_pending; + } + + if (m_previewcomponent != nullptr) { m_previewcomponent->processBlock(getSampleRate(), buffer); return; } - if (m_prebuffering_inited == false) + + if (m_prebuffering_inited == false) return; - if (m_is_recording == true) + + if (m_is_recording == true || recfade != 0.0f) { - if (m_playposinfo.isPlaying == false && m_capture_when_host_plays == true) + if (m_playposinfo.isPlaying == false && m_capture_when_host_plays == true && !m_standalone) { + if (!m_is_recording) + m_is_recording_finished = true; return; + } + int recbuflenframes = m_max_reclen * getSampleRate(); - copyAudioBufferWrappingPosition(buffer, m_recbuffer, m_rec_pos, recbuflenframes); - m_thumb->addBlock(m_rec_pos, buffer, 0, buffer.getNumSamples()); + copyAudioBufferWrappingPosition(m_input_buffer, buffer.getNumSamples(), m_recbuffer, m_rec_pos, recbuflenframes, recfade); + m_thumb->addBlock(m_rec_pos, m_input_buffer, 0, buffer.getNumSamples()); m_rec_pos = (m_rec_pos + buffer.getNumSamples()) % recbuflenframes; m_rec_count += buffer.getNumSamples(); + + if (!m_is_recording) { + // to signal that it may be written, etc + m_is_recording_finished = true; + } + if (m_rec_count 0.0f) { + buffer.applyGainRamp(0, buffer.getNumSamples(), 0.0f, 1.0f); + } + else { + buffer.clear(); + } + } if (m_mute_processed_while_capturing == true) return; @@ -904,17 +1004,30 @@ void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, M double t1 = *getFloatParameter(cpi_soundend); sanitizeTimeRange(t0, t1); m_stretch_source->setPlayRange({ t0,t1 }); + + float fadeproc = 0.0f; + if (m_last_host_playing == false && m_playposinfo.isPlaying) { - m_stretch_source->seekPercent(*getFloatParameter(cpi_soundstart)); + if (m_play_when_host_plays) { + // should we even do this ever? + if (seektostart) + m_stretch_source->seekPercent(*getFloatParameter(cpi_soundstart)); + fadeproc = 1.0f; // fadein + } m_last_host_playing = true; } else if (m_last_host_playing == true && m_playposinfo.isPlaying == false) { m_last_host_playing = false; + if (m_play_when_host_plays) { + fadeproc = -1.0f; // fadeout + } } - if (m_play_when_host_plays == true && m_playposinfo.isPlaying == false) + + if (m_play_when_host_plays == true && m_playposinfo.isPlaying == false && !m_standalone && fadeproc == 0.0f) return; + m_free_filter_envelope->m_transform_x_shift = *getFloatParameter(cpi_freefilter_shiftx); m_free_filter_envelope->m_transform_y_shift = *getFloatParameter(cpi_freefilter_shifty); m_free_filter_envelope->m_transform_y_scale = *getFloatParameter(cpi_freefilter_scaley); @@ -995,13 +1108,31 @@ void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, M { m_buffering_source->getNextAudioBlock(aif); } - if ( getParameter(cpi_passthrough) > 0.5f) + + // fade processing if necessary + if (fadeproc != 0.0f) { + buffer.applyGainRamp(0, buffer.getNumSamples(), fadeproc > 0.0f ? 0.0f : 1.0f, fadeproc > 0.0f ? 1.0f : 0.0f); + } + + if (fadepassthru != 0.0f + || (passthruEnabled && (!m_is_recording || !m_mute_while_capturing)) + || (recfade != 0.0f && m_mute_while_capturing)) { + if (recfade != 0.0f && m_mute_while_capturing) { + // DBG("Invert recfade"); + fadepassthru = -recfade; + } + for (int i = 0; i < totalNumInputChannels; ++i) { - buffer.addFrom(i, 0, m_input_buffer, i, 0, buffer.getNumSamples()); + if (fadepassthru != 0.0f) { + buffer.addFromWithRamp(i, 0, m_input_buffer.getReadPointer(i), buffer.getNumSamples(), fadepassthru > 0.0f ? 0.0f : 1.0f, fadepassthru > 0.0f ? 1.0f : 0.0f); + } + else + buffer.addFrom(i, 0, m_input_buffer, i, 0, buffer.getNumSamples()); } - } + } + bool abnordetected = false; for (int i = 0; i < buffer.getNumChannels(); ++i) { @@ -1078,22 +1209,23 @@ void PaulstretchpluginAudioProcessor::setRecordingEnabled(bool b) m_recbuffer.clear(); m_rec_pos = 0; m_thumb->reset(m_recbuffer.getNumChannels(), getSampleRateChecked(), lenbufframes); - m_is_recording = true; m_recorded_range = Range(); m_rec_count = 0; + m_is_recording_pending = true; } else { - if (m_is_recording == true) - { - finishRecording(lenbufframes); - } + if (m_is_recording == true) { + + m_is_recording_finished = false; // will be marked true when the recording is truly done + m_is_recording_pending = false; + } } } double PaulstretchpluginAudioProcessor::getRecordingPositionPercent() { - if (m_is_recording==false) + if (m_is_recording_pending==false) return 0.0; return 1.0 / m_recbuffer.getNumSamples()*m_rec_pos; } @@ -1117,9 +1249,14 @@ String PaulstretchpluginAudioProcessor::setAudioFile(const URL & url) } if (m_thumb) m_thumb->setSource(new FileInputSource(file)); - ScopedLock locker(m_cs); - m_stretch_source->setAudioFile(url); - //Range currange{ *getFloatParameter(cpi_soundstart),*getFloatParameter(cpi_soundend) }; + + + // lets not lock + //ScopedLock locker(m_cs); + + m_stretch_source->setAudioFile(url); + + //Range currange{ *getFloatParameter(cpi_soundstart),*getFloatParameter(cpi_soundend) }; //if (currange.contains(m_stretch_source->getInfilePositionPercent())==false) m_stretch_source->seekPercent(*getFloatParameter(cpi_soundstart)); m_current_file = url; @@ -1160,16 +1297,25 @@ void PaulstretchpluginAudioProcessor::timerCallback(int id) m_max_reclen = *getFloatParameter(cpi_max_capture_len); //Logger::writeToLog("Changing max capture len to " + String(m_max_reclen)); } - if (capture == true && m_is_recording == false) + if (capture == true && m_is_recording_pending == false) { setRecordingEnabled(true); return; } - if (capture == false && m_is_recording == true) + if (capture == false && m_is_recording_pending == true) { setRecordingEnabled(false); return; } + + if (m_is_recording_finished) { + DBG("Recording is actually done, commit the finish"); + int lenbufframes = getSampleRateChecked()*m_max_reclen; + finishRecording(lenbufframes); + m_is_recording_finished = false; + } + + if (m_cur_num_out_chans != *m_outchansparam) { jassert(m_curmaxblocksize > 0); @@ -1224,7 +1370,8 @@ pointer_sized_int PaulstretchpluginAudioProcessor::handleVstManufacturerSpecific void PaulstretchpluginAudioProcessor::finishRecording(int lenrecording) { - m_is_recording = false; + m_is_recording_finished = false; + m_is_recording_pending = false; m_current_file = URL(); m_stretch_source->setAudioBufferAsInputSource(&m_recbuffer, getSampleRateChecked(), lenrecording); *getFloatParameter(cpi_soundstart) = 0.0f; diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index f456082..094762d 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -1,19 +1,6 @@ -/* - -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell #pragma once @@ -198,7 +185,7 @@ public: void setDirty(); void setRecordingEnabled(bool b); - bool isRecordingEnabled() { return m_is_recording; } + bool isRecordingEnabled() { return m_is_recording_pending; } double getRecordingPositionPercent(); String setAudioFile(const URL& url); URL getAudioFile() { return m_current_file; } @@ -217,6 +204,8 @@ public: bool m_mute_processed_while_capturing = false; bool m_use_backgroundbuffering = true; bool m_restore_playstate = true; + bool m_lastpassthru = false; + bool m_standalone = false; void resetParameters(); void setPreBufferAmount(int x); @@ -268,6 +257,8 @@ private: URL m_current_file; Time m_current_file_date; bool m_is_recording = false; + volatile bool m_is_recording_pending = false; + volatile bool m_is_recording_finished = false; TimeSliceThread m_bufferingthread; std::unique_ptr m_stretch_source; std::unique_ptr m_buffering_source; diff --git a/Source/RenderSettingsComponent.cpp b/Source/RenderSettingsComponent.cpp index fb3054e..61e2c6d 100644 --- a/Source/RenderSettingsComponent.cpp +++ b/Source/RenderSettingsComponent.cpp @@ -1,19 +1,7 @@ -/* +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ #include "PluginProcessor.h" diff --git a/Source/RenderSettingsComponent.h b/Source/RenderSettingsComponent.h index b44c79c..790b0e7 100644 --- a/Source/RenderSettingsComponent.h +++ b/Source/RenderSettingsComponent.h @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell + #pragma once -/* -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 2 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 2) for more details. - -You should have received a copy of the GNU General Public License (version 2) -along with this program; if not, write to the Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - #include "../JuceLibraryCode/JuceHeader.h" class PaulstretchpluginAudioProcessor; diff --git a/Source/envelope_component.cpp b/Source/envelope_component.cpp index bba6a0c..c3cd0cd 100644 --- a/Source/envelope_component.cpp +++ b/Source/envelope_component.cpp @@ -1,19 +1,7 @@ -/* +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ #include "envelope_component.h" diff --git a/Source/envelope_component.h b/Source/envelope_component.h index bcb3b57..427ffcb 100644 --- a/Source/envelope_component.h +++ b/Source/envelope_component.h @@ -1,19 +1,7 @@ -/* +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ #pragma once diff --git a/Source/jcdp_envelope.h b/Source/jcdp_envelope.h index 36bdb02..bfebfe6 100644 --- a/Source/jcdp_envelope.h +++ b/Source/jcdp_envelope.h @@ -1,19 +1,7 @@ -/* +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ #pragma once diff --git a/Source/ps3_BufferingAudioSource.cpp b/Source/ps3_BufferingAudioSource.cpp index c457b1c..3b8e497 100644 --- a/Source/ps3_BufferingAudioSource.cpp +++ b/Source/ps3_BufferingAudioSource.cpp @@ -1,19 +1,6 @@ -/* - -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell #include "ps3_BufferingAudioSource.h" diff --git a/Source/ps3_BufferingAudioSource.h b/Source/ps3_BufferingAudioSource.h index 472d502..b4c9bf3 100644 --- a/Source/ps3_BufferingAudioSource.h +++ b/Source/ps3_BufferingAudioSource.h @@ -1,19 +1,7 @@ -/* +// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception +// Copyright (C) 2017 Xenakios +// Copyright (C) 2020 Jesse Chappell -Copyright (C) 2017 Xenakios - -This program is free software; you can redistribute it and/or modify -it under the terms of version 3 of the GNU General Public License -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License (version 3) for more details. - -www.gnu.org/licenses - -*/ #pragma once