source: roaraudio/roard/driver_sndio.c @ 2367:bdbcf1c16820

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

added server stream para to all drivers

File size: 5.3 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(*): 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 unsigned d;
184
185 switch (cmd) {
186  case data(ROAR_VIO_CTL_SET_SSTREAMID)
187    self->ssid = *(int *)data;
188   break;
189  case data(ROAR_VIO_CTL_SET_SSTREAM)
190    self->stream = data;
191   break;
192  case data(ROAR_VIO_CTL_GET_AUINFO)
193    memcpy(data, &(self->info), sizeof(struct roar_audio_info));
194   break;
195  case data(ROAR_VIO_CTL_SET_AUINFO)
196    memcpy(&(self->info), data, sizeof(struct roar_audio_info));
197    return driver_sndio_reopen_device(self);
198   break;
199  case ROAR_VIO_CTL_SET_VOLUME:
200    switch (self->info.channels) {
201     case 1:
202       d = ROAR_MIXER(data)->mixer[0] * SIO_MAXVOL / ROAR_MIXER(data)->scale;
203      break;
204     case 2:
205       if ( ROAR_MIXER(data)->mixer[0] != ROAR_MIXER(data)->mixer[1] )
206        return -1;
207       d = ROAR_MIXER(data)->mixer[0] * SIO_MAXVOL / ROAR_MIXER(data)->scale;
208      break;
209     default:
210      return -1;
211    }
212    return sio_setvol(self->handle, d) == 0 ? -1 : 0;
213   break;
214  default:
215    return -1;
216   break;
217 }
218
219 return 0;
220}
221
222#endif
223
224//ll
Note: See TracBrowser for help on using the repository browser.