kopia lustrzana https://github.com/jameshball/osci-render
Add support for opening audio files in sosci
rodzic
dcfd9e1db2
commit
214dbbdffd
|
@ -12,34 +12,56 @@ void SosciAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::M
|
||||||
juce::ScopedNoDenormals noDenormals;
|
juce::ScopedNoDenormals noDenormals;
|
||||||
|
|
||||||
auto input = getBusBuffer(buffer, true, 0);
|
auto input = getBusBuffer(buffer, true, 0);
|
||||||
|
auto output = getBusBuffer(buffer, false, 0);
|
||||||
float EPSILON = 0.0001f;
|
float EPSILON = 0.0001f;
|
||||||
|
|
||||||
midiMessages.clear();
|
midiMessages.clear();
|
||||||
|
|
||||||
auto inputArray = input.getArrayOfWritePointers();
|
auto inputArray = input.getArrayOfWritePointers();
|
||||||
|
auto outputArray = output.getArrayOfWritePointers();
|
||||||
|
|
||||||
|
juce::CriticalSection::ScopedLockType lock2(wavParserLock);
|
||||||
|
bool readingFromWav = wavParser != nullptr;
|
||||||
|
|
||||||
for (int sample = 0; sample < input.getNumSamples(); ++sample) {
|
for (int sample = 0; sample < input.getNumSamples(); ++sample) {
|
||||||
float x = input.getNumChannels() > 0 ? inputArray[0][sample] : 0.0f;
|
OsciPoint point;
|
||||||
float y = input.getNumChannels() > 1 ? inputArray[1][sample] : 0.0f;
|
|
||||||
float brightness = 1.0f;
|
if (readingFromWav) {
|
||||||
if (input.getNumChannels() > 2 && !forceDisableBrightnessInput) {
|
point = wavParser->getSample();
|
||||||
float brightnessChannel = inputArray[2][sample];
|
point.z = 1.0f;
|
||||||
// Only enable brightness if we actually receive a signal on the brightness channel
|
} else {
|
||||||
if (!brightnessEnabled && brightnessChannel > EPSILON) {
|
float x = input.getNumChannels() > 0 ? inputArray[0][sample] : 0.0f;
|
||||||
brightnessEnabled = true;
|
float y = input.getNumChannels() > 1 ? inputArray[1][sample] : 0.0f;
|
||||||
}
|
float brightness = 1.0f;
|
||||||
if (brightnessEnabled) {
|
if (input.getNumChannels() > 2 && !forceDisableBrightnessInput) {
|
||||||
brightness = brightnessChannel;
|
float brightnessChannel = inputArray[2][sample];
|
||||||
|
// Only enable brightness if we actually receive a signal on the brightness channel
|
||||||
|
if (!brightnessEnabled && brightnessChannel > EPSILON) {
|
||||||
|
brightnessEnabled = true;
|
||||||
|
}
|
||||||
|
if (brightnessEnabled) {
|
||||||
|
brightness = brightnessChannel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
point = { x, y, brightness };
|
||||||
}
|
}
|
||||||
|
|
||||||
OsciPoint point = { x, y, brightness };
|
|
||||||
|
|
||||||
for (auto& effect : effects) {
|
for (auto& effect : effects) {
|
||||||
point = effect->apply(sample, point);
|
point = effect->apply(sample, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
threadManager.write(point);
|
threadManager.write(point);
|
||||||
|
|
||||||
|
if (output.getNumChannels() > 0) {
|
||||||
|
outputArray[0][sample] = point.x;
|
||||||
|
}
|
||||||
|
if (output.getNumChannels() > 1) {
|
||||||
|
outputArray[1][sample] = point.y;
|
||||||
|
}
|
||||||
|
if (output.getNumChannels() > 2) {
|
||||||
|
outputArray[2][sample] = point.z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +165,19 @@ 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() {
|
juce::AudioProcessorEditor* SosciAudioProcessor::createEditor() {
|
||||||
auto editor = new SosciPluginEditor(*this);
|
auto editor = new SosciPluginEditor(*this);
|
||||||
return editor;
|
return editor;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "audio/SampleRateManager.h"
|
#include "audio/SampleRateManager.h"
|
||||||
#include "visualiser/VisualiserSettings.h"
|
#include "visualiser/VisualiserSettings.h"
|
||||||
#include "audio/Effect.h"
|
#include "audio/Effect.h"
|
||||||
|
#include "wav/WavParser.h"
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
|
@ -29,9 +30,16 @@ public:
|
||||||
|
|
||||||
void getStateInformation(juce::MemoryBlock& destData) override;
|
void getStateInformation(juce::MemoryBlock& destData) override;
|
||||||
void setStateInformation(const void* data, int sizeInBytes) override;
|
void setStateInformation(const void* data, int sizeInBytes) override;
|
||||||
|
|
||||||
|
void loadAudioFile(const juce::File& file);
|
||||||
|
void stopAudioFile();
|
||||||
|
|
||||||
juce::AudioProcessorEditor* createEditor() override;
|
juce::AudioProcessorEditor* createEditor() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
juce::CriticalSection wavParserLock;
|
||||||
|
std::unique_ptr<WavParser> wavParser;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SosciAudioProcessor)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SosciAudioProcessor)
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,9 +36,22 @@ SosciMainMenuBarModel::SosciMainMenuBarModel(SosciPluginEditor& e, SosciAudioPro
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
addMenuItem(0, "Open", [&]() { editor.openProject(); });
|
addMenuItem(0, "Open Audio File", [&]() {
|
||||||
addMenuItem(0, "Save", [&]() { editor.saveProject(); });
|
fileChooser = std::make_unique<juce::FileChooser>("Open Audio File", processor.lastOpenedDirectory, "*.wav;*.aiff");
|
||||||
addMenuItem(0, "Save As", [&]() { editor.saveProjectAs(); });
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
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(); });
|
||||||
if (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
|
if (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
|
||||||
addMenuItem(0, "Create New Project", [&]() { editor.resetToDefault(); });
|
addMenuItem(0, "Create New Project", [&]() { editor.resetToDefault(); });
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,5 +13,7 @@ public:
|
||||||
SosciPluginEditor& editor;
|
SosciPluginEditor& editor;
|
||||||
SosciAudioProcessor& processor;
|
SosciAudioProcessor& processor;
|
||||||
|
|
||||||
|
std::unique_ptr<juce::FileChooser> fileChooser;
|
||||||
|
|
||||||
const int SUBMENU_ID = 100;
|
const int SUBMENU_ID = 100;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "../shape/Line.h"
|
#include "../shape/Line.h"
|
||||||
#include "../shape/CircleArc.h"
|
#include "../shape/CircleArc.h"
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
|
#include "../PluginProcessor.h"
|
||||||
|
|
||||||
FileParser::FileParser(OscirenderAudioProcessor &p, std::function<void(int, juce::String, juce::String)> errorCallback) : errorCallback(errorCallback), audioProcessor(p) {}
|
FileParser::FileParser(OscirenderAudioProcessor &p, std::function<void(int, juce::String, juce::String)> errorCallback) : errorCallback(errorCallback), audioProcessor(p) {}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "WavParser.h"
|
#include "WavParser.h"
|
||||||
#include "../PluginProcessor.h"
|
#include "../CommonPluginProcessor.h"
|
||||||
|
|
||||||
|
|
||||||
WavParser::WavParser(OscirenderAudioProcessor& p, std::unique_ptr<juce::InputStream> stream) : audioProcessor(p) {
|
WavParser::WavParser(CommonAudioProcessor& p, std::unique_ptr<juce::InputStream> stream) : audioProcessor(p) {
|
||||||
juce::AudioFormatManager formatManager;
|
juce::AudioFormatManager formatManager;
|
||||||
formatManager.registerBasicFormats();
|
formatManager.registerBasicFormats();
|
||||||
juce::AudioFormatReader* reader = formatManager.createReaderFor(std::move(stream));
|
juce::AudioFormatReader* reader = formatManager.createReaderFor(std::move(stream));
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
#include "../shape/OsciPoint.h"
|
#include "../shape/OsciPoint.h"
|
||||||
#include <JuceHeader.h>
|
#include <JuceHeader.h>
|
||||||
|
|
||||||
class OscirenderAudioProcessor;
|
class CommonAudioProcessor;
|
||||||
class WavParser {
|
class WavParser {
|
||||||
public:
|
public:
|
||||||
WavParser(OscirenderAudioProcessor& p, std::unique_ptr<juce::InputStream> stream);
|
WavParser(CommonAudioProcessor& p, std::unique_ptr<juce::InputStream> stream);
|
||||||
~WavParser();
|
~WavParser();
|
||||||
|
|
||||||
OsciPoint getSample();
|
OsciPoint getSample();
|
||||||
|
@ -18,5 +18,5 @@ private:
|
||||||
int currentSample = 0;
|
int currentSample = 0;
|
||||||
int fileSampleRate;
|
int fileSampleRate;
|
||||||
int currentSampleRate;
|
int currentSampleRate;
|
||||||
OscirenderAudioProcessor& audioProcessor;
|
CommonAudioProcessor& audioProcessor;
|
||||||
};
|
};
|
||||||
|
|
Plik binarny nie jest wyświetlany.
Przed Szerokość: | Wysokość: | Rozmiar: 16 MiB Po Szerokość: | Wysokość: | Rozmiar: 541 KiB |
|
@ -63,6 +63,10 @@
|
||||||
</GROUP>
|
</GROUP>
|
||||||
</GROUP>
|
</GROUP>
|
||||||
<GROUP id="{75439074-E50C-362F-1EDF-8B4BE9011259}" name="Source">
|
<GROUP id="{75439074-E50C-362F-1EDF-8B4BE9011259}" name="Source">
|
||||||
|
<GROUP id="{C63A0AA5-8550-16AC-EE89-C05416216534}" name="wav">
|
||||||
|
<FILE id="jxAiTf" name="WavParser.cpp" compile="1" resource="0" file="Source/wav/WavParser.cpp"/>
|
||||||
|
<FILE id="Q6iTsL" name="WavParser.h" compile="0" resource="0" file="Source/wav/WavParser.h"/>
|
||||||
|
</GROUP>
|
||||||
<FILE id="qJ122J" name="CommonPluginEditor.cpp" compile="1" resource="0"
|
<FILE id="qJ122J" name="CommonPluginEditor.cpp" compile="1" resource="0"
|
||||||
file="Source/CommonPluginEditor.cpp"/>
|
file="Source/CommonPluginEditor.cpp"/>
|
||||||
<FILE id="ANZRtQ" name="CommonPluginEditor.h" compile="0" resource="0"
|
<FILE id="ANZRtQ" name="CommonPluginEditor.h" compile="0" resource="0"
|
||||||
|
|
Ładowanie…
Reference in New Issue