source: roaraudio/roard/driver_jack.c @ 5278:b3e0dd3f3141

Last change on this file since 5278:b3e0dd3f3141 was 5278:b3e0dd3f3141, checked in by phi, 12 years ago

last parts of merging _nonblock into _ctl and fixed sizeof(cmd) of _ctls

File size: 7.9 KB
Line 
1//driver_jack.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2011
5 *      Copyright (C) Nedko Arnaudov <nedko@arnaudov.name> - 2010
6 *
7 *  This file is part of roard a part of RoarAudio,
8 *  a cross-platform sound system for both, home and professional use.
9 *  See README for details.
10 *
11 *  This file is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License version 3
13 *  as published by the Free Software Foundation.
14 *
15 *  RoarAudio is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this software; see the file COPYING.  If not, write to
22 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 *  Boston, MA 02110-1301, USA.
24 *
25 */
26
27#include "roard.h"
28
29#ifdef ROAR_HAVE_LIBJACK
30
31static void unregister_ports(struct driver_jack * self) {
32 while(self->channels--) {
33  if ( self->ports_in != NULL )
34   if ( self->ports_in [self->channels] != NULL )
35    jack_port_unregister(self->client, self->ports_in [self->channels]);
36  if ( self->ports_out[self->channels] != NULL )
37   jack_port_unregister(self->client, self->ports_out[self->channels]);
38 }
39}
40
41int driver_jack_open_vio  (struct roar_vio_calls * inst,
42                           char * device,
43                           struct roar_audio_info * info,
44                           int fh,
45                           struct roar_stream_server * sstream) {
46 struct driver_jack * self;
47 char port_name[128];
48 jack_nframes_t new_rate;
49 int autoconfig            = 0;
50 int recsource             = 0;
51
52 // we are not FH Safe, return error if fh != -1:
53 if ( fh != -1 )
54  return -1;
55
56 if ( sstream != NULL ) {
57  autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF);
58  recsource  = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_RECSOURCE);
59 }
60
61 // set up VIO:
62 memset(inst, 0, sizeof(struct roar_vio_calls));
63
64 inst->read     = driver_jack_read;
65 inst->write    = driver_jack_write;
66 inst->lseek    = NULL; // no seeking on this device
67 inst->sync     = driver_jack_sync;
68 inst->ctl      = driver_jack_ctl;
69 inst->close    = driver_jack_close;
70
71 // set up internal struct:
72 if ( (self = roar_mm_malloc(sizeof(struct driver_jack))) == NULL )
73  return -1;
74
75 memset(self, 0, sizeof(struct driver_jack));
76
77 inst->inst     = self;
78
79 if ( (self->client = jack_client_open("roard", JackNullOption, NULL)) == NULL ) {
80  roar_mm_free(self);
81  return -1;
82 }
83
84 new_rate = jack_get_sample_rate(self->client);
85
86 // need to check if we need to change stream's parameters:
87 if ( info->rate != new_rate || info->bits != 32 || info->codec != ROAR_CODEC_DEFAULT ) {
88  if ( autoconfig ) {
89   // we are allowed to change the parameters
90   info->rate  = new_rate;
91   info->bits  = 32;
92   info->codec = ROAR_CODEC_DEFAULT;
93  } else {
94   // we are not allowed to change the parameters
95   ROAR_WARN("driver_jack_open_vio(*): Can not open jack driver with given parameters, try -oO ...,autoconf");
96   goto free_close;
97  }
98 }
99
100 if ( recsource )
101  if ( (self->ports_in = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL )
102   goto free_close;
103
104 if ( (self->ports_out = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL )
105  goto free_ins;
106
107 // NULL ports so we do not segfaul if something goes wrong.
108 if ( self->ports_in != NULL )
109  memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels);
110 memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels);
111
112 for (self->channels = 0; self->channels < info->channels; self->channels++) {
113  if ( recsource ) {
114   snprintf(port_name, sizeof(port_name), "in_%03u", self->channels);
115   if ( (self->ports_in [self->channels] = jack_port_register(self->client, port_name,
116                                                              JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL )
117    goto unregister_ports;
118  }
119
120  snprintf(port_name, sizeof(port_name), "out_%03u", self->channels);
121  if ( (self->ports_out[self->channels] = jack_port_register(self->client, port_name,
122                                                             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL ) {
123   jack_port_unregister(self->client, self->ports_in[self->channels]);
124   goto unregister_ports;
125  }
126 }
127
128 if (jack_activate(self->client) != 0)
129  goto unregister_ports;
130
131 return 0;
132
133unregister_ports:
134 unregister_ports(self);
135free_ins:
136 if ( self->ports_in != NULL )
137  roar_mm_free(self->ports_in);
138free_close:
139 jack_client_close(self->client);
140 roar_mm_free(self);
141 return -1; // error
142}
143
144ssize_t driver_jack_read    (struct roar_vio_calls * vio, void *buf, size_t count) {
145 struct driver_jack * self = vio->inst;
146 // read up to count bytes into buf.
147 // return the number of bits read.
148 return -1;
149}
150
151ssize_t driver_jack_write   (struct roar_vio_calls * vio, void *buf, size_t count) {
152 struct driver_jack * self = vio->inst;
153 // write up to count bytes from buf.
154 // return the number of written bytes.
155 return -1;
156}
157
158int     driver_jack_sync    (struct roar_vio_calls * vio) {
159 struct driver_jack * self = vio->inst;
160 // init to sync data to device.
161 // sync does not need to be complet when this function returns.
162 return 0;
163}
164
165int     driver_jack_ctl     (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) {
166 struct driver_jack * self = vio->inst;
167 // function for a lot control features.
168
169 switch (cmd) {
170  case ROAR_VIO_CTL_GET_NAME:
171    if ( data == NULL )
172     return -1;
173
174    *(char**)data = "driver_jack";
175    return 0;
176   break;
177  case ROAR_VIO_CTL_GET_FH:
178  case ROAR_VIO_CTL_GET_READ_FH:
179  case ROAR_VIO_CTL_GET_WRITE_FH:
180  case ROAR_VIO_CTL_GET_SELECT_FH:
181  case ROAR_VIO_CTL_GET_SELECT_READ_FH:
182  case ROAR_VIO_CTL_GET_SELECT_WRITE_FH:
183/* Return FH if possible:
184    *(int*)data = FH...;
185*/
186    roar_err_set(ROAR_ERROR_NOTSUP);
187    return -1;
188   break;
189  case ROAR_VIO_CTL_SET_NOSYNC:
190    vio->sync = NULL;
191    return 0;
192   break;
193  case ROAR_VIO_CTL_NONBLOCK:
194    // control if read and write calls should block untill all data is read or written.
195    // state is in *(int*)data and could be:
196    //  ROAR_SOCKET_BLOCK    - Block untill the data is read or written
197    //  ROAR_SOCKET_NONBLOCK - Return as soon as possible
198    roar_err_set(ROAR_ERROR_NOTSUP);
199    return -1;
200   break;
201  case ROAR_VIO_CTL_GET_AUINFO:
202  case ROAR_VIO_CTL_SET_AUINFO:
203    // get or set audio info, data is a struct roar_audio_info*.
204    roar_err_set(ROAR_ERROR_NOTSUP);
205    return -1;
206   break;
207  case ROAR_VIO_CTL_GET_DBLKSIZE:
208  case ROAR_VIO_CTL_SET_DBLKSIZE:
209    // get or set block size used, data is uint_least32_t*, number of bytes.
210    roar_err_set(ROAR_ERROR_NOTSUP);
211    return -1;
212   break;
213  case ROAR_VIO_CTL_GET_DBLOCKS:
214  case ROAR_VIO_CTL_SET_DBLOCKS:
215    // get or set number of blocks used, data is uint_least32_t*.
216    roar_err_set(ROAR_ERROR_NOTSUP);
217    return -1;
218   break;
219  case ROAR_VIO_CTL_SET_SSTREAM:
220    // set server stream object for this stream, data is struct roar_stream_server*
221    roar_err_set(ROAR_ERROR_NOTSUP);
222    return -1;
223   break;
224  case ROAR_VIO_CTL_SET_SSTREAMID:
225    // set stream ID for this stream, data is int*
226    roar_err_set(ROAR_ERROR_NOTSUP);
227    return -1;
228   break;
229  case ROAR_VIO_CTL_SET_VOLUME:
230    // set volume for this device, data is struct roar_mixer_settings*
231    roar_err_set(ROAR_ERROR_NOTSUP);
232    return -1;
233   break;
234  case ROAR_VIO_CTL_GET_DELAY:
235    // get delay of this stream, data is uint_least32_t*, in bytes
236    // there is more about delay. please ask.
237    roar_err_set(ROAR_ERROR_NOTSUP);
238    return -1;
239   break;
240 }
241
242 roar_err_set(ROAR_ERROR_BADRQC);
243 return -1;
244}
245
246int     driver_jack_close   (struct roar_vio_calls * vio) {
247 struct driver_jack * self = vio->inst;
248 // close and free everything in here...
249
250 jack_deactivate(self->client);
251 unregister_ports(self);
252 jack_client_close(self->client);
253
254 roar_mm_free(self);
255
256 return 0;
257}
258
259#endif
260
261//ll
Note: See TracBrowser for help on using the repository browser.