source: roaraudio/roard/driver_jack.c @ 5439:7950543cabbc

Last change on this file since 5439:7950543cabbc was 5388:e5cc8e03a3e1, checked in by phi, 12 years ago

Added support for refcount based VIOs as well as dynamically allocated VIOs (non-stack or global VIOs) (Closes: #127)

File size: 8.0 KB
Line 
1//driver_jack.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2012
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 inst->flags    = ROAR_VIO_FLAGS_NONE;
64 inst->refc     = 1;
65
66 inst->read     = driver_jack_read;
67 inst->write    = driver_jack_write;
68 inst->lseek    = NULL; // no seeking on this device
69 inst->sync     = driver_jack_sync;
70 inst->ctl      = driver_jack_ctl;
71 inst->close    = driver_jack_close;
72
73 // set up internal struct:
74 if ( (self = roar_mm_malloc(sizeof(struct driver_jack))) == NULL )
75  return -1;
76
77 memset(self, 0, sizeof(struct driver_jack));
78
79 inst->inst     = self;
80
81 if ( (self->client = jack_client_open("roard", JackNullOption, NULL)) == NULL ) {
82  roar_mm_free(self);
83  return -1;
84 }
85
86 new_rate = jack_get_sample_rate(self->client);
87
88 // need to check if we need to change stream's parameters:
89 if ( info->rate != new_rate || info->bits != 32 || info->codec != ROAR_CODEC_DEFAULT ) {
90  if ( autoconfig ) {
91   // we are allowed to change the parameters
92   info->rate  = new_rate;
93   info->bits  = 32;
94   info->codec = ROAR_CODEC_DEFAULT;
95  } else {
96   // we are not allowed to change the parameters
97   ROAR_WARN("driver_jack_open_vio(*): Can not open jack driver with given parameters, try -oO ...,autoconf");
98   goto free_close;
99  }
100 }
101
102 if ( recsource )
103  if ( (self->ports_in = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL )
104   goto free_close;
105
106 if ( (self->ports_out = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL )
107  goto free_ins;
108
109 // NULL ports so we do not segfaul if something goes wrong.
110 if ( self->ports_in != NULL )
111  memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels);
112 memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels);
113
114 for (self->channels = 0; self->channels < info->channels; self->channels++) {
115  if ( recsource ) {
116   snprintf(port_name, sizeof(port_name), "in_%03u", self->channels);
117   if ( (self->ports_in [self->channels] = jack_port_register(self->client, port_name,
118                                                              JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL )
119    goto unregister_ports;
120  }
121
122  snprintf(port_name, sizeof(port_name), "out_%03u", self->channels);
123  if ( (self->ports_out[self->channels] = jack_port_register(self->client, port_name,
124                                                             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL ) {
125   jack_port_unregister(self->client, self->ports_in[self->channels]);
126   goto unregister_ports;
127  }
128 }
129
130 if (jack_activate(self->client) != 0)
131  goto unregister_ports;
132
133 return 0;
134
135unregister_ports:
136 unregister_ports(self);
137free_ins:
138 if ( self->ports_in != NULL )
139  roar_mm_free(self->ports_in);
140free_close:
141 jack_client_close(self->client);
142 roar_mm_free(self);
143 return -1; // error
144}
145
146ssize_t driver_jack_read    (struct roar_vio_calls * vio, void *buf, size_t count) {
147 struct driver_jack * self = vio->inst;
148 // read up to count bytes into buf.
149 // return the number of bits read.
150 return -1;
151}
152
153ssize_t driver_jack_write   (struct roar_vio_calls * vio, void *buf, size_t count) {
154 struct driver_jack * self = vio->inst;
155 // write up to count bytes from buf.
156 // return the number of written bytes.
157 return -1;
158}
159
160int     driver_jack_sync    (struct roar_vio_calls * vio) {
161 struct driver_jack * self = vio->inst;
162 // init to sync data to device.
163 // sync does not need to be complet when this function returns.
164 return 0;
165}
166
167int     driver_jack_ctl     (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) {
168 struct driver_jack * self = vio->inst;
169 // function for a lot control features.
170
171 switch (cmd) {
172  case ROAR_VIO_CTL_GET_NAME:
173    if ( data == NULL )
174     return -1;
175
176    *(char**)data = "driver_jack";
177    return 0;
178   break;
179  case ROAR_VIO_CTL_GET_FH:
180  case ROAR_VIO_CTL_GET_READ_FH:
181  case ROAR_VIO_CTL_GET_WRITE_FH:
182  case ROAR_VIO_CTL_GET_SELECT_FH:
183  case ROAR_VIO_CTL_GET_SELECT_READ_FH:
184  case ROAR_VIO_CTL_GET_SELECT_WRITE_FH:
185/* Return FH if possible:
186    *(int*)data = FH...;
187*/
188    roar_err_set(ROAR_ERROR_NOTSUP);
189    return -1;
190   break;
191  case ROAR_VIO_CTL_SET_NOSYNC:
192    vio->sync = NULL;
193    return 0;
194   break;
195  case ROAR_VIO_CTL_NONBLOCK:
196    // control if read and write calls should block untill all data is read or written.
197    // state is in *(int*)data and could be:
198    //  ROAR_SOCKET_BLOCK    - Block untill the data is read or written
199    //  ROAR_SOCKET_NONBLOCK - Return as soon as possible
200    roar_err_set(ROAR_ERROR_NOTSUP);
201    return -1;
202   break;
203  case ROAR_VIO_CTL_GET_AUINFO:
204  case ROAR_VIO_CTL_SET_AUINFO:
205    // get or set audio info, data is a struct roar_audio_info*.
206    roar_err_set(ROAR_ERROR_NOTSUP);
207    return -1;
208   break;
209  case ROAR_VIO_CTL_GET_DBLKSIZE:
210  case ROAR_VIO_CTL_SET_DBLKSIZE:
211    // get or set block size used, data is uint_least32_t*, number of bytes.
212    roar_err_set(ROAR_ERROR_NOTSUP);
213    return -1;
214   break;
215  case ROAR_VIO_CTL_GET_DBLOCKS:
216  case ROAR_VIO_CTL_SET_DBLOCKS:
217    // get or set number of blocks used, data is uint_least32_t*.
218    roar_err_set(ROAR_ERROR_NOTSUP);
219    return -1;
220   break;
221  case ROAR_VIO_CTL_SET_SSTREAM:
222    // set server stream object for this stream, data is struct roar_stream_server*
223    roar_err_set(ROAR_ERROR_NOTSUP);
224    return -1;
225   break;
226  case ROAR_VIO_CTL_SET_SSTREAMID:
227    // set stream ID for this stream, data is int*
228    roar_err_set(ROAR_ERROR_NOTSUP);
229    return -1;
230   break;
231  case ROAR_VIO_CTL_SET_VOLUME:
232    // set volume for this device, data is struct roar_mixer_settings*
233    roar_err_set(ROAR_ERROR_NOTSUP);
234    return -1;
235   break;
236  case ROAR_VIO_CTL_GET_DELAY:
237    // get delay of this stream, data is uint_least32_t*, in bytes
238    // there is more about delay. please ask.
239    roar_err_set(ROAR_ERROR_NOTSUP);
240    return -1;
241   break;
242 }
243
244 roar_err_set(ROAR_ERROR_BADRQC);
245 return -1;
246}
247
248int     driver_jack_close   (struct roar_vio_calls * vio) {
249 struct driver_jack * self = vio->inst;
250 // close and free everything in here...
251
252 jack_deactivate(self->client);
253 unregister_ports(self);
254 jack_client_close(self->client);
255
256 roar_mm_free(self);
257
258 return 0;
259}
260
261#endif
262
263//ll
Note: See TracBrowser for help on using the repository browser.