It's 2020...
[terminatorX.git] / src / tX_audiodevice.cc
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_aduiodevice.cc
19  
20     Description: Implements Audiodevice handling... 
21 */    
22
23 #define ALSA_PCM_NEW_HW_PARAMS_API
24
25 #include "tX_audiodevice.h"
26 #include "tX_vtt.h"
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <sys/ioctl.h>
31 #include <fcntl.h>
32 #include <sys/soundcard.h>
33 #include <config.h>
34 #include <string.h>
35
36 #include "tX_endian.h"
37
38 #ifndef __USE_XOPEN
39 #       define __USE_XOPEN // we need this for swab()
40 #       include <unistd.h>
41 #       undef __USE_XOPEN
42 #else
43 #       include <unistd.h>
44 #endif
45
46 #include <string.h>
47 #include <errno.h>
48 #include <stdlib.h>
49 #include "tX_engine.h"
50
51 tX_audiodevice :: tX_audiodevice() : samples_per_buffer(0),
52 current_buffer(0), buffer_pos(0), is_open(false)
53 {
54         sample_buffer[0]=NULL;
55         sample_buffer[1]=NULL;
56         engine=tX_engine::get_instance();
57 }
58
59 void tX_audiodevice :: start() {
60         sample_buffer[0]=new int16_t[samples_per_buffer*2];
61         sample_buffer[1]=new int16_t[samples_per_buffer*2];
62         int current=0;
63         vtt_buffer_size=vtt_class::get_mix_buffer_size()<<1;
64         
65         buffer_pos=0;
66         
67         while (!engine->is_stopped()) {
68                 current=current ? 0 : 1;
69                 
70                 int16_t *current_buffer=sample_buffer[current];
71                 int16_t *next_buffer=sample_buffer[current ? 0 : 1];
72                 
73                 fill_buffer(current_buffer, next_buffer);
74                 play(current_buffer);
75         }
76         
77         delete [] sample_buffer[0];
78         delete [] sample_buffer[1];
79 }
80
81 void tX_audiodevice :: fill_buffer(int16_t *target_buffer, int16_t *next_target_buffer) {
82         int prefill=0;
83         
84         while (buffer_pos <= samples_per_buffer) {
85                 int16_t *data=engine->render_cycle();
86                 
87                 int rest=(buffer_pos+vtt_buffer_size)-samples_per_buffer;
88                 
89                 if (rest<=0) {
90                         memcpy(&target_buffer[buffer_pos], data, vtt_buffer_size << 1);
91                 } else {
92                         memcpy(&target_buffer[buffer_pos], data, (vtt_buffer_size-rest) << 1);
93                         memcpy(next_target_buffer, &data[vtt_buffer_size-rest], rest << 1);
94                         prefill=rest;
95                 }
96                 
97                 buffer_pos+=vtt_buffer_size;
98         }
99         
100         buffer_pos=prefill;
101 }
102
103 /* Driver Specific Code follows.. */
104
105 #ifdef USE_OSS
106
107 int tX_audiodevice_oss :: open()
108 {
109         int i=0;
110         int p;
111         int buff_cfg;
112
113         if (fd) return (1);
114         fd=::open(globals.oss_device, O_WRONLY, 0);
115         
116         if (fd==-1) {
117                 tX_error("tX_audiodevice_oss::open() can't open device: %s", strerror(errno));
118                 return -1;
119         }
120         
121         is_open=true;
122         
123         /* setting buffer size */       
124         buff_cfg=(globals.oss_buff_no<<16) | globals.oss_buff_size;
125         p=buff_cfg;
126
127         tX_debug("tX_audiodevice_oss::open() - buff_no: %i, buff_size: %i, buff_cfg: %08x", globals.oss_buff_no, globals.oss_buff_size, buff_cfg);
128                 
129         i = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &p);
130         ioctl(fd, SNDCTL_DSP_RESET, 0);         
131
132         /* 16 Bits */
133         
134         p =  16;
135         i +=  ioctl(fd, SOUND_PCM_WRITE_BITS, &p);
136
137         /* STEREO :) */
138         
139         p =  2;
140         i += ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &p);
141         
142         /* 44.1 khz */
143
144         p =  globals.oss_samplerate;
145         i += ioctl(fd, SOUND_PCM_WRITE_RATE, &p);
146         
147         sample_rate=globals.oss_samplerate;
148         
149         /* Figure actual blocksize.. */
150         
151         i += ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blocksize);
152
153         samples_per_buffer=blocksize/sizeof(int16_t);
154
155         tX_debug("tX_adudiodevice_oss::open() - blocksize: %i, samples_per_buffer: %i", blocksize, samples_per_buffer);
156         
157         ioctl(fd, SNDCTL_DSP_SYNC, 0);
158
159         return i;
160 }
161
162 int tX_audiodevice_oss :: close()
163 {
164         if (!fd) {      
165                 return(1);              
166         }
167         is_open=false;
168         ::close(fd);
169         fd=0;
170         blocksize=0;
171                 
172         return 0;
173 }
174
175 tX_audiodevice_oss :: tX_audiodevice_oss() : tX_audiodevice(),
176 fd(0), blocksize(0) {}
177
178 void tX_audiodevice_oss :: play(int16_t *buffer)
179 {
180 #ifdef BIG_ENDIAN_MACHINE
181         swapbuffer (buffer, samples_per_buffer);
182 #endif
183         int res=write(fd, buffer, blocksize);   
184         if (res==-1) {
185                 tX_error("failed to write to audiodevice: %s", strerror(errno));
186                 exit(-1);
187         }
188 }
189
190 #endif //USE_OSS
191
192 #ifdef USE_ALSA
193
194 #define tX_abs(x) (x<0 ? -x : x)
195
196 int tX_audiodevice_alsa :: open()
197 {
198         snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
199         snd_pcm_hw_params_t *hw_params;
200         char pcm_name[64];
201         char *pos;
202         
203         strncpy(pcm_name, globals.alsa_device_id, sizeof(pcm_name));
204         if ((pos = strchr(pcm_name, '#')) != NULL) *pos = 0;
205         
206         if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) {
207                 tX_error("ALSA: Failed to access PCM device \"%s\"", pcm_name);
208                 return -1;
209         }
210         
211         is_open=true;
212
213         snd_pcm_hw_params_alloca(&hw_params);   
214         
215         if (snd_pcm_hw_params_any(pcm_handle, hw_params) < 0) {
216                 tX_error("ALSA: Failed to configure PCM device \"%s\"", pcm_name);
217                 snd_pcm_hw_params_free (hw_params);
218                 return -1;
219         }
220         
221         /* Setting INTERLEAVED stereo... */
222 #ifdef USE_ALSA_MEMCPY
223         if (snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
224 #else
225         if (snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
226 #endif  
227                 tX_error("ALSA: Failed to set interleaved access for PCM device \"%s\"", pcm_name);
228                 snd_pcm_hw_params_free (hw_params);
229                 return -1;
230         }
231         
232         /* Make it 16 Bit native endian */
233         if (snd_pcm_hw_params_set_format(pcm_handle, hw_params, SND_PCM_FORMAT_S16) < 0) {
234                 tX_error("ALSA: Error setting 16 Bit sample width for PCM device \"%s\"", pcm_name);
235                 snd_pcm_hw_params_free (hw_params);
236                 return -1;
237         }
238         
239         /* Setting sampling rate */
240         unsigned int hw_rate=(unsigned int)globals.alsa_samplerate;
241         int dir;
242         
243         if (snd_pcm_hw_params_set_rate_near(pcm_handle, hw_params, &hw_rate, &dir) < 0) {
244                 tX_error("ALSA: Failed setting sample rate: %i", globals.alsa_samplerate);
245                 snd_pcm_hw_params_free (hw_params);
246                 return -1;
247         }
248         
249         if (dir != 0) {
250                 if (tX_abs(globals.alsa_samplerate - hw_rate) > 2) {
251                         tX_warning("ALSA: The PCM device \"%s\" doesn\'t support %i Hz playback - using %i instead", pcm_name, globals.alsa_samplerate, hw_rate);
252                 }
253         }       
254
255         sample_rate=hw_rate;
256         
257         /* Using stereo output */
258         if (snd_pcm_hw_params_set_channels(pcm_handle, hw_params, 2) < 0) {
259                 tX_error("ALSA: PCM device \"%s\" does not support stereo operation", pcm_name);
260                 snd_pcm_hw_params_free (hw_params);
261                 return -1;
262         }
263         
264         unsigned int buffer_time=globals.alsa_buffer_time;
265         unsigned int period_time=globals.alsa_period_time;
266         
267         if (snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hw_params, &buffer_time, &dir) < 0) {
268                 tX_error("ALSA: failed to set the buffer time opf %i usecs", globals.alsa_buffer_time);
269                 return -1;
270         }
271
272         long unsigned int buffer_size;
273
274         if (snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size) < 0) {
275                 tX_error("ALSA: failed to retrieve buffer size");
276                 return -1;
277         }
278         
279         tX_debug("ALSA: buffer size is %lu", buffer_size);
280         
281         if (snd_pcm_hw_params_set_period_time_near(pcm_handle, hw_params, &period_time, &dir) < 0) {
282                 tX_error("ALSA: failed to set period time %i", globals.alsa_period_time);
283                 return -1;
284         }
285         
286         if (snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir)<0) {
287                 tX_error("ALSA: failed to retrieve period size");
288                 return -1;
289         }
290         
291         samples_per_buffer=period_size;
292         
293         /* Apply all that setup work.. */
294         if (snd_pcm_hw_params(pcm_handle, hw_params) < 0) {
295                 tX_error("ALSA: Failed to apply settings to PCM device \"%s\"", pcm_name);
296                 snd_pcm_hw_params_free (hw_params);
297                 return -1;
298         }
299         
300         if (globals.alsa_free_hwstats) {
301                 snd_pcm_hw_params_free (hw_params);
302         }
303         
304         return 0; //snd_pcm_prepare(pcm_handle);
305 }
306
307 int tX_audiodevice_alsa :: close()
308 {
309         if (is_open) {
310                 snd_pcm_close(pcm_handle);
311         }
312         is_open=false;
313         
314         return 0;
315 }
316
317 tX_audiodevice_alsa :: tX_audiodevice_alsa() : tX_audiodevice(),
318 pcm_handle(NULL) {}
319
320 void tX_audiodevice_alsa :: play(int16_t *buffer)
321 {
322         int underrun_ctr=0;
323         snd_pcm_sframes_t pcmreturn;
324         
325 #ifdef USE_ALSA_MEMCPY
326         pcmreturn = snd_pcm_writei(pcm_handle, buffer, samples_per_buffer >> 1);
327 #else   
328         pcmreturn = snd_pcm_mmap_writei(pcm_handle, buffer, samples_per_buffer >> 1);
329 #endif
330         
331         while (pcmreturn==-EPIPE) {
332                 snd_pcm_prepare(pcm_handle);
333                 
334 #ifdef USE_ALSA_MEMCPY
335                 pcmreturn = snd_pcm_writei(pcm_handle, buffer, samples_per_buffer >> 1);
336 #else   
337                 pcmreturn = snd_pcm_mmap_writei(pcm_handle, buffer, samples_per_buffer >> 1);
338 #endif
339                 underrun_ctr++;
340                 if (underrun_ctr>100) {
341                         tX_error("tX_audiodevice_alsa::play() more than 10 EPIPE cycles. Giving up.");
342                         break;
343                 }
344                 //tX_warning("ALSA: ** buffer underrun **");
345         }
346         
347         if (pcmreturn<0) {
348                 printf("snd_pcm_writei says: %s.\n", strerror(-1*pcmreturn));
349         }
350 }
351
352 #endif //USE_ALSA
353
354 #ifdef USE_PULSE
355 #include <pulse/error.h>
356
357 void tX_audiodevice_pulse::wrap_stream_started_callback(pa_stream *stream, void *userdata) {
358         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
359         device->stream_started_callback(stream);
360 }
361
362 void tX_audiodevice_pulse::wrap_stream_underflow_callback(pa_stream *stream, void *userdata) {
363         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
364         device->stream_underflow_callback(stream);
365 }
366
367 void tX_audiodevice_pulse::wrap_stream_overflow_callback(pa_stream *stream, void *userdata) {
368         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
369         device->stream_overflow_callback(stream);
370 }
371
372 void tX_audiodevice_pulse::wrap_stream_drain_complete_callback(pa_stream *stream, int success, void *userdata) {
373         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
374         device->stream_drain_complete_callback(stream, success);
375 }
376
377 void tX_audiodevice_pulse::wrap_stream_trigger_success_callback(pa_stream *stream, int success, void *userdata) {
378         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
379         device->stream_trigger_success_callback(stream, success);
380 }
381
382 void tX_audiodevice_pulse::wrap_stream_write_callback(pa_stream *stream, size_t length, void *userdata) {
383         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
384         device->stream_write_callback(stream, length);
385 }
386
387 void tX_audiodevice_pulse::wrap_context_state_callback(pa_context *context, void *userdata) {
388         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
389         device->context_state_callback(context);
390 }
391
392 void tX_audiodevice_pulse::context_state_callback(pa_context *context) {
393         pa_context_state_t state;
394
395         state = pa_context_get_state(context);
396
397         tX_debug("pulseaudio context state: %i", state);
398         switch (state) {
399                 case PA_CONTEXT_UNCONNECTED:
400                 case PA_CONTEXT_CONNECTING:
401                 case PA_CONTEXT_AUTHORIZING:
402                 case PA_CONTEXT_SETTING_NAME:
403                         break;
404                 case PA_CONTEXT_FAILED:
405                 case PA_CONTEXT_TERMINATED:
406                         if (!engine->is_stopped()) {
407                                 tX_error("pulseaudio disconnected");
408                         }
409                         break;
410
411                 case PA_CONTEXT_READY:
412                         pa_sample_spec spec = {
413                                 .format = PA_SAMPLE_S16LE,
414                                 .rate = 44100,
415                                 .channels = 2
416                         };
417         
418                         pa_buffer_attr attr = {
419                                 .maxlength = (uint32_t) -1,
420                                 .tlength = (uint32_t) (globals.pulse_buffer_length * 2 * sizeof(int16_t)), // 2 bytes per sample, 2 channels
421                                 .prebuf = (uint32_t) -1,
422                                 .minreq = (uint32_t) -1,
423                                 .fragsize = (uint32_t) -1
424                         };
425
426                         pa_stream_flags_t flags = PA_STREAM_ADJUST_LATENCY;
427
428                         if ((stream = pa_stream_new(context, "terminatorX", &spec, NULL))) {
429                                 tX_debug("pulseaudio stream created");
430                                 //pa_stream_set_started_callback(stream, tX_audiodevice_pulse::wrap_stream_started_callback, this);
431                                 //pa_stream_set_underflow_callback(stream, tX_audiodevice_pulse::wrap_stream_underflow_callback, this);
432                                 pa_stream_set_overflow_callback(stream, tX_audiodevice_pulse::wrap_stream_overflow_callback, this);
433                                 pa_stream_set_write_callback(stream, tX_audiodevice_pulse::wrap_stream_write_callback, this);
434
435                                 if (pa_stream_connect_playback(stream, NULL, &attr, flags, NULL, NULL) >= 0) {
436                                         // start the playback.
437                                         pa_stream_trigger(stream, tX_audiodevice_pulse::wrap_stream_trigger_success_callback, this);
438                                 } else {
439                                         tX_error("Failed to connect pulseaudio stream playback: %s", pa_strerror(pa_context_errno(context)));
440                                 }
441                         }       else {
442                                 tX_error("Failed to create pulseaudio stream: %s", pa_strerror(pa_context_errno(context)));
443                         }
444                         break;
445         }
446 }
447
448 void tX_audiodevice_pulse::wrap_context_drain_complete_callback(pa_context *context, void *userdata) {
449         tX_audiodevice_pulse *device = (tX_audiodevice_pulse *) userdata;
450         device->context_drain_complete_callback(context);
451 }
452
453 void tX_audiodevice_pulse::context_drain_complete_callback(pa_context *context) {
454         pa_context_disconnect(context);
455         is_open = false;
456         pa_mainloop_quit(mainloop, 0);
457 }
458
459 void tX_audiodevice_pulse::stream_started_callback(pa_stream *stream) {
460         tX_debug("pulseaudio stream started");
461 }
462
463 void tX_audiodevice_pulse::stream_underflow_callback(pa_stream *stream) {
464         tX_debug("pulseaudio stream underflow");
465 }
466
467 void tX_audiodevice_pulse::stream_overflow_callback(pa_stream *stream) {
468         tX_debug("pulseaudio stream overflow");
469 }
470
471 void tX_audiodevice_pulse::stream_trigger_success_callback(pa_stream *stream, int success) {
472         tX_debug("pulseaudio trigger success %i", success);
473 }
474
475 void tX_audiodevice_pulse::stream_drain_complete_callback(pa_stream *stream, int success) {
476         if (!success) {
477                 tX_debug("pulseaudio drain failed %s", pa_strerror(pa_context_errno(context)));
478         } else {
479                 pa_operation *operation;
480                 pa_stream_disconnect(stream);
481                 pa_stream_unref(stream);
482                 stream = NULL;
483
484                 if (!(operation = pa_context_drain(context, tX_audiodevice_pulse::wrap_context_drain_complete_callback, this))) {
485                         pa_context_disconnect(context);
486                         is_open = false;
487                         pa_mainloop_quit(mainloop, -1);
488                 } else {
489                         pa_operation_unref(operation);
490                 }
491         }
492 }
493
494 void tX_audiodevice_pulse::stream_write_callback(pa_stream *stream, size_t length) {
495         size_t sample_length = length/2;
496
497         if (engine->is_stopped()) {
498                 tX_debug("pulseaudio write callback trying to disconnect pulseaudio");
499                 pa_operation *operation;
500                 pa_stream_set_write_callback(stream, NULL, NULL);
501                 if (!(operation = pa_stream_drain(stream, tX_audiodevice_pulse::wrap_stream_drain_complete_callback, this))) {
502                         tX_error("pulseaudio failed to initiate drain %s", pa_strerror(pa_context_errno(context)));
503                 }
504                 pa_operation_unref(operation);
505         } else {
506                 unsigned int outbuffer_pos=0;
507                 unsigned int sample;
508         
509                 int16_t *outbuffer = NULL;
510                 size_t outbuffer_bytes = length;
511                 pa_stream_begin_write(stream, (void **) &outbuffer, &outbuffer_bytes);
512
513                 if (samples_in_overrun_buffer) {
514                         memcpy(outbuffer, overrun_buffer, sizeof(int16_t) * samples_in_overrun_buffer);
515                         outbuffer_pos+=samples_in_overrun_buffer;
516                 }
517         
518                 while (outbuffer_pos<sample_length) {
519                         int16_t *data=engine->render_cycle();
520
521                         sample = tX_min(vtt_class::samples_in_mix_buffer, (sample_length - outbuffer_pos));
522
523                         memcpy(&outbuffer[outbuffer_pos], data, sizeof(int16_t) * sample);
524                         outbuffer_pos+=sample;
525                 
526                         if (sample < vtt_class::samples_in_mix_buffer) {
527                                 samples_in_overrun_buffer=vtt_class::samples_in_mix_buffer-sample;
528                                 /* There's more data in the mixbuffer... */
529                                 memcpy(overrun_buffer, &data[sample], sizeof(int16_t) * samples_in_overrun_buffer);
530                         } else {
531                                 samples_in_overrun_buffer=0;
532                         }
533                 }
534         
535                 if (pa_stream_write(stream, (uint8_t *) outbuffer, length, NULL, 0, PA_SEEK_RELATIVE) < 0) {
536                         tX_error("pulseaudio error writing to stream: %s", pa_strerror(pa_context_errno(context)));
537                 }
538                 outbuffer = NULL;
539         }
540 }
541
542 void tX_audiodevice_pulse::start() {
543         overrun_buffer=new int16_t[vtt_class::samples_in_mix_buffer];
544         samples_in_overrun_buffer = 0;
545         int result;
546         
547         tX_debug("handover flow control to pulseaudio");
548
549         while (!engine->is_stopped()) {
550                 pa_mainloop_run(mainloop, &result);
551                 tX_debug("pulseaudio mainloop has terminated: %i", result);
552         }       
553         
554         delete [] overrun_buffer;
555 }
556
557 int tX_audiodevice_pulse::open() {
558         mainloop = pa_mainloop_new();
559         mainloop_api = pa_mainloop_get_api(mainloop);
560         context = pa_context_new(mainloop_api, "terminatorX");
561         pa_context_flags_t flags = PA_CONTEXT_NOFLAGS;
562         pa_context_connect(context, NULL, flags, NULL);
563         pa_context_set_state_callback(context, tX_audiodevice_pulse::wrap_context_state_callback, this);
564
565         sample_rate=44100;
566         tX_debug("pulseaudio opened.");
567
568         is_open = true;
569         return 0;
570 }
571
572 int tX_audiodevice_pulse :: close() {
573         return 0;
574 }
575
576 tX_audiodevice_pulse :: tX_audiodevice_pulse() : tX_audiodevice(),
577 mainloop(NULL), mainloop_api(NULL), context(NULL), stream(NULL)  {
578 }
579
580 void tX_audiodevice_pulse :: play(int16_t *buffer) {
581         tX_error("tX_audiodevice_pulse::play()");
582 }
583
584 tX_audiodevice_pulse :: ~tX_audiodevice_pulse() {
585 }
586
587 #endif //USE_PULSE
588
589 #ifdef USE_JACK
590
591 tX_jack_client tX_jack_client::instance;
592
593
594 bool tX_jack_client::init()
595 {
596         if (!client_initialized) {
597                 if ((client=jack_client_open("terminatorX", (jack_options_t) NULL, NULL))==0) {
598                         tX_error("tX_jack_client() -> failed to connect to jackd.");
599                 } else {
600                         client_initialized = true;
601                         const char **ports;
602                         
603                         /* Setting up jack callbacks... */              
604                         jack_set_process_callback(client, tX_jack_client::process, NULL);
605                         jack_set_sample_rate_callback(client, tX_jack_client::srate, NULL);             
606                         jack_on_shutdown (client, tX_jack_client::shutdown, NULL);
607                         
608                         /* Creating the port... */
609                         left_port = jack_port_register (client, "output_1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
610                         right_port = jack_port_register (client, "output_2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
611                 
612                         /* Action... */
613                         jack_activate(client);
614                         
615                         /* Connect some ports... */
616                         if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
617                                 tX_error("tX_jack_client() no ports to connect to found. Connect manually.");
618                         } else if (ports[0] && ports[1]) {
619                                 if (jack_connect (client, jack_port_name(left_port), ports[0])) {
620                                         tX_error("tX_jack_client() failed to connect left port.");
621                                 }
622                                 if (jack_connect (client, jack_port_name(right_port), ports[1])) {
623                                         tX_error("tX_jack_client() failed to connect right port.");
624                                 }
625                                 free (ports);
626                         }
627                 }
628         }
629         
630         return client_initialized;
631 }
632
633 tX_jack_client::tX_jack_client():device(NULL),jack_shutdown(false),client_initialized(false)
634 {
635         jack_set_error_function(tX_jack_client::error);
636 }
637
638 tX_jack_client::~tX_jack_client()
639 {
640         if (client) jack_client_close(client);
641 }
642
643 void tX_jack_client::error(const char *desc)
644 {
645         tX_error("jack error: %s.", desc);
646 }
647
648 int tX_jack_client::srate(jack_nframes_t nframes, void *arg)
649 {
650         tX_error("tX_jack_client::srate() jack changed samplerate - ignored.");
651         return 0;
652 }
653
654 void tX_jack_client::shutdown(void *arg)
655 {
656         tX_error("tX_jack_client::shutdown() jack daemon has shut down. Bad!");
657         instance.jack_shutdown=true;
658 }
659
660 int tX_jack_client::process(jack_nframes_t nframes, void *arg)
661 {
662         return instance.play(nframes);
663         
664         /* Hmm, what to do in such a case? */
665         return 0;
666 }
667
668 int tX_jack_client::play(jack_nframes_t nframes)
669 {
670         jack_default_audio_sample_t *left = (jack_default_audio_sample_t *) jack_port_get_buffer (left_port, nframes);
671         jack_default_audio_sample_t *right = (jack_default_audio_sample_t *) jack_port_get_buffer (right_port, nframes);
672
673         if (device) {
674                 device->fill_frames(left, right, nframes);
675         } else {
676                 memset(left, 0, sizeof (jack_default_audio_sample_t) * nframes);
677                 memset(right, 0, sizeof (jack_default_audio_sample_t) * nframes);
678         }
679         
680         return 0;
681 }
682
683 int tX_jack_client::get_sample_rate() 
684 {
685         return jack_get_sample_rate(client);
686 }
687
688 /* tX_audiodevice_jack */
689
690 tX_audiodevice_jack::tX_audiodevice_jack():tX_audiodevice()
691 {
692         client=NULL;
693 }
694
695 int tX_audiodevice_jack::open()
696 {
697         tX_jack_client *jack_client=tX_jack_client::get_instance();
698         
699         if (jack_client) {
700                 if (jack_client->init()) {
701                         sample_rate=jack_client->get_sample_rate();
702                         client=jack_client;
703                         is_open=true;
704                         
705                         return 0;
706                 }
707         }
708         
709         return 1;
710 }
711
712 int tX_audiodevice_jack::close()
713 {
714         if (client) {
715                 client->set_device(NULL);
716         }
717         
718         is_open=false;  
719         
720         return 0;
721 }
722
723 void tX_audiodevice_jack::play(int16_t *buffer)
724 {
725         tX_error("tX_audiodevice_jack::play()");
726 }
727
728 void tX_audiodevice_jack::start()
729 {
730         overrun_buffer=new f_prec[vtt_class::samples_in_mix_buffer];
731         
732         client->set_device(this);
733         while ((!engine->is_stopped()) && !(client->get_jack_shutdown())) {
734                 usleep(100);
735         }       
736         client->set_device(NULL);
737         
738         delete [] overrun_buffer;
739 }
740
741 void tX_audiodevice_jack::fill_frames(jack_default_audio_sample_t *left, jack_default_audio_sample_t *right, jack_nframes_t nframes)
742 {
743         unsigned int outbuffer_pos=0;
744         unsigned int sample;
745         
746         if (samples_in_overrun_buffer) {
747                 for (sample=0; ((sample<samples_in_overrun_buffer) && (outbuffer_pos<nframes));) {
748                         left[outbuffer_pos]=overrun_buffer[sample++]/32767.0;
749                         right[outbuffer_pos++]=overrun_buffer[sample++]/32767.0;
750                 }
751         }
752         
753         while (outbuffer_pos<nframes) {
754                 engine->render_cycle();
755                 
756                 for (sample=0; ((sample<(unsigned int) vtt_class::samples_in_mix_buffer) && (outbuffer_pos<nframes));) {
757                         left[outbuffer_pos]=vtt_class::mix_buffer[sample++]/32767.0;
758                         right[outbuffer_pos++]=vtt_class::mix_buffer[sample++]/32767.0;
759                 }
760                 
761                 if (sample<(unsigned int) vtt_class::samples_in_mix_buffer) {
762                         samples_in_overrun_buffer=vtt_class::samples_in_mix_buffer-sample;
763                         /* There's more data in the mixbuffer... */
764                         memcpy(overrun_buffer, &vtt_class::mix_buffer[sample], sizeof(f_prec) * samples_in_overrun_buffer);
765                 } else {
766                         samples_in_overrun_buffer=0;
767                 }
768         }
769 }
770
771 #endif // USE_JACK