1 /* 2 * Copyright (c) 1998-2001 Yoshihide SONODA 3 * 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 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <sys/types.h> 35 #include <sys/ioctl.h> 36 37 #if defined (__FreeBSD__) && __FreeBSD__ < 4 38 #include <machine/soundcard.h> 39 #else 40 #include <sys/soundcard.h> 41 #endif 42 43 #include "wavefmt.h" 44 45 #ifndef DEFAULT_DSP 46 #define DEFAULT_DSP "/dev/dsp" 47 #endif 48 49 #ifndef DEFAULT_BUFFERSIZE 50 #define DEFAULT_BUFFERSIZE 2048 51 #endif 52 53 /* �ؿ��ץ�ȥ����� */ 54 int readWaveFile(int fd, PWAVEFORMAT pwavefmt, u_int *datasize); 55 int openDSP(const char* devname, PWAVEFORMAT pwf); 56 int closeDSP(int fd); 57 int playWave(int data_fd, int dsp_fd, u_int datasize); 58 int playRaw(int data_fd, int dsp_fd); 59 int play(const char* filename); 60 61 /* �����Х��ѿ� */ 62 static int vflag = 1; 63 static int cflag = 0; 64 static int rflag = 0; 65 static int sampling_rate = 44100; 66 static int channels = 2; 67 static int bits_per_sample = 16; 68 69 static size_t bsize = DEFAULT_BUFFERSIZE; 70 static char *dsp_fname = DEFAULT_DSP; 71 static char *sbuf = NULL; 72 73 int main(int argc, char* argv[]) 74 { 75 int ch; 76 int rc = 0; 77 78 while ((ch = getopt(argc, argv, "csrhb:f:B:C:S:")) != -1) 79 { 80 switch(ch) 81 { 82 case 'b': 83 bsize = (size_t)strtol(optarg, NULL, 10) * 1024; 84 if (bsize == 0) 85 bsize = DEFAULT_BUFFERSIZE; 86 break; 87 case 'c': 88 cflag = 1; 89 break; 90 case 'f': 91 dsp_fname = optarg; 92 break; 93 case 's': 94 vflag = 0; 95 break; 96 case 'r': 97 rflag = 1; 98 break; 99 case 'S': 100 rflag = 1; 101 sampling_rate = (int)strtol(optarg, NULL, 10); 102 break; 103 case 'B': 104 rflag = 1; 105 bits_per_sample = (int)strtol(optarg, NULL, 10); 106 break; 107 case 'C': 108 rflag = 1; 109 channels = (int)strtol(optarg, NULL, 10); 110 break; 111 case 'h': 112 default: 113 fprintf(stderr, 114 "Usage: waveplay [-b size] [-f dev] [-chrs]\n" 115 " [-S rate] [-B bits] [-C channels] [-] [wavefile | pcmfile]\n"); 116 return 1; 117 break; 118 } 119 } 120 argc -= optind; 121 argv += optind; 122 123 if (argc == 0) 124 rc += play("-"); 125 else 126 { 127 while (*argv) 128 { 129 rc += play(argv[0]); 130 argv++; 131 //usleep(1000); 132 } 133 } 134 135 /* ���ͤϥ��顼�θĿ� */ 136 if (rc < 0) 137 rc = -rc; 138 139 return rc; 140 } 141 142 int play(const char* filename) 143 { 144 int in_fd; 145 int out_fd; 146 WAVEFORMAT wf; 147 u_int datasize; 148 int rc; 149 int stdin_flag = !strcmp(filename, "-"); 150 151 if (stdin_flag) 152 in_fd = STDIN_FILENO; 153 else 154 { 155 if ((in_fd = open(filename, O_RDONLY)) == -1) 156 { 157 fprintf(stderr, "%s - ", filename); 158 perror("open"); 159 return in_fd; 160 } 161 } 162 163 if (rflag) 164 { 165 wf.nSamplesPerSec = sampling_rate; 166 wf.wBitsPerSample = bits_per_sample; 167 wf.nChannels = channels; 168 } 169 else 170 { 171 if (readWaveFile(in_fd, &wf, &datasize)) 172 { 173 close(in_fd); 174 return -1; 175 } 176 } 177 178 if (vflag) 179 { 180 if (!stdin_flag) 181 fprintf(stderr, "File name : %s\n", filename); 182 fprintf(stderr, "Sampling rate : %d Hz\n", wf.nSamplesPerSec); 183 fprintf(stderr, "Bits/Sample : %d Bits\n", wf.wBitsPerSample); 184 fprintf(stderr, "Channels : %d\n", wf.nChannels); 185 if (!rflag) 186 fprintf(stderr, "Size : %d Bytes\n", datasize); 187 fprintf(stderr, "\n"); 188 } 189 190 if (cflag) 191 out_fd = STDOUT_FILENO; 192 else 193 { 194 if ((out_fd = openDSP(dsp_fname, &wf)) == -1) 195 { 196 //perror("openDSP"); 197 close(in_fd); 198 return -1; 199 } 200 } 201 202 sbuf = (char *)malloc(bsize); 203 if (sbuf == NULL) 204 { 205 fprintf(stderr, "Error: Can't alloc memory."); 206 return -1; 207 } 208 209 if (rflag) 210 rc = playRaw(in_fd, out_fd); 211 else 212 rc = playWave(in_fd, out_fd, datasize); 213 214 close(in_fd); 215 if (!cflag) 216 closeDSP(out_fd); 217 218 free(sbuf); 219 return rc; 220 } 221 222 int readWaveFile(int fd, PWAVEFORMAT pwavefmt, u_int *datasize) 223 { 224 int header = 0; 225 int size = 0; 226 char *buff; 227 228 *datasize = 0; 229 read(fd, (char *)&header, sizeof(int)); 230 if (header != H_RIFF) 231 { 232 fprintf(stderr, "Error: Not RIFF file.\n"); 233 return 1; 234 } 235 236 read(fd, (char *)&size, sizeof(int)); 237 read(fd, (char *)&header, sizeof(int)); 238 if (header != H_WAVE) 239 { 240 fprintf(stderr, "Error: Not WAVE file.\n"); 241 return 2; 242 } 243 244 while(read(fd, (char *)&header, sizeof(int)) == sizeof(int)) 245 { 246 read(fd, (char *)&size, sizeof(int)); 247 248 if (header == H_FMT) 249 { 250 if ((size_t)size < sizeof(WAVEFORMAT)) 251 { 252 fprintf(stderr, "Error: Illegal header.\n"); 253 return 3; 254 } 255 buff = malloc((size_t)size); 256 read(fd, buff, size); 257 memcpy((void *)pwavefmt, (void *)buff, sizeof(WAVEFORMAT)); 258 free(buff); 259 if (pwavefmt->wFormatTag != 1) 260 { 261 fprintf(stderr, "Error: Unsupported format(0x%x).\n", 262 pwavefmt->wFormatTag); 263 return 4; 264 } 265 } 266 else if (header == H_DATA) 267 { 268 /* �ե�����ݥ���data�������ã������ؿ���λ */ 269 *datasize = (u_int)size; 270 return 0; 271 } 272 else 273 { 274 /* ;�פʥ�����ɤ����Ф� */ 275 lseek(fd, size, SEEK_CUR); 276 } 277 } 278 279 fprintf(stderr, "Error: data chunk not found.\n"); 280 return 10; 281 } 282 283 int openDSP(const char* devname, PWAVEFORMAT pwf) 284 { 285 int fd; 286 int status; 287 int arg; 288 289 if ((fd = open(devname, O_WRONLY)) == -1) { 290 fprintf(stderr, "%s - ", devname); 291 perror("openDSP"); 292 return fd; 293 } 294 295 /* �����ͥ�(STEREO or MONAURAL)������ */ 296 arg = (int)(pwf->nChannels); 297 status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); 298 if (status < 0) 299 { 300 perror("openDSP"); 301 close(fd); 302 return -1; 303 } 304 305 if (arg != (int)(pwf->nChannels)) 306 { 307 fprintf(stderr, "Can't set channels.\n"); 308 close(fd); 309 return -1; 310 } 311 312 /* ����ץ�졼�Ȥ����� */ 313 arg = (int)(pwf->nSamplesPerSec); 314 status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); 315 if (status < 0) 316 { 317 perror("openDSP"); 318 fprintf(stderr, "Can't set sampling rate.\n"); 319 close(fd); 320 return -1; 321 } 322 323 if (vflag && (arg != (int)pwf->nSamplesPerSec)) 324 { 325 fprintf(stderr, "Warning: Can't set sampling rate %d Hz.\n", 326 (int)pwf->nSamplesPerSec); 327 fprintf(stderr, "Using %d Hz instead.\n", arg); 328 } 329 #ifdef DEBUG 330 printf("DSP - Sampling rate: %d\n", arg); 331 #endif 332 333 /* �̻Ҳ��ӥåȿ�(8 or 16Bit)������ */ 334 arg = (int)(pwf->wBitsPerSample); 335 status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); 336 if (status < 0) 337 { 338 perror("openDSP"); 339 close(fd); 340 return -1; 341 } 342 343 if (arg != (int)(pwf->wBitsPerSample)) 344 { 345 if (vflag) 346 fprintf(stderr, "Can't set bit width.\n"); 347 close(fd); 348 return -1; 349 } 350 351 return fd; 352 } 353 354 int closeDSP(int fd) 355 { 356 ioctl(fd, SNDCTL_DSP_SYNC); 357 return close(fd); 358 } 359 360 int playRaw(int data_fd, int dsp_fd) 361 { 362 register int nr, nw, off; 363 364 while ((nr = read(data_fd, sbuf, bsize)) > 0) 365 { 366 for (off = 0; nr; nr -= nw, off += nw) 367 { 368 if ((nw = write(dsp_fd, sbuf + off, nr)) < 0) 369 { 370 fprintf(stderr, "Error: playRaw - write data\n"); 371 return -1; 372 } 373 } 374 } 375 376 return 0; 377 } 378 379 int playWave(int data_fd, int dsp_fd, u_int datasize) 380 { 381 register int i, nr, nw, off; 382 int tr, rd; 383 384 #ifdef DEBUG 385 fprintf(stderr, "datasize = %d, bsize = %d\n", datasize, bsize); 386 #endif 387 tr = datasize / bsize; 388 rd = datasize % bsize; 389 390 for (i = 0; i < tr + 1; i++) 391 { 392 if (i == tr) 393 { 394 if (rd == 0) 395 break; 396 397 if ((nr = read(data_fd, sbuf, rd)) <= 0) 398 break; 399 } 400 else 401 { 402 if ((nr = read(data_fd, sbuf, bsize)) <= 0) 403 break; 404 } 405 406 for (off = 0; nr; nr -= nw, off += nw) 407 { 408 if ((nw = write(dsp_fd, sbuf + off, nr)) < 0) 409 { 410 fprintf(stderr, "Error: playWave - write data\n"); 411 return -1; 412 } 413 } 414 } 415 416 return 0; 417 } 418