2
Sun Audio API driver for Jack
3
Copyright (C) 2008 Jacob Meuser <jakemsr@sdf.lonestar.org>
4
Based heavily on oss_driver.c which came with the following
7
Copyright (C) 2003-2007 Jussi Laako <jussi@sonarnerd.net>
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place, Suite 330, Boston,
37
#include <sys/types.h>
38
#include <sys/ioctl.h>
39
#include <sys/audioio.h>
54
#include <jack/types.h>
55
#include <jack/internal.h>
56
#include <jack/engine.h>
57
#include <jack/thread.h>
58
#include <sysdeps/time.h>
60
#include "sun_driver.h"
63
#define SUN_DRIVER_N_PARAMS 11
64
const static jack_driver_param_desc_t sun_params[SUN_DRIVER_N_PARAMS] = {
68
{ .ui = SUN_DRIVER_DEF_FS },
75
{ .ui = SUN_DRIVER_DEF_BLKSIZE },
82
{ .ui = SUN_DRIVER_DEF_NPERIODS },
83
"number of periods in buffer",
84
"number of periods in buffer"
89
{ .i = SUN_DRIVER_DEF_BITS },
96
{ .ui = SUN_DRIVER_DEF_INS },
103
{ .ui = SUN_DRIVER_DEF_OUTS },
109
JackDriverParamString,
110
{ .str = SUN_DRIVER_DEF_DEV },
116
JackDriverParamString,
117
{ .str = SUN_DRIVER_DEF_DEV },
125
"ignore hardware period size",
126
"ignore hardware period size"
132
"system input latency",
133
"system input latency"
139
"system output latency",
140
"system output latency"
145
/* internal functions */
149
set_period_size (sun_driver_t *driver, jack_nframes_t new_period_size)
151
driver->period_size = new_period_size;
153
driver->period_usecs =
154
((double) driver->period_size /
155
(double) driver->sample_rate) * 1e6;
156
driver->last_wait_ust = 0;
157
driver->iodelay = 0.0F;
158
driver->poll_timeout = (int)(driver->period_usecs / 666);
163
sun_driver_write_silence (sun_driver_t *driver, jack_nframes_t nframes)
169
localsize = nframes * driver->sample_bytes * driver->playback_channels;
170
localbuf = malloc(localsize);
171
if (localbuf == NULL)
173
jack_error("sun_driver: malloc() failed: %s@%i",
178
bzero(localbuf, localsize);
179
io_res = write(driver->outfd, localbuf, localsize);
180
if (io_res < (ssize_t) localsize)
182
jack_error("sun_driver: write() failed: %s: "
183
"count=%d/%d: %s@%i", strerror(errno), io_res,
184
localsize, __FILE__, __LINE__);
191
sun_driver_read_silence (sun_driver_t *driver, jack_nframes_t nframes)
197
localsize = nframes * driver->sample_bytes * driver->capture_channels;
198
localbuf = malloc(localsize);
199
if (localbuf == NULL)
201
jack_error("sun_driver: malloc() failed: %s@%i",
206
io_res = read(driver->infd, localbuf, localsize);
207
if (io_res < (ssize_t) localsize)
209
jack_error("sun_driver: read() failed: %s: "
210
"count=%d/%d: %s@%i", strerror(errno), io_res,
211
localsize, __FILE__, __LINE__);
217
static jack_nframes_t
218
sun_driver_wait (sun_driver_t *driver, int *status, float *iodelay)
221
struct pollfd pfd[2];
224
jack_time_t poll_enter;
225
jack_time_t poll_ret;
226
int need_capture = 0;
227
int need_playback = 0;
228
int capture_errors = 0;
229
int playback_errors = 0;
236
pfd[0].fd = driver->infd;
237
pfd[0].events = POLLIN;
238
if (driver->infd >= 0)
241
pfd[1].fd = driver->outfd;
242
pfd[1].events = POLLOUT;
243
if (driver->outfd >= 0)
246
poll_enter = jack_get_microseconds();
247
if (poll_enter > driver->poll_next)
249
/* late. don't count as wakeup delay. */
250
driver->poll_next = 0;
253
while (need_capture || need_playback)
255
nfds = poll(pfd, 2, driver->poll_timeout);
257
((pfd[0].revents | pfd[1].revents) &
258
(POLLERR | POLLHUP | POLLNVAL)) )
260
jack_error("sun_driver: poll() error: %s: %s@%i",
261
strerror(errno), __FILE__, __LINE__);
268
jack_error("sun_driver: poll() timeout: %s@%i",
274
if (need_capture && (pfd[0].revents & POLLIN))
280
if (need_playback && (pfd[1].revents & POLLOUT))
287
poll_ret = jack_get_microseconds();
289
if (driver->poll_next && poll_ret > driver->poll_next)
290
*iodelay = poll_ret - driver->poll_next;
292
driver->poll_last = poll_ret;
293
driver->poll_next = poll_ret + driver->period_usecs;
294
driver->engine->transport_cycle_start(driver->engine, poll_ret);
296
#if defined(AUDIO_RERROR) && defined(AUDIO_PERROR)
298
/* low level error reporting and recovery. recovery is necessary
299
* when doing both playback and capture and using AUMODE_PLAY,
300
* because we process one period of both playback and capture data
301
* in each cycle, and we wait in each cycle for that to be possible.
302
* for example, playback will continuously underrun if it underruns
303
* and we have to wait for capture data to become available
304
* before we can write enough playback data to catch up.
307
if (driver->infd >= 0)
309
if (ioctl(driver->infd, AUDIO_RERROR, &capture_errors) < 0)
311
jack_error("sun_driver: AUDIO_RERROR failed: %s: %s@%i",
312
strerror(errno), __FILE__, __LINE__);
315
capture_errors -= driver->capture_drops;
316
driver->capture_drops += capture_errors;
318
if (capture_errors > 0)
320
delay = (capture_errors * 1000.0) / driver->sample_rate;
321
printf("sun_driver: capture xrun of %d frames (%f msec)\n",
322
capture_errors, delay);
325
if (driver->outfd >= 0)
327
if (ioctl(driver->outfd, AUDIO_PERROR, &playback_errors) < 0)
329
jack_error("sun_driver: AUDIO_PERROR failed: %s: %s@%i",
330
strerror(errno), __FILE__, __LINE__);
333
playback_errors -= driver->playback_drops;
334
driver->playback_drops += playback_errors;
336
if (playback_errors > 0)
338
delay = (playback_errors * 1000.0) / driver->sample_rate;
339
printf("sun_driver: playback xrun of %d frames (%f msec)\n",
340
playback_errors, delay);
343
if ((driver->outfd >= 0 && driver->infd >= 0) &&
344
(capture_errors || playback_errors))
346
if (ioctl(driver->infd, AUDIO_GETINFO, &auinfo) < 0)
348
jack_error("sun_driver: AUDIO_GETINFO failed: %s: "
349
"%s@%i", strerror(errno), __FILE__, __LINE__);
352
capture_seek = auinfo.record.seek;
354
if (driver->infd == driver->outfd)
355
playback_seek = auinfo.play.seek;
358
if (ioctl(driver->outfd, AUDIO_GETINFO, &auinfo) < 0)
360
jack_error("sun_driver: AUDIO_GETINFO failed: "
361
"%s: %s@%i", strerror(errno),
365
playback_seek = auinfo.play.seek;
368
capture_seek /= driver->capture_channels *
369
driver->sample_bytes;
370
playback_seek /= driver->playback_channels *
371
driver->sample_bytes;
373
if (playback_seek == driver->period_size &&
374
capture_seek == driver->period_size &&
377
/* normally, 1 period in each buffer is exactly
378
* what we want, but if there was an error then
379
* we effectively have 0 periods in the playback
380
* buffer, because the period in the buffer will
381
* be used to catch up to realtime.
383
printf("sun_driver: writing %d frames of silence "
384
"to correct I/O sync\n", driver->period_size);
385
sun_driver_write_silence(driver, driver->period_size);
387
else if (capture_errors && playback_errors)
389
/* serious delay. we've lost the ability to
390
* write capture_errors frames to catch up on
393
printf("sun_driver: writing %d frames of silence "
394
"to correct I/O sync\n", capture_errors);
395
sun_driver_write_silence(driver, capture_errors);
399
#endif // AUDIO_RERROR && AUDIO_PERROR
401
driver->last_wait_ust = poll_ret;
405
return driver->period_size;
410
sun_driver_run_cycle (sun_driver_t *driver)
412
jack_nframes_t nframes;
417
nframes = sun_driver_wait (driver, &wait_status, &iodelay);
428
now = jack_get_microseconds();
429
if (now > driver->poll_next)
431
iodelay = now - driver->poll_next;
432
driver->poll_next = now + driver->period_usecs;
433
driver->engine->delay(driver->engine, iodelay);
434
printf("sun_driver: iodelay = %f\n", iodelay);
438
/* any other fatal error */
443
return driver->engine->run_cycle(driver->engine, nframes, iodelay);
448
copy_and_convert_in (jack_sample_t *dst, void *src,
449
size_t nframes, int channel, int chcount, int bits)
453
signed short *s16src = (signed short *) src;
454
signed int *s32src = (signed int *) src;
455
double *f64src = (double *) src;
462
scale = 1.0f / 0x7fff;
463
for (dstidx = 0; dstidx < nframes; dstidx++)
465
dst[dstidx] = (jack_sample_t)
466
s16src[srcidx] * scale;
471
scale = 1.0f / 0x7fffff;
472
for (dstidx = 0; dstidx < nframes; dstidx++)
474
dst[dstidx] = (jack_sample_t)
475
s32src[srcidx] * scale;
480
scale = 1.0f / 0x7fffffff;
481
for (dstidx = 0; dstidx < nframes; dstidx++)
483
dst[dstidx] = (jack_sample_t)
484
s32src[srcidx] * scale;
489
for (dstidx = 0; dstidx < nframes; dstidx++)
491
dst[dstidx] = (jack_sample_t) f64src[srcidx];
500
copy_and_convert_out (void *dst, jack_sample_t *src,
501
size_t nframes, int channel, int chcount, int bits)
505
signed short *s16dst = (signed short *) dst;
506
signed int *s32dst = (signed int *) dst;
507
double *f64dst = (double *) dst;
515
for (srcidx = 0; srcidx < nframes; srcidx++)
517
s16dst[dstidx] = (signed short)
518
(src[srcidx] >= 0.0f) ?
519
(src[srcidx] * scale + 0.5f) :
520
(src[srcidx] * scale - 0.5f);
526
for (srcidx = 0; srcidx < nframes; srcidx++)
528
s32dst[dstidx] = (signed int)
529
(src[srcidx] >= 0.0f) ?
530
(src[srcidx] * scale + 0.5f) :
531
(src[srcidx] * scale - 0.5f);
537
for (srcidx = 0; srcidx < nframes; srcidx++)
539
s32dst[dstidx] = (signed int)
540
(src[srcidx] >= 0.0f) ?
541
(src[srcidx] * scale + 0.5f) :
542
(src[srcidx] * scale - 0.5f);
547
for (srcidx = 0; srcidx < nframes; srcidx++)
549
f64dst[dstidx] = (double) src[srcidx];
557
/* jack driver interface */
561
sun_driver_attach (sun_driver_t *driver)
565
char channel_name[64];
568
driver->engine->set_buffer_size(driver->engine, driver->period_size);
569
driver->engine->set_sample_rate(driver->engine, driver->sample_rate);
571
port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
573
for (channel = 0; channel < driver->capture_channels; channel++)
575
snprintf(channel_name, sizeof(channel_name),
576
"capture_%u", channel + 1);
577
port = jack_port_register(driver->client, channel_name,
578
JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
581
jack_error("sun_driver: cannot register port for %s: "
582
"%s@%i", channel_name, __FILE__, __LINE__);
585
jack_port_set_latency(port,
586
driver->period_size + driver->sys_in_latency);
587
driver->capture_ports =
588
jack_slist_append(driver->capture_ports, port);
591
port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
592
for (channel = 0; channel < driver->playback_channels; channel++)
594
snprintf(channel_name, sizeof(channel_name),
595
"playback_%u", channel + 1);
596
port = jack_port_register(driver->client, channel_name,
597
JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
600
jack_error("sun_driver: cannot register port for "
601
"%s: %s@%i", channel_name, __FILE__, __LINE__);
604
jack_port_set_latency(port,
605
driver->period_size + driver->sys_out_latency);
606
driver->playback_ports =
607
jack_slist_append(driver->playback_ports, port);
610
return jack_activate(driver->client);
615
sun_driver_detach (sun_driver_t *driver)
619
if (driver->engine == NULL)
622
node = driver->capture_ports;
625
jack_port_unregister(driver->client,
626
((jack_port_t *) node->data));
627
node = jack_slist_next(node);
629
jack_slist_free(driver->capture_ports);
630
driver->capture_ports = NULL;
632
node = driver->playback_ports;
635
jack_port_unregister(driver->client,
636
((jack_port_t *) node->data));
637
node = jack_slist_next(node);
639
jack_slist_free(driver->playback_ports);
640
driver->playback_ports = NULL;
647
sun_driver_start (sun_driver_t *driver)
649
audio_info_t audio_if;
651
if (driver->infd >= 0)
653
#if defined(AUDIO_FLUSH)
654
if (ioctl(driver->infd, AUDIO_FLUSH, NULL) < 0)
656
jack_error("sun_driver: capture flush failed: %s: "
657
"%s@%i", strerror(errno), __FILE__, __LINE__);
661
AUDIO_INITINFO(&audio_if);
662
audio_if.record.pause = 1;
663
if (driver->outfd == driver->infd)
664
audio_if.play.pause = 1;
665
if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
667
jack_error("sun_driver: pause capture failed: %s: "
668
"%s@%i", strerror(errno), __FILE__, __LINE__);
672
if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
674
#if defined(AUDIO_FLUSH)
675
if (ioctl(driver->outfd, AUDIO_FLUSH, NULL) < 0)
677
jack_error("sun_driver: playback flush failed: %s: "
678
"%s@%i", strerror(errno), __FILE__, __LINE__);
682
AUDIO_INITINFO(&audio_if);
683
audio_if.play.pause = 1;
684
if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
686
jack_error("sun_driver: pause playback failed: %s: "
687
"%s@%i", strerror(errno), __FILE__, __LINE__);
692
/* AUDIO_FLUSH resets the counters these work with */
693
driver->playback_drops = driver->capture_drops = 0;
695
if (driver->outfd >= 0)
697
/* "prime" the playback buffer. if we don't do this, we'll
698
* end up underrunning. it would get really ugly in duplex
699
* mode, for example, where we have to wait for a period to
700
* be available to read before we can write. also helps to
701
* keep constant latency from the beginning.
703
sun_driver_write_silence(driver,
704
driver->nperiods * driver->period_size);
707
if (driver->infd >= 0)
709
AUDIO_INITINFO(&audio_if);
710
audio_if.record.pause = 0;
711
if (driver->outfd == driver->infd)
712
audio_if.play.pause = 0;
713
if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
715
jack_error("sun_driver: start capture failed: %s: "
716
"%s@%i", strerror(errno), __FILE__, __LINE__);
720
if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
722
AUDIO_INITINFO(&audio_if);
723
audio_if.play.pause = 0;
724
if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
726
jack_error("sun_driver: trigger playback failed: %s: "
727
"%s@%i", strerror(errno), __FILE__, __LINE__);
737
enc_equal(int a, int b)
742
#if defined(AUDIO_ENCODING_SLINEAR)
743
#if BYTE_ORDER == LITTLE_ENDIAN
744
if ((a == AUDIO_ENCODING_SLINEAR && b == AUDIO_ENCODING_SLINEAR_LE) ||
745
(a == AUDIO_ENCODING_SLINEAR_LE && b == AUDIO_ENCODING_SLINEAR) ||
746
(a == AUDIO_ENCODING_ULINEAR && b == AUDIO_ENCODING_ULINEAR_LE) ||
747
(a == AUDIO_ENCODING_ULINEAR_LE && b == AUDIO_ENCODING_ULINEAR))
749
#elif BYTE_ORDER == BIG_ENDIAN
750
if ((a == AUDIO_ENCODING_SLINEAR && b == AUDIO_ENCODING_SLINEAR_BE) ||
751
(a == AUDIO_ENCODING_SLINEAR_BE && b == AUDIO_ENCODING_SLINEAR) ||
752
(a == AUDIO_ENCODING_ULINEAR && b == AUDIO_ENCODING_ULINEAR_BE) ||
753
(a == AUDIO_ENCODING_ULINEAR_BE && b == AUDIO_ENCODING_ULINEAR))
756
#endif // AUDIO_ENCODING_SLINEAR
762
sun_driver_set_parameters (sun_driver_t *driver)
764
audio_info_t audio_if_in, audio_if_out;
768
unsigned int cap_period = 0, play_period = 0, period_size = 0;
769
const char *indev = driver->indev;
770
const char *outdev = driver->outdev;
772
driver->indevbuf = NULL;
773
driver->outdevbuf = NULL;
774
driver->sample_bytes = driver->bits / 8;
776
if ((strcmp(indev, outdev) == 0) &&
777
((driver->capture_channels > 0) && (driver->playback_channels > 0)))
779
infd = outfd = open(indev, O_RDWR);
782
jack_error("sun_driver: failed to open duplex device "
783
"%s: %s: %s@%i", indev, strerror(errno),
787
#if defined(AUDIO_SETFD)
788
if (ioctl(infd, AUDIO_SETFD, &s) < 0)
790
jack_error("sun_driver: failed to enable full duplex: "
791
"%s: %s@%i", strerror(errno),
799
if (driver->capture_channels > 0)
801
infd = open(indev, O_RDONLY);
804
jack_error("sun_driver: failed to open input "
805
"device %s: %s: %s@%i", indev,
806
strerror(errno), __FILE__, __LINE__);
810
if (driver->playback_channels > 0)
812
outfd = open(outdev, O_WRONLY);
815
jack_error("sun_driver: failed to open output "
816
"device %s: %s: %s@%i", outdev,
817
strerror(errno), __FILE__, __LINE__);
822
if (infd == -1 && outfd == -1)
824
jack_error("sun_driver: no device was opened: %s@%i",
830
driver->outfd = outfd;
832
AUDIO_INITINFO(&audio_if_in);
833
AUDIO_INITINFO(&audio_if_out);
837
audio_if_in.record.encoding = driver->format;
838
audio_if_in.record.precision = driver->bits;
839
audio_if_in.record.channels = driver->capture_channels;
840
audio_if_in.record.sample_rate = driver->sample_rate;
841
audio_if_in.record.pause = 1;
845
audio_if_out.play.encoding = driver->format;
846
audio_if_out.play.precision = driver->bits;
847
audio_if_out.play.channels = driver->playback_channels;
848
audio_if_out.play.sample_rate = driver->sample_rate;
849
audio_if_out.play.pause = 1;
852
#if defined(__OpenBSD__) || defined(__NetBSD__)
853
#if defined(__OpenBSD__)
854
if (driver->infd >= 0)
855
audio_if_in.record.block_size = driver->capture_channels *
856
driver->period_size * driver->sample_bytes;
857
if (driver->outfd >= 0)
858
audio_if_out.play.block_size = driver->playback_channels *
859
driver->period_size * driver->sample_bytes;
861
if (driver->infd >= 0)
862
audio_if_in.blocksize = driver->capture_channels *
863
driver->period_size * driver->sample_bytes;
864
if (driver->outfd >= 0)
865
audio_if_out.blocksize = driver->playback_channels *
866
driver->period_size * driver->sample_bytes;
869
audio_if_in.play = audio_if_out.play;
871
/* this only affects playback. the capture buffer is
872
* always the max (64k on OpenBSD).
874
audio_if_in.hiwat = audio_if_out.hiwat = driver->nperiods;
876
/* AUMODE_PLAY makes us "catch up to realtime" if we underrun
877
* playback. that means, if we are N frames late, the next
878
* N frames written will be discarded. this keeps playback
879
* time from expanding with each underrun.
883
audio_if_in.mode = AUMODE_PLAY | AUMODE_RECORD;
888
audio_if_in.mode = AUMODE_RECORD;
891
audio_if_out.mode = AUMODE_PLAY;
894
#endif // OpenBSD || NetBSD
898
if (ioctl(infd, AUDIO_SETINFO, &audio_if_in) < 0)
900
jack_error("sun_driver: failed to set parameters for "
901
"%s: %s: %s@%i", indev, strerror(errno),
907
if (outfd >= 0 && outfd != infd)
909
if (ioctl(outfd, AUDIO_SETINFO, &audio_if_out) < 0)
911
jack_error("sun_driver: failed to set parameters for "
912
"%s: %s: %s@%i", outdev, strerror(errno),
920
if (ioctl(infd, AUDIO_GETINFO, &audio_if_in) < 0)
922
jack_error("sun_driver: AUDIO_GETINFO failed: %s: "
923
"%s@%i", strerror(errno), __FILE__, __LINE__);
927
if (!enc_equal(audio_if_in.record.encoding, driver->format) ||
928
audio_if_in.record.precision != driver->bits ||
929
audio_if_in.record.channels != driver->capture_channels ||
930
audio_if_in.record.sample_rate != driver->sample_rate)
932
jack_error("sun_driver: setting capture parameters "
933
"failed: %s@%i", __FILE__, __LINE__);
936
#if defined(__OpenBSD__)
937
cap_period = audio_if_in.record.block_size /
938
driver->capture_channels / driver->sample_bytes;
939
#elif defined(__NetBSD__)
940
cap_period = audio_if_in.blocksize /
941
driver->capture_channels / driver->sample_bytes;
943
/* how is this done on Solaris? */
944
cap_period = driver->period_size;
952
audio_if_out.play = audio_if_in.play;
956
if (ioctl(outfd, AUDIO_GETINFO, &audio_if_out) < 0)
958
jack_error("sun_driver: AUDIO_GETINFO failed: "
959
"%s: %s@%i", strerror(errno),
965
if (!enc_equal(audio_if_out.play.encoding, driver->format) ||
966
audio_if_out.play.precision != driver->bits ||
967
audio_if_out.play.channels != driver->playback_channels ||
968
audio_if_out.play.sample_rate != driver->sample_rate)
970
jack_error("sun_driver: playback settings failed: "
971
"%s@%i", __FILE__, __LINE__);
974
#if defined(__OpenBSD__)
975
play_period = audio_if_out.play.block_size /
976
driver->playback_channels / driver->sample_bytes;
977
#elif defined(__NetBSD__)
978
play_period = audio_if_out.blocksize /
979
driver->playback_channels / driver->sample_bytes;
981
/* how is this done on Solaris? */
982
play_period = driver->period_size;
986
if (infd >= 0 && outfd >= 0 && play_period != cap_period)
988
jack_error("sun_driver: play and capture periods differ: "
989
"%s@%i", __FILE__, __LINE__);
993
period_size = cap_period;
995
period_size = play_period;
997
if (period_size != 0 && period_size != driver->period_size &&
998
!driver->ignorehwbuf)
1000
printf("sun_driver: period size update: %u\n", period_size);
1002
set_period_size (driver, period_size);
1005
driver->engine->set_buffer_size(driver->engine,
1006
driver->period_size);
1009
if (driver->infd >= 0 && driver->capture_channels > 0)
1011
driver->indevbufsize = driver->period_size *
1012
driver->capture_channels * driver->sample_bytes;
1013
driver->indevbuf = malloc(driver->indevbufsize);
1014
if (driver->indevbuf == NULL)
1016
jack_error( "sun_driver: malloc() failed: %s@%i",
1017
__FILE__, __LINE__);
1020
bzero(driver->indevbuf, driver->indevbufsize);
1024
driver->indevbufsize = 0;
1025
driver->indevbuf = NULL;
1028
if (driver->outfd >= 0 && driver->playback_channels > 0)
1030
driver->outdevbufsize = driver->period_size *
1031
driver->playback_channels * driver->sample_bytes;
1032
driver->outdevbuf = malloc(driver->outdevbufsize);
1033
if (driver->outdevbuf == NULL)
1035
jack_error("sun_driver: malloc() failed: %s@%i",
1036
__FILE__, __LINE__);
1039
bzero(driver->outdevbuf, driver->outdevbufsize);
1043
driver->outdevbufsize = 0;
1044
driver->outdevbuf = NULL;
1047
printf("sun_driver: indevbuf %zd B, outdevbuf %zd B\n",
1048
driver->indevbufsize, driver->outdevbufsize);
1055
sun_driver_stop (sun_driver_t *driver)
1057
audio_info_t audio_if;
1059
if (driver->infd >= 0)
1061
AUDIO_INITINFO(&audio_if);
1062
audio_if.record.pause = 1;
1063
if (driver->outfd == driver->infd)
1064
audio_if.play.pause = 1;
1065
if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
1067
jack_error("sun_driver: capture pause failed: %s: "
1068
"%s@%i", strerror(errno), __FILE__, __LINE__);
1073
if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
1075
AUDIO_INITINFO(&audio_if);
1076
audio_if.play.pause = 1;
1077
if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
1079
jack_error("sun_driver: playback pause failed: %s: "
1080
"%s@%i", strerror(errno), __FILE__, __LINE__);
1090
sun_driver_read (sun_driver_t *driver, jack_nframes_t nframes)
1092
jack_nframes_t nbytes;
1095
jack_sample_t *portbuf;
1099
if (driver->engine->freewheeling || driver->infd < 0)
1102
if (nframes > driver->period_size)
1104
jack_error("sun_driver: read failed: nframes > period_size: "
1105
"(%u/%u): %s@%i", nframes, driver->period_size,
1106
__FILE__, __LINE__);
1110
node = driver->capture_ports;
1112
while (node != NULL)
1114
port = (jack_port_t *) node->data;
1116
if (jack_port_connected(port))
1118
portbuf = jack_port_get_buffer(port, nframes);
1119
copy_and_convert_in(portbuf, driver->indevbuf,
1121
driver->capture_channels,
1125
node = jack_slist_next(node);
1129
nbytes = nframes * driver->capture_channels * driver->sample_bytes;
1133
io_res = read(driver->infd, driver->indevbuf, nbytes);
1136
jack_error("sun_driver: read() failed: %s: %s@%i",
1137
strerror(errno), __FILE__, __LINE__);
1149
sun_driver_write (sun_driver_t *driver, jack_nframes_t nframes)
1151
jack_nframes_t nbytes;
1154
jack_sample_t *portbuf;
1159
if (driver->engine->freewheeling || driver->outfd < 0)
1162
if (nframes > driver->period_size)
1164
jack_error("sun_driver: write failed: nframes > period_size "
1165
"(%u/%u): %s@%i", nframes, driver->period_size,
1166
__FILE__, __LINE__);
1170
bzero(driver->outdevbuf, driver->outdevbufsize);
1172
node = driver->playback_ports;
1174
while (node != NULL)
1176
port = (jack_port_t *) node->data;
1178
if (jack_port_connected(port))
1180
portbuf = jack_port_get_buffer(port, nframes);
1181
copy_and_convert_out(driver->outdevbuf, portbuf,
1183
driver->playback_channels,
1187
node = jack_slist_next(node);
1191
nbytes = nframes * driver->playback_channels * driver->sample_bytes;
1195
io_res = write(driver->outfd, driver->outdevbuf, nbytes);
1198
jack_error("sun_driver: write() failed: %s: %s@%i",
1199
strerror(errno), __FILE__, __LINE__);
1211
sun_driver_null_cycle (sun_driver_t *driver, jack_nframes_t nframes)
1213
if (nframes > driver->period_size)
1215
jack_error("sun_driver: null cycle failed: "
1216
"nframes > period_size (%u/%u): %s@%i", nframes,
1217
driver->period_size, __FILE__, __LINE__);
1221
printf("sun_driver: running null cycle\n");
1223
if (driver->outfd >= 0)
1224
sun_driver_write_silence (driver, nframes);
1226
if (driver->infd >= 0)
1227
sun_driver_read_silence (driver, nframes);
1234
sun_driver_bufsize (sun_driver_t *driver, jack_nframes_t nframes)
1236
return sun_driver_set_parameters(driver);
1241
sun_driver_delete (sun_driver_t *driver)
1243
if (driver->outfd >= 0 && driver->outfd != driver->infd)
1245
close(driver->outfd);
1248
if (driver->infd >= 0)
1250
close(driver->infd);
1254
if (driver->indevbuf != NULL)
1256
free(driver->indevbuf);
1257
driver->indevbuf = NULL;
1259
if (driver->outdevbuf != NULL)
1261
free(driver->outdevbuf);
1262
driver->outdevbuf = NULL;
1265
if (driver->indev != NULL)
1266
free(driver->indev);
1268
if (driver->outdev != NULL)
1269
free(driver->outdev);
1271
jack_driver_nt_finish((jack_driver_nt_t *) driver);
1278
driver_finish (jack_driver_t *driver)
1280
sun_driver_delete ((sun_driver_t *)driver);
1284
static jack_driver_t *
1285
sun_driver_new (char *indev, char *outdev, jack_client_t *client,
1286
jack_nframes_t sample_rate, jack_nframes_t period_size,
1287
jack_nframes_t nperiods, int bits,
1288
int capture_channels, int playback_channels,
1289
jack_nframes_t in_latency, jack_nframes_t out_latency,
1292
sun_driver_t *driver;
1294
driver = (sun_driver_t *) malloc(sizeof(sun_driver_t));
1297
jack_error("sun_driver: malloc() failed: %s: %s@%i",
1298
strerror(errno), __FILE__, __LINE__);
1301
driver->engine = NULL;
1302
jack_driver_nt_init((jack_driver_nt_t *) driver);
1304
driver->nt_attach = (JackDriverNTAttachFunction) sun_driver_attach;
1305
driver->nt_detach = (JackDriverNTDetachFunction) sun_driver_detach;
1306
driver->read = (JackDriverReadFunction) sun_driver_read;
1307
driver->write = (JackDriverWriteFunction) sun_driver_write;
1308
driver->null_cycle = (JackDriverNullCycleFunction)
1309
sun_driver_null_cycle;
1310
driver->nt_bufsize = (JackDriverNTBufSizeFunction) sun_driver_bufsize;
1311
driver->nt_start = (JackDriverNTStartFunction) sun_driver_start;
1312
driver->nt_stop = (JackDriverNTStopFunction) sun_driver_stop;
1313
driver->nt_run_cycle = (JackDriverNTRunCycleFunction) sun_driver_run_cycle;
1316
driver->indev = strdup(indev);
1318
driver->outdev = strdup(outdev);
1320
driver->ignorehwbuf = ignorehwbuf;
1322
driver->sample_rate = sample_rate;
1323
driver->period_size = period_size;
1324
driver->nperiods = nperiods;
1325
driver->bits = bits;
1326
driver->capture_channels = capture_channels;
1327
driver->playback_channels = playback_channels;
1328
driver->sys_in_latency = in_latency;
1329
driver->sys_out_latency = out_latency;
1331
set_period_size(driver, period_size);
1333
if (driver->indev == NULL)
1334
driver->indev = strdup(SUN_DRIVER_DEF_DEV);
1335
if (driver->outdev == NULL)
1336
driver->outdev = strdup(SUN_DRIVER_DEF_DEV);
1339
#if defined(AUDIO_ENCODING_SLINEAR)
1340
driver->format = AUDIO_ENCODING_SLINEAR;
1342
driver->format = AUDIO_ENCODING_LINEAR;
1344
driver->indevbuf = driver->outdevbuf = NULL;
1346
driver->capture_ports = NULL;
1347
driver->playback_ports = NULL;
1349
driver->iodelay = 0.0F;
1350
driver->poll_last = driver->poll_next = 0;
1352
if (sun_driver_set_parameters (driver) < 0)
1358
driver->client = client;
1360
return (jack_driver_t *) driver;
1364
/* jack driver published interface */
1367
const char driver_client_name[] = "sun";
1370
jack_driver_desc_t *
1371
driver_get_descriptor ()
1373
jack_driver_desc_t *desc;
1374
jack_driver_param_desc_t *params;
1376
desc = (jack_driver_desc_t *) calloc(1, sizeof(jack_driver_desc_t));
1379
jack_error("sun_driver: calloc() failed: %s: %s@%i",
1380
strerror(errno), __FILE__, __LINE__);
1383
strcpy(desc->name, driver_client_name);
1384
desc->nparams = SUN_DRIVER_N_PARAMS;
1386
params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
1389
jack_error("sun_driver: calloc() failed: %s: %s@%i",
1390
strerror(errno), __FILE__, __LINE__);
1393
memcpy(params, sun_params,
1394
desc->nparams * sizeof(jack_driver_param_desc_t));
1395
desc->params = params;
1402
driver_initialize (jack_client_t *client, JSList * params)
1404
int bits = SUN_DRIVER_DEF_BITS;
1405
jack_nframes_t sample_rate = SUN_DRIVER_DEF_FS;
1406
jack_nframes_t period_size = SUN_DRIVER_DEF_BLKSIZE;
1407
jack_nframes_t in_latency = 0;
1408
jack_nframes_t out_latency = 0;
1409
unsigned int nperiods = SUN_DRIVER_DEF_NPERIODS;
1410
unsigned int capture_channels = SUN_DRIVER_DEF_INS;
1411
unsigned int playback_channels = SUN_DRIVER_DEF_OUTS;
1412
const JSList *pnode;
1413
const jack_driver_param_t *param;
1416
int ignorehwbuf = 0;
1418
indev = strdup(SUN_DRIVER_DEF_DEV);
1419
outdev = strdup(SUN_DRIVER_DEF_DEV);
1422
while (pnode != NULL)
1424
param = (const jack_driver_param_t *) pnode->data;
1426
switch (param->character)
1429
sample_rate = param->value.ui;
1432
period_size = param->value.ui;
1435
nperiods = param->value.ui;
1438
bits = param->value.i;
1441
capture_channels = param->value.ui;
1444
playback_channels = param->value.ui;
1447
indev = strdup(param->value.str);
1450
outdev = strdup(param->value.str);
1456
in_latency = param->value.ui;
1459
out_latency = param->value.ui;
1462
pnode = jack_slist_next(pnode);
1465
return sun_driver_new (indev, outdev, client, sample_rate, period_size,
1466
nperiods, bits, capture_channels, playback_channels, in_latency,
1467
out_latency, ignorehwbuf);