[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.5

1.5     ! jakemsr     1: /*     $OpenBSD: legacy.c,v 1.4 2008/11/08 10:40:52 ratchov 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:
1.5     ! jakemsr    41: /*
        !            42:  * This table converts a (8 bit) mu-law value two a 16 bit value.
        !            43:  * The 16 bits are represented as an array of two bytes for easier access
        !            44:  * to the individual bytes.
        !            45:  */
        !            46: const u_char mulawtolin16[256][2] = {
        !            47:        {0x02,0x84}, {0x06,0x84}, {0x0a,0x84}, {0x0e,0x84},
        !            48:        {0x12,0x84}, {0x16,0x84}, {0x1a,0x84}, {0x1e,0x84},
        !            49:        {0x22,0x84}, {0x26,0x84}, {0x2a,0x84}, {0x2e,0x84},
        !            50:        {0x32,0x84}, {0x36,0x84}, {0x3a,0x84}, {0x3e,0x84},
        !            51:        {0x41,0x84}, {0x43,0x84}, {0x45,0x84}, {0x47,0x84},
        !            52:        {0x49,0x84}, {0x4b,0x84}, {0x4d,0x84}, {0x4f,0x84},
        !            53:        {0x51,0x84}, {0x53,0x84}, {0x55,0x84}, {0x57,0x84},
        !            54:        {0x59,0x84}, {0x5b,0x84}, {0x5d,0x84}, {0x5f,0x84},
        !            55:        {0x61,0x04}, {0x62,0x04}, {0x63,0x04}, {0x64,0x04},
        !            56:        {0x65,0x04}, {0x66,0x04}, {0x67,0x04}, {0x68,0x04},
        !            57:        {0x69,0x04}, {0x6a,0x04}, {0x6b,0x04}, {0x6c,0x04},
        !            58:        {0x6d,0x04}, {0x6e,0x04}, {0x6f,0x04}, {0x70,0x04},
        !            59:        {0x70,0xc4}, {0x71,0x44}, {0x71,0xc4}, {0x72,0x44},
        !            60:        {0x72,0xc4}, {0x73,0x44}, {0x73,0xc4}, {0x74,0x44},
        !            61:        {0x74,0xc4}, {0x75,0x44}, {0x75,0xc4}, {0x76,0x44},
        !            62:        {0x76,0xc4}, {0x77,0x44}, {0x77,0xc4}, {0x78,0x44},
        !            63:        {0x78,0xa4}, {0x78,0xe4}, {0x79,0x24}, {0x79,0x64},
        !            64:        {0x79,0xa4}, {0x79,0xe4}, {0x7a,0x24}, {0x7a,0x64},
        !            65:        {0x7a,0xa4}, {0x7a,0xe4}, {0x7b,0x24}, {0x7b,0x64},
        !            66:        {0x7b,0xa4}, {0x7b,0xe4}, {0x7c,0x24}, {0x7c,0x64},
        !            67:        {0x7c,0x94}, {0x7c,0xb4}, {0x7c,0xd4}, {0x7c,0xf4},
        !            68:        {0x7d,0x14}, {0x7d,0x34}, {0x7d,0x54}, {0x7d,0x74},
        !            69:        {0x7d,0x94}, {0x7d,0xb4}, {0x7d,0xd4}, {0x7d,0xf4},
        !            70:        {0x7e,0x14}, {0x7e,0x34}, {0x7e,0x54}, {0x7e,0x74},
        !            71:        {0x7e,0x8c}, {0x7e,0x9c}, {0x7e,0xac}, {0x7e,0xbc},
        !            72:        {0x7e,0xcc}, {0x7e,0xdc}, {0x7e,0xec}, {0x7e,0xfc},
        !            73:        {0x7f,0x0c}, {0x7f,0x1c}, {0x7f,0x2c}, {0x7f,0x3c},
        !            74:        {0x7f,0x4c}, {0x7f,0x5c}, {0x7f,0x6c}, {0x7f,0x7c},
        !            75:        {0x7f,0x88}, {0x7f,0x90}, {0x7f,0x98}, {0x7f,0xa0},
        !            76:        {0x7f,0xa8}, {0x7f,0xb0}, {0x7f,0xb8}, {0x7f,0xc0},
        !            77:        {0x7f,0xc8}, {0x7f,0xd0}, {0x7f,0xd8}, {0x7f,0xe0},
        !            78:        {0x7f,0xe8}, {0x7f,0xf0}, {0x7f,0xf8}, {0x80,0x00},
        !            79:        {0xfd,0x7c}, {0xf9,0x7c}, {0xf5,0x7c}, {0xf1,0x7c},
        !            80:        {0xed,0x7c}, {0xe9,0x7c}, {0xe5,0x7c}, {0xe1,0x7c},
        !            81:        {0xdd,0x7c}, {0xd9,0x7c}, {0xd5,0x7c}, {0xd1,0x7c},
        !            82:        {0xcd,0x7c}, {0xc9,0x7c}, {0xc5,0x7c}, {0xc1,0x7c},
        !            83:        {0xbe,0x7c}, {0xbc,0x7c}, {0xba,0x7c}, {0xb8,0x7c},
        !            84:        {0xb6,0x7c}, {0xb4,0x7c}, {0xb2,0x7c}, {0xb0,0x7c},
        !            85:        {0xae,0x7c}, {0xac,0x7c}, {0xaa,0x7c}, {0xa8,0x7c},
        !            86:        {0xa6,0x7c}, {0xa4,0x7c}, {0xa2,0x7c}, {0xa0,0x7c},
        !            87:        {0x9e,0xfc}, {0x9d,0xfc}, {0x9c,0xfc}, {0x9b,0xfc},
        !            88:        {0x9a,0xfc}, {0x99,0xfc}, {0x98,0xfc}, {0x97,0xfc},
        !            89:        {0x96,0xfc}, {0x95,0xfc}, {0x94,0xfc}, {0x93,0xfc},
        !            90:        {0x92,0xfc}, {0x91,0xfc}, {0x90,0xfc}, {0x8f,0xfc},
        !            91:        {0x8f,0x3c}, {0x8e,0xbc}, {0x8e,0x3c}, {0x8d,0xbc},
        !            92:        {0x8d,0x3c}, {0x8c,0xbc}, {0x8c,0x3c}, {0x8b,0xbc},
        !            93:        {0x8b,0x3c}, {0x8a,0xbc}, {0x8a,0x3c}, {0x89,0xbc},
        !            94:        {0x89,0x3c}, {0x88,0xbc}, {0x88,0x3c}, {0x87,0xbc},
        !            95:        {0x87,0x5c}, {0x87,0x1c}, {0x86,0xdc}, {0x86,0x9c},
        !            96:        {0x86,0x5c}, {0x86,0x1c}, {0x85,0xdc}, {0x85,0x9c},
        !            97:        {0x85,0x5c}, {0x85,0x1c}, {0x84,0xdc}, {0x84,0x9c},
        !            98:        {0x84,0x5c}, {0x84,0x1c}, {0x83,0xdc}, {0x83,0x9c},
        !            99:        {0x83,0x6c}, {0x83,0x4c}, {0x83,0x2c}, {0x83,0x0c},
        !           100:        {0x82,0xec}, {0x82,0xcc}, {0x82,0xac}, {0x82,0x8c},
        !           101:        {0x82,0x6c}, {0x82,0x4c}, {0x82,0x2c}, {0x82,0x0c},
        !           102:        {0x81,0xec}, {0x81,0xcc}, {0x81,0xac}, {0x81,0x8c},
        !           103:        {0x81,0x74}, {0x81,0x64}, {0x81,0x54}, {0x81,0x44},
        !           104:        {0x81,0x34}, {0x81,0x24}, {0x81,0x14}, {0x81,0x04},
        !           105:        {0x80,0xf4}, {0x80,0xe4}, {0x80,0xd4}, {0x80,0xc4},
        !           106:        {0x80,0xb4}, {0x80,0xa4}, {0x80,0x94}, {0x80,0x84},
        !           107:        {0x80,0x78}, {0x80,0x70}, {0x80,0x68}, {0x80,0x60},
        !           108:        {0x80,0x58}, {0x80,0x50}, {0x80,0x48}, {0x80,0x40},
        !           109:        {0x80,0x38}, {0x80,0x30}, {0x80,0x28}, {0x80,0x20},
        !           110:        {0x80,0x18}, {0x80,0x10}, {0x80,0x08}, {0x80,0x00},
        !           111: };
        !           112:
        !           113: const u_char alawtolin16[256][2] = {
        !           114:        {0x6a,0x80}, {0x6b,0x80}, {0x68,0x80}, {0x69,0x80},
        !           115:        {0x6e,0x80}, {0x6f,0x80}, {0x6c,0x80}, {0x6d,0x80},
        !           116:        {0x62,0x80}, {0x63,0x80}, {0x60,0x80}, {0x61,0x80},
        !           117:        {0x66,0x80}, {0x67,0x80}, {0x64,0x80}, {0x65,0x80},
        !           118:        {0x75,0x40}, {0x75,0xc0}, {0x74,0x40}, {0x74,0xc0},
        !           119:        {0x77,0x40}, {0x77,0xc0}, {0x76,0x40}, {0x76,0xc0},
        !           120:        {0x71,0x40}, {0x71,0xc0}, {0x70,0x40}, {0x70,0xc0},
        !           121:        {0x73,0x40}, {0x73,0xc0}, {0x72,0x40}, {0x72,0xc0},
        !           122:        {0x2a,0x00}, {0x2e,0x00}, {0x22,0x00}, {0x26,0x00},
        !           123:        {0x3a,0x00}, {0x3e,0x00}, {0x32,0x00}, {0x36,0x00},
        !           124:        {0x0a,0x00}, {0x0e,0x00}, {0x02,0x00}, {0x06,0x00},
        !           125:        {0x1a,0x00}, {0x1e,0x00}, {0x12,0x00}, {0x16,0x00},
        !           126:        {0x55,0x00}, {0x57,0x00}, {0x51,0x00}, {0x53,0x00},
        !           127:        {0x5d,0x00}, {0x5f,0x00}, {0x59,0x00}, {0x5b,0x00},
        !           128:        {0x45,0x00}, {0x47,0x00}, {0x41,0x00}, {0x43,0x00},
        !           129:        {0x4d,0x00}, {0x4f,0x00}, {0x49,0x00}, {0x4b,0x00},
        !           130:        {0x7e,0xa8}, {0x7e,0xb8}, {0x7e,0x88}, {0x7e,0x98},
        !           131:        {0x7e,0xe8}, {0x7e,0xf8}, {0x7e,0xc8}, {0x7e,0xd8},
        !           132:        {0x7e,0x28}, {0x7e,0x38}, {0x7e,0x08}, {0x7e,0x18},
        !           133:        {0x7e,0x68}, {0x7e,0x78}, {0x7e,0x48}, {0x7e,0x58},
        !           134:        {0x7f,0xa8}, {0x7f,0xb8}, {0x7f,0x88}, {0x7f,0x98},
        !           135:        {0x7f,0xe8}, {0x7f,0xf8}, {0x7f,0xc8}, {0x7f,0xd8},
        !           136:        {0x7f,0x28}, {0x7f,0x38}, {0x7f,0x08}, {0x7f,0x18},
        !           137:        {0x7f,0x68}, {0x7f,0x78}, {0x7f,0x48}, {0x7f,0x58},
        !           138:        {0x7a,0xa0}, {0x7a,0xe0}, {0x7a,0x20}, {0x7a,0x60},
        !           139:        {0x7b,0xa0}, {0x7b,0xe0}, {0x7b,0x20}, {0x7b,0x60},
        !           140:        {0x78,0xa0}, {0x78,0xe0}, {0x78,0x20}, {0x78,0x60},
        !           141:        {0x79,0xa0}, {0x79,0xe0}, {0x79,0x20}, {0x79,0x60},
        !           142:        {0x7d,0x50}, {0x7d,0x70}, {0x7d,0x10}, {0x7d,0x30},
        !           143:        {0x7d,0xd0}, {0x7d,0xf0}, {0x7d,0x90}, {0x7d,0xb0},
        !           144:        {0x7c,0x50}, {0x7c,0x70}, {0x7c,0x10}, {0x7c,0x30},
        !           145:        {0x7c,0xd0}, {0x7c,0xf0}, {0x7c,0x90}, {0x7c,0xb0},
        !           146:        {0x95,0x80}, {0x94,0x80}, {0x97,0x80}, {0x96,0x80},
        !           147:        {0x91,0x80}, {0x90,0x80}, {0x93,0x80}, {0x92,0x80},
        !           148:        {0x9d,0x80}, {0x9c,0x80}, {0x9f,0x80}, {0x9e,0x80},
        !           149:        {0x99,0x80}, {0x98,0x80}, {0x9b,0x80}, {0x9a,0x80},
        !           150:        {0x8a,0xc0}, {0x8a,0x40}, {0x8b,0xc0}, {0x8b,0x40},
        !           151:        {0x88,0xc0}, {0x88,0x40}, {0x89,0xc0}, {0x89,0x40},
        !           152:        {0x8e,0xc0}, {0x8e,0x40}, {0x8f,0xc0}, {0x8f,0x40},
        !           153:        {0x8c,0xc0}, {0x8c,0x40}, {0x8d,0xc0}, {0x8d,0x40},
        !           154:        {0xd6,0x00}, {0xd2,0x00}, {0xde,0x00}, {0xda,0x00},
        !           155:        {0xc6,0x00}, {0xc2,0x00}, {0xce,0x00}, {0xca,0x00},
        !           156:        {0xf6,0x00}, {0xf2,0x00}, {0xfe,0x00}, {0xfa,0x00},
        !           157:        {0xe6,0x00}, {0xe2,0x00}, {0xee,0x00}, {0xea,0x00},
        !           158:        {0xab,0x00}, {0xa9,0x00}, {0xaf,0x00}, {0xad,0x00},
        !           159:        {0xa3,0x00}, {0xa1,0x00}, {0xa7,0x00}, {0xa5,0x00},
        !           160:        {0xbb,0x00}, {0xb9,0x00}, {0xbf,0x00}, {0xbd,0x00},
        !           161:        {0xb3,0x00}, {0xb1,0x00}, {0xb7,0x00}, {0xb5,0x00},
        !           162:        {0x81,0x58}, {0x81,0x48}, {0x81,0x78}, {0x81,0x68},
        !           163:        {0x81,0x18}, {0x81,0x08}, {0x81,0x38}, {0x81,0x28},
        !           164:        {0x81,0xd8}, {0x81,0xc8}, {0x81,0xf8}, {0x81,0xe8},
        !           165:        {0x81,0x98}, {0x81,0x88}, {0x81,0xb8}, {0x81,0xa8},
        !           166:        {0x80,0x58}, {0x80,0x48}, {0x80,0x78}, {0x80,0x68},
        !           167:        {0x80,0x18}, {0x80,0x08}, {0x80,0x38}, {0x80,0x28},
        !           168:        {0x80,0xd8}, {0x80,0xc8}, {0x80,0xf8}, {0x80,0xe8},
        !           169:        {0x80,0x98}, {0x80,0x88}, {0x80,0xb8}, {0x80,0xa8},
        !           170:        {0x85,0x60}, {0x85,0x20}, {0x85,0xe0}, {0x85,0xa0},
        !           171:        {0x84,0x60}, {0x84,0x20}, {0x84,0xe0}, {0x84,0xa0},
        !           172:        {0x87,0x60}, {0x87,0x20}, {0x87,0xe0}, {0x87,0xa0},
        !           173:        {0x86,0x60}, {0x86,0x20}, {0x86,0xe0}, {0x86,0xa0},
        !           174:        {0x82,0xb0}, {0x82,0x90}, {0x82,0xf0}, {0x82,0xd0},
        !           175:        {0x82,0x30}, {0x82,0x10}, {0x82,0x70}, {0x82,0x50},
        !           176:        {0x83,0xb0}, {0x83,0x90}, {0x83,0xf0}, {0x83,0xd0},
        !           177:        {0x83,0x30}, {0x83,0x10}, {0x83,0x70}, {0x83,0x50},
        !           178: };
        !           179:
        !           180: void
        !           181: mulaw_to_slinear16_le(u_char *p, int cc)
        !           182: {
        !           183:        u_char *q = p;
        !           184:
        !           185:        p += cc;
        !           186:        q += cc << 1;
        !           187:        while (--cc >= 0) {
        !           188:                --p;
        !           189:                q -= 2;
        !           190:                q[1] = mulawtolin16[*p][0] ^ 0x80;
        !           191:                q[0] = mulawtolin16[*p][1];
        !           192:        }
        !           193: }
        !           194:
        !           195: void
        !           196: alaw_to_slinear16_le(u_char *p, int cc)
        !           197: {
        !           198:        u_char *q = p;
        !           199:
        !           200:        p += cc;
        !           201:        q += cc << 1;
        !           202:        while (--cc >= 0) {
        !           203:                --p;
        !           204:                q -= 2;
        !           205:                q[1] = alawtolin16[*p][0] ^ 0x80;
        !           206:                q[0] = alawtolin16[*p][1];
        !           207:        }
        !           208: }
        !           209:
1.1       ratchov   210:
                    211: /* headerless data files.  played at /dev/audio's defaults.
                    212:  */
                    213: #define FMT_RAW        0
                    214:
                    215: /* Sun/NeXT .au files.  header is skipped and /dev/audio is configured
                    216:  * for monaural 8-bit ulaw @ 8kHz, the de facto format for .au files,
                    217:  * as well as the historical default configuration for /dev/audio.
                    218:  */
                    219: #define FMT_AU 1
                    220:
                    221: /* RIFF WAV files.  header is parsed for format details which are
                    222:  * applied to /dev/audio.
                    223:  */
                    224: #define FMT_WAV        2
                    225:
1.3       ratchov   226:
1.1       ratchov   227: int
                    228: legacy_play(char *dev, char *aufile)
                    229: {
1.5     ! jakemsr   230:        struct sio_hdl *hdl;
        !           231:        struct sio_par spar, par;
        !           232:        struct aparams apar;
1.1       ratchov   233:        ssize_t rd;
                    234:        off_t datasz;
                    235:        char buf[5120];
1.5     ! jakemsr   236:        size_t readsz;
        !           237:        int fd, fmt = FMT_RAW;
        !           238:        u_int32_t pos = 0, snd_fmt = 1, rate = 8000, chan = 1;
1.1       ratchov   239:        char magic[4];
1.5     ! jakemsr   240:        int is_ulaw, is_alaw, wav_fmt;
1.1       ratchov   241:
                    242:        if ((fd = open(aufile, O_RDONLY)) < 0) {
                    243:                warn("cannot open %s", aufile);
                    244:                return(1);
                    245:        }
                    246:
                    247:        if (read(fd, magic, sizeof(magic)) != sizeof(magic)) {
                    248:                /* read() error, or the file is smaller than sizeof(magic).
                    249:                 * treat as a raw file, like previous versions of aucat.
                    250:                 */
                    251:        } else if (!strncmp(magic, ".snd", 4)) {
                    252:                fmt = FMT_AU;
                    253:                if (read(fd, &pos, sizeof(pos)) == sizeof(pos))
                    254:                        pos = ntohl(pos);
1.5     ! jakemsr   255:                /* data size */
        !           256:                if (lseek(fd, 4, SEEK_CUR) == -1)
        !           257:                        warn("lseek hdr");
        !           258:                if (read(fd, &snd_fmt, sizeof(snd_fmt)) == sizeof(snd_fmt))
        !           259:                        snd_fmt = ntohl(snd_fmt);
        !           260:                if (read(fd, &rate, sizeof(rate)) == sizeof(rate))
        !           261:                        rate = ntohl(rate);
        !           262:                if (read(fd, &chan, sizeof(chan)) == sizeof(chan))
        !           263:                        chan = ntohl(chan);
1.1       ratchov   264:        } else if (!strncmp(magic, "RIFF", 4) &&
1.5     ! jakemsr   265:                    wav_readhdr(fd, &apar, &datasz, &wav_fmt)) {
1.1       ratchov   266:                        fmt = FMT_WAV;
                    267:        }
                    268:
                    269:        /* seek to start of audio data.  wav_readhdr already took care
                    270:         * of this for FMT_WAV.
                    271:         */
                    272:        if (fmt == FMT_RAW || fmt == FMT_AU)
                    273:                if (lseek(fd, (off_t)pos, SEEK_SET) == -1)
                    274:                        warn("lseek");
1.5     ! jakemsr   275:
        !           276:        if ((hdl = sio_open(dev, SIO_PLAY, 0)) < 0) {
        !           277:                warnx("can't get sndio handle");
1.1       ratchov   278:                return(1);
                    279:        }
                    280:
1.5     ! jakemsr   281:        sio_initpar(&par);
        !           282:        is_ulaw = is_alaw = 0;
1.1       ratchov   283:        switch(fmt) {
                    284:        case FMT_WAV:
1.5     ! jakemsr   285:                par.rate = apar.rate;
        !           286:                par.pchan = apar.cmax - apar.cmin + 1;
        !           287:                par.sig = apar.sig;
        !           288:                par.bits = apar.bits;
        !           289:                par.le = apar.le;
        !           290:                if (wav_fmt == 6 || wav_fmt == 7) {
        !           291:                        if (wav_fmt == 6)
        !           292:                                is_alaw = 1;
        !           293:                        else if (wav_fmt == 7)
        !           294:                                is_ulaw = 1;
        !           295:                        par.sig = 1;
        !           296:                        par.bits = 16;
        !           297:                        par.le = 1;
        !           298:                } else if (wav_fmt != 1)
        !           299:                        warnx("format not supported");
1.1       ratchov   300:                break;
                    301:        case FMT_AU:
1.5     ! jakemsr   302:                par.rate = rate;
        !           303:                par.pchan = chan;
        !           304:                par.sig = 1;
        !           305:                par.bits = 16;
        !           306:                par.le = 1;
        !           307:                is_ulaw = 1;
        !           308:                if (snd_fmt == 27)
        !           309:                        is_alaw = 1;
1.1       ratchov   310:                break;
                    311:        case FMT_RAW:
                    312:        default:
                    313:                break;
                    314:        }
1.5     ! jakemsr   315:        spar = par;
1.1       ratchov   316:
1.5     ! jakemsr   317:        if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
        !           318:                warnx("can't set audio parameters");
1.1       ratchov   319:                /* only WAV could fail in previous aucat versions (unless
                    320:                 * the parameters returned by AUDIO_GETINFO would fail,
                    321:                 * which is unlikely)
                    322:                 */
                    323:                if (fmt == FMT_WAV)
                    324:                        return(1);
                    325:        }
                    326:
                    327:        /* parameters may be silently modified.  see audio(9)'s
                    328:         * description of set_params.  for compatability with previous
                    329:         * aucat versions, continue running if something doesn't match.
                    330:         */
1.5     ! jakemsr   331:        if (par.bits != spar.bits ||
        !           332:            par.sig != par.sig ||
        !           333:            par.le != spar.le ||
        !           334:            par.pchan != spar.pchan ||
1.1       ratchov   335:            /* devices may return a very close rate, such as 44099 when
                    336:             * 44100 was requested.  the difference is inaudible.  allow
                    337:             * 2% deviation as an example of how to cope.
                    338:             */
1.5     ! jakemsr   339:            (par.rate > spar.rate * 1.02 || par.rate < spar.rate * 0.98)) {
        !           340:                warnx("format not supported");
        !           341:        }
        !           342:        if (!sio_start(hdl)) {
        !           343:                warnx("could not start sndio");
        !           344:                exit(1);
1.1       ratchov   345:        }
                    346:
1.5     ! jakemsr   347:        readsz = sizeof(buf);
        !           348:        if (is_ulaw || is_alaw)
        !           349:                readsz /= 2;
        !           350:        while ((rd = read(fd, buf, readsz)) > 0) {
        !           351:                if (is_ulaw) {
        !           352:                        mulaw_to_slinear16_le(buf, rd);
        !           353:                        rd *= 2;
        !           354:                } else if (is_alaw) {
        !           355:                        alaw_to_slinear16_le(buf, rd);
        !           356:                        rd *= 2;
        !           357:                }
        !           358:                if (sio_write(hdl, buf, rd) != rd)
        !           359:                        warnx("sio_write: short write");
        !           360:        }
1.1       ratchov   361:        if (rd == -1)
                    362:                warn("read");
                    363:
1.5     ! jakemsr   364:        sio_close(hdl);
1.1       ratchov   365:        (void) close(fd);
                    366:
                    367:        return(0);
                    368: }