[BACK]Return to aparams.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / aucat

Annotation of src/usr.bin/aucat/aparams.c, Revision 1.11

1.11    ! ratchov     1: /*     $OpenBSD: aparams.c,v 1.10 2010/01/10 21:47:41 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 "aparams.h"
1.10      ratchov    19: #ifdef DEBUG
                     20: #include "dbg.h"
                     21: #endif
1.4       ratchov    22:
                     23: int aparams_ctltovol[128] = {
                     24:            0,
                     25:          256,    266,    276,    287,    299,    310,    323,    335,
                     26:          348,    362,    376,    391,    406,    422,    439,    456,
                     27:          474,    493,    512,    532,    553,    575,    597,    621,
                     28:          645,    670,    697,    724,    753,    782,    813,    845,
                     29:          878,    912,    948,    985,   1024,   1064,   1106,   1149,
                     30:         1195,   1241,   1290,   1341,   1393,   1448,   1505,   1564,
                     31:         1625,   1689,   1756,   1825,   1896,   1971,   2048,   2128,
                     32:         2212,   2299,   2389,   2483,   2580,   2682,   2787,   2896,
                     33:         3010,   3128,   3251,   3379,   3511,   3649,   3792,   3941,
                     34:         4096,   4257,   4424,   4598,   4778,   4966,   5161,   5363,
                     35:         5574,   5793,   6020,   6256,   6502,   6757,   7023,   7298,
                     36:         7585,   7883,   8192,   8514,   8848,   9195,   9556,   9931,
                     37:        10321,  10726,  11148,  11585,  12040,  12513,  13004,  13515,
                     38:        14045,  14596,  15170,  15765,  16384,  17027,  17696,  18390,
                     39:        19112,  19863,  20643,  21453,  22295,  23170,  24080,  25025,
                     40:        26008,  27029,  28090,  29193,  30339,  31530,  32768
                     41: };
1.8       ratchov    42:
                     43: /*
                     44:  * Fake parameters for byte-streams
                     45:  */
                     46: struct aparams aparams_none = { 1, 0, 0, 0, 0, 0, 0, 0 };
1.1       ratchov    47:
                     48: /*
1.2       ratchov    49:  * Generate a string corresponding to the encoding in par,
1.7       ratchov    50:  * return the length of the resulting string.
1.2       ratchov    51:  */
                     52: int
                     53: aparams_enctostr(struct aparams *par, char *ostr)
                     54: {
                     55:        char *p = ostr;
                     56:
                     57:        *p++ = par->sig ? 's' : 'u';
                     58:        if (par->bits > 9)
                     59:                *p++ = '0' + par->bits / 10;
                     60:        *p++ = '0' + par->bits % 10;
                     61:        if (par->bps > 1) {
                     62:                *p++ = par->le ? 'l' : 'b';
                     63:                *p++ = 'e';
                     64:                if (par->bps != APARAMS_BPS(par->bits) ||
                     65:                    par->bits < par->bps * 8) {
                     66:                        *p++ = par->bps + '0';
                     67:                        if (par->bits < par->bps * 8) {
                     68:                                *p++ = par->msb ? 'm' : 'l';
                     69:                                *p++ = 's';
                     70:                                *p++ = 'b';
                     71:                        }
                     72:                }
                     73:        }
                     74:        *p++ = '\0';
                     75:        return p - ostr - 1;
                     76: }
                     77:
                     78: /*
                     79:  * Parse an encoding string, examples: s8, u8, s16, s16le, s24be ...
1.7       ratchov    80:  * set *istr to the char following the encoding. Return the number
                     81:  * of bytes consumed.
1.2       ratchov    82:  */
                     83: int
                     84: aparams_strtoenc(struct aparams *par, char *istr)
                     85: {
                     86:        char *p = istr;
                     87:        int i, sig, bits, le, bps, msb;
1.6       ratchov    88:
1.2       ratchov    89: #define IS_SEP(c)                      \
                     90:        (((c) < 'a' || (c) > 'z') &&    \
                     91:         ((c) < 'A' || (c) > 'Z') &&    \
                     92:         ((c) < '0' || (c) > '9'))
                     93:
                     94:        /*
                     95:         * get signedness
                     96:         */
                     97:        if (*p == 's') {
                     98:                sig = 1;
                     99:        } else if (*p == 'u') {
                    100:                sig = 0;
                    101:        } else
                    102:                return 0;
                    103:        p++;
1.6       ratchov   104:
1.2       ratchov   105:        /*
                    106:         * get number of bits per sample
                    107:         */
                    108:        bits = 0;
                    109:        for (i = 0; i < 2; i++) {
                    110:                if (*p < '0' || *p > '9')
                    111:                        break;
                    112:                bits = (bits * 10) + *p - '0';
                    113:                p++;
                    114:        }
                    115:        if (bits < BITS_MIN || bits > BITS_MAX)
                    116:                return 0;
                    117:        bps = APARAMS_BPS(bits);
                    118:        msb = 1;
                    119:        le = NATIVE_LE;
                    120:
                    121:        /*
1.7       ratchov   122:         * get (optional) endianness
1.2       ratchov   123:         */
                    124:        if (p[0] == 'l' && p[1] == 'e') {
                    125:                le = 1;
                    126:                p += 2;
                    127:        } else if (p[0] == 'b' && p[1] == 'e') {
                    128:                le = 0;
                    129:                p += 2;
                    130:        } else if (IS_SEP(*p)) {
                    131:                goto done;
                    132:        } else
                    133:                return 0;
                    134:
                    135:        /*
1.7       ratchov   136:         * get (optional) number of bytes
1.2       ratchov   137:         */
                    138:        if (*p >= '0' && *p <= '9') {
                    139:                bps = *p - '0';
                    140:                if (bps < (bits + 7) / 8 ||
                    141:                    bps > (BITS_MAX + 7) / 8)
                    142:                        return 0;
                    143:                p++;
                    144:
                    145:                /*
1.7       ratchov   146:                 * get (optional) alignement
1.2       ratchov   147:                 */
                    148:                if (p[0] == 'm' && p[1] == 's' && p[2] == 'b') {
                    149:                        msb = 1;
                    150:                        p += 3;
                    151:                } else if (p[0] == 'l' && p[1] == 's' && p[2] == 'b') {
                    152:                        msb = 0;
                    153:                        p += 3;
                    154:                } else if (IS_SEP(*p)) {
                    155:                        goto done;
                    156:                } else
                    157:                        return 0;
                    158:        } else if (!IS_SEP(*p))
                    159:                return 0;
                    160:
                    161: done:
                    162:                par->msb = msb;
                    163:        par->sig = sig;
                    164:        par->bits = bits;
                    165:        par->bps = bps;
                    166:        par->le = le;
                    167:        return p - istr;
                    168: }
                    169:
                    170: /*
1.1       ratchov   171:  * Initialise parameters structure with the defaults natively supported
                    172:  * by the machine.
                    173:  */
                    174: void
                    175: aparams_init(struct aparams *par, unsigned cmin, unsigned cmax, unsigned rate)
                    176: {
1.11    ! ratchov   177:        par->bps = sizeof(adata_t);
        !           178:        par->bits = ADATA_BITS;
        !           179:        par->sig = 1;
1.1       ratchov   180:        par->le = NATIVE_LE;
1.11    ! ratchov   181:        par->msb = ADATA_MSB;
1.1       ratchov   182:        par->cmin = cmin;
                    183:        par->cmax = cmax;
                    184:        par->rate = rate;
                    185: }
                    186:
