source: roaraudio/libroarsndio/para.c @ 6084:3239837aa782

Last change on this file since 6084:3239837aa782 was 6084:3239837aa782, checked in by phi, 9 years ago

relax check on alignment: allow MSB-aligned in case bits == bps*8

File size: 5.8 KB
Line 
1//para.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2015
5 *  The code (may) include prototypes and comments (and maybe
6 *  other code fragements) from OpenBSD's sndio.
7 *  See 'Copyright for sndio' below for more information on
8 *  code fragments taken from OpenBSD's sndio.
9 *
10 * --- Copyright for sndio ---
11 * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
12 *
13 * Permission to use, copy, modify, and distribute this software for any
14 * purpose with or without fee is hereby granted, provided that the above
15 * copyright notice and this permission notice appear in all copies.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * --- End of Copyright for sndio ---
25 *
26 *  This file is part of libroaresd a part of RoarAudio,
27 *  a cross-platform sound system for both, home and professional use.
28 *  See README for details.
29 *
30 *  This file is free software; you can redistribute it and/or modify
31 *  it under the terms of the GNU General Public License version 3
32 *  as published by the Free Software Foundation.
33 *
34 *  RoarAudio is distributed in the hope that it will be useful,
35 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
36 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37 *  GNU General Public License for more details.
38 *
39 *  You should have received a copy of the GNU General Public License
40 *  along with this software; see the file COPYING.  If not, write to
41 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
42 *  Boston, MA 02110-1301, USA.
43 *
44 *  NOTE for everyone want's to change something and send patches:
45 *  read README and HACKING! There a addition information on
46 *  the license of this document you need to read before you send
47 *  any patches.
48 */
49
50#define ROAR_USE_OWN_SNDIO_HDL
51#include "libroarsndio.h"
52
53//#ifndef DEBUG
54//#define DEBUG
55//#endif
56
57void   sio_initpar(struct sio_par * par) {
58 if ( par == NULL )
59  return;
60
61 memset(par, 0, sizeof(struct sio_par));
62
63 par->bits  = ROAR_BITS_DEFAULT;
64 par->sig   = 1;
65 par->le    = SIO_LE_NATIVE;
66 par->msb   = 1;
67 par->rchan = 0;
68 par->pchan = ROAR_CHANNELS_DEFAULT;
69 par->rate  = ROAR_RATE_DEFAULT;
70 par->bufsz = ROAR_BITS_DEFAULT * ROAR_CHANNELS_DEFAULT * ROAR_RATE_DEFAULT / 800.0;
71 par->round = 1;
72 par->xrun  = SIO_IGNORE;
73
74 return;
75}
76
77int    sio_setpar (struct sio_hdl * hdl, struct sio_par * par) {
78 if ( hdl == NULL || par == NULL ) {
79  ROAR_DBG("sio_setpar(*): Invalid handle or parameter pointer");
80  return 0;
81 }
82
83 if ( par->bits == 0 || par->bits > ROAR_BITS_MAX ) {
84  ROAR_DBG("sio_setpar(*): Invalid number of bits: %i Bit", par->bits);
85  return 0;
86 }
87
88 if ( par->bps == 0 )
89  par->bps = SIO_BPS(par->bits);
90
91 if ( par->bps > ROAR_BITS_MAX/8 ) {
92  ROAR_DBG("sio_setpar(*): Invalid number of bytes: %i Byte", par->bps);
93  return 0;
94 }
95
96 if ( SIO_BPS(par->bits) > par->bps ) {
97  ROAR_DBG("sio_setpar(*): Number of bits/8 > number of bytes: %i/8 > %i", par->bits, par->bps);
98  return 0;
99 }
100
101 hdl->info.bits = par->bps * 8;
102
103 switch ((par->sig << 4) | par->le) {
104  case 0x00:
105    hdl->info.codec = ROAR_CODEC_PCM_U_BE;
106   break;
107  case 0x01:
108    hdl->info.codec = ROAR_CODEC_PCM_U_LE;
109   break;
110  case 0x10:
111    hdl->info.codec = ROAR_CODEC_PCM_S_BE;
112   break;
113  case 0x11:
114    hdl->info.codec = ROAR_CODEC_PCM_S_LE;
115   break;
116  default:
117    ROAR_DBG("sio_setpar(*): Invalid codec: sig=%i, le=%i", par->sig, par->le);
118    return 0;
119 }
120
121 if ( par->msb == 0 && (par->bits != 8*par->bps) ) {
122  ROAR_DBG("sio_setpar(*): LSM alignment not supported");
123  return 0;
124 }
125
126 if ( par->rchan != 0 ) { /* not supported yet */
127  ROAR_DBG("sio_setpar(*): Recording not supported");
128  return 0;
129 }
130
131 if ( par->pchan == 0 || par->pchan > ROAR_MAX_CHANNELS ) {
132  ROAR_DBG("sio_setpar(*): Invalid number of playback channels: %i", par->pchan);
133  return 0;
134 }
135
136 hdl->info.channels = par->pchan;
137
138 if ( par->rate == 0 ) {
139  ROAR_DBG("sio_setpar(*): Invalid sample rate: %iHz", par->rate);
140  return 0;
141 }
142
143 hdl->info.rate = par->rate;
144
145 if ( par->xrun != SIO_IGNORE ) {
146  ROAR_DBG("sio_setpar(*): Unsupported xrun mode: %i", par->xrun);
147  return 0;
148 }
149
150 memcpy(&(hdl->para), par, sizeof(struct sio_par));
151
152 return 1;
153}
154
155int    sio_getpar (struct sio_hdl * hdl, struct sio_par * par) {
156 if ( hdl == NULL || par == NULL )
157  return 0;
158
159 memcpy(par, &(hdl->para), sizeof(struct sio_par));
160
161 return 1;
162}
163
164int    sio_getcap (struct sio_hdl * hdl, struct sio_cap * cap) {
165 struct roar_stream s;
166 unsigned int i;
167 unsigned int bytes;
168 unsigned int sign;
169 unsigned int le;
170 unsigned int mask = 0;
171
172 if ( cap == NULL )
173  return 0;
174
175 if ( roar_server_oinfo(&(hdl->con), &s, ROAR_DIR_PLAY) == -1 )
176  return 0;
177
178 i = 0;
179 for (bytes = 1; bytes <= s.info.bits/8; bytes++) {
180  for (sign = 0; sign  < 2; sign++) {
181   for (le  = 0; le    < 2; le++) {
182    cap->enc[i].bits =   8*bytes;
183    cap->enc[i].bps  =     bytes;
184    cap->enc[i].sig  =     sign;
185    cap->enc[i].le   =     le;
186    cap->enc[i].msb  =   1;
187    mask |= 1 << i;
188    i++;
189   }
190  }
191 }
192
193 // TODO: fix this (at least include server channels,
194 //                 do nit include confusing setups)
195 if ( s.info.channels > SIO_NCHAN ) {
196  s.info.channels = SIO_NCHAN;
197 }
198
199 for (i = 0; i < s.info.channels; i++) {
200  cap->rchan[i] = i+1;
201  cap->pchan[i] = i+1;
202 }
203
204 cap->rate[0] = s.info.rate;
205
206 cap->nconf = 1;
207
208 cap->confs[0].enc   = mask;
209 cap->confs[0].rchan = mask;
210 cap->confs[0].pchan = mask;
211 cap->confs[0].rate  = 0x0001;
212
213 return 1;
214}
215
216
217//ll
Note: See TracBrowser for help on using the repository browser.