Some improvements. To keep things saner use the single stretch source for now.
This commit is contained in:
		| @@ -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,6 +190,7 @@ bool PaulstretchpluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& | |||||||
|  |  | ||||||
| void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) | void PaulstretchpluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) | ||||||
| { | { | ||||||
|  | 	std::lock_guard<std::mutex> locker(m_mutex); | ||||||
| 	ScopedNoDenormals noDenormals; | 	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" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 xenakios
					xenakios