source: roaraudio/roard/driver_sndio.c @ 1583:a06ebe83db1a

Last change on this file since 1583:a06ebe83db1a was 1583:a06ebe83db1a, checked in by phi, 15 years ago

added debug macros, fixed double configure bug, changed code in order to help finding some bugs on what happens in case device can't be opened

File size: 4.8 KB
Line 
1//driver_sndio.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio 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.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "roard.h"
26#ifdef ROAR_HAVE_LIBSNDIO
27
28int driver_sndio_init_vio(struct roar_vio_calls * vio, struct driver_sndio * inst) {
29 if ( vio == NULL )
30  return -1;
31
32 memset(vio, 0, sizeof(struct roar_vio_calls));
33
34 vio->close    = driver_sndio_close_vio;
35 vio->write    = driver_sndio_write;
36 vio->sync     = driver_sndio_sync;
37 vio->ctl      = driver_sndio_ctl;
38
39 vio->inst     = (void*) inst;
40
41 return 0;
42}
43
44#define er() if ( self->handle ) sio_close(self->handle); if ( self->device ) free(self->device); free(self); return -1
45int driver_sndio_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh) {
46 struct driver_sndio * self = NULL;
47
48 if ( (self = malloc(sizeof(struct driver_sndio))) == NULL ) {
49  ROAR_ERR("driver_sndio_open(*): Can not malloc() instance data: %s", strerror(errno));
50  return -1;
51 }
52
53 memset(self, 0, sizeof(struct driver_sndio));
54 memcpy(&(self->info), info, sizeof(struct roar_audio_info));
55
56 self->ssid = -1;
57
58 if ( device != NULL )
59  self->device = strdup(device);
60
61 if ( driver_sndio_init_vio(inst, self) == -1 ) {
62  ROAR_ERR("driver_sndio_open(*): Can not init vio interface");
63  er();
64 }
65
66 if ( driver_sndio_open_device(self) == -1 ) {
67  ROAR_ERR("driver_sndio_open(*): Can not open audio device");
68  if ( self->handle )
69   sio_close(self->handle);
70
71  if ( self->device )
72   free(self->device);
73
74  free(self);
75
76  return -1;
77//  er();
78 }
79
80 ROAR_DBG("driver_sndio_open(*): OSS devices opened :)");
81
82 return 0;
83}
84#undef er
85
86int     driver_sndio_close_vio    (struct roar_vio_calls * vio) {
87 struct driver_sndio * self = vio->inst;
88
89 if ( self->handle != NULL )
90  sio_close(self->handle);
91
92 if ( self->device != NULL )
93  free(self->device);
94
95 free(self);
96
97 return 0;
98}
99
100int     driver_sndio_open_device  (struct driver_sndio * self) {
101
102 if ( (self->handle = sio_open(self->device, SIO_PLAY, 0)) == NULL ) {
103  ROAR_ERR("driver_sndio_open_device(*): Can not open sndio audio device");
104  return -1;
105 }
106
107 self->need_config = 1;
108
109 return 0;
110}
111
112int     driver_sndio_config_device(struct driver_sndio * self) {
113 struct sio_par par;
114
115 sio_initpar(&par);
116
117 par.bits  = self->info.bits;
118 par.rate  = self->info.rate;
119 par.pchan = self->info.channels;
120
121 switch (self->info.codec) {
122  case ROAR_CODEC_PCM_S_LE:
123    par.le  = 1;
124    par.sig = 1;
125   break;
126  case ROAR_CODEC_PCM_S_BE:
127    par.le  = 0;
128    par.sig = 1;
129   break;
130  case ROAR_CODEC_PCM_U_LE:
131    par.le  = 1;
132    par.sig = 0;
133   break;
134  case ROAR_CODEC_PCM_U_BE:
135    par.le  = 0;
136    par.sig = 0;
137   break;
138  default:
139    return -1;
140   break;
141 }
142
143 if ( sio_setpar(self->handle, &par) == 0 ) {
144  ROAR_ERR("driver_sndio_config_device(*): Can not set stream parameters");
145  return -1;
146 }
147
148 if ( sio_start(self->handle) == 0 ) {
149  ROAR_ERR("driver_sndio_config_device(*): Can not start stream");
150  return -1;
151 }
152
153 self->need_config = 0;
154
155 return 0;
156}
157
158int     driver_sndio_reopen_device(struct driver_sndio * self) {
159 return -1;
160}
161
162ssize_t driver_sndio_write        (struct roar_vio_calls * vio, void *buf, size_t count) {
163 struct driver_sndio * self = vio->inst;
164
165 if ( self->need_config ) {
166  if ( driver_sndio_config_device(vio->inst) == -1 ) {
167   return -1;
168  }
169 }
170
171 return sio_write(self->handle, buf, count);
172}
173
174int     driver_sndio_sync         (struct roar_vio_calls * vio) {
175 return -1;
176}
177
178#define data(x) x: if ( data == NULL ) return -1;
179#define no_data(x) x: if ( data != NULL ) return -1;
180
181int     driver_sndio_ctl          (struct roar_vio_calls * vio, int cmd, void * data) {
182 struct driver_sndio * self = vio->inst;
183
184 switch (cmd) {
185  case data(ROAR_VIO_CTL_SET_SSTREAMID)
186    self->ssid = *(int *)data;
187   break;
188  case data(ROAR_VIO_CTL_SET_SSTREAM)
189    self->stream = data;
190   break;
191  case data(ROAR_VIO_CTL_GET_AUINFO)
192    memcpy(data, &(self->info), sizeof(struct roar_audio_info));
193   break;
194  case data(ROAR_VIO_CTL_SET_AUINFO)
195    memcpy(&(self->info), data, sizeof(struct roar_audio_info));
196    return driver_sndio_reopen_device(self);
197   break;
198  default:
199    return -1;
200   break;
201 }
202
203 return 0;
204}
205
206#endif
207
208//ll
Note: See TracBrowser for help on using the repository browser.