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