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