Annotation of src/usr.bin/aucat/aparams.c, Revision 1.5
1.5 ! ratchov 1: /* $OpenBSD: aparams.c,v 1.4 2008/11/10 23:25:37 ratchov Exp $ */
1.1 ratchov 2: /*
3: * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <stdio.h>
19: #include <stdlib.h>
20: #include <string.h>
21:
22: #include "aparams.h"
1.4 ratchov 23:
24: int aparams_ctltovol[128] = {
25: 0,
26: 256, 266, 276, 287, 299, 310, 323, 335,
27: 348, 362, 376, 391, 406, 422, 439, 456,
28: 474, 493, 512, 532, 553, 575, 597, 621,
29: 645, 670, 697, 724, 753, 782, 813, 845,
30: 878, 912, 948, 985, 1024, 1064, 1106, 1149,
31: 1195, 1241, 1290, 1341, 1393, 1448, 1505, 1564,
32: 1625, 1689, 1756, 1825, 1896, 1971, 2048, 2128,
33: 2212, 2299, 2389, 2483, 2580, 2682, 2787, 2896,
34: 3010, 3128, 3251, 3379, 3511, 3649, 3792, 3941,
35: 4096, 4257, 4424, 4598, 4778, 4966, 5161, 5363,
36: 5574, 5793, 6020, 6256, 6502, 6757, 7023, 7298,
37: 7585, 7883, 8192, 8514, 8848, 9195, 9556, 9931,
38: 10321, 10726, 11148, 11585, 12040, 12513, 13004, 13515,
39: 14045, 14596, 15170, 15765, 16384, 17027, 17696, 18390,
40: 19112, 19863, 20643, 21453, 22295, 23170, 24080, 25025,
41: 26008, 27029, 28090, 29193, 30339, 31530, 32768
42: };
1.1 ratchov 43:
44: /*
1.2 ratchov 45: * Generate a string corresponding to the encoding in par,
46: * return the length of the resulting string
47: */
48: int
49: aparams_enctostr(struct aparams *par, char *ostr)
50: {
51: char *p = ostr;
52:
53: *p++ = par->sig ? 's' : 'u';
54: if (par->bits > 9)
55: *p++ = '0' + par->bits / 10;
56: *p++ = '0' + par->bits % 10;
57: if (par->bps > 1) {
58: *p++ = par->le ? 'l' : 'b';
59: *p++ = 'e';
60: if (par->bps != APARAMS_BPS(par->bits) ||
61: par->bits < par->bps * 8) {
62: *p++ = par->bps + '0';
63: if (par->bits < par->bps * 8) {
64: *p++ = par->msb ? 'm' : 'l';
65: *p++ = 's';
66: *p++ = 'b';
67: }
68: }
69: }
70: *p++ = '\0';
71: return p - ostr - 1;
72: }
73:
74: /*
75: * Parse an encoding string, examples: s8, u8, s16, s16le, s24be ...
76: * set *istr to the char following the encoding. Retrun the number
77: * of bytes consumed
78: */
79: int
80: aparams_strtoenc(struct aparams *par, char *istr)
81: {
82: char *p = istr;
83: int i, sig, bits, le, bps, msb;
84:
85: #define IS_SEP(c) \
86: (((c) < 'a' || (c) > 'z') && \
87: ((c) < 'A' || (c) > 'Z') && \
88: ((c) < '0' || (c) > '9'))
89:
90: /*
91: * get signedness
92: */
93: if (*p == 's') {
94: sig = 1;
95: } else if (*p == 'u') {
96: sig = 0;
97: } else
98: return 0;
99: p++;
100:
101: /*
102: * get number of bits per sample
103: */
104: bits = 0;
105: for (i = 0; i < 2; i++) {
106: if (*p < '0' || *p > '9')
107: break;
108: bits = (bits * 10) + *p - '0';
109: p++;
110: }
111: if (bits < BITS_MIN || bits > BITS_MAX)
112: return 0;
113: bps = APARAMS_BPS(bits);
114: msb = 1;
115: le = NATIVE_LE;
116:
117: /*
118: * get (optionnal) endianness
119: */
120: if (p[0] == 'l' && p[1] == 'e') {
121: le = 1;
122: p += 2;
123: } else if (p[0] == 'b' && p[1] == 'e') {
124: le = 0;
125: p += 2;
126: } else if (IS_SEP(*p)) {
127: goto done;
128: } else
129: return 0;
130:
131: /*
132: * get (optionnal) number of bytes
133: */
134: if (*p >= '0' && *p <= '9') {
135: bps = *p - '0';
136: if (bps < (bits + 7) / 8 ||
137: bps > (BITS_MAX + 7) / 8)
138: return 0;
139: p++;
140:
141: /*
142: * get (optionnal) alignement
143: */
144: if (p[0] == 'm' && p[1] == 's' && p[2] == 'b') {
145: msb = 1;
146: p += 3;
147: } else if (p[0] == 'l' && p[1] == 's' && p[2] == 'b') {
148: msb = 0;
149: p += 3;
150: } else if (IS_SEP(*p)) {
151: goto done;
152: } else
153: return 0;
154: } else if (!IS_SEP(*p))
155: return 0;
156:
157: done:
158: par->msb = msb;
159: par->sig = sig;
160: par->bits = bits;
161: par->bps = bps;
162: par->le = le;
163: return p - istr;
164: }
165:
166: /*
1.1 ratchov 167: * Initialise parameters structure with the defaults natively supported
168: * by the machine.
169: */
170: void
171: aparams_init(struct aparams *par, unsigned cmin, unsigned cmax, unsigned rate)
172: {
173: par->bps = 2; /* 2 bytes per sample */
174: par->bits = 16; /* 16 significant bits per sample */
175: par->sig = 1; /* samples are signed */
176: par->le = NATIVE_LE;
177: par->msb = 1; /* msb justified */
178: par->cmin = cmin;
179: par->cmax = cmax;
180: par->rate = rate;
181: }
182:
183: /*
184: * Print the format/channels/encoding on stderr.
185: */
186: void
187: aparams_print(struct aparams *par)
188: {
1.2 ratchov 189: char enc[ENCMAX];
190:
191: aparams_enctostr(par, enc);
192: fprintf(stderr, "%s", enc);
1.1 ratchov 193: fprintf(stderr, ",%u:%u", par->cmin, par->cmax);
194: fprintf(stderr, ",%uHz", par->rate);
195: }
196:
197: void
198: aparams_print2(struct aparams *par1, struct aparams *par2)
199: {
200: aparams_print(par1);
201: fprintf(stderr, " -> ");
202: aparams_print(par2);
203: }
204:
205: /*
1.3 ratchov 206: * Return true if both encodings are the same.
1.1 ratchov 207: */
208: int
1.3 ratchov 209: aparams_eqenc(struct aparams *par1, struct aparams *par2)
1.1 ratchov 210: {
211: if (par1->bps != par2->bps ||
212: par1->bits != par2->bits ||
1.3 ratchov 213: par1->sig != par2->sig)
1.1 ratchov 214: return 0;
215: if ((par1->bits != 8 * par1->bps) && par1->msb != par2->msb)
216: return 0;
217: if (par1->bps > 1 && par1->le != par2->le)
218: return 0;
219: return 1;
220: }
1.3 ratchov 221:
222: /*
223: * Return true if both parameters are the same.
224: */
225: int
226: aparams_eq(struct aparams *par1, struct aparams *par2)
227: {
228: if (!aparams_eqenc(par1, par2) ||
229: par1->cmin != par2->cmin ||
230: par1->cmax != par2->cmax ||
231: par1->rate != par2->rate)
232: return 0;
233: return 1;
234: }
235:
236: /*
237: * Retrurn true if first channel range includes second range
238: */
239: int
240: aparams_subset(struct aparams *subset, struct aparams *set)
241: {
242: return subset->cmin >= set->cmin && subset->cmax <= set->cmax;
243: }
244:
245: /*
1.5 ! ratchov 246: * grow channels range and sample rate of ``set'' in order ``subset'' to
! 247: * become an actual subset of it.
! 248: */
! 249: void
! 250: aparams_grow(struct aparams *set, struct aparams *subset)
! 251: {
! 252: if (set->cmin > subset->cmin)
! 253: set->cmin = subset->cmin;
! 254: if (set->cmax < subset->cmax)
! 255: set->cmax = subset->cmax;
! 256: if (set->rate < subset->rate)
! 257: set->rate = subset->rate;
! 258: }
! 259:
! 260: /*
1.3 ratchov 261: * Return true if rates are the same
262: */
263: int
264: aparams_eqrate(struct aparams *p1, struct aparams *p2)
265: {
266: /* XXX: allow 1/9 halftone of difference */
267: return p1->rate == p2->rate;
268: }
269:
1.1 ratchov 270:
271: /*
272: * Return the number of bytes per frame with the given parameters.
273: */
274: unsigned
275: aparams_bpf(struct aparams *par)
276: {
277: return (par->cmax - par->cmin + 1) * par->bps;
278: }
1.2 ratchov 279:
280: void
281: aparams_copyenc(struct aparams *dst, struct aparams *src)
282: {
283: dst->sig = src->sig;
284: dst->le = src->le;
285: dst->msb = src->msb;
286: dst->bits = src->bits;
287: dst->bps = src->bps;
288: }