diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-07-13 11:25:59 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-07-13 11:25:59 +0200 | 
| commit | 633bac9e82aef192a803666aaf3d3dcff920ac0c (patch) | |
| tree | b4b253162c0dcdbace27807e11e5915ebce1cfab /drumgizmo | |
| parent | 7557e5d1713337f4acc3f531e5b88a1195476eec (diff) | |
Use the latency reported by the engine in the jack and wavfile output modules.
Diffstat (limited to 'drumgizmo')
| -rw-r--r-- | drumgizmo/drumgizmoc.cc | 1 | ||||
| -rw-r--r-- | drumgizmo/jackclient.cc | 20 | ||||
| -rw-r--r-- | drumgizmo/jackclient.h | 3 | ||||
| -rw-r--r-- | drumgizmo/output/jackaudio.cc | 36 | ||||
| -rw-r--r-- | drumgizmo/output/jackaudio.h | 4 | ||||
| -rw-r--r-- | drumgizmo/output/wavfile.cc | 35 | ||||
| -rw-r--r-- | drumgizmo/output/wavfile.h | 14 | 
7 files changed, 102 insertions, 11 deletions
| diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc index 6433d9d..4f3123b 100644 --- a/drumgizmo/drumgizmoc.cc +++ b/drumgizmo/drumgizmoc.cc @@ -383,6 +383,7 @@ int main(int argc, char* argv[])  	}  	gizmo.setSamplerate(oe->getSamplerate()); +	oe->onLatencyChange(gizmo.getLatency());  	if(!gizmo.init())  	{ diff --git a/drumgizmo/jackclient.cc b/drumgizmo/jackclient.cc index e493e1b..fb71b1b 100644 --- a/drumgizmo/jackclient.cc +++ b/drumgizmo/jackclient.cc @@ -57,6 +57,12 @@ int JackClient::wrapJackProcess(jack_nframes_t nframes, void* arg)  	return static_cast<JackClient*>(arg)->process(nframes);  } +void JackClient::latencyCallback(jack_latency_callback_mode_t mode, +                                 void* arg) +{ +	static_cast<JackClient*>(arg)->jackLatencyCallback(mode); +} +  JackClient::JackClient()  	: client{nullptr}  	, processes{} @@ -65,6 +71,12 @@ JackClient::JackClient()  	jack_status_t status;  	client = jack_client_open("DrumGizmo", JackNullOption, &status);  	jack_set_process_callback(client, JackClient::wrapJackProcess, this); + +	// Register callback which is called by jack when it wants to know about the +	// current port latency. +	jack_set_latency_callback(client, +	                          JackClient::latencyCallback, +	                          this);  }  JackClient::~JackClient() @@ -103,6 +115,14 @@ int JackClient::process(jack_nframes_t num_frames)  	return 0;  } +void JackClient::jackLatencyCallback(jack_latency_callback_mode_t mode) +{ +	for(auto& ptr : processes) +	{ +		ptr->jackLatencyCallback(mode); +	} +} +  std::size_t JackClient::getBufferSize() const  {  	return jack_get_buffer_size(client); diff --git a/drumgizmo/jackclient.h b/drumgizmo/jackclient.h index 82cc0ed..83e5339 100644 --- a/drumgizmo/jackclient.h +++ b/drumgizmo/jackclient.h @@ -40,6 +40,7 @@ class JackProcess  public:  	virtual ~JackProcess();  	virtual void process(jack_nframes_t num_frames) = 0; +	virtual void jackLatencyCallback(jack_latency_callback_mode_t mode) {}  };  // -------------------------------------------------------------------- @@ -78,6 +79,8 @@ private:  	bool is_active;  	int process(jack_nframes_t num_frames); +	void jackLatencyCallback(jack_latency_callback_mode_t mode);  	static int wrapJackProcess(jack_nframes_t nframes, void* arg); +	static void latencyCallback(jack_latency_callback_mode_t mode, void* arg);  }; diff --git a/drumgizmo/output/jackaudio.cc b/drumgizmo/output/jackaudio.cc index abd7d4f..75766d1 100644 --- a/drumgizmo/output/jackaudio.cc +++ b/drumgizmo/output/jackaudio.cc @@ -33,6 +33,7 @@ JackAudioOutputEngine::JackAudioOutputEngine(JackClient& client)  	: AudioOutputEngine{}  	, client(client)  	, channels{} +	, latency{0}  {  	client.add(*this);  } @@ -122,6 +123,11 @@ size_t JackAudioOutputEngine::getSamplerate() const  	return client.getSampleRate();  } +void JackAudioOutputEngine::onLatencyChange(std::size_t latency) +{ +	this->latency = latency; +} +  JackAudioOutputEngine::Channel::Channel(JackClient& client,                                          const std::string& name,                                          std::size_t buffer_size) @@ -130,3 +136,33 @@ JackAudioOutputEngine::Channel::Channel(JackClient& client,  {  	samples.resize(buffer_size);  } + +void JackAudioOutputEngine::jackLatencyCallback(jack_latency_callback_mode_t mode) +{ +	jack_latency_range_t range; +	switch(mode) +	{ +	case JackCaptureLatency: +		// We do not have any audio input ports. Use this for when we do... +//		jack_port_get_latency_range(port_feeding_input_port, +//		                            JackPlaybackLatency, +//		                            &range); +//		range.min += 0; +//		range.max += 0; +//		jack_port_set_latency_range(input_port, JackPlaybackLatency, &range); +		break; +	case JackPlaybackLatency: +		for(auto& channel : channels) +		{ +			jack_port_get_latency_range(channel.port.port, +			                            JackPlaybackLatency, +			                            &range); +			range.min += latency; +			range.max += latency; +			jack_port_set_latency_range(channel.port.port, +			                            JackPlaybackLatency, +			                            &range); +		} +		break; +	} +} diff --git a/drumgizmo/output/jackaudio.h b/drumgizmo/output/jackaudio.h index 324e95a..b8fbcab 100644 --- a/drumgizmo/output/jackaudio.h +++ b/drumgizmo/output/jackaudio.h @@ -49,11 +49,14 @@ public:  	void post(size_t nsamples) override;  	size_t getBufferSize() const override;  	size_t getSamplerate() const override; +	void onLatencyChange(std::size_t latency) override;  	// based on JackProcess  	void process(jack_nframes_t num_frames) override; +	void jackLatencyCallback(jack_latency_callback_mode_t mode) override;  private: +  	struct Channel  	{  		JackPort port; @@ -66,4 +69,5 @@ private:  	JackClient& client;  	std::vector<Channel> channels;  	Semaphore sema; +	std::size_t latency{0};  }; diff --git a/drumgizmo/output/wavfile.cc b/drumgizmo/output/wavfile.cc index a9d8b0b..20b63bd 100644 --- a/drumgizmo/output/wavfile.cc +++ b/drumgizmo/output/wavfile.cc @@ -33,6 +33,7 @@ WavfileOutputEngine::WavfileOutputEngine()  	, info{}  	, channels{}  	, file{"output"} +	, latency{0}  {  	info.samplerate = 44100;  	info.channels = 1; @@ -69,7 +70,8 @@ bool WavfileOutputEngine::init(const Channels& data)  	return true;  } -void WavfileOutputEngine::setParm(const std::string& parm, const std::string& value) +void WavfileOutputEngine::setParm(const std::string& parm, +                                  const std::string& value)  {  	if(parm == "file")  	{ @@ -105,11 +107,11 @@ void WavfileOutputEngine::stop()  {  } -void WavfileOutputEngine::pre(size_t nsamples) +void WavfileOutputEngine::pre(std::size_t nsamples)  {  } -void WavfileOutputEngine::run(int ch, sample_t* samples, size_t nsamples) +void WavfileOutputEngine::run(int ch, sample_t* samples, std::size_t nsamples)  {  	if(static_cast<unsigned int>(ch) >= channels.size())  	{ @@ -118,14 +120,35 @@ void WavfileOutputEngine::run(int ch, sample_t* samples, size_t nsamples)  		return;  	} -	sf_writef_float(channels[ch], samples, nsamples); +	// Skip the initial 'latency' samples. +	if(nsamples <= latency) +	{ +		return; +	} + +	nsamples -= latency; + +	sf_writef_float(channels[ch], samples + latency, nsamples);  } -void WavfileOutputEngine::post(size_t nsamples) +void WavfileOutputEngine::post(std::size_t nsamples)  { +	if(latency > nsamples) +	{ +		latency -= nsamples; +	} +	else +	{ +		latency = 0; +	}  } -size_t WavfileOutputEngine::getSamplerate() const +std::size_t WavfileOutputEngine::getSamplerate() const  {  	return info.samplerate;  } + +void WavfileOutputEngine::onLatencyChange(std::size_t latency) +{ +	this->latency = latency; +} diff --git a/drumgizmo/output/wavfile.h b/drumgizmo/output/wavfile.h index dfe422c..656c0cd 100644 --- a/drumgizmo/output/wavfile.h +++ b/drumgizmo/output/wavfile.h @@ -25,6 +25,8 @@   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */  #pragma once + +#include <cstddef>  #include <string>  #include <vector> @@ -44,15 +46,17 @@ public:  	void setParm(const std::string& parm, const std::string& value) override;  	bool start() override;  	void stop() override; -	void pre(size_t nsamples) override; -	void run(int ch, sample_t* samples, size_t nsamples) override; -	void post(size_t nsamples) override; -	size_t getSamplerate() const override; +	void pre(std::size_t nsamples) override; +	void run(int ch, sample_t* samples, std::size_t nsamples) override; +	void post(std::size_t nsamples) override; +	std::size_t getSamplerate() const override; +	void onLatencyChange(std::size_t latency) override;  private:  	SF_INFO info;  	std::vector<SNDFILE*> channels; -	size_t num_channels; +	std::size_t num_channels;  	std::string file; +	std::size_t latency;  }; | 
