source: roaraudio/roard/driver_sndio.c @ 2369:6c28f6f71c9d

Last change on this file since 2369:6c28f6f71c9d was 2369:6c28f6f71c9d, checked in by phi, 15 years ago

OSS->sndio

File size: 5.4 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, struct roar_stream_server * sstream) {
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(*): sndio devices opened :)");
81
82 if ( sstream != NULL )
83  driver_sndio_ctl(inst, ROAR_VIO_CTL_SET_SSTREAM, sstream);
84
85 return 0;
86}
87#undef er
88
89int     driver_sndio_close_vio    (struct roar_vio_calls * vio) {
90 struct driver_sndio * self = vio->inst;
91
92 if ( self->handle != NULL )
93  sio_close(self->handle);
94
95 if ( self->device != NULL )
96  free(self->device);
97
98 free(self);
99
100 return 0;
101}
102
103int     driver_sndio_open_device  (struct driver_sndio * self) {
104
105 if ( (self->handle = sio_open(self->device, SIO_PLAY, 0)) == NULL ) {
106  ROAR_ERR("driver_sndio_open_device(*): Can not open sndio audio device");
107  return -1;
108 }
109
110 self->need_config = 1;
111
112 return 0;
113}
114
115int     driver_sndio_config_device(struct driver_sndio * self) {
116 struct sio_par par;
117
118 sio_initpar(&par);
119
120 par.bits  = self->info.bits;
121 par.rate  = self->info.rate;
122 par.pchan = self->info.channels;
123
124 switch (self->info.codec) {
125  case ROAR_CODEC_PCM_S_LE:
126    par.le  = 1;
127    par.sig = 1;
128   break;
129  case ROAR_CODEC_PCM_S_BE:
130    par.le  = 0;
131    par.sig = 1;
132   break;
133  case ROAR_CODEC_PCM_U_LE:
134    par.le  = 1;
135    par.sig = 0;
136   break;
137  case ROAR_CODEC_PCM_U_BE:
138    par.le  = 0;
139    par.sig = 0;
140   break;
141  default:
142    return -1;
143   break;
144 }
145
146 if ( sio_setpar(self->handle, &par) == 0 ) {
147  ROAR_ERR("driver_sndio_config_device(*): Can not set stream parameters");
148  return -1;
149 }
150
151 if ( sio_start(self->handle) == 0 ) {
152  ROAR_ERR("driver_sndio_config_device(*): Can not start stream");
153  return -1;
154 }
155
156 self->need_config = 0;
157
158 return 0;
159}
160
161int     driver_sndio_reopen_device(struct driver_sndio * self) {
162 return -1;
163}
164
165ssize_t driver_sndio_write        (struct roar_vio_calls * vio, void *buf, size_t count) {
166 struct driver_sndio * self = vio->inst;
167
168 if ( self->need_config ) {
169  if ( driver_sndio_config_device(vio->inst) == -1 ) {
170   return -1;
171  }
172 }
173
174 return sio_write(self->handle, buf, count);
175}
176
177int     driver_sndio_sync         (struct roar_vio_calls * vio) {
178 return -1;
179}
180
181#define data(x) x: if ( data == NULL ) return -1;
182#define no_data(x) x: if ( data != NULL ) return -1;
183
184int     driver_sndio_ctl          (struct roar_vio_calls * vio, int cmd, void * data) {
185 struct driver_sndio * self = vio->inst;
186 unsigned d;
187
188 switch (cmd) {
189  case data(ROAR_VIO_CTL_SET_SSTREAMID)
190    self->ssid = *(int *)data;
191   break;
192  case data(ROAR_VIO_CTL_SET_SSTREAM)
193    self->stream = data;
194   break;
195  case data(ROAR_VIO_CTL_GET_AUINFO)
196    memcpy(data, &(self->info), sizeof(struct roar_audio_info));
197   break;
198  case data(ROAR_VIO_CTL_SET_AUINFO)
199    memcpy(&(self->info), data, sizeof(struct roar_audio_info));
200    return driver_sndio_reopen_device(self);
201   break;
202  case ROAR_VIO_CTL_SET_VOLUME:
203    switch (self->info.channels) {
204     case 1:
205       d = ROAR_MIXER(data)->mixer[0] * SIO_MAXVOL / ROAR_MIXER(data)->scale;
206      break;
207     case 2:
208       if ( ROAR_MIXER(data)->mixer[0] != ROAR_MIXER(data)->mixer[1] )
209        return -1;
210       d = ROAR_MIXER(data)->mixer[0] * SIO_MAXVOL / ROAR_MIXER(data)->scale;
211      break;
212     default:
213      return -1;
214    }
215    return sio_setvol(self->handle, d) == 0 ? -1 : 0;
216   break;
217  default:
218    return -1;
219   break;
220 }
221
222 return 0;
223}
224
225#endif
226
227//ll
Note: See TracBrowser for help on using the repository browser.