kopia lustrzana https://github.com/jameshball/osci-render
Fix several bugs, add audio player at bottom for sosci
rodzic
ed027bbfc4
commit
dd3d051793
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M10,16.5L16,12L10,7.5V16.5Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 273 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6,5.75L10.25,10H7V16H13.5L15.5,18H7A2,2 0 0,1 5,16V10H1.75L6,5.75M18,18.25L13.75,14H17V8H10.5L8.5,6H17A2,2 0 0,1 19,8V14H22.25L18,18.25Z" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 216 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4M9,9V15H15V9" /></svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 257 B |
|
@ -44,7 +44,7 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
|
|||
|
||||
recordingSettings.setLookAndFeel(&getLookAndFeel());
|
||||
recordingSettings.setSize(300, 200);
|
||||
recordingSettingsWindow.centreWithSize(300, 200);
|
||||
recordingSettingsWindow.centreWithSize(300, 230);
|
||||
#if JUCE_WINDOWS
|
||||
// if not standalone, use native title bar for compatibility with DAWs
|
||||
recordingSettingsWindow.setUsingNativeTitleBar(processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone);
|
||||
|
|
|
@ -52,15 +52,13 @@ public:
|
|||
RecordingSettings recordingSettings = RecordingSettings(audioProcessor.recordingParameters);
|
||||
SettingsWindow recordingSettingsWindow = SettingsWindow("Recording Settings", recordingSettings);
|
||||
VisualiserComponent visualiser{
|
||||
audioProcessor.lastOpenedDirectory,
|
||||
audioProcessor,
|
||||
#if SOSCI_FEATURES
|
||||
sharedTextureManager,
|
||||
#endif
|
||||
applicationFolder.getChildFile(ffmpegFileName),
|
||||
audioProcessor.haltRecording,
|
||||
audioProcessor.threadManager,
|
||||
visualiserSettings,
|
||||
audioProcessor.recordingParameters,
|
||||
recordingSettings,
|
||||
nullptr,
|
||||
appName == "sosci"
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "CommonPluginProcessor.h"
|
||||
#include "CommonPluginEditor.h"
|
||||
#include "audio/EffectParameter.h"
|
||||
#include "components/AudioPlayerComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
CommonAudioProcessor::CommonAudioProcessor()
|
||||
|
@ -182,3 +183,36 @@ bool CommonAudioProcessor::hasEditor() const {
|
|||
double CommonAudioProcessor::getSampleRate() {
|
||||
return currentSampleRate;
|
||||
}
|
||||
|
||||
void CommonAudioProcessor::loadAudioFile(const juce::File& file) {
|
||||
auto stream = std::make_unique<juce::FileInputStream>(file);
|
||||
if (stream->openedOk()) {
|
||||
juce::SpinLock::ScopedLockType lock(wavParserLock);
|
||||
wavParser = std::make_shared<WavParser>(*this, std::move(stream));
|
||||
|
||||
juce::SpinLock::ScopedLockType lock2(audioPlayerListenersLock);
|
||||
for (auto listener : audioPlayerListeners) {
|
||||
listener->parserChanged(wavParser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommonAudioProcessor::stopAudioFile() {
|
||||
juce::SpinLock::ScopedLockType lock(wavParserLock);
|
||||
wavParser = nullptr;
|
||||
|
||||
juce::SpinLock::ScopedLockType lock2(audioPlayerListenersLock);
|
||||
for (auto listener : audioPlayerListeners) {
|
||||
listener->parserChanged(wavParser);
|
||||
}
|
||||
}
|
||||
|
||||
void CommonAudioProcessor::addAudioPlayerListener(AudioPlayerListener* listener) {
|
||||
juce::SpinLock::ScopedLockType lock(audioPlayerListenersLock);
|
||||
audioPlayerListeners.push_back(listener);
|
||||
}
|
||||
|
||||
void CommonAudioProcessor::removeAudioPlayerListener(AudioPlayerListener* listener) {
|
||||
juce::SpinLock::ScopedLockType lock(audioPlayerListenersLock);
|
||||
audioPlayerListeners.erase(std::remove(audioPlayerListeners.begin(), audioPlayerListeners.end(), listener), audioPlayerListeners.end());
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
#include "visualiser/VisualiserSettings.h"
|
||||
#include "visualiser/RecordingSettings.h"
|
||||
#include "audio/Effect.h"
|
||||
#include "wav/WavParser.h"
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
|
||||
class AudioPlayerListener;
|
||||
class CommonAudioProcessor : public juce::AudioProcessor, public SampleRateManager
|
||||
#if JucePlugin_Enable_ARA
|
||||
, public juce::AudioProcessorARAExtension
|
||||
|
@ -54,6 +54,13 @@ public:
|
|||
const juce::String getProgramName(int index) override;
|
||||
void changeProgramName(int index, const juce::String& newName) override;
|
||||
double getSampleRate() override;
|
||||
void loadAudioFile(const juce::File& file);
|
||||
void stopAudioFile();
|
||||
void addAudioPlayerListener(AudioPlayerListener* listener);
|
||||
void removeAudioPlayerListener(AudioPlayerListener* listener);
|
||||
|
||||
juce::SpinLock audioPlayerListenersLock;
|
||||
std::vector<AudioPlayerListener*> audioPlayerListeners;
|
||||
|
||||
std::atomic<double> volume = 1.0;
|
||||
std::atomic<double> threshold = 1.0;
|
||||
|
@ -82,6 +89,9 @@ public:
|
|||
)
|
||||
);
|
||||
|
||||
juce::SpinLock wavParserLock;
|
||||
std::shared_ptr<WavParser> wavParser;
|
||||
|
||||
std::atomic<double> currentSampleRate = 0.0;
|
||||
juce::SpinLock effectsLock;
|
||||
VisualiserParameters visualiserParameters;
|
||||
|
|
|
@ -30,5 +30,8 @@ void SosciPluginEditor::resized() {
|
|||
visualiserSettings.setSize(settingsArea.getWidth(), 550);
|
||||
visualiserSettingsWrapper.setBounds(settingsArea);
|
||||
|
||||
if (area.getWidth() < 10 || area.getHeight() < 10) {
|
||||
return;
|
||||
}
|
||||
visualiser.setBounds(area);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ void SosciAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::M
|
|||
auto inputArray = input.getArrayOfWritePointers();
|
||||
auto outputArray = output.getArrayOfWritePointers();
|
||||
|
||||
juce::CriticalSection::ScopedLockType lock2(wavParserLock);
|
||||
juce::SpinLock::ScopedLockType lock2(wavParserLock);
|
||||
bool readingFromWav = wavParser != nullptr;
|
||||
|
||||
for (int sample = 0; sample < input.getNumSamples(); ++sample) {
|
||||
|
@ -175,19 +175,6 @@ void SosciAudioProcessor::setStateInformation(const void* data, int sizeInBytes)
|
|||
}
|
||||
}
|
||||
|
||||
void SosciAudioProcessor::loadAudioFile(const juce::File& file) {
|
||||
auto stream = std::make_unique<juce::FileInputStream>(file);
|
||||
if (stream->openedOk()) {
|
||||
juce::CriticalSection::ScopedLockType lock(wavParserLock);
|
||||
wavParser = std::make_unique<WavParser>(*this, std::move(stream));
|
||||
}
|
||||
}
|
||||
|
||||
void SosciAudioProcessor::stopAudioFile() {
|
||||
juce::CriticalSection::ScopedLockType lock(wavParserLock);
|
||||
wavParser = nullptr;
|
||||
}
|
||||
|
||||
juce::AudioProcessorEditor* SosciAudioProcessor::createEditor() {
|
||||
auto editor = new SosciPluginEditor(*this);
|
||||
return editor;
|
||||
|
|
|
@ -30,16 +30,9 @@ public:
|
|||
|
||||
void getStateInformation(juce::MemoryBlock& destData) override;
|
||||
void setStateInformation(const void* data, int sizeInBytes) override;
|
||||
|
||||
void loadAudioFile(const juce::File& file);
|
||||
void stopAudioFile();
|
||||
|
||||
juce::AudioProcessorEditor* createEditor() override;
|
||||
|
||||
private:
|
||||
juce::CriticalSection wavParserLock;
|
||||
std::unique_ptr<WavParser> wavParser;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SosciAudioProcessor)
|
||||
};
|
||||
|
|
|
@ -129,8 +129,6 @@ private:
|
|||
// value is not necessarily in the range [min, max] so effect applications may need to clip to a valid range
|
||||
std::atomic<float> value = 0.0;
|
||||
juce::String label;
|
||||
|
||||
JUCE_HEAVYWEIGHT_LEAK_DETECTOR(FloatParameter)
|
||||
};
|
||||
|
||||
class IntParameter : public juce::AudioProcessorParameterWithID {
|
||||
|
@ -253,8 +251,6 @@ public:
|
|||
private:
|
||||
// value is not necessarily in the range [min, max] so effect applications may need to clip to a valid range
|
||||
std::atomic<int> value = 0;
|
||||
|
||||
JUCE_HEAVYWEIGHT_LEAK_DETECTOR(IntParameter)
|
||||
};
|
||||
|
||||
enum class LfoType : int {
|
||||
|
@ -404,6 +400,4 @@ public:
|
|||
}
|
||||
|
||||
EffectParameter(juce::String name, juce::String description, juce::String id, int versionHint, float value, float min, float max, float step = 0.01, bool smoothValueChange = true) : FloatParameter(name, id, versionHint, value, min, max, step), smoothValueChange(smoothValueChange), description(description) {}
|
||||
|
||||
JUCE_HEAVYWEIGHT_LEAK_DETECTOR(EffectParameter)
|
||||
};
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
#include "AudioPlayerComponent.h"
|
||||
#include "../CommonPluginProcessor.h"
|
||||
|
||||
AudioPlayerComponent::AudioPlayerComponent(CommonAudioProcessor& processor) : audioProcessor(processor) {
|
||||
setOpaque(false);
|
||||
|
||||
audioProcessor.addAudioPlayerListener(this);
|
||||
|
||||
parser = audioProcessor.wavParser;
|
||||
|
||||
addAndMakeVisible(slider);
|
||||
slider.setSliderStyle(juce::Slider::SliderStyle::LinearHorizontal);
|
||||
slider.setTextBoxStyle(juce::Slider::NoTextBox, true, 0, 0);
|
||||
slider.setOpaque(false);
|
||||
slider.setRange(0, 1, 0.001);
|
||||
slider.setLookAndFeel(&timelineLookAndFeel);
|
||||
slider.setColour(juce::Slider::ColourIds::thumbColourId, juce::Colours::black);
|
||||
|
||||
slider.onValueChange = [this]() {
|
||||
juce::SpinLock::ScopedLockType sl(audioProcessor.wavParserLock);
|
||||
|
||||
if (parser != nullptr) {
|
||||
parser->setProgress(slider.getValue());
|
||||
} else {
|
||||
slider.setValue(0, juce::dontSendNotification);
|
||||
}
|
||||
};
|
||||
|
||||
addChildComponent(playButton);
|
||||
addChildComponent(pauseButton);
|
||||
|
||||
playButton.setTooltip("Play audio file");
|
||||
pauseButton.setTooltip("Pause audio file");
|
||||
|
||||
repeatButton.setToggleState(true, juce::dontSendNotification);
|
||||
|
||||
playButton.onClick = [this]() {
|
||||
juce::SpinLock::ScopedLockType sl(audioProcessor.wavParserLock);
|
||||
|
||||
if (parser != nullptr) {
|
||||
parser->setPaused(false);
|
||||
playButton.setVisible(false);
|
||||
pauseButton.setVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
pauseButton.onClick = [this]() {
|
||||
juce::SpinLock::ScopedLockType sl(audioProcessor.wavParserLock);
|
||||
|
||||
if (parser != nullptr) {
|
||||
parser->setPaused(true);
|
||||
playButton.setVisible(true);
|
||||
pauseButton.setVisible(false);
|
||||
}
|
||||
};
|
||||
|
||||
addAndMakeVisible(repeatButton);
|
||||
|
||||
repeatButton.setTooltip("Repeat audio file once it finishes playing");
|
||||
|
||||
repeatButton.onClick = [this]() {
|
||||
juce::SpinLock::ScopedLockType sl(audioProcessor.wavParserLock);
|
||||
|
||||
if (parser != nullptr) {
|
||||
parser->setLooping(repeatButton.getToggleState());
|
||||
}
|
||||
};
|
||||
|
||||
addAndMakeVisible(stopButton);
|
||||
|
||||
stopButton.setTooltip("Stop and close audio file");
|
||||
|
||||
stopButton.onClick = [this]() {
|
||||
audioProcessor.stopAudioFile();
|
||||
};
|
||||
|
||||
{
|
||||
juce::SpinLock::ScopedLockType sl(audioProcessor.wavParserLock);
|
||||
setup();
|
||||
}
|
||||
}
|
||||
|
||||
AudioPlayerComponent::~AudioPlayerComponent() {
|
||||
audioProcessor.removeAudioPlayerListener(this);
|
||||
juce::SpinLock::ScopedLockType sl(audioProcessor.wavParserLock);
|
||||
if (parser != nullptr) {
|
||||
parser->onProgress = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// must hold lock
|
||||
void AudioPlayerComponent::setup() {
|
||||
if (parser != nullptr) {
|
||||
slider.setVisible(true);
|
||||
repeatButton.setVisible(true);
|
||||
stopButton.setVisible(true);
|
||||
parser->onProgress = [this](double progress) {
|
||||
juce::WeakReference<AudioPlayerComponent> weakRef(this);
|
||||
juce::MessageManager::callAsync([this, progress, weakRef]() {
|
||||
if (weakRef) {
|
||||
slider.setValue(progress, juce::dontSendNotification);
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
};
|
||||
playButton.setVisible(parser->isPaused());
|
||||
pauseButton.setVisible(!parser->isPaused());
|
||||
parser->setLooping(repeatButton.getToggleState());
|
||||
} else {
|
||||
slider.setVisible(false);
|
||||
repeatButton.setVisible(false);
|
||||
stopButton.setVisible(false);
|
||||
slider.setValue(0);
|
||||
playButton.setVisible(false);
|
||||
pauseButton.setVisible(false);
|
||||
}
|
||||
|
||||
parserWasNull = parser == nullptr;
|
||||
}
|
||||
|
||||
void AudioPlayerComponent::setPaused(bool paused) {
|
||||
if (paused) {
|
||||
pauseButton.triggerClick();
|
||||
} else {
|
||||
playButton.triggerClick();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayerComponent::parserChanged(std::shared_ptr<WavParser> parser) {
|
||||
this->parser = parser;
|
||||
setup();
|
||||
repaint();
|
||||
}
|
||||
|
||||
void AudioPlayerComponent::resized() {
|
||||
auto r = getLocalBounds();
|
||||
|
||||
auto playPauseBounds = r.removeFromLeft(25);
|
||||
playButton.setBounds(playPauseBounds);
|
||||
pauseButton.setBounds(playPauseBounds);
|
||||
stopButton.setBounds(r.removeFromLeft(25));
|
||||
|
||||
repeatButton.setBounds(r.removeFromRight(25));
|
||||
|
||||
slider.setBounds(r);
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "../CommonPluginProcessor.h"
|
||||
#include "../LookAndFeel.h"
|
||||
#include "../wav/WavParser.h"
|
||||
|
||||
class TimelineLookAndFeel : public OscirenderLookAndFeel {
|
||||
public:
|
||||
TimelineLookAndFeel() {}
|
||||
|
||||
void drawLinearSlider(juce::Graphics& g, int x, int y, int width, int height, float sliderPos, float minSliderPos, float maxSliderPos, const juce::Slider::SliderStyle style, juce::Slider& slider) override {
|
||||
auto trackWidth = juce::jmin (6.0f, slider.isHorizontal() ? (float) height * 0.25f : (float) width * 0.25f);
|
||||
|
||||
juce::Point<float> startPoint (slider.isHorizontal() ? (float) x : (float) x + (float) width * 0.5f,
|
||||
slider.isHorizontal() ? (float) y + (float) height * 0.5f : (float) (height + y));
|
||||
|
||||
juce::Point<float> endPoint (slider.isHorizontal() ? (float) (width + x) : startPoint.x,
|
||||
slider.isHorizontal() ? startPoint.y : (float) y);
|
||||
|
||||
juce::Path backgroundTrack;
|
||||
backgroundTrack.startNewSubPath (startPoint);
|
||||
backgroundTrack.lineTo (endPoint);
|
||||
g.setColour (slider.findColour (juce::Slider::backgroundColourId));
|
||||
g.strokePath (backgroundTrack, { trackWidth, juce::PathStrokeType::curved, juce::PathStrokeType::rounded });
|
||||
|
||||
juce::Path valueTrack;
|
||||
juce::Point<float> minPoint, maxPoint, thumbPoint;
|
||||
|
||||
auto kx = slider.isHorizontal() ? sliderPos : ((float) x + (float) width * 0.5f);
|
||||
auto ky = slider.isHorizontal() ? ((float) y + (float) height * 0.5f) : sliderPos;
|
||||
|
||||
minPoint = startPoint;
|
||||
maxPoint = { kx, ky };
|
||||
|
||||
auto thumbWidth = getSliderThumbRadius (slider);
|
||||
|
||||
valueTrack.startNewSubPath (minPoint);
|
||||
valueTrack.lineTo (maxPoint);
|
||||
g.setColour (slider.findColour (juce::Slider::trackColourId));
|
||||
g.strokePath (valueTrack, { trackWidth, juce::PathStrokeType::curved, juce::PathStrokeType::rounded });
|
||||
|
||||
g.setColour (slider.findColour (juce::Slider::thumbColourId));
|
||||
g.fillRect (juce::Rectangle<float> (thumbWidth / 2, 1.5 * thumbWidth).withCentre (maxPoint));
|
||||
|
||||
g.setColour(slider.findColour(sliderThumbOutlineColourId).withAlpha(slider.isEnabled() ? 1.0f : 0.5f));
|
||||
g.drawRect(juce::Rectangle<float>(thumbWidth / 2, 1.5 * thumbWidth).withCentre(maxPoint));
|
||||
}
|
||||
};
|
||||
|
||||
class AudioPlayerListener {
|
||||
public:
|
||||
virtual void parserChanged(std::shared_ptr<WavParser> parser) = 0;
|
||||
};
|
||||
|
||||
class CommonAudioProcessor;
|
||||
class AudioPlayerComponent : public juce::Component, public AudioPlayerListener {
|
||||
public:
|
||||
AudioPlayerComponent(CommonAudioProcessor& processor);
|
||||
~AudioPlayerComponent() override;
|
||||
|
||||
void resized() override;
|
||||
void setup();
|
||||
void parserChanged(std::shared_ptr<WavParser> parser) override;
|
||||
void setPaused(bool paused);
|
||||
|
||||
private:
|
||||
CommonAudioProcessor& audioProcessor;
|
||||
|
||||
bool parserWasNull = true;
|
||||
std::shared_ptr<WavParser> parser;
|
||||
|
||||
TimelineLookAndFeel timelineLookAndFeel;
|
||||
|
||||
SvgButton playButton{ "Play", BinaryData::play_svg, juce::Colours::white, juce::Colours::white};
|
||||
SvgButton pauseButton{ "Pause", BinaryData::pause_svg, juce::Colours::white, juce::Colours::white };
|
||||
SvgButton repeatButton{ "Repeat", BinaryData::repeat_svg, juce::Colours::white, Colours::accentColor };
|
||||
SvgButton stopButton{ "Stop", BinaryData::stop_svg, juce::Colours::white, juce::Colours::white };
|
||||
juce::Slider slider;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioPlayerComponent)
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE(AudioPlayerComponent)
|
||||
};
|
|
@ -37,18 +37,16 @@ SosciMainMenuBarModel::SosciMainMenuBarModel(SosciPluginEditor& e, SosciAudioPro
|
|||
};
|
||||
|
||||
addMenuItem(0, "Open Audio File", [&]() {
|
||||
fileChooser = std::make_unique<juce::FileChooser>("Open Audio File", processor.lastOpenedDirectory, "*.wav;*.aiff;*.flac;*.ogg");
|
||||
fileChooser = std::make_unique<juce::FileChooser>("Open Audio File", processor.lastOpenedDirectory, "*.wav;*.aiff;*.flac;*.ogg;*.mp3");
|
||||
auto flags = juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectFiles;
|
||||
fileChooser->launchAsync(flags, [&](const juce::FileChooser& chooser) {
|
||||
auto file = chooser.getResult();
|
||||
if (file != juce::File()) {
|
||||
processor.loadAudioFile(file);
|
||||
processor.lastOpenedDirectory = file.getParentDirectory();
|
||||
}
|
||||
});
|
||||
});
|
||||
addMenuItem(0, "Stop Audio File", [&]() {
|
||||
processor.stopAudioFile();
|
||||
});
|
||||
addMenuItem(0, "Open Project", [&]() { editor.openProject(); });
|
||||
addMenuItem(0, "Save Project", [&]() { editor.saveProject(); });
|
||||
addMenuItem(0, "Save Project As", [&]() { editor.saveProjectAs(); });
|
||||
|
|
|
@ -38,24 +38,6 @@ public:
|
|||
|
||||
juce::String compressionPreset = "fast";
|
||||
|
||||
int getCRF() {
|
||||
double quality = juce::jlimit(0.0, 1.0, qualityEffect.getValue());
|
||||
// mapping to 0-51 for ffmpeg's crf value
|
||||
return 51 * (1.0 - quality) ;
|
||||
}
|
||||
|
||||
bool recordingVideo() {
|
||||
return recordVideo.getBoolValue();
|
||||
}
|
||||
|
||||
bool recordingAudio() {
|
||||
return recordAudio.getBoolValue();
|
||||
}
|
||||
|
||||
juce::String getCompressionPreset() {
|
||||
return compressionPreset;
|
||||
}
|
||||
|
||||
void save(juce::XmlElement* xml) {
|
||||
auto settingsXml = xml->createNewChildElement("recordingSettings");
|
||||
recordAudio.save(settingsXml->createNewChildElement("recordAudio"));
|
||||
|
@ -94,6 +76,24 @@ public:
|
|||
|
||||
void resized() override;
|
||||
|
||||
int getCRF() {
|
||||
double quality = juce::jlimit(0.0, 1.0, parameters.qualityEffect.getValue());
|
||||
// mapping to 0-51 for ffmpeg's crf value
|
||||
return 51 * (1.0 - quality) ;
|
||||
}
|
||||
|
||||
bool recordingVideo() {
|
||||
return parameters.recordVideo.getBoolValue();
|
||||
}
|
||||
|
||||
bool recordingAudio() {
|
||||
return parameters.recordAudio.getBoolValue();
|
||||
}
|
||||
|
||||
juce::String getCompressionPreset() {
|
||||
return parameters.compressionPreset;
|
||||
}
|
||||
|
||||
RecordingParameters& parameters;
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "../LookAndFeel.h"
|
||||
#include "VisualiserComponent.h"
|
||||
#include "../CommonPluginProcessor.h"
|
||||
|
||||
#include "BlurFragmentShader.glsl"
|
||||
#include "BlurVertexShader.glsl"
|
||||
#include "WideBlurFragmentShader.glsl"
|
||||
|
@ -16,28 +18,24 @@
|
|||
#include "TexturedVertexShader.glsl"
|
||||
|
||||
VisualiserComponent::VisualiserComponent(
|
||||
juce::File& lastOpenedDirectory,
|
||||
CommonAudioProcessor& processor,
|
||||
#if SOSCI_FEATURES
|
||||
SharedTextureManager& sharedTextureManager,
|
||||
#endif
|
||||
juce::File ffmpegFile,
|
||||
std::function<void()>& haltRecording,
|
||||
AudioBackgroundThreadManager& threadManager,
|
||||
VisualiserSettings& settings,
|
||||
RecordingParameters& recordingParameters,
|
||||
RecordingSettings& recordingSettings,
|
||||
VisualiserComponent* parent,
|
||||
bool visualiserOnly
|
||||
) : lastOpenedDirectory(lastOpenedDirectory),
|
||||
) : audioProcessor(processor),
|
||||
ffmpegFile(ffmpegFile),
|
||||
#if SOSCI_FEATURES
|
||||
sharedTextureManager(sharedTextureManager),
|
||||
#endif
|
||||
haltRecording(haltRecording),
|
||||
settings(settings),
|
||||
recordingParameters(recordingParameters),
|
||||
threadManager(threadManager),
|
||||
recordingSettings(recordingSettings),
|
||||
visualiserOnly(visualiserOnly),
|
||||
AudioBackgroundThread("VisualiserComponent" + juce::String(parent != nullptr ? " Child" : ""), threadManager),
|
||||
AudioBackgroundThread("VisualiserComponent" + juce::String(parent != nullptr ? " Child" : ""), processor.threadManager),
|
||||
parent(parent) {
|
||||
#if SOSCI_FEATURES
|
||||
addAndMakeVisible(ffmpegDownloader);
|
||||
|
@ -45,11 +43,18 @@ VisualiserComponent::VisualiserComponent(
|
|||
ffmpegDownloader.onSuccessfulDownload = [this] {
|
||||
juce::MessageManager::callAsync([this] {
|
||||
record.setEnabled(true);
|
||||
juce::Timer::callAfterDelay(3000, [this] {
|
||||
juce::MessageManager::callAsync([this] {
|
||||
ffmpegDownloader.setVisible(false);
|
||||
downloading = false;
|
||||
resized();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
#endif
|
||||
|
||||
haltRecording = [this] {
|
||||
audioProcessor.haltRecording = [this] {
|
||||
setRecording(false);
|
||||
};
|
||||
|
||||
|
@ -110,6 +115,8 @@ VisualiserComponent::VisualiserComponent(
|
|||
popoutWindow();
|
||||
};
|
||||
|
||||
addAndMakeVisible(audioPlayer);
|
||||
|
||||
setFullScreen(false);
|
||||
|
||||
openGLContext.setRenderer(this);
|
||||
|
@ -121,7 +128,7 @@ VisualiserComponent::VisualiserComponent(
|
|||
VisualiserComponent::~VisualiserComponent() {
|
||||
setRecording(false);
|
||||
if (parent == nullptr) {
|
||||
haltRecording = nullptr;
|
||||
audioProcessor.haltRecording = nullptr;
|
||||
}
|
||||
openGLContext.detach();
|
||||
setShouldBeRunning(false, [this] {
|
||||
|
@ -255,6 +262,7 @@ void VisualiserComponent::setPaused(bool paused) {
|
|||
active = !paused;
|
||||
renderingSemaphore.release();
|
||||
setShouldBeRunning(active);
|
||||
audioPlayer.setPaused(paused);
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
@ -289,8 +297,8 @@ void VisualiserComponent::setRecording(bool recording) {
|
|||
|
||||
if (recording) {
|
||||
#if SOSCI_FEATURES
|
||||
recordingVideo = recordingParameters.recordingVideo();
|
||||
recordingAudio = recordingParameters.recordingAudio();
|
||||
recordingVideo = recordingSettings.recordingVideo();
|
||||
recordingAudio = recordingSettings.recordingAudio();
|
||||
if (!recordingVideo && !recordingAudio) {
|
||||
record.setToggleState(false, juce::NotificationType::dontSendNotification);
|
||||
return;
|
||||
|
@ -311,6 +319,9 @@ void VisualiserComponent::setRecording(bool recording) {
|
|||
if (result == 1) {
|
||||
record.setEnabled(false);
|
||||
ffmpegDownloader.download();
|
||||
ffmpegDownloader.setVisible(true);
|
||||
downloading = true;
|
||||
resized();
|
||||
}
|
||||
});
|
||||
record.setToggleState(false, juce::NotificationType::dontSendNotification);
|
||||
|
@ -325,10 +336,10 @@ void VisualiserComponent::setRecording(bool recording) {
|
|||
" -s " + resolution +
|
||||
" -i -" +
|
||||
" -threads 4" +
|
||||
" -preset " + recordingParameters.getCompressionPreset() +
|
||||
" -preset " + recordingSettings.getCompressionPreset() +
|
||||
" -y" +
|
||||
" -pix_fmt yuv420p" +
|
||||
" -crf " + juce::String(recordingParameters.getCRF()) +
|
||||
" -crf " + juce::String(recordingSettings.getCRF()) +
|
||||
" -vf vflip" +
|
||||
" \"" + tempVideoFile->getFile().getFullPathName() + "\"";
|
||||
|
||||
|
@ -366,7 +377,7 @@ void VisualiserComponent::setRecording(bool recording) {
|
|||
audioRecorder.stop();
|
||||
juce::String extension = "wav";
|
||||
#endif
|
||||
chooser = std::make_unique<juce::FileChooser>("Save recording", lastOpenedDirectory, "*." + extension);
|
||||
chooser = std::make_unique<juce::FileChooser>("Save recording", audioProcessor.lastOpenedDirectory, "*." + extension);
|
||||
auto flags = juce::FileBrowserComponent::saveMode | juce::FileBrowserComponent::canSelectFiles | juce::FileBrowserComponent::warnAboutOverwriting;
|
||||
|
||||
#if SOSCI_FEATURES
|
||||
|
@ -381,7 +392,7 @@ void VisualiserComponent::setRecording(bool recording) {
|
|||
} else if (wasRecordingVideo) {
|
||||
tempVideoFile->getFile().copyFileTo(file);
|
||||
}
|
||||
lastOpenedDirectory = file.getParentDirectory();
|
||||
audioProcessor.lastOpenedDirectory = file.getParentDirectory();
|
||||
}
|
||||
});
|
||||
#else
|
||||
|
@ -389,7 +400,7 @@ void VisualiserComponent::setRecording(bool recording) {
|
|||
auto file = chooser.getResult();
|
||||
if (file != juce::File()) {
|
||||
tempAudioFile->getFile().copyFileTo(file);
|
||||
lastOpenedDirectory = file.getParentDirectory();
|
||||
audioProcessor.lastOpenedDirectory = file.getParentDirectory();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
@ -430,11 +441,13 @@ void VisualiserComponent::resized() {
|
|||
stopwatch.setVisible(false);
|
||||
}
|
||||
#if SOSCI_FEATURES
|
||||
if (child == nullptr) {
|
||||
if (child == nullptr && downloading) {
|
||||
auto bounds = buttons.removeFromRight(160);
|
||||
ffmpegDownloader.setBounds(bounds.withSizeKeepingCentre(bounds.getWidth() - 10, bounds.getHeight() - 10));
|
||||
}
|
||||
#endif
|
||||
buttons.removeFromRight(10); // padding
|
||||
audioPlayer.setBounds(buttons);
|
||||
viewportArea = area;
|
||||
viewportChanged(viewportArea);
|
||||
}
|
||||
|
@ -447,15 +460,13 @@ void VisualiserComponent::popoutWindow() {
|
|||
#endif
|
||||
setRecording(false);
|
||||
auto visualiser = new VisualiserComponent(
|
||||
lastOpenedDirectory,
|
||||
audioProcessor,
|
||||
#if SOSCI_FEATURES
|
||||
sharedTextureManager,
|
||||
#endif
|
||||
ffmpegFile,
|
||||
haltRecording,
|
||||
threadManager,
|
||||
settings,
|
||||
recordingParameters,
|
||||
recordingSettings,
|
||||
this
|
||||
);
|
||||
visualiser->settings.setLookAndFeel(&getLookAndFeel());
|
||||
|
@ -481,12 +492,12 @@ void VisualiserComponent::childUpdated() {
|
|||
#endif
|
||||
record.setVisible(child == nullptr);
|
||||
if (child != nullptr) {
|
||||
haltRecording = [this] {
|
||||
audioProcessor.haltRecording = [this] {
|
||||
setRecording(false);
|
||||
child->setRecording(false);
|
||||
};
|
||||
} else {
|
||||
haltRecording = [this] {
|
||||
audioProcessor.haltRecording = [this] {
|
||||
setRecording(false);
|
||||
};
|
||||
}
|
||||
|
@ -660,7 +671,7 @@ void VisualiserComponent::renderOpenGL() {
|
|||
|
||||
void VisualiserComponent::viewportChanged(juce::Rectangle<int> area) {
|
||||
using namespace juce::gl;
|
||||
|
||||
|
||||
if (openGLContext.isAttached()) {
|
||||
float realWidth = area.getWidth() * renderScale;
|
||||
float realHeight = area.getHeight() * renderScale;
|
||||
|
@ -1175,11 +1186,7 @@ void VisualiserComponent::checkGLErrors(const juce::String& location) {
|
|||
|
||||
|
||||
void VisualiserComponent::paint(juce::Graphics& g) {
|
||||
#if SOSCI_FEATURES
|
||||
g.setColour(settings.getScreenType() == ScreenType::Real ? Colours::dark : Colours::veryDark);
|
||||
#else
|
||||
g.setColour(Colours::veryDark);
|
||||
#endif
|
||||
g.fillRect(buttonRow);
|
||||
if (!active) {
|
||||
// draw a translucent overlay
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "../components/DownloaderComponent.h"
|
||||
#include "../concurrency/WriteProcess.h"
|
||||
#include "../audio/AudioRecorder.h"
|
||||
#include "../wav/WavParser.h"
|
||||
#include "../components/AudioPlayerComponent.h"
|
||||
|
||||
#define FILE_RENDER_DUMMY 0
|
||||
#define FILE_RENDER_PNG 1
|
||||
|
@ -29,19 +31,18 @@ struct Texture {
|
|||
int height;
|
||||
};
|
||||
|
||||
class CommonAudioProcessor;
|
||||
class VisualiserWindow;
|
||||
class VisualiserComponent : public juce::Component, public AudioBackgroundThread, public juce::MouseListener, public juce::OpenGLRenderer, public juce::AsyncUpdater {
|
||||
public:
|
||||
VisualiserComponent(
|
||||
juce::File& lastOpenedDirectory,
|
||||
CommonAudioProcessor& processor,
|
||||
#if SOSCI_FEATURES
|
||||
SharedTextureManager& sharedTextureManager,
|
||||
#endif
|
||||
juce::File ffmpegFile,
|
||||
std::function<void()>& haltRecording,
|
||||
AudioBackgroundThreadManager& threadManager,
|
||||
VisualiserSettings& settings,
|
||||
RecordingParameters& recordingParameters,
|
||||
RecordingSettings& recordingSettings,
|
||||
VisualiserComponent* parent = nullptr,
|
||||
bool visualiserOnly = false
|
||||
);
|
||||
|
@ -76,13 +77,13 @@ public:
|
|||
std::atomic<bool> active = true;
|
||||
|
||||
private:
|
||||
CommonAudioProcessor& audioProcessor;
|
||||
|
||||
float intensity;
|
||||
const double FRAME_RATE = 60.0;
|
||||
|
||||
bool visualiserOnly;
|
||||
std::function<void()>& haltRecording;
|
||||
|
||||
AudioBackgroundThreadManager& threadManager;
|
||||
AudioPlayerComponent audioPlayer{audioProcessor};
|
||||
|
||||
SvgButton fullScreenButton{ "fullScreen", BinaryData::fullscreen_svg, juce::Colours::white, juce::Colours::white };
|
||||
SvgButton popOutButton{ "popOut", BinaryData::open_in_new_svg, juce::Colours::white, juce::Colours::white };
|
||||
|
@ -97,12 +98,13 @@ private:
|
|||
std::function<void(FullScreenMode)> fullScreenCallback;
|
||||
|
||||
VisualiserSettings& settings;
|
||||
RecordingParameters& recordingParameters;
|
||||
RecordingSettings& recordingSettings;
|
||||
juce::File ffmpegFile;
|
||||
bool recordingAudio = true;
|
||||
|
||||
#if SOSCI_FEATURES
|
||||
bool recordingVideo = true;
|
||||
bool downloading = false;
|
||||
|
||||
long numFrames = 0;
|
||||
std::vector<unsigned char> framePixels;
|
||||
|
@ -144,7 +146,6 @@ private:
|
|||
StopwatchComponent stopwatch;
|
||||
SvgButton record{"Record", BinaryData::record_svg, juce::Colours::red, juce::Colours::red.withAlpha(0.01f)};
|
||||
|
||||
juce::File& lastOpenedDirectory;
|
||||
std::unique_ptr<juce::FileChooser> chooser;
|
||||
std::unique_ptr<juce::TemporaryFile> tempAudioFile;
|
||||
AudioRecorder audioRecorder;
|
||||
|
@ -260,7 +261,6 @@ private:
|
|||
void viewportChanged(juce::Rectangle<int> area);
|
||||
|
||||
void renderScope(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints);
|
||||
int renderAudioFile(juce::File& sourceAudio, int method = 1, int width = 1024, int height = 1024);
|
||||
|
||||
double getSweepIncrement();
|
||||
|
||||
|
|
|
@ -307,11 +307,12 @@ private:
|
|||
juce::Component& component;
|
||||
};
|
||||
|
||||
class SettingsWindow : public juce::DocumentWindow {
|
||||
class SettingsWindow : public juce::DialogWindow {
|
||||
public:
|
||||
SettingsWindow(juce::String name, juce::Component& component) : juce::DocumentWindow(name, Colours::darker, juce::DocumentWindow::TitleBarButtons::closeButton), component(component) {
|
||||
juce::Component::addAndMakeVisible(viewport);
|
||||
SettingsWindow(juce::String name, juce::Component& component) : juce::DialogWindow(name, Colours::darker, true, true), component(component) {
|
||||
setContentComponent(&viewport);
|
||||
setResizable(false, false);
|
||||
viewport.setColour(juce::ScrollBar::trackColourId, juce::Colours::white);
|
||||
viewport.setViewedComponent(&component, false);
|
||||
viewport.setScrollBarsShown(true, false, true, false);
|
||||
setAlwaysOnTop(true);
|
||||
|
@ -321,10 +322,6 @@ public:
|
|||
setVisible(false);
|
||||
}
|
||||
|
||||
void resized() override {
|
||||
viewport.setBounds(getLocalBounds());
|
||||
}
|
||||
|
||||
private:
|
||||
juce::Viewport viewport;
|
||||
juce::Component& component;
|
||||
|
|
|
@ -9,7 +9,8 @@ WavParser::WavParser(CommonAudioProcessor& p, std::unique_ptr<juce::InputStream>
|
|||
if (reader == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto* afSource = new juce::AudioFormatReaderSource(reader, true);
|
||||
afSource = new juce::AudioFormatReaderSource(reader, true);
|
||||
totalSamples = afSource->getTotalLength();
|
||||
afSource->setLooping(true);
|
||||
source = std::make_unique<juce::ResamplingAudioSource>(afSource, true);
|
||||
fileSampleRate = reader->sampleRate;
|
||||
|
@ -32,11 +33,23 @@ OsciPoint WavParser::getSample() {
|
|||
if (currentSampleRate != audioProcessor.currentSampleRate) {
|
||||
setSampleRate(audioProcessor.currentSampleRate);
|
||||
}
|
||||
if (source == nullptr) {
|
||||
if (source == nullptr || paused) {
|
||||
return OsciPoint();
|
||||
}
|
||||
|
||||
source->getNextAudioBlock(juce::AudioSourceChannelInfo(audioBuffer));
|
||||
currentSample += source->getResamplingRatio();
|
||||
counter++;
|
||||
if (currentSample >= totalSamples && afSource->isLooping()) {
|
||||
currentSample = 0;
|
||||
counter = 0;
|
||||
afSource->setNextReadPosition(0);
|
||||
}
|
||||
if (counter % currentSampleRate == 0) {
|
||||
if (onProgress != nullptr) {
|
||||
onProgress((double)currentSample / totalSamples);
|
||||
}
|
||||
}
|
||||
|
||||
if (audioBuffer.getNumChannels() == 1) {
|
||||
return OsciPoint(audioBuffer.getSample(0, 0), audioBuffer.getSample(0, 0));
|
||||
|
@ -44,3 +57,29 @@ OsciPoint WavParser::getSample() {
|
|||
return OsciPoint(audioBuffer.getSample(0, 0), audioBuffer.getSample(1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void WavParser::setProgress(double progress) {
|
||||
if (source == nullptr) {
|
||||
return;
|
||||
}
|
||||
afSource->setNextReadPosition(progress * totalSamples);
|
||||
currentSample = progress * totalSamples;
|
||||
}
|
||||
|
||||
void WavParser::setLooping(bool looping) {
|
||||
afSource->setLooping(looping);
|
||||
this->looping = looping;
|
||||
}
|
||||
|
||||
bool WavParser::isLooping() {
|
||||
return looping;
|
||||
}
|
||||
|
||||
void WavParser::setPaused(bool paused) {
|
||||
this->paused = paused;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
bool WavParser::isPaused() {
|
||||
return paused;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,25 @@ public:
|
|||
|
||||
OsciPoint getSample();
|
||||
|
||||
void setProgress(double progress);
|
||||
void setPaused(bool paused);
|
||||
bool isPaused();
|
||||
void setLooping(bool looping);
|
||||
bool isLooping();
|
||||
|
||||
std::function<void(double)> onProgress;
|
||||
|
||||
private:
|
||||
void setSampleRate(double sampleRate);
|
||||
|
||||
juce::AudioFormatReaderSource* afSource;
|
||||
bool looping = true;
|
||||
std::unique_ptr<juce::ResamplingAudioSource> source;
|
||||
juce::AudioBuffer<float> audioBuffer;
|
||||
int currentSample = 0;
|
||||
long totalSamples;
|
||||
long counter = 0;
|
||||
std::atomic<double> currentSample = 0;
|
||||
std::atomic<bool> paused = false;
|
||||
int fileSampleRate;
|
||||
int currentSampleRate;
|
||||
CommonAudioProcessor& audioProcessor;
|
||||
|
|
|
@ -58,11 +58,14 @@
|
|||
<FILE id="pSc1mq" name="osci.svg" compile="0" resource="1" file="Resources/svg/osci.svg"/>
|
||||
<FILE id="f2D5tv" name="pause.svg" compile="0" resource="1" file="Resources/svg/pause.svg"/>
|
||||
<FILE id="D2AI1b" name="pencil.svg" compile="0" resource="1" file="Resources/svg/pencil.svg"/>
|
||||
<FILE id="sfWuFd" name="play.svg" compile="0" resource="1" file="Resources/svg/play.svg"/>
|
||||
<FILE id="PFc2q2" name="random.svg" compile="0" resource="1" file="Resources/svg/random.svg"/>
|
||||
<FILE id="CE6di2" name="range.svg" compile="0" resource="1" file="Resources/svg/range.svg"/>
|
||||
<FILE id="n79IAy" name="record.svg" compile="0" resource="1" file="Resources/svg/record.svg"/>
|
||||
<FILE id="vOGcgi" name="repeat.svg" compile="0" resource="1" file="Resources/svg/repeat.svg"/>
|
||||
<FILE id="OaqZb1" name="right_arrow.svg" compile="0" resource="1" file="Resources/svg/right_arrow.svg"/>
|
||||
<FILE id="yiDo4s" name="spout.svg" compile="0" resource="1" file="Resources/svg/spout.svg"/>
|
||||
<FILE id="EOWhGi" name="stop.svg" compile="0" resource="1" file="Resources/svg/stop.svg"/>
|
||||
<FILE id="rXjNlx" name="threshold.svg" compile="0" resource="1" file="Resources/svg/threshold.svg"/>
|
||||
<FILE id="rFYmV8" name="timer.svg" compile="0" resource="1" file="Resources/svg/timer.svg"/>
|
||||
<FILE id="qC6QiP" name="volume.svg" compile="0" resource="1" file="Resources/svg/volume.svg"/>
|
||||
|
@ -148,6 +151,10 @@
|
|||
file="Source/components/AboutComponent.cpp"/>
|
||||
<FILE id="vDlOTn" name="AboutComponent.h" compile="0" resource="0"
|
||||
file="Source/components/AboutComponent.h"/>
|
||||
<FILE id="xxiMAy" name="AudioPlayerComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/AudioPlayerComponent.cpp"/>
|
||||
<FILE id="DSvDMv" name="AudioPlayerComponent.h" compile="0" resource="0"
|
||||
file="Source/components/AudioPlayerComponent.h"/>
|
||||
<FILE id="kUinTt" name="ComponentList.cpp" compile="1" resource="0"
|
||||
file="Source/components/ComponentList.cpp"/>
|
||||
<FILE id="HGTPEW" name="ComponentList.h" compile="0" resource="0" file="Source/components/ComponentList.h"/>
|
||||
|
|
|
@ -53,11 +53,14 @@
|
|||
<FILE id="pSc1mq" name="osci.svg" compile="0" resource="1" file="Resources/svg/osci.svg"/>
|
||||
<FILE id="f2D5tv" name="pause.svg" compile="0" resource="1" file="Resources/svg/pause.svg"/>
|
||||
<FILE id="D2AI1b" name="pencil.svg" compile="0" resource="1" file="Resources/svg/pencil.svg"/>
|
||||
<FILE id="Tf7MT4" name="play.svg" compile="0" resource="1" file="Resources/svg/play.svg"/>
|
||||
<FILE id="PFc2q2" name="random.svg" compile="0" resource="1" file="Resources/svg/random.svg"/>
|
||||
<FILE id="CE6di2" name="range.svg" compile="0" resource="1" file="Resources/svg/range.svg"/>
|
||||
<FILE id="n79IAy" name="record.svg" compile="0" resource="1" file="Resources/svg/record.svg"/>
|
||||
<FILE id="WDxwSi" name="repeat.svg" compile="0" resource="1" file="Resources/svg/repeat.svg"/>
|
||||
<FILE id="OaqZb1" name="right_arrow.svg" compile="0" resource="1" file="Resources/svg/right_arrow.svg"/>
|
||||
<FILE id="z3A7FT" name="spout.svg" compile="0" resource="1" file="Resources/svg/spout.svg"/>
|
||||
<FILE id="wD6mre" name="stop.svg" compile="0" resource="1" file="Resources/svg/stop.svg"/>
|
||||
<FILE id="rXjNlx" name="threshold.svg" compile="0" resource="1" file="Resources/svg/threshold.svg"/>
|
||||
<FILE id="rFYmV8" name="timer.svg" compile="0" resource="1" file="Resources/svg/timer.svg"/>
|
||||
<FILE id="qC6QiP" name="volume.svg" compile="0" resource="1" file="Resources/svg/volume.svg"/>
|
||||
|
@ -102,6 +105,10 @@
|
|||
file="Source/components/AboutComponent.cpp"/>
|
||||
<FILE id="FtOv3F" name="AboutComponent.h" compile="0" resource="0"
|
||||
file="Source/components/AboutComponent.h"/>
|
||||
<FILE id="bbqJIb" name="AudioPlayerComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/AudioPlayerComponent.cpp"/>
|
||||
<FILE id="UJoX67" name="AudioPlayerComponent.h" compile="0" resource="0"
|
||||
file="Source/components/AudioPlayerComponent.h"/>
|
||||
<FILE id="aihIvJ" name="DownloaderComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/DownloaderComponent.cpp"/>
|
||||
<FILE id="wBQEfb" name="DownloaderComponent.h" compile="0" resource="0"
|
||||
|
@ -198,7 +205,7 @@
|
|||
</GROUP>
|
||||
</MAINGROUP>
|
||||
<JUCEOPTIONS JUCE_STRICT_REFCOUNTEDPOINTER="1" JUCE_VST3_CAN_REPLACE_VST2="0"
|
||||
JUCE_WIN_PER_MONITOR_DPI_AWARE="0" JUCE_WEB_BROWSER="0"/>
|
||||
JUCE_WIN_PER_MONITOR_DPI_AWARE="0" JUCE_WEB_BROWSER="0" JUCE_USE_MP3AUDIOFORMAT="1"/>
|
||||
<EXPORTFORMATS>
|
||||
<LINUX_MAKE targetFolder="Builds/sosci/LinuxMakefile" smallIcon="KigaoN"
|
||||
bigIcon="KigaoN">
|
||||
|
|
Ładowanie…
Reference in New Issue