diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index de6adfe..f81f0bd 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -97,9 +97,11 @@ void PaulstretchpluginAudioProcessorEditor::timerCallback(int id) if (processor.isRecordingEnabled() != m_rec_enable.getToggleState()) m_rec_enable.setToggleState(processor.isRecordingEnabled(), dontSendNotification); if (processor.isRecordingEnabled()) - m_info_label.setText(String(processor.getRecordingPositionPercent()*100.0, 1),dontSendNotification); - else - m_info_label.setText(String(processor.m_control->getStretchAudioSource()->m_param_change_count), dontSendNotification); + { + m_wavecomponent.setRecordingPosition(processor.getRecordingPositionPercent()); + } else + m_wavecomponent.setRecordingPosition(-1.0); + m_info_label.setText(String(processor.m_control->getStretchAudioSource()->m_param_change_count), dontSendNotification); } } @@ -116,6 +118,16 @@ void PaulstretchpluginAudioProcessorEditor::setAudioBuffer(AudioBuffer* b }); } +void PaulstretchpluginAudioProcessorEditor::beginAddingAudioBlocks(int channels, int samplerate, int totalllen) +{ + m_wavecomponent.beginAddingAudioBlocks(channels, samplerate, totalllen); +} + +void PaulstretchpluginAudioProcessorEditor::addAudioBlock(AudioBuffer& buf, int samplerate, int pos) +{ + m_wavecomponent.addAudioBlock(buf, samplerate, pos); +} + WaveformComponent::WaveformComponent(AudioFormatManager* afm) : m_thumbcache(100) { TimeSelectionChangedCallback = [](Range, int) {}; @@ -217,6 +229,12 @@ void WaveformComponent::paint(Graphics & g) double pos = jmap(CursorPosCallback(), m_view_range.getStart(), m_view_range.getEnd(), 0, getWidth()); g.fillRect((int)pos, m_topmargin, 1, getHeight() - m_topmargin); } + if (m_rec_pos >= 0.0) + { + g.setColour(Colours::lightpink); + double pos = jmap(m_rec_pos, m_view_range.getStart(), m_view_range.getEnd(), 0, getWidth()); + g.fillRect((int)pos, m_topmargin, 1, getHeight() - m_topmargin); + } g.setColour(Colours::aqua.darker()); g.drawText(m_curfile.getFullPathName(), 2, m_topmargin + 2, getWidth(), 20, Justification::topLeft); } @@ -248,6 +266,18 @@ void WaveformComponent::setAudioBuffer(AudioBuffer* buf, int samplerate, m_thumb->addBlock(0, *buf, 0, len); } +void WaveformComponent::beginAddingAudioBlocks(int channels, int samplerate, int totalllen) +{ + m_waveimage = Image(); + m_curfile = File(); + m_thumb->reset(channels, samplerate, totalllen); +} + +void WaveformComponent::addAudioBlock(AudioBuffer& buf, int samplerate, int pos) +{ + m_thumb->addBlock(pos, buf, 0, buf.getNumSamples()); +} + void WaveformComponent::timerCallback() { repaint(); diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 8ccb01d..d07a6c6 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -79,6 +79,8 @@ public: void paint(Graphics& g) override; void setAudioFile(File f); void setAudioBuffer(AudioBuffer* buf, int samplerate, int len); + void beginAddingAudioBlocks(int channels, int samplerate, int totalllen); + void addAudioBlock(AudioBuffer& buf, int samplerate, int pos); void timerCallback() override; std::function CursorPosCallback; std::function SeekCallback; @@ -105,6 +107,7 @@ public: void setTimerEnabled(bool b); void setViewRange(Range rng); Value ShowFileCacheRange; + void setRecordingPosition(double pos) { m_rec_pos = pos; } private: AudioThumbnailCache m_thumbcache; @@ -124,6 +127,7 @@ private: Image m_waveimage; OpenGLContext m_ogl; bool m_use_opengl = false; + double m_rec_pos = 0.0; }; @@ -140,6 +144,8 @@ public: void timerCallback(int id) override; void setAudioFile(File f); void setAudioBuffer(AudioBuffer* buf, int samplerate, int len); + void beginAddingAudioBlocks(int channels, int samplerate, int totalllen); + void addAudioBlock(AudioBuffer& buf, int samplerate, int pos); private: PaulstretchpluginAudioProcessor& processor; std::vector> m_parcomps; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 312a9cb..7ba073d 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -10,7 +10,8 @@ #include "PluginProcessor.h" #include "PluginEditor.h" -std::unique_ptr g_propsfile; +#undef min +#undef max //============================================================================== PaulstretchpluginAudioProcessor::PaulstretchpluginAudioProcessor() @@ -30,7 +31,7 @@ PaulstretchpluginAudioProcessor::PaulstretchpluginAudioProcessor() m_afm = std::make_unique(); m_afm->registerBasicFormats(); m_control = std::make_unique(m_afm.get()); - m_control->setPreBufferAmount(3); + m_control->setPreBufferAmount(2); m_control->ppar.pitch_shift.enabled = true; m_control->ppar.freq_shift.enabled = true; m_control->setOnsetDetection(0.0); @@ -126,7 +127,7 @@ void PaulstretchpluginAudioProcessor::prepareToPlay(double sampleRate, int sampl } if (m_ready_to_play == false) { - m_control->setFFTSize(0.7); + m_control->setFFTSize(0.2); m_control->update_player_stretch(); m_control->update_process_parameters(); @@ -169,6 +170,25 @@ bool PaulstretchpluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& } #endif +void copyAudioBufferWrappingPosition(const AudioBuffer& src, AudioBuffer& dest, int destbufpos, int maxdestpos) +{ + for (int i = 0; i < dest.getNumChannels(); ++i) + { + int channel_to_copy = i % src.getNumChannels(); + if (destbufpos + src.getNumSamples() > 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); + } + else + { + dest.copyFrom(channel_to_copy, destbufpos, src, channel_to_copy, 0, src.getNumSamples()); + } + } +} + void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { std::lock_guard locker(m_mutex); @@ -182,16 +202,13 @@ void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, M return; if (m_is_recording == true) { - if (m_rec_pos + buffer.getNumSamples() < m_recbuffer.getNumSamples()) + int recbuflenframes = m_max_reclen * getSampleRate(); + copyAudioBufferWrappingPosition(buffer, m_recbuffer, m_rec_pos, recbuflenframes); + callGUI([this, &buffer](PaulstretchpluginAudioProcessorEditor*ed) { - m_recbuffer.copyFrom(0, m_rec_pos, buffer, 0, 0, buffer.getNumSamples()); - m_recbuffer.copyFrom(1, m_rec_pos, buffer, 1, 0, buffer.getNumSamples()); - } - m_rec_pos += buffer.getNumSamples(); - if (m_rec_pos >= m_max_reclen * getSampleRate()) - { - finishRecording(m_max_reclen*getSampleRate()); - } + ed->addAudioBlock(buffer, getSampleRate(), m_rec_pos); + }, false); + m_rec_pos = (m_rec_pos + buffer.getNumSamples()) % recbuflenframes; return; } m_control->getStretchAudioSource()->val_MainVolume = (float)*getFloatParameter(0); @@ -239,18 +256,23 @@ void PaulstretchpluginAudioProcessor::setStateInformation (const void* data, int void PaulstretchpluginAudioProcessor::setRecordingEnabled(bool b) { std::lock_guard locker(m_mutex); + int lenbufframes = getSampleRate()*m_max_reclen; if (b == true) { m_recbuffer.setSize(2, m_max_reclen*getSampleRate()+4096); m_recbuffer.clear(); m_rec_pos = 0; + callGUI([this,lenbufframes](PaulstretchpluginAudioProcessorEditor* ed) + { + ed->beginAddingAudioBlocks(2, getSampleRate(), lenbufframes); + },false); m_is_recording = true; } else { if (m_is_recording == true) { - finishRecording(m_rec_pos); + finishRecording(lenbufframes); } } } @@ -281,7 +303,7 @@ void PaulstretchpluginAudioProcessor::finishRecording(int lenrecording) auto ed = dynamic_cast(getActiveEditor()); if (ed) { - ed->setAudioBuffer(&m_recbuffer, getSampleRate(), lenrecording); + //ed->setAudioBuffer(&m_recbuffer, getSampleRate(), lenrecording); } } diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 4744651..605c221 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -71,7 +71,7 @@ private: bool m_ready_to_play = false; AudioBuffer m_recbuffer; - double m_max_reclen = 10.0; + double m_max_reclen = 5; bool m_is_recording = false; int m_rec_pos = 0; void finishRecording(int lenrecorded);