1
/* -*- mode: c; c-file-style: "linux"; -*- */
3
Copyright (C) 2003 Robert Ham <rah@bash.sh>
4
Copyright (C) 2001 Paul Davis
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
#include <jack/types.h>
32
#include <jack/internal.h>
33
#include <jack/engine.h>
34
#include <sysdeps/time.h>
36
#include "dummy_driver.h"
40
/* this is used for calculate what counts as an xrun */
41
#define PRETEND_BUFFER_SIZE 4096
44
FakeVideoSync( dummy_driver_t *driver )
46
#define VIDEO_SYNC_PERIOD (48000 / 30)
47
static int vidCounter = VIDEO_SYNC_PERIOD;
49
int period = driver->period_size;
50
jack_position_t *position = &driver->engine->control->current_time;
52
if ( period >= VIDEO_SYNC_PERIOD ) {
53
jack_error("JACK driver period size too large for simple video sync emulation. Halting.");
57
//enable video sync, whether it occurs in this period or not
58
position->audio_frames_per_video_frame = VIDEO_SYNC_PERIOD;
59
position->valid = (jack_position_bits_t) (position->valid | JackAudioVideoRatio);
61
//no video pulse found in this period, just decrement the counter
62
if ( vidCounter > period ) {
66
//video pulse occurs in this period
67
if ( vidCounter <= period ) {
68
int remainder = period - vidCounter;
69
vidCounter = VIDEO_SYNC_PERIOD - remainder;
71
position->video_offset = vidCounter;
72
position->valid = (jack_position_bits_t) (position->valid | JackVideoFrameOffset);
76
#ifdef HAVE_CLOCK_GETTIME
77
static inline unsigned long long ts_to_nsec(struct timespec ts)
79
return ts.tv_sec * 1000000000LL + ts.tv_nsec;
82
static inline struct timespec nsec_to_ts(unsigned long long nsecs)
85
ts.tv_sec = nsecs / (1000000000LL);
86
ts.tv_nsec = nsecs % (1000000000LL);
90
static inline struct timespec add_ts(struct timespec ts, unsigned int usecs)
92
unsigned long long nsecs = ts_to_nsec(ts);
93
nsecs += usecs * 1000LL;
94
return nsec_to_ts(nsecs);
97
static inline int cmp_lt_ts(struct timespec ts1, struct timespec ts2)
99
if(ts1.tv_sec < ts2.tv_sec) {
101
} else if (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec < ts2.tv_nsec) {
106
static jack_nframes_t
107
dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status,
108
float *delayed_usecs)
110
jack_nframes_t nframes = driver->period_size;
114
/* this driver doesn't work so well if we report a delay */
115
*delayed_usecs = 0; /* lie about it */
117
clock_gettime(CLOCK_REALTIME, &now);
119
if (cmp_lt_ts(driver->next_wakeup, now)) {
120
if (driver->next_wakeup.tv_sec == 0) {
121
/* first time through */
122
clock_gettime(CLOCK_REALTIME, &driver->next_wakeup);
123
} else if ((ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL
124
> (PRETEND_BUFFER_SIZE * 1000000LL
125
/ driver->sample_rate)) {
127
jack_error("**** dummy: xrun of %ju usec",
128
(uintmax_t)(ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL);
131
/* late, but handled by our "buffer"; try to
132
* get back on track */
134
driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time);
136
if(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &driver->next_wakeup, NULL)) {
137
jack_error("error while sleeping");
140
clock_gettime(CLOCK_REALTIME, &now);
141
// guaranteed to sleep long enough for this to be correct
142
*delayed_usecs = (ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup));
143
*delayed_usecs /= 1000.0;
145
driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time);
148
driver->last_wait_ust = jack_get_microseconds ();
149
driver->engine->transport_cycle_start (driver->engine,
150
driver->last_wait_ust);
157
static jack_nframes_t
158
dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status,
159
float *delayed_usecs)
161
jack_time_t now = jack_get_microseconds();
163
if (driver->next_time < now) {
164
if (driver->next_time == 0) {
165
/* first time through */
166
driver->next_time = now + driver->wait_time;
167
} else if (now - driver->next_time
168
> (PRETEND_BUFFER_SIZE * 1000000LL
169
/ driver->sample_rate)) {
171
jack_error("**** dummy: xrun of %ju usec",
172
(uintmax_t)now - driver->next_time);
173
driver->next_time = now + driver->wait_time;
175
/* late, but handled by our "buffer"; try to
176
* get back on track */
177
driver->next_time += driver->wait_time;
180
jack_time_t wait = driver->next_time - now;
181
struct timespec ts = { .tv_sec = wait / 1000000,
182
.tv_nsec = (wait % 1000000) * 1000 };
184
driver->next_time += driver->wait_time;
187
driver->last_wait_ust = jack_get_microseconds ();
188
driver->engine->transport_cycle_start (driver->engine,
189
driver->last_wait_ust);
191
/* this driver doesn't work so well if we report a delay */
192
*delayed_usecs = 0; /* lie about it */
194
return driver->period_size;
199
dummy_driver_run_cycle (dummy_driver_t *driver)
201
jack_engine_t *engine = driver->engine;
205
jack_nframes_t nframes = dummy_driver_wait (driver, -1, &wait_status,
208
/* we detected an xrun and restarted: notify
209
* clients about the delay. */
210
engine->delay (engine, delayed_usecs);
214
// FakeVideoSync (driver);
216
if (wait_status == 0)
217
return engine->run_cycle (engine, nframes, delayed_usecs);
226
dummy_driver_null_cycle (dummy_driver_t* driver, jack_nframes_t nframes)
232
dummy_driver_bufsize (dummy_driver_t* driver, jack_nframes_t nframes)
234
driver->period_size = nframes;
235
driver->period_usecs = driver->wait_time =
236
(jack_time_t) floor ((((float) nframes) / driver->sample_rate)
239
/* tell the engine to change its buffer size */
240
driver->engine->set_buffer_size (driver->engine, nframes);
246
dummy_driver_write (dummy_driver_t* driver, jack_nframes_t nframes)
253
dummy_driver_attach (dummy_driver_t *driver)
260
driver->engine->set_buffer_size (driver->engine, driver->period_size);
261
driver->engine->set_sample_rate (driver->engine, driver->sample_rate);
263
port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
265
for (chn = 0; chn < driver->capture_channels; chn++)
267
snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1);
269
port = jack_port_register (driver->client, buf,
270
JACK_DEFAULT_AUDIO_TYPE,
274
jack_error ("DUMMY: cannot register port for %s", buf);
278
driver->capture_ports =
279
jack_slist_append (driver->capture_ports, port);
282
port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
284
for (chn = 0; chn < driver->playback_channels; chn++)
286
snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1);
288
port = jack_port_register (driver->client, buf,
289
JACK_DEFAULT_AUDIO_TYPE,
294
jack_error ("DUMMY: cannot register port for %s", buf);
298
driver->playback_ports =
299
jack_slist_append (driver->playback_ports, port);
302
jack_activate (driver->client);
308
dummy_driver_detach (dummy_driver_t *driver)
312
if (driver->engine == 0)
315
for (node = driver->capture_ports; node; node = jack_slist_next (node))
316
jack_port_unregister (driver->client,
317
((jack_port_t *) node->data));
319
jack_slist_free (driver->capture_ports);
320
driver->capture_ports = NULL;
323
for (node = driver->playback_ports; node; node = jack_slist_next (node))
324
jack_port_unregister (driver->client,
325
((jack_port_t *) node->data));
327
jack_slist_free (driver->playback_ports);
328
driver->playback_ports = NULL;
335
dummy_driver_delete (dummy_driver_t *driver)
337
jack_driver_nt_finish ((jack_driver_nt_t *) driver);
341
static jack_driver_t *
342
dummy_driver_new (jack_client_t * client,
344
unsigned int capture_ports,
345
unsigned int playback_ports,
346
jack_nframes_t sample_rate,
347
jack_nframes_t period_size,
348
unsigned long wait_time)
350
dummy_driver_t * driver;
352
jack_info ("creating dummy driver ... %s|%" PRIu32 "|%" PRIu32
353
"|%lu|%u|%u", name, sample_rate, period_size, wait_time,
354
capture_ports, playback_ports);
356
driver = (dummy_driver_t *) calloc (1, sizeof (dummy_driver_t));
358
jack_driver_nt_init ((jack_driver_nt_t *) driver);
360
driver->write = (JackDriverReadFunction) dummy_driver_write;
361
driver->null_cycle = (JackDriverNullCycleFunction) dummy_driver_null_cycle;
362
driver->nt_attach = (JackDriverNTAttachFunction) dummy_driver_attach;
363
driver->nt_detach = (JackDriverNTDetachFunction) dummy_driver_detach;
364
driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_driver_bufsize;
365
driver->nt_run_cycle = (JackDriverNTRunCycleFunction) dummy_driver_run_cycle;
367
driver->period_usecs =
368
(jack_time_t) floor ((((float) period_size) / sample_rate)
370
driver->sample_rate = sample_rate;
371
driver->period_size = period_size;
372
driver->wait_time = wait_time;
373
//driver->next_time = 0; // not needed since calloc clears the memory
374
driver->last_wait_ust = 0;
376
driver->capture_channels = capture_ports;
377
driver->capture_ports = NULL;
378
driver->playback_channels = playback_ports;
379
driver->playback_ports = NULL;
381
driver->client = client;
382
driver->engine = NULL;
384
return (jack_driver_t *) driver;
388
/* DRIVER "PLUGIN" INTERFACE */
391
driver_get_descriptor ()
393
jack_driver_desc_t * desc;
394
jack_driver_param_desc_t * params;
397
desc = calloc (1, sizeof (jack_driver_desc_t));
398
strcpy (desc->name, "dummy");
401
params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
404
strcpy (params[i].name, "capture");
405
params[i].character = 'C';
406
params[i].type = JackDriverParamUInt;
407
params[i].value.ui = 2U;
408
strcpy (params[i].short_desc, "Number of capture ports");
409
strcpy (params[i].long_desc, params[i].short_desc);
412
strcpy (params[i].name, "playback");
413
params[i].character = 'P';
414
params[i].type = JackDriverParamUInt;
415
params[1].value.ui = 2U;
416
strcpy (params[i].short_desc, "Number of playback ports");
417
strcpy (params[i].long_desc, params[i].short_desc);
420
strcpy (params[i].name, "rate");
421
params[i].character = 'r';
422
params[i].type = JackDriverParamUInt;
423
params[i].value.ui = 48000U;
424
strcpy (params[i].short_desc, "Sample rate");
425
strcpy (params[i].long_desc, params[i].short_desc);
428
strcpy (params[i].name, "period");
429
params[i].character = 'p';
430
params[i].type = JackDriverParamUInt;
431
params[i].value.ui = 1024U;
432
strcpy (params[i].short_desc, "Frames per period");
433
strcpy (params[i].long_desc, params[i].short_desc);
436
strcpy (params[i].name, "wait");
437
params[i].character = 'w';
438
params[i].type = JackDriverParamUInt;
439
params[i].value.ui = 21333U;
440
strcpy (params[i].short_desc,
441
"Number of usecs to wait between engine processes");
442
strcpy (params[i].long_desc, params[i].short_desc);
444
desc->params = params;
449
const char driver_client_name[] = "dummy_pcm";
452
driver_initialize (jack_client_t *client, const JSList * params)
454
jack_nframes_t sample_rate = 48000;
455
jack_nframes_t period_size = 1024;
456
unsigned int capture_ports = 2;
457
unsigned int playback_ports = 2;
458
int wait_time_set = 0;
459
unsigned long wait_time = 0;
461
const jack_driver_param_t * param;
463
for (node = params; node; node = jack_slist_next (node)) {
464
param = (const jack_driver_param_t *) node->data;
466
switch (param->character) {
469
capture_ports = param->value.ui;
473
playback_ports = param->value.ui;
477
sample_rate = param->value.ui;
481
period_size = param->value.ui;
485
wait_time = param->value.ui;
493
wait_time = (((float)period_size) / ((float)sample_rate)) * 1000000.0;
495
return dummy_driver_new (client, "dummy_pcm", capture_ports,
496
playback_ports, sample_rate, period_size,
501
driver_finish (jack_driver_t *driver)
503
dummy_driver_delete ((dummy_driver_t *) driver);