1 /*
2  * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef __libbackend_alsa_slave_h__
20 #define __libbackend_alsa_slave_h__
21 
22 #include <pthread.h>
23 
24 #include "pbd/ringbuffer.h"
25 #include "pbd/g_atomic_compat.h"
26 
27 #include "zita-resampler/vresampler.h"
28 #include "zita-alsa-pcmi.h"
29 
30 namespace ARDOUR {
31 
32 class AlsaAudioSlave
33 {
34 public:
35 	AlsaAudioSlave (
36 			const char   *play_name,
37 			const char   *capt_name,
38 			unsigned int  master_rate,
39 			unsigned int  master_samples_per_period,
40 			unsigned int  slave_rate,
41 			unsigned int  slave_samples_per_period,
42 			unsigned int  periods_per_cycle);
43 
44 	virtual ~AlsaAudioSlave ();
45 
46 	bool start ();
47 	void stop ();
48 
49 	void cycle_start (double, double, bool);
50 	void cycle_end ();
51 
52 	uint32_t capt_chan (uint32_t chn, float* dst, uint32_t n_samples);
53 	uint32_t play_chan (uint32_t chn, float* src, uint32_t n_samples);
54 
running()55 	bool running () const { return _active; }
56 	void freewheel (bool);
57 
state(void)58 	int      state (void) const { return _pcmi.state (); }
nplay(void)59 	uint32_t nplay (void) const { return _pcmi.nplay (); }
ncapt(void)60 	uint32_t ncapt (void) const { return _pcmi.ncapt (); }
61 
62 	PBD::Signal0<void> Halted;
63 
64 protected:
65 	virtual void update_latencies (uint32_t, uint32_t) = 0;
66 
67 private:
68 	Alsa_pcmi _pcmi;
69 
70 	static void* _process_thread (void *);
71 	void* process_thread ();
72 	pthread_t _thread;
73 
74 	bool  _run; /* keep going or stop, ardour thread */
75 	bool  _active; /* is running, process thread */
76 
77 	/* DLL, track slave process callback */
78 	double _t0, _t1;
79 	uint64_t _samples_since_dll_reset;
80 
81 	double   _ratio;
82 	uint32_t _capt_latency;
83 	double   _play_latency;
84 
85 	volatile double _slave_speed;
86 
87 	GATOMIC_QUAL gint _draining;
88 
89 	PBD::RingBuffer<float> _rb_capture;
90 	PBD::RingBuffer<float> _rb_playback;
91 
92 	size_t _samples_per_period; // master
93 
94 	float* _capt_buff;
95 	float* _play_buff;
96 	float* _src_buff;
97 
98 	ArdourZita::VResampler _src_capt;
99 	ArdourZita::VResampler _src_play;
100 
101 	static void reset_resampler (ArdourZita::VResampler&);
102 
103 }; // class AlsaAudioSlave
104 
105 } // namespace
106 #endif /* __libbackend_alsa_slave_h__ */
107