It's 2020...
[terminatorX.git] / src / tX_audiodevice.h
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2020  Alexander K├Ânig
4  
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9  
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  
18     File: tX_audiodevice.h
19  
20     Description: Header to tX_mastergui.cc
21 */    
22
23 #ifndef _h_tx_audiodevice
24 #define _h_tx_audiodevice 1
25
26 #include "tX_types.h"
27 #include "tX_global.h"
28 #include "pthread.h"
29 #include <config.h>
30
31 #include <sys/time.h>
32
33 #define NON_RT_BUFF 12
34
35 #ifdef USE_ALSA
36 #include <alsa/asoundlib.h>
37 #endif
38
39 #ifdef USE_JACK
40 #include <jack/jack.h>
41 #endif
42
43 #ifdef USE_PULSE
44 #include <pulse/pulseaudio.h>
45 #endif
46
47 class tX_engine;
48
49 class tX_audiodevice
50 {
51         protected:
52         int samples_per_buffer;
53         int16_t *sample_buffer[2];
54         int current_buffer;
55         int buffer_pos;
56         int vtt_buffer_size;
57         tX_engine *engine;
58         bool is_open;
59         
60         int sample_rate;
61         tX_audiodevice();
62         
63         public:
64         int get_buffersize() { return samples_per_buffer; } /* call only valid *after* open() */
65         int get_sample_rate() { return sample_rate; }
66         
67         virtual int open()=0;
68         virtual int close()=0;
69         
70         void fill_buffer(int16_t *target_buffer, int16_t *next_target_buffer);
71
72         bool get_is_open() { return is_open; }
73         virtual void start();   
74         virtual void play(int16_t*)=0; /* play blocked */
75         virtual ~tX_audiodevice() {}
76 };
77
78
79 #ifdef USE_OSS
80
81 class tX_audiodevice_oss : public tX_audiodevice
82 {
83         int fd;
84         int blocksize;  
85
86         public:
87         virtual int open();
88         virtual int close();
89         virtual void play(int16_t*);
90         
91         tX_audiodevice_oss();
92 };
93
94 #endif
95
96
97 #ifdef USE_ALSA
98
99 class tX_audiodevice_alsa : public tX_audiodevice
100 {
101         snd_pcm_t *pcm_handle;
102         snd_pcm_uframes_t period_size;
103         
104         public:
105         virtual int open();
106         virtual int close();
107         virtual void play(int16_t*);
108         
109         tX_audiodevice_alsa();
110 };
111
112 #endif
113
114 #ifdef USE_PULSE
115
116 class tX_audiodevice_pulse : public tX_audiodevice
117 {
118         pa_mainloop *mainloop;
119         pa_mainloop_api *mainloop_api;
120         pa_context *context;
121         pa_stream *stream;
122         int16_t *overrun_buffer;
123         unsigned int samples_in_overrun_buffer;
124
125         public:
126         virtual int open();
127         virtual int close();
128         virtual void start();
129         virtual void play(int16_t*);
130
131         tX_audiodevice_pulse();
132         ~tX_audiodevice_pulse();
133         
134         private:
135         // context callbacks
136         static void wrap_context_state_callback(pa_context *context, void *userdata);
137         void context_state_callback(pa_context *context);
138
139         static void wrap_context_drain_complete_callback(pa_context *context, void *userdata);
140         void context_drain_complete_callback(pa_context *context);
141
142         // stream callbacks
143         static void wrap_stream_started_callback(pa_stream *stream, void *userdata);
144         void stream_started_callback(pa_stream *stream);
145
146         static void wrap_stream_underflow_callback(pa_stream *stream, void *userdata);
147         void stream_underflow_callback(pa_stream *stream);
148         
149         static void wrap_stream_overflow_callback(pa_stream *stream, void *userdata);
150         void stream_overflow_callback(pa_stream *stream);
151         
152         static void wrap_stream_drain_complete_callback(pa_stream *stream, int success, void *userdata);
153         void stream_drain_complete_callback(pa_stream *stream, int success);
154
155         static void wrap_stream_trigger_success_callback(pa_stream *stream, int success, void *userdata);
156         void stream_trigger_success_callback(pa_stream *stream, int success);
157
158         static void wrap_stream_write_callback(pa_stream *stream, size_t length, void *userdata);
159         void stream_write_callback(pa_stream *stream, size_t length);
160 };
161
162 #endif
163
164 #ifdef USE_JACK
165
166 class tX_jack_client;
167
168 class tX_audiodevice_jack : public tX_audiodevice
169 {
170         private:
171         tX_jack_client *client;
172         jack_default_audio_sample_t *overrun_buffer;
173         unsigned int samples_in_overrun_buffer;
174         
175         public:
176         virtual int open();
177         virtual int close();
178         virtual void play(int16_t*);
179         virtual void start();
180         void fill_frames(jack_default_audio_sample_t *left, jack_default_audio_sample_t *right, jack_nframes_t nframes);
181         
182         tX_audiodevice_jack();  
183 };
184
185 class tX_jack_client
186 {
187         public:
188         static tX_jack_client *get_instance() { return &instance; };
189         bool init();
190         ~tX_jack_client();
191         
192         private:
193         tX_jack_client();       
194         static tX_jack_client instance;
195         static void error(const char *desc);
196         static int srate(jack_nframes_t nframes, void *arg);
197         static void shutdown(void *arg);
198         static int process(jack_nframes_t nframes, void *arg);
199         
200         jack_client_t *client;  
201         tX_audiodevice_jack *device;
202         jack_port_t *left_port;
203         jack_port_t *right_port;
204         bool jack_shutdown;
205         bool client_initialized;
206         int play(jack_nframes_t nframes);
207         
208         public:
209         int get_sample_rate();
210         bool get_jack_shutdown() { return jack_shutdown; }
211         void set_device(tX_audiodevice_jack *dev) { device=dev; }
212 };
213
214 #endif
215
216 #endif