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

Annotation of src/usr.bin/aucat/legacy.c, Revision 1.6

1.6     ! ratchov     1: /*     $OpenBSD: legacy.c,v 1.5 2009/04/11 10:24:21 jakemsr Exp $      */
1.1       ratchov     2: /*
                      3:  * Copyright (c) 1997 Kenneth Stailey.  All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by Kenneth Stailey.
                     16:  * 4. The name of the author may not be used to endorse or promote products
                     17:  *    derived from this software without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     20:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     21:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     22:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     23:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     24:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     25:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     26:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     27:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     28:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     29:  */
                     30:
1.5       jakemsr    31: #include <sndio.h>
1.2       ratchov    32:
1.4       ratchov    33: #include <stdlib.h>
1.1       ratchov    34: #include <fcntl.h>
1.2       ratchov    35: #include <string.h>
1.1       ratchov    36: #include <unistd.h>
                     37: #include <err.h>
                     38:
1.3       ratchov    39: #include "wav.h"
1.1       ratchov    40:
                     41: /* headerless data files.  played at /dev/audio's defaults.
                     42:  */
                     43: #define FMT_RAW        0
                     44:
                     45: /* Sun/NeXT .au files.  header is skipped and /dev/audio is configured
                     46:  * for monaural 8-bit ulaw @ 8kHz, the de facto format for .au files,
                     47:  * as well as the historical default configuration for /dev/audio.
                     48:  */
                     49: #define FMT_AU 1
                     50:
                     51: /* RIFF WAV files.  header is parsed for format details which are
                     52:  * applied to /dev/audio.
                     53:  */
                     54: #define FMT_WAV        2
                     55:
