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

Annotation of src/usr.bin/aucat/wav.c, Revision 1.7

1.7     ! ratchov     1: /*
        !             2:  * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
        !             3:  *
        !             4:  * Permission to use, copy, modify, and distribute this software for any
        !             5:  * purpose with or without fee is hereby granted, provided that the above
        !             6:  * copyright notice and this permission notice appear in all copies.
        !             7:  *
        !             8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !             9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            15:  */
        !            16:
1.1       ratchov    17: #include <sys/types.h>
1.7     ! ratchov    18:
1.1       ratchov    19: #include <err.h>
                     20: #include <fcntl.h>
                     21: #include <stdio.h>
                     22: #include <stdlib.h>
                     23: #include <unistd.h>
                     24:
                     25: #include "conf.h"
                     26: #include "wav.h"
                     27:
1.6       ratchov    28: short wav_ulawmap[256] = {
                     29:        -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
                     30:        -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
                     31:        -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
                     32:        -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
                     33:         -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
                     34:         -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
                     35:         -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
                     36:         -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
                     37:         -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
                     38:         -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
                     39:          -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
                     40:          -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
                     41:          -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
                     42:          -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
                     43:          -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
                     44:           -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
                     45:         32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
                     46:         23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
                     47:         15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
                     48:         11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
                     49:          7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
                     50:          5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
                     51:          3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
                     52:          2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
                     53:          1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
                     54:          1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
                     55:           876,    844,    812,    780,    748,    716,    684,    652,
                     56:           620,    588,    556,    524,    492,    460,    428,    396,
                     57:           372,    356,    340,    324,    308,    292,    276,    260,
                     58:           244,    228,    212,    196,    180,    164,    148,    132,
                     59:           120,    112,    104,     96,     88,     80,     72,     64,
                     60:            56,     48,     40,     32,     24,     16,      8,      0
                     61: };
                     62:
                     63: short wav_alawmap[256] = {
                     64:         -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
                     65:         -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
                     66:         -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
                     67:         -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
                     68:        -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
                     69:        -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
                     70:        -11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
                     71:        -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
                     72:          -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
                     73:          -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
                     74:           -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
                     75:          -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
                     76:         -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
                     77:         -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
                     78:          -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
                     79:          -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
                     80:          5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
                     81:          7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
                     82:          2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
                     83:          3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
                     84:         22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
                     85:         30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
                     86:         11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
                     87:         15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
                     88:           344,    328,    376,    360,    280,    264,    312,    296,
                     89:           472,    456,    504,    488,    408,    392,    440,    424,
                     90:            88,     72,    120,    104,     24,      8,     56,     40,
                     91:           216,    200,    248,    232,    152,    136,    184,    168,
                     92:          1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
                     93:          1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
                     94:           688,    656,    752,    720,    560,    528,    624,    592,
                     95:           944,    912,   1008,    976,    816,    784,    880,    848
                     96: };
                     97:
1.1       ratchov    98: /*
1.7     ! ratchov    99:  * Max data of a .wav file. The total file size must be smaller than
1.1       ratchov   100:  * 2^31, and we also have to leave some space for the headers (around 40
1.7     ! ratchov   101:  * bytes).
1.3       ratchov   102:  */
1.1       ratchov   103: #define WAV_DATAMAX    (0x7fff0000)
                    104:
                    105: struct fileops wav_ops = {
                    106:        "wav",
                    107:        sizeof(struct wav),
                    108:        wav_close,
                    109:        wav_read,
                    110:        wav_write,
                    111:        NULL, /* start */
                    112:        NULL, /* stop */
                    113:        pipe_nfds,
                    114:        pipe_pollfd,
                    115:        pipe_revents
                    116: };
                    117:
                    118: struct wav *
                    119: wav_new_in(struct fileops *ops, int fd, char *name,
                    120:     struct aparams *par, unsigned hdr)
                    121: {
                    122:        struct wav *f;
                    123:
                    124:        f = (struct wav *)pipe_new(ops, fd, name);
1.4       ratchov   125:        if (f == NULL)
                    126:                return NULL;
1.1       ratchov   127:        if (hdr == HDR_WAV) {
1.6       ratchov   128:                if (!wav_readhdr(f->pipe.fd, par, &f->rbytes, &f->map))
1.1       ratchov   129:                        exit(1);
                    130:                f->hpar = *par;
1.6       ratchov   131:        } else {
1.1       ratchov   132:                f->rbytes = -1;
1.6       ratchov   133:                f->map = NULL;
                    134:        }
1.1       ratchov   135:        f->hdr = 0;
                    136:        return f;
                    137: }
                    138:
                    139: struct wav *
                    140: wav_new_out(struct fileops *ops, int fd, char *name,
                    141:     struct aparams *par, unsigned hdr)
                    142: {
                    143:        struct wav *f;
                    144:
                    145:        f = (struct wav *)pipe_new(ops, fd, name);
1.4       ratchov   146:        if (f == NULL)
                    147:                return NULL;
1.1       ratchov   148:        if (hdr == HDR_WAV) {
1.2       ratchov   149:                par->le = 1;
1.3       ratchov   150:                par->sig = (par->bits <= 8) ? 0 : 1;
1.2       ratchov   151:                par->bps = (par->bits + 7) / 8;
1.1       ratchov   152:                if (!wav_writehdr(f->pipe.fd, par))
                    153:                        exit(1);
                    154:                f->hpar = *par;
                    155:                f->wbytes = WAV_DATAMAX;
                    156:        } else
                    157:                f->wbytes = -1;
                    158:        f->hdr = hdr;
                    159:        return f;
                    160: }
                    161:
1.6       ratchov   162: void
                    163: wav_conv(unsigned char *data, unsigned count, short *map)
                    164: {
                    165:        unsigned i;
                    166:        unsigned char *iptr;
                    167:        short *optr;
                    168:
                    169:        iptr = data + count;
                    170:        optr = (short *)data + count;
                    171:        for (i = count; i > 0; i--) {
                    172:                --optr;
                    173:                --iptr;
                    174:                *optr = map[*iptr];
                    175:        }
                    176: }
                    177:
1.1       ratchov   178: unsigned
                    179: wav_read(struct file *file, unsigned char *data, unsigned count)
                    180: {
                    181:        struct wav *f = (struct wav *)file;
                    182:        unsigned n;
                    183:
1.6       ratchov   184:        if (f->map)
                    185:                count /= sizeof(short);
1.1       ratchov   186:        if (f->rbytes >= 0 && count > f->rbytes) {
                    187:                count = f->rbytes; /* file->rbytes fits in count */
                    188:                if (count == 0) {
                    189:                        DPRINTFN(2, "wav_read: %s: complete\n", f->pipe.file.name);
                    190:                        file_eof(&f->pipe.file);
                    191:                        return 0;
                    192:                }
                    193:        }
                    194:        n = pipe_read(file, data, count);
                    195:        if (f->rbytes >= 0)
                    196:                f->rbytes -= n;
1.6       ratchov   197:        if (f->map) {
                    198:                wav_conv(data, n, f->map);
                    199:                n *= sizeof(short);
                    200:        }
1.1       ratchov   201:        return n;
                    202: }
                    203:
                    204: unsigned
                    205: wav_write(struct file *file, unsigned char *data, unsigned count)
                    206: {
                    207:        struct wav *f = (struct wav *)file;
                    208:        unsigned n;
1.3       ratchov   209:
1.1       ratchov   210:        if (f->wbytes >= 0 && count > f->wbytes) {
                    211:                count = f->wbytes; /* wbytes fits in count */
                    212:                if (count == 0) {
                    213:                        DPRINTFN(2, "wav_write: %s: complete\n",
                    214:                            f->pipe.file.name);
                    215:                        file_hup(&f->pipe.file);
                    216:                        return 0;
                    217:                }
                    218:        }
                    219:        n = pipe_write(file, data, count);
                    220:        if (f->wbytes >= 0)
                    221:                f->wbytes -= n;
                    222:        return n;
                    223: }
                    224:
                    225: void
                    226: wav_close(struct file *file)
                    227: {
                    228:        struct wav *f = (struct wav *)file;
                    229:
                    230:        if (f->hdr == HDR_WAV)
                    231:                wav_writehdr(f->pipe.fd, &f->hpar);
                    232:        pipe_close(file);
                    233: }