[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.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: }