1.3       ratchov    56:
1.1       ratchov    57: int
                     58: legacy_play(char *dev, char *aufile)
                     59: {
1.5       jakemsr    60:        struct sio_hdl *hdl;
                     61:        struct sio_par spar, par;
                     62:        struct aparams apar;
1.1       ratchov    63:        ssize_t rd;
                     64:        off_t datasz;
                     65:        char buf[5120];
1.5       jakemsr    66:        size_t readsz;
                     67:        int fd, fmt = FMT_RAW;
                     68:        u_int32_t pos = 0, snd_fmt = 1, rate = 8000, chan = 1;
1.1       ratchov    69:        char magic[4];
1.6     ! ratchov    70:        short *map;
1.1       ratchov    71:
                     72:        if ((fd = open(aufile, O_RDONLY)) < 0) {
                     73:                warn("cannot open %s", aufile);
                     74:                return(1);
                     75:        }
                     76:
                     77:        if (read(fd, magic, sizeof(magic)) != sizeof(magic)) {
                     78:                /* read() error, or the file is smaller than sizeof(magic).
                     79:                 * treat as a raw file, like previous versions of aucat.
                     80:                 */
                     81:        } else if (!strncmp(magic, ".snd", 4)) {
                     82:                fmt = FMT_AU;
                     83:                if (read(fd, &pos, sizeof(pos)) == sizeof(pos))
                     84:                        pos = ntohl(pos);
1.5       jakemsr    85:                /* data size */
                     86:                if (lseek(fd, 4, SEEK_CUR) == -1)
                     87:                        warn("lseek hdr");
                     88:                if (read(fd, &snd_fmt, sizeof(snd_fmt)) == sizeof(snd_fmt))
                     89:                        snd_fmt = ntohl(snd_fmt);
                     90:                if (read(fd, &rate, sizeof(rate)) == sizeof(rate))
                     91:                        rate = ntohl(rate);
                     92:                if (read(fd, &chan, sizeof(chan)) == sizeof(chan))
                     93:                        chan = ntohl(chan);
1.1       ratchov    94:        } else if (!strncmp(magic, "RIFF", 4) &&
1.6     ! ratchov    95:                    wav_readhdr(fd, &apar, &datasz, &map)) {
1.1       ratchov    96:                        fmt = FMT_WAV;
                     97:        }
                     98:
                     99:        /* seek to start of audio data.  wav_readhdr already took care
                    100:         * of this for FMT_WAV.
                    101:         */
                    102:        if (fmt == FMT_RAW || fmt == FMT_AU)
                    103:                if (lseek(fd, (off_t)pos, SEEK_SET) == -1)
                    104:                        warn("lseek");
1.5       jakemsr   105:
                    106:        if ((hdl = sio_open(dev, SIO_PLAY, 0)) < 0) {
                    107:                warnx("can't get sndio handle");
1.1       ratchov   108:                return(1);
                    109:        }
                    110:
1.5       jakemsr   111:        sio_initpar(&par);
1.1       ratchov   112:        switch(fmt) {
                    113:        case FMT_WAV:
1.5       jakemsr   114:                par.rate = apar.rate;
                    115:                par.pchan = apar.cmax - apar.cmin + 1;
                    116:                par.sig = apar.sig;
                    117:                par.bits = apar.bits;
                    118:                par.le = apar.le;
1.1       ratchov   119:                break;
                    120:        case FMT_AU:
1.5       jakemsr   121:                par.rate = rate;
                    122:                par.pchan = chan;
                    123:                par.sig = 1;
                    124:                par.bits = 16;
                    125:                par.le = 1;
1.6     ! ratchov   126:                map = wav_ulawmap;
1.5       jakemsr   127:                if (snd_fmt == 27)
1.6     ! ratchov   128:                        map = wav_alawmap;
1.1       ratchov   129:                break;
                    130:        case FMT_RAW:
                    131:        default:
                    132:                break;
                    133:        }
1.5       jakemsr   134:        spar = par;
1.1       ratchov   135:
1.5       jakemsr   136:        if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
                    137:                warnx("can't set audio parameters");
1.1       ratchov   138:                /* only WAV could fail in previous aucat versions (unless
                    139:                 * the parameters returned by AUDIO_GETINFO would fail,
                    140:                 * which is unlikely)
                    141:                 */
                    142:                if (fmt == FMT_WAV)
                    143:                        return(1);
                    144:        }
                    145:
                    146:        /* parameters may be silently modified.  see audio(9)'s
                    147:         * description of set_params.  for compatability with previous
                    148:         * aucat versions, continue running if something doesn't match.
                    149:         */
1.5       jakemsr   150:        if (par.bits != spar.bits ||
                    151:            par.sig != par.sig ||
                    152:            par.le != spar.le ||
                    153:            par.pchan != spar.pchan ||
1.1       ratchov   154:            /* devices may return a very close rate, such as 44099 when
                    155:             * 44100 was requested.  the difference is inaudible.  allow
                    156:             * 2% deviation as an example of how to cope.
                    157:             */
1.5       jakemsr   158:            (par.rate > spar.rate * 1.02 || par.rate < spar.rate * 0.98)) {
                    159:                warnx("format not supported");
                    160:        }
                    161:        if (!sio_start(hdl)) {
                    162:                warnx("could not start sndio");
                    163:                exit(1);
1.1       ratchov   164:        }
                    165:
1.5       jakemsr   166:        readsz = sizeof(buf);
1.6     ! ratchov   167:        if (map)
1.5       jakemsr   168:                readsz /= 2;
                    169:        while ((rd = read(fd, buf, readsz)) > 0) {
1.6     ! ratchov   170:                if (map) {
        !           171:                        wav_conv(buf, rd, map);
1.5       jakemsr   172:                        rd *= 2;
                    173:                }
                    174:                if (sio_write(hdl, buf, rd) != rd)
                    175:                        warnx("sio_write: short write");
                    176:        }
1.1       ratchov   177:        if (rd == -1)
                    178:                warn("read");
                    179:
1.5       jakemsr   180:        sio_close(hdl);
1.1       ratchov   181:        (void) close(fd);
                    182:
                    183:        return(0);
                    184: }