Various items before 1.5.1
- fixed passthrough when capturing - added declicking fades when bypassing input passthrough, playback, and recording - layout tweaks for extra small windows - waveform scrollbar improvements, visible edge drag handles, and allows dragging from anywhere - minor visual tweaks - license header mods, and LICENSE file consolidation
This commit is contained in:
parent
26bd7513b7
commit
c89c1558e3
@ -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
|
||||
|
15
LICENSE
15
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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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")
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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<double>(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<Drawable> 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<MyFileBrowserComponent>(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<double> rng, bool docallback)
|
||||
@ -2408,7 +2485,7 @@ void zoom_scrollbar::setRange(Range<double> 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
|
||||
|
@ -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<void(Range<double>)> 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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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<float>(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<AudioThumbnail>(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<StretchAudioSource>(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<float>& src, AudioBuffer<float>& dest, int destbufpos, int maxdestpos)
|
||||
static void copyAudioBufferWrappingPosition(const AudioBuffer<float>& src, int numSamples, AudioBuffer<float>& 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<recbuflenframes)
|
||||
m_recorded_range = { 0, m_rec_count };
|
||||
if (m_mute_while_capturing == true)
|
||||
buffer.clear();
|
||||
if (m_mute_while_capturing == true && passthruEnabled) {
|
||||
if (recfade < 0.0f) {
|
||||
buffer.applyGainRamp(0, buffer.getNumSamples(), 1.0f, 0.0f);
|
||||
}
|
||||
else if (recfade > 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<int>();
|
||||
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<double> currange{ *getFloatParameter(cpi_soundstart),*getFloatParameter(cpi_soundend) };
|
||||
|
||||
|
||||
// lets not lock
|
||||
//ScopedLock locker(m_cs);
|
||||
|
||||
m_stretch_source->setAudioFile(url);
|
||||
|
||||
//Range<double> 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;
|
||||
|
@ -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<StretchAudioSource> m_stretch_source;
|
||||
std::unique_ptr<MyBufferingAudioSource> m_buffering_source;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user