1.10      ratchov   187: #ifdef DEBUG
                    188: /*
                    189:  * Print the format/channels/encoding on stderr.
                    190:  */
                    191: void
                    192: aparams_dbg(struct aparams *par)
                    193: {
                    194:        char enc[ENCMAX];
                    195:
                    196:        aparams_enctostr(par, enc);
                    197:        dbg_puts(enc);
                    198:        dbg_puts(",");
                    199:        dbg_putu(par->cmin);
                    200:        dbg_puts(":");
                    201:        dbg_putu(par->cmax);
                    202:        dbg_puts(",");
                    203:        dbg_putu(par->rate);
                    204: }
                    205: #endif
1.1       ratchov   206:
                    207: /*
1.3       ratchov   208:  * Return true if both encodings are the same.
1.1       ratchov   209:  */
                    210: int
1.3       ratchov   211: aparams_eqenc(struct aparams *par1, struct aparams *par2)
1.1       ratchov   212: {
                    213:        if (par1->bps != par2->bps ||
                    214:            par1->bits != par2->bits ||
1.3       ratchov   215:            par1->sig != par2->sig)
1.1       ratchov   216:                return 0;
                    217:        if ((par1->bits != 8 * par1->bps) && par1->msb != par2->msb)
                    218:                return 0;
                    219:        if (par1->bps > 1 && par1->le != par2->le)
                    220:                return 0;
                    221:        return 1;
                    222: }
1.3       ratchov   223:
                    224: /*
                    225:  * Return true if both parameters are the same.
                    226:  */
                    227: int
                    228: aparams_eq(struct aparams *par1, struct aparams *par2)
                    229: {
                    230:        if (!aparams_eqenc(par1, par2) ||
                    231:            par1->cmin != par2->cmin ||
                    232:            par1->cmax != par2->cmax ||
                    233:            par1->rate != par2->rate)
                    234:                return 0;
                    235:        return 1;
                    236: }
                    237:
                    238: /*
1.7       ratchov   239:  * Return true if first channel range includes second range.
1.3       ratchov   240:  */
                    241: int
                    242: aparams_subset(struct aparams *subset, struct aparams *set)
                    243: {
                    244:        return subset->cmin >= set->cmin && subset->cmax <= set->cmax;
                    245: }
                    246:
                    247: /*
1.7       ratchov   248:  * Grow channels range and sample rate of ``set'' in order ``subset'' to
1.5       ratchov   249:  * become an actual subset of it.
                    250:  */
                    251: void
                    252: aparams_grow(struct aparams *set, struct aparams *subset)
                    253: {
                    254:        if (set->cmin > subset->cmin)
                    255:                set->cmin = subset->cmin;
                    256:        if (set->cmax < subset->cmax)
                    257:                set->cmax = subset->cmax;
                    258:        if (set->rate < subset->rate)
                    259:                set->rate = subset->rate;
                    260: }
                    261:
                    262: /*
1.7       ratchov   263:  * Return true if rates are the same.
1.3       ratchov   264:  */
                    265: int
                    266: aparams_eqrate(struct aparams *p1, struct aparams *p2)
                    267: {
                    268:        /* XXX: allow 1/9 halftone of difference */
                    269:        return p1->rate == p2->rate;
                    270: }
                    271:
1.1       ratchov   272:
                    273: /*
                    274:  * Return the number of bytes per frame with the given parameters.
                    275:  */
                    276: unsigned
                    277: aparams_bpf(struct aparams *par)
                    278: {
                    279:        return (par->cmax - par->cmin + 1) * par->bps;
                    280: }
1.2       ratchov   281:
                    282: void
                    283: aparams_copyenc(struct aparams *dst, struct aparams *src)
                    284: {
                    285:        dst->sig = src->sig;
                    286:        dst->le = src->le;
                    287:        dst->msb = src->msb;
                    288:        dst->bits = src->bits;
                    289:        dst->bps = src->bps;
                    290: }