kopia lustrzana https://github.com/jameshball/osci-render
Allow multiple files to be opened, allow files to be closed, and use j and k to change file
rodzic
0ff71379e4
commit
ac67c1bec6
|
@ -7,30 +7,56 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
|
||||||
setText("Main Settings");
|
setText("Main Settings");
|
||||||
|
|
||||||
addAndMakeVisible(fileButton);
|
addAndMakeVisible(fileButton);
|
||||||
|
fileButton.setButtonText("Choose File(s)");
|
||||||
fileButton.setButtonText("Choose File");
|
|
||||||
|
|
||||||
fileButton.onClick = [this] {
|
fileButton.onClick = [this] {
|
||||||
chooser = std::make_unique<juce::FileChooser>("Open", juce::File::getSpecialLocation(juce::File::userHomeDirectory), "*.obj;*.svg;*.lua;*.txt");
|
chooser = std::make_unique<juce::FileChooser>("Open", juce::File::getSpecialLocation(juce::File::userHomeDirectory), "*.obj;*.svg;*.lua;*.txt");
|
||||||
auto flags = juce::FileBrowserComponent::openMode;
|
auto flags = juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectMultipleItems;
|
||||||
|
|
||||||
chooser->launchAsync(flags, [this](const juce::FileChooser& chooser) {
|
chooser->launchAsync(flags, [this](const juce::FileChooser& chooser) {
|
||||||
if (chooser.getURLResult().isLocalFile()) {
|
for (auto& url : chooser.getURLResults()) {
|
||||||
auto file = chooser.getResult();
|
if (url.isLocalFile()) {
|
||||||
audioProcessor.addFile(file);
|
auto file = url.getLocalFile();
|
||||||
pluginEditor.updateCodeEditor();
|
audioProcessor.addFile(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pluginEditor.updateCodeEditor();
|
||||||
|
updateFileLabel();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
addAndMakeVisible(closeFileButton);
|
||||||
|
closeFileButton.setButtonText("Close File");
|
||||||
|
|
||||||
|
closeFileButton.onClick = [this] {
|
||||||
|
audioProcessor.removeFile(audioProcessor.getCurrentFileIndex());
|
||||||
|
pluginEditor.updateCodeEditor();
|
||||||
|
updateFileLabel();
|
||||||
|
};
|
||||||
|
|
||||||
|
addAndMakeVisible(fileLabel);
|
||||||
|
updateFileLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainComponent::~MainComponent() {
|
MainComponent::~MainComponent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainComponent::resized() {
|
void MainComponent::updateFileLabel() {
|
||||||
auto xPadding = 10;
|
if (audioProcessor.getCurrentFileIndex() == -1) {
|
||||||
auto yPadding = 20;
|
fileLabel.setText("No file open", juce::dontSendNotification);
|
||||||
auto buttonWidth = 100;
|
return;
|
||||||
auto buttonHeight = 40;
|
}
|
||||||
fileButton.setBounds(xPadding, yPadding, buttonWidth, buttonHeight);
|
|
||||||
|
fileLabel.setText(audioProcessor.getCurrentFile().getFileName(), juce::dontSendNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainComponent::resized() {
|
||||||
|
auto baseYPadding = 10;
|
||||||
|
auto xPadding = 10;
|
||||||
|
auto yPadding = 10;
|
||||||
|
auto buttonWidth = 120;
|
||||||
|
auto buttonHeight = 40;
|
||||||
|
fileButton.setBounds(xPadding, baseYPadding + yPadding, buttonWidth, buttonHeight);
|
||||||
|
closeFileButton.setBounds(xPadding, baseYPadding + yPadding + buttonHeight + yPadding, buttonWidth, buttonHeight);
|
||||||
|
fileLabel.setBounds(xPadding + buttonWidth + xPadding, baseYPadding + yPadding, getWidth() - xPadding - buttonWidth - xPadding, buttonHeight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,16 @@ public:
|
||||||
~MainComponent() override;
|
~MainComponent() override;
|
||||||
|
|
||||||
void resized() override;
|
void resized() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OscirenderAudioProcessor& audioProcessor;
|
OscirenderAudioProcessor& audioProcessor;
|
||||||
OscirenderAudioProcessorEditor& pluginEditor;
|
OscirenderAudioProcessorEditor& pluginEditor;
|
||||||
|
|
||||||
std::unique_ptr<juce::FileChooser> chooser;
|
std::unique_ptr<juce::FileChooser> chooser;
|
||||||
juce::TextButton fileButton;
|
juce::TextButton fileButton;
|
||||||
|
juce::TextButton closeFileButton;
|
||||||
|
juce::Label fileLabel;
|
||||||
|
|
||||||
|
void updateFileLabel();
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainComponent)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainComponent)
|
||||||
};
|
};
|
|
@ -54,6 +54,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
|
||||||
collapseButton.setShape(path, false, true, true);
|
collapseButton.setShape(path, false, true, true);
|
||||||
} else {
|
} else {
|
||||||
codeEditor->setVisible(true);
|
codeEditor->setVisible(true);
|
||||||
|
updateCodeEditor();
|
||||||
juce::Path path;
|
juce::Path path;
|
||||||
path.addTriangle(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
|
path.addTriangle(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
|
||||||
collapseButton.setShape(path, false, true, true);
|
collapseButton.setShape(path, false, true, true);
|
||||||
|
@ -93,15 +94,40 @@ void OscirenderAudioProcessorEditor::resized() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessorEditor::updateCodeEditor() {
|
void OscirenderAudioProcessorEditor::updateCodeEditor() {
|
||||||
codeEditor->loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(audioProcessor.getCurrentFile()), false).readEntireStreamAsString());
|
if (codeEditor->isVisible() && audioProcessor.getCurrentFileIndex() != -1) {
|
||||||
|
codeEditor->loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(audioProcessor.getCurrentFileIndex()), false).readEntireStreamAsString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessorEditor::codeDocumentTextInserted(const juce::String& newText, int insertIndex) {
|
void OscirenderAudioProcessorEditor::codeDocumentTextInserted(const juce::String& newText, int insertIndex) {
|
||||||
juce::String file = codeDocument.getAllContent();
|
juce::String file = codeDocument.getAllContent();
|
||||||
audioProcessor.updateFileBlock(audioProcessor.getCurrentFile(), std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1));
|
audioProcessor.updateFileBlock(audioProcessor.getCurrentFileIndex(), std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessorEditor::codeDocumentTextDeleted(int startIndex, int endIndex) {
|
void OscirenderAudioProcessorEditor::codeDocumentTextDeleted(int startIndex, int endIndex) {
|
||||||
juce::String file = codeDocument.getAllContent();
|
juce::String file = codeDocument.getAllContent();
|
||||||
audioProcessor.updateFileBlock(audioProcessor.getCurrentFile(), std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1));
|
audioProcessor.updateFileBlock(audioProcessor.getCurrentFileIndex(), std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) {
|
||||||
|
int numFiles = audioProcessor.numFiles();
|
||||||
|
int currentFile = audioProcessor.getCurrentFileIndex();
|
||||||
|
if (key.getTextCharacter() == 'j') {
|
||||||
|
currentFile++;
|
||||||
|
if (currentFile == numFiles) {
|
||||||
|
currentFile = 0;
|
||||||
|
}
|
||||||
|
audioProcessor.changeCurrentFile(currentFile);
|
||||||
|
updateCodeEditor();
|
||||||
|
return true;
|
||||||
|
} else if (key.getTextCharacter() == 'k') {
|
||||||
|
currentFile--;
|
||||||
|
if (currentFile < 0) {
|
||||||
|
currentFile = numFiles - 1;
|
||||||
|
}
|
||||||
|
audioProcessor.changeCurrentFile(currentFile);
|
||||||
|
updateCodeEditor();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,5 +41,7 @@ private:
|
||||||
void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override;
|
void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override;
|
||||||
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
|
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
|
||||||
|
|
||||||
|
bool keyPressed(const juce::KeyPress& key) override;
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OscirenderAudioProcessorEditor)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OscirenderAudioProcessorEditor)
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,10 +29,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
||||||
)
|
)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
parsers.push_back(std::make_unique<FileParser>());
|
producer = std::make_unique<FrameProducer>(*this, std::make_shared<FileParser>());
|
||||||
files.emplace_back();
|
|
||||||
fileBlocks.emplace_back();
|
|
||||||
producer = std::make_unique<FrameProducer>(*this, parsers[0]);
|
|
||||||
producer->startThread();
|
producer->startThread();
|
||||||
|
|
||||||
allEffects.push_back(std::make_shared<Effect>(std::make_unique<BitCrushEffect>(), "Bit Crush", "bitCrush"));
|
allEffects.push_back(std::make_shared<Effect>(std::make_unique<BitCrushEffect>(), "Bit Crush", "bitCrush"));
|
||||||
|
@ -197,24 +194,6 @@ void OscirenderAudioProcessor::updateAngleDelta() {
|
||||||
thetaDelta = cyclesPerSample * 2.0 * juce::MathConstants<double>::pi;
|
thetaDelta = cyclesPerSample * 2.0 * juce::MathConstants<double>::pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessor::addFrame(std::vector<std::unique_ptr<Shape>> frame) {
|
|
||||||
const auto scope = frameFifo.write(1);
|
|
||||||
|
|
||||||
if (scope.blockSize1 > 0) {
|
|
||||||
frameBuffer[scope.startIndex1].clear();
|
|
||||||
for (auto& shape : frame) {
|
|
||||||
frameBuffer[scope.startIndex1].push_back(std::move(shape));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope.blockSize2 > 0) {
|
|
||||||
frameBuffer[scope.startIndex2].clear();
|
|
||||||
for (auto& shape : frame) {
|
|
||||||
frameBuffer[scope.startIndex2].push_back(std::move(shape));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OscirenderAudioProcessor::enableEffect(std::shared_ptr<Effect> effect) {
|
void OscirenderAudioProcessor::enableEffect(std::shared_ptr<Effect> effect) {
|
||||||
// need to make a new vector because the old one is being iterated over in another thread
|
// need to make a new vector because the old one is being iterated over in another thread
|
||||||
std::shared_ptr<std::vector<std::shared_ptr<Effect>>> newEffects = std::make_shared<std::vector<std::shared_ptr<Effect>>>();
|
std::shared_ptr<std::vector<std::shared_ptr<Effect>>> newEffects = std::make_shared<std::vector<std::shared_ptr<Effect>>>();
|
||||||
|
@ -282,8 +261,10 @@ void OscirenderAudioProcessor::addFile(juce::File file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessor::removeFile(int index) {
|
void OscirenderAudioProcessor::removeFile(int index) {
|
||||||
openFile(index - 1);
|
if (index < 0 || index >= fileBlocks.size()) {
|
||||||
parsers[index]->disable();
|
return;
|
||||||
|
}
|
||||||
|
changeCurrentFile(index - 1);
|
||||||
fileBlocks.erase(fileBlocks.begin() + index);
|
fileBlocks.erase(fileBlocks.begin() + index);
|
||||||
files.erase(files.begin() + index);
|
files.erase(files.begin() + index);
|
||||||
parsers.erase(parsers.begin() + index);
|
parsers.erase(parsers.begin() + index);
|
||||||
|
@ -294,19 +275,56 @@ int OscirenderAudioProcessor::numFiles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessor::openFile(int index) {
|
void OscirenderAudioProcessor::openFile(int index) {
|
||||||
currentFile = index;
|
if (index < 0 || index >= fileBlocks.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
parsers[index]->parse(files[index].getFileExtension(), std::make_unique<juce::MemoryInputStream>(*fileBlocks[index], false));
|
parsers[index]->parse(files[index].getFileExtension(), std::make_unique<juce::MemoryInputStream>(*fileBlocks[index], false));
|
||||||
producer->setSource(parsers[index]);
|
producer->setSource(parsers[index], index);
|
||||||
|
currentFile = index;
|
||||||
|
invalidateFrameBuffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OscirenderAudioProcessor::getCurrentFile() {
|
void OscirenderAudioProcessor::changeCurrentFile(int index) {
|
||||||
|
if (index < 0 || index >= fileBlocks.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
producer->setSource(parsers[index], index);
|
||||||
|
currentFile = index;
|
||||||
|
invalidateFrameBuffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OscirenderAudioProcessor::getCurrentFileIndex() {
|
||||||
return currentFile;
|
return currentFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
juce::File OscirenderAudioProcessor::getCurrentFile() {
|
||||||
|
return files[currentFile];
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<juce::MemoryBlock> OscirenderAudioProcessor::getFileBlock(int index) {
|
std::shared_ptr<juce::MemoryBlock> OscirenderAudioProcessor::getFileBlock(int index) {
|
||||||
return fileBlocks[index];
|
return fileBlocks[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OscirenderAudioProcessor::addFrame(std::vector<std::unique_ptr<Shape>> frame, int fileIndex) {
|
||||||
|
const auto scope = frameFifo.write(1);
|
||||||
|
|
||||||
|
if (scope.blockSize1 > 0) {
|
||||||
|
frameBuffer[scope.startIndex1].clear();
|
||||||
|
for (auto& shape : frame) {
|
||||||
|
frameBuffer[scope.startIndex1].push_back(std::move(shape));
|
||||||
|
}
|
||||||
|
frameBufferIndices[scope.startIndex1] = fileIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scope.blockSize2 > 0) {
|
||||||
|
frameBuffer[scope.startIndex2].clear();
|
||||||
|
for (auto& shape : frame) {
|
||||||
|
frameBuffer[scope.startIndex2].push_back(std::move(shape));
|
||||||
|
}
|
||||||
|
frameBufferIndices[scope.startIndex2] = fileIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessor::updateFrame() {
|
void OscirenderAudioProcessor::updateFrame() {
|
||||||
currentShape = 0;
|
currentShape = 0;
|
||||||
shapeDrawn = 0.0;
|
shapeDrawn = 0.0;
|
||||||
|
@ -318,8 +336,10 @@ void OscirenderAudioProcessor::updateFrame() {
|
||||||
|
|
||||||
if (scope.blockSize1 > 0) {
|
if (scope.blockSize1 > 0) {
|
||||||
frame.swap(frameBuffer[scope.startIndex1]);
|
frame.swap(frameBuffer[scope.startIndex1]);
|
||||||
|
currentBufferIndex = frameBufferIndices[scope.startIndex1];
|
||||||
} else if (scope.blockSize2 > 0) {
|
} else if (scope.blockSize2 > 0) {
|
||||||
frame.swap(frameBuffer[scope.startIndex2]);
|
frame.swap(frameBuffer[scope.startIndex2]);
|
||||||
|
currentBufferIndex = frameBufferIndices[scope.startIndex2];
|
||||||
}
|
}
|
||||||
|
|
||||||
frameLength = Shape::totalLength(frame);
|
frameLength = Shape::totalLength(frame);
|
||||||
|
@ -349,6 +369,17 @@ void OscirenderAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, j
|
||||||
|
|
||||||
auto* channelData = buffer.getArrayOfWritePointers();
|
auto* channelData = buffer.getArrayOfWritePointers();
|
||||||
auto numSamples = buffer.getNumSamples();
|
auto numSamples = buffer.getNumSamples();
|
||||||
|
|
||||||
|
if (invalidateFrameBuffer) {
|
||||||
|
frameFifo.reset();
|
||||||
|
// keeps getting the next frame until the frame comes from the file that we want to render.
|
||||||
|
// this MIGHT be hacky and cause issues later down the line, but for now it works as a
|
||||||
|
// solution to get instant changing of current file when pressing j and k.
|
||||||
|
while (currentBufferIndex != currentFile) {
|
||||||
|
updateFrame();
|
||||||
|
}
|
||||||
|
invalidateFrameBuffer = false;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto sample = 0; sample < numSamples; ++sample) {
|
for (auto sample = 0; sample < numSamples; ++sample) {
|
||||||
updateLengthIncrement();
|
updateLengthIncrement();
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
|
|
||||||
BitCrushEffect bitCrushEffect = BitCrushEffect();
|
BitCrushEffect bitCrushEffect = BitCrushEffect();
|
||||||
BulgeEffect bulgeEffect = BulgeEffect();
|
BulgeEffect bulgeEffect = BulgeEffect();
|
||||||
|
|
||||||
std::vector<std::shared_ptr<FileParser>> parsers;
|
std::vector<std::shared_ptr<FileParser>> parsers;
|
||||||
std::vector<std::shared_ptr<juce::MemoryBlock>> fileBlocks;
|
std::vector<std::shared_ptr<juce::MemoryBlock>> fileBlocks;
|
||||||
std::vector<juce::File> files;
|
std::vector<juce::File> files;
|
||||||
|
@ -83,7 +83,7 @@ public:
|
||||||
std::unique_ptr<FrameProducer> producer;
|
std::unique_ptr<FrameProducer> producer;
|
||||||
|
|
||||||
void updateAngleDelta();
|
void updateAngleDelta();
|
||||||
void addFrame(std::vector<std::unique_ptr<Shape>> frame) override;
|
void addFrame(std::vector<std::unique_ptr<Shape>> frame, int fileIndex) override;
|
||||||
void enableEffect(std::shared_ptr<Effect> effect);
|
void enableEffect(std::shared_ptr<Effect> effect);
|
||||||
void disableEffect(std::shared_ptr<Effect> effect);
|
void disableEffect(std::shared_ptr<Effect> effect);
|
||||||
void updateEffectPrecedence();
|
void updateEffectPrecedence();
|
||||||
|
@ -92,7 +92,9 @@ public:
|
||||||
void removeFile(int index);
|
void removeFile(int index);
|
||||||
int numFiles();
|
int numFiles();
|
||||||
void openFile(int index);
|
void openFile(int index);
|
||||||
int getCurrentFile();
|
void changeCurrentFile(int index);
|
||||||
|
int getCurrentFileIndex();
|
||||||
|
juce::File getCurrentFile();
|
||||||
std::shared_ptr<juce::MemoryBlock> getFileBlock(int index);
|
std::shared_ptr<juce::MemoryBlock> getFileBlock(int index);
|
||||||
private:
|
private:
|
||||||
double theta = 0.0;
|
double theta = 0.0;
|
||||||
|
@ -100,13 +102,16 @@ private:
|
||||||
|
|
||||||
juce::AbstractFifo frameFifo{ 10 };
|
juce::AbstractFifo frameFifo{ 10 };
|
||||||
std::vector<std::unique_ptr<Shape>> frameBuffer[10];
|
std::vector<std::unique_ptr<Shape>> frameBuffer[10];
|
||||||
|
int frameBufferIndices[10];
|
||||||
|
|
||||||
int currentShape = 0;
|
int currentShape = 0;
|
||||||
std::vector<std::unique_ptr<Shape>> frame;
|
std::vector<std::unique_ptr<Shape>> frame;
|
||||||
|
int currentBufferIndex = -1;
|
||||||
double frameLength;
|
double frameLength;
|
||||||
double shapeDrawn = 0.0;
|
double shapeDrawn = 0.0;
|
||||||
double frameDrawn = 0.0;
|
double frameDrawn = 0.0;
|
||||||
double lengthIncrement = 0.0;
|
double lengthIncrement = 0.0;
|
||||||
|
bool invalidateFrameBuffer = false;
|
||||||
|
|
||||||
void updateFrame();
|
void updateFrame();
|
||||||
void updateLengthIncrement();
|
void updateLengthIncrement();
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
|
|
||||||
class FrameConsumer {
|
class FrameConsumer {
|
||||||
public:
|
public:
|
||||||
virtual void addFrame(std::vector<std::unique_ptr<Shape>> frame) = 0;
|
virtual void addFrame(std::vector<std::unique_ptr<Shape>> frame, int fileIndex) = 0;
|
||||||
};
|
};
|
|
@ -9,11 +9,12 @@ FrameProducer::~FrameProducer() {
|
||||||
|
|
||||||
void FrameProducer::run() {
|
void FrameProducer::run() {
|
||||||
while (!threadShouldExit() && frameSource->isActive()) {
|
while (!threadShouldExit() && frameSource->isActive()) {
|
||||||
frameConsumer.addFrame(frameSource->next());
|
frameConsumer.addFrame(frameSource->next(), sourceFileIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameProducer::setSource(std::shared_ptr<FrameSource> source) {
|
void FrameProducer::setSource(std::shared_ptr<FrameSource> source, int fileIndex) {
|
||||||
// TODO: should make this atomic
|
// TODO: should make this atomic
|
||||||
frameSource = source;
|
frameSource = source;
|
||||||
|
sourceFileIndex = fileIndex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,9 @@ public:
|
||||||
~FrameProducer() override;
|
~FrameProducer() override;
|
||||||
|
|
||||||
void run() override;
|
void run() override;
|
||||||
void setSource(std::shared_ptr<FrameSource>);
|
void setSource(std::shared_ptr<FrameSource>, int fileIndex);
|
||||||
private:
|
private:
|
||||||
FrameConsumer& frameConsumer;
|
FrameConsumer& frameConsumer;
|
||||||
std::shared_ptr<FrameSource> frameSource;
|
std::shared_ptr<FrameSource> frameSource;
|
||||||
|
int sourceFileIndex = 0;
|
||||||
};
|
};
|
Ładowanie…
Reference in New Issue