Some improvements. To keep things saner use the single stretch source for now.
This commit is contained in:
parent
962d4806b5
commit
1590110a24
@ -48,6 +48,7 @@ public:
|
|||||||
PlayRangeEndCallback=[](AInputS*){};
|
PlayRangeEndCallback=[](AInputS*){};
|
||||||
}
|
}
|
||||||
~AInputS() {}
|
~AInputS() {}
|
||||||
|
|
||||||
void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len)
|
void setAudioBuffer(AudioBuffer<float>* buf, int samplerate, int len)
|
||||||
{
|
{
|
||||||
m_afreader = nullptr;
|
m_afreader = nullptr;
|
||||||
@ -60,6 +61,7 @@ public:
|
|||||||
m_loop_enabled = true;
|
m_loop_enabled = true;
|
||||||
m_crossfadebuf.setSize(info.nchannels, m_crossfadebuf.getNumSamples());
|
m_crossfadebuf.setSize(info.nchannels, m_crossfadebuf.getNumSamples());
|
||||||
m_cached_file_range = { 0,len };
|
m_cached_file_range = { 0,len };
|
||||||
|
seek(m_activerange.getStart());
|
||||||
updateXFadeCache();
|
updateXFadeCache();
|
||||||
}
|
}
|
||||||
bool openAudioFile(File file) override
|
bool openAudioFile(File file) override
|
||||||
|
@ -33,7 +33,7 @@ extern std::unique_ptr<PropertiesFile> g_propsfile;
|
|||||||
|
|
||||||
Control::Control(AudioFormatManager* afm) : m_afm(afm), m_bufferingthread("stretchbufferingthread")
|
Control::Control(AudioFormatManager* afm) : m_afm(afm), m_bufferingthread("stretchbufferingthread")
|
||||||
{
|
{
|
||||||
m_stretch_source = std::make_unique<MultiStretchAudioSource>(2,m_afm);
|
m_stretch_source = std::make_unique<StretchAudioSource>(2,m_afm);
|
||||||
|
|
||||||
|
|
||||||
wavinfo.samplerate=44100;
|
wavinfo.samplerate=44100;
|
||||||
@ -619,91 +619,3 @@ void Control::update_process_parameters()
|
|||||||
//if (player)
|
//if (player)
|
||||||
// player->set_process_parameters(&ppar,&bbpar);
|
// player->set_process_parameters(&ppar,&bbpar);
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioCallback::AudioCallback() : AudioIODeviceCallback(),
|
|
||||||
m_writethread("audio_out_record_thread")
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioCallback::audioDeviceAboutToStart(AudioIODevice * device)
|
|
||||||
{
|
|
||||||
m_debugcount = 0;
|
|
||||||
m_outpos = 0.0;
|
|
||||||
m_outsr = device->getCurrentSampleRate();
|
|
||||||
if (m_aviscomponent)
|
|
||||||
m_aviscomponent->setNumChannels(m_numoutchans);
|
|
||||||
if (m_bufferingsource)
|
|
||||||
{
|
|
||||||
if (m_prebufferthread->isThreadRunning()==false)
|
|
||||||
m_prebufferthread->startThread(g_propsfile->getIntValue("prebufthreadpriority",5));
|
|
||||||
int bufsize = std::max(512, device->getCurrentBufferSizeSamples());
|
|
||||||
//Logger::writeToLog("Using buffer size " + String(bufsize));
|
|
||||||
m_bufferingsource->prepareToPlay(bufsize, m_outsr);
|
|
||||||
}
|
|
||||||
m_playing = true;
|
|
||||||
//Logger::writeToLog("hw samplerate " + String(m_outsr));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioCallback::audioDeviceStopped()
|
|
||||||
{
|
|
||||||
m_writer = nullptr;
|
|
||||||
if (m_writethread.isThreadRunning() == true)
|
|
||||||
{
|
|
||||||
if (m_writethread.stopThread(1000) == false)
|
|
||||||
{
|
|
||||||
Logger::writeToLog("OUCH, live output recording thread didn't stop cleanly!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_bufferingsource)
|
|
||||||
{
|
|
||||||
m_bufferingsource->releaseResources();
|
|
||||||
if (m_prebufferthread->isThreadRunning() == true)
|
|
||||||
{
|
|
||||||
if (m_prebufferthread->stopThread(1000) == false)
|
|
||||||
Logger::writeToLog("OUCH, prebuffering thread did not stop cleanly!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_playing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioCallback::audioDeviceIOCallback(const float ** /*inputChannelData*/, int, float ** outputChannelData, int numOutputChannels, int numSamples)
|
|
||||||
{
|
|
||||||
if (m_bufferingsource == nullptr)
|
|
||||||
return;
|
|
||||||
AudioBuffer<float> buf(outputChannelData, numOutputChannels, numSamples);
|
|
||||||
AudioSourceChannelInfo ainfo(buf);
|
|
||||||
m_bufferingsource->getNextAudioBlock(ainfo);
|
|
||||||
if (m_aviscomponent && m_aviscomponent->isVisible())
|
|
||||||
{
|
|
||||||
m_aviscomponent->pushBuffer((const float**)outputChannelData, m_numoutchans, numSamples);
|
|
||||||
}
|
|
||||||
if (m_writer && m_is_recording == true)
|
|
||||||
{
|
|
||||||
m_writer->write((const float**)outputChannelData, numSamples);
|
|
||||||
}
|
|
||||||
m_outpos += (double)numSamples / m_outsr;
|
|
||||||
}
|
|
||||||
|
|
||||||
String AudioCallback::startRecording(File outfile)
|
|
||||||
{
|
|
||||||
WavAudioFormat wavformat;
|
|
||||||
auto outstream = outfile.createOutputStream();
|
|
||||||
if (outstream == nullptr)
|
|
||||||
return "Could not create output stream";
|
|
||||||
auto writer = wavformat.createWriterFor(outstream, m_outsr, m_numoutchans, 32, StringPairArray(), 0);
|
|
||||||
if (writer != nullptr)
|
|
||||||
{
|
|
||||||
if (m_writethread.isThreadRunning()==false)
|
|
||||||
m_writethread.startThread();
|
|
||||||
m_writer = std::make_unique<AudioFormatWriter::ThreadedWriter>(writer, m_writethread, 65536);
|
|
||||||
m_is_recording = true;
|
|
||||||
return String();
|
|
||||||
}
|
|
||||||
return "Could not create audio writer";
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioCallback::setNumOutchans(int numchans)
|
|
||||||
{
|
|
||||||
m_numoutchans = jlimit(2, g_maxnumoutchans, numchans);
|
|
||||||
}
|
|
||||||
|
@ -26,36 +26,6 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../JuceLibraryCode/JuceHeader.h"
|
#include "../JuceLibraryCode/JuceHeader.h"
|
||||||
#include "../ps3_BufferingAudioSource.h"
|
#include "../ps3_BufferingAudioSource.h"
|
||||||
|
|
||||||
class AudioCallback : public AudioIODeviceCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AudioCallback();
|
|
||||||
void audioDeviceAboutToStart(AudioIODevice* device) override;
|
|
||||||
void audioDeviceStopped() override;
|
|
||||||
void audioDeviceIOCallback (const float** inputChannelData,
|
|
||||||
int numInputChannels,
|
|
||||||
float** outputChannelData,
|
|
||||||
int numOutputChannels,
|
|
||||||
int numSamples) override;
|
|
||||||
String startRecording(File outfile);
|
|
||||||
|
|
||||||
std::atomic<bool> m_is_recording{ false };
|
|
||||||
AudioVisualiserComponent* m_aviscomponent = nullptr;
|
|
||||||
std::unique_ptr<AudioFormatWriter::ThreadedWriter> m_writer;
|
|
||||||
TimeSliceThread m_writethread;
|
|
||||||
TimeSliceThread* m_prebufferthread = nullptr;
|
|
||||||
MyBufferingAudioSource* m_bufferingsource = nullptr;
|
|
||||||
MultiStretchAudioSource* m_sas = nullptr;
|
|
||||||
std::atomic<bool> m_playing{false};
|
|
||||||
double m_outpos = 0.0;
|
|
||||||
void setNumOutchans(int numchans);
|
|
||||||
private:
|
|
||||||
std::mutex m_mutex;
|
|
||||||
int m_debugcount = 0;
|
|
||||||
int m_outsr = 44100;
|
|
||||||
int m_numoutchans = 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RenderInfo
|
class RenderInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -102,7 +72,7 @@ public:
|
|||||||
void setFFTSize(double size);
|
void setFFTSize(double size);
|
||||||
int getFFTSize() { return m_fft_size_to_use; }
|
int getFFTSize() { return m_fft_size_to_use; }
|
||||||
void setOnsetDetection(double x);
|
void setOnsetDetection(double x);
|
||||||
MultiStretchAudioSource* getStretchAudioSource() { return m_stretch_source.get(); }
|
StretchAudioSource* getStretchAudioSource() { return m_stretch_source.get(); }
|
||||||
void set_input_file(File filename, std::function<void(String)> cb);//return non empty String if the file cannot be opened
|
void set_input_file(File filename, std::function<void(String)> cb);//return non empty String if the file cannot be opened
|
||||||
String get_input_filename();
|
String get_input_filename();
|
||||||
String get_stretch_info(Range<double> playrange);
|
String get_stretch_info(Range<double> playrange);
|
||||||
@ -169,7 +139,7 @@ private:
|
|||||||
REALTYPE seek_pos;
|
REALTYPE seek_pos;
|
||||||
AudioFormatManager* m_afm = nullptr;
|
AudioFormatManager* m_afm = nullptr;
|
||||||
TimeSliceThread m_bufferingthread;
|
TimeSliceThread m_bufferingthread;
|
||||||
std::unique_ptr<MultiStretchAudioSource> m_stretch_source;
|
std::unique_ptr<StretchAudioSource> m_stretch_source;
|
||||||
std::unique_ptr<MyBufferingAudioSource> m_buffering_source;
|
std::unique_ptr<MyBufferingAudioSource> m_buffering_source;
|
||||||
int m_prebuffer_amount = 1;
|
int m_prebuffer_amount = 1;
|
||||||
bool m_recreate_buffering_source = true;
|
bool m_recreate_buffering_source = true;
|
||||||
|
@ -123,6 +123,8 @@ void StretchAudioSource::setAudioBufferAsInputSource(AudioBuffer<float>* buf, in
|
|||||||
m_seekpos = 0.0;
|
m_seekpos = 0.0;
|
||||||
m_lastinpos = 0.0;
|
m_lastinpos = 0.0;
|
||||||
m_curfile = File();
|
m_curfile = File();
|
||||||
|
if (m_playrange.isEmpty())
|
||||||
|
setPlayRange({ 0.0,1.0 }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StretchAudioSource::getNextAudioBlock(const AudioSourceChannelInfo & bufferToFill)
|
void StretchAudioSource::getNextAudioBlock(const AudioSourceChannelInfo & bufferToFill)
|
||||||
|
@ -40,6 +40,7 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor (Pa
|
|||||||
};
|
};
|
||||||
m_wavecomponent.ShowFileCacheRange = true;
|
m_wavecomponent.ShowFileCacheRange = true;
|
||||||
startTimer(1, 100);
|
startTimer(1, 100);
|
||||||
|
m_wavecomponent.startTimer(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
PaulstretchpluginAudioProcessorEditor::~PaulstretchpluginAudioProcessorEditor()
|
PaulstretchpluginAudioProcessorEditor::~PaulstretchpluginAudioProcessorEditor()
|
||||||
|
@ -114,7 +114,17 @@ void PaulstretchpluginAudioProcessor::changeProgramName (int index, const String
|
|||||||
void PaulstretchpluginAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
|
void PaulstretchpluginAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
|
||||||
{
|
{
|
||||||
if (m_using_memory_buffer == true)
|
if (m_using_memory_buffer == true)
|
||||||
m_control->getStretchAudioSource()->setAudioBufferAsInputSource(&m_recbuffer, getSampleRate(), m_recbuffer.getNumSamples());
|
{
|
||||||
|
int len = jlimit(100,m_recbuffer.getNumSamples(), m_rec_pos);
|
||||||
|
m_control->getStretchAudioSource()->setAudioBufferAsInputSource(&m_recbuffer,
|
||||||
|
getSampleRate(),
|
||||||
|
len);
|
||||||
|
auto ed = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(getActiveEditor());
|
||||||
|
if (ed)
|
||||||
|
{
|
||||||
|
ed->setAudioBuffer(&m_recbuffer, getSampleRate(), len);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m_ready_to_play == false)
|
if (m_ready_to_play == false)
|
||||||
{
|
{
|
||||||
m_control->update_player_stretch();
|
m_control->update_player_stretch();
|
||||||
@ -180,7 +190,8 @@ bool PaulstretchpluginAudioProcessor::isBusesLayoutSupported (const BusesLayout&
|
|||||||
|
|
||||||
void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
|
void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
|
||||||
{
|
{
|
||||||
ScopedNoDenormals noDenormals;
|
std::lock_guard<std::mutex> locker(m_mutex);
|
||||||
|
ScopedNoDenormals noDenormals;
|
||||||
const int totalNumInputChannels = getTotalNumInputChannels();
|
const int totalNumInputChannels = getTotalNumInputChannels();
|
||||||
const int totalNumOutputChannels = getTotalNumOutputChannels();
|
const int totalNumOutputChannels = getTotalNumOutputChannels();
|
||||||
|
|
||||||
@ -245,6 +256,7 @@ 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);
|
||||||
if (b == true)
|
if (b == true)
|
||||||
{
|
{
|
||||||
m_is_recording = true;
|
m_is_recording = true;
|
||||||
@ -272,10 +284,11 @@ void PaulstretchpluginAudioProcessor::finishRecording(int lenrecording)
|
|||||||
{
|
{
|
||||||
m_is_recording = false;
|
m_is_recording = false;
|
||||||
m_control->getStretchAudioSource()->setAudioBufferAsInputSource(&m_recbuffer, getSampleRate(), lenrecording);
|
m_control->getStretchAudioSource()->setAudioBufferAsInputSource(&m_recbuffer, getSampleRate(), lenrecording);
|
||||||
|
m_control->getStretchAudioSource()->setPlayRange({ *getFloatParameter(5),*getFloatParameter(6) }, true);
|
||||||
auto ed = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(getActiveEditor());
|
auto ed = dynamic_cast<PaulstretchpluginAudioProcessorEditor*>(getActiveEditor());
|
||||||
if (ed)
|
if (ed)
|
||||||
{
|
{
|
||||||
ed->setAudioBuffer(&m_recbuffer, getSampleRate(), m_rec_pos);
|
ed->setAudioBuffer(&m_recbuffer, getSampleRate(), lenrecording);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ private:
|
|||||||
int m_rec_pos = 0;
|
int m_rec_pos = 0;
|
||||||
void finishRecording(int lenrecorded);
|
void finishRecording(int lenrecorded);
|
||||||
bool m_using_memory_buffer = true;
|
bool m_using_memory_buffer = true;
|
||||||
|
std::mutex m_mutex;
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessor)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaulstretchpluginAudioProcessor)
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<JUCERPROJECT id="fn1Rg8" name="paulstretchplugin" displaySplashScreen="0"
|
<JUCERPROJECT id="fn1Rg8" name="paulstretchplugin" displaySplashScreen="0"
|
||||||
reportAppUsage="1" splashScreenColour="Dark" projectType="audioplug"
|
reportAppUsage="0" splashScreenColour="Dark" projectType="audioplug"
|
||||||
version="1.0.0" bundleIdentifier="com.yourcompany.paulstretchplugin"
|
version="1.0.0" bundleIdentifier="com.yourcompany.paulstretchplugin"
|
||||||
includeBinaryInAppConfig="1" cppLanguageStandard="latest" companyCopyright=""
|
includeBinaryInAppConfig="1" cppLanguageStandard="latest" companyCopyright=""
|
||||||
buildVST="1" buildVST3="0" buildAU="1" buildAUv3="0" buildRTAS="0"
|
buildVST="1" buildVST3="0" buildAU="1" buildAUv3="0" buildRTAS="0"
|
||||||
|
Loading…
Reference in New Issue
Block a user