OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / play / play.c
1 /*****************************************************************************/
2
3 /*
4  *      play -- play "wav" files, through the an audio driver.
5  *
6  *      (C) Copyright 1999-2001, Greg Ungerer (gerg@snapgear.com)
7  *      (C) Copyright 2000-2001, Lineo Inc. (www.lineo.com) 
8  */
9
10 /*****************************************************************************/
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <fcntl.h>
15 #include <errno.h>
16 #include <getopt.h>
17
18 #include <linux/soundcard.h>
19
20 #include "wav.h"
21
22 /*****************************************************************************/
23
24 #define DACDEVICE       "/dev/dsp"
25
26 int                     verbose = 1;
27 int                     raw = 0;
28 unsigned char           buf[16*1024];
29
30 struct wavefileheader   hdr;
31 struct wavedataheader   datahdr;
32
33
34 /*
35  *      Endian re-arranger :-)
36  */
37 #define SWAPLONG(a)     ((((a) & 0xff000000) >> 24) | \
38                         (((a) & 0x00ff0000) >> 8) | \
39                         (((a) & 0x0000ff00) << 8) | \
40                         (((a) & 0x000000ff) << 24))
41
42 #define SWAPSHORT(a)    (((a) >> 8) | ((a) << 8))
43
44 /*****************************************************************************/
45
46 void usage(void)
47 {
48         printf("usage: play [-vrmsbw] [-f frequency] filename\n\n");
49         printf("            -v          verbose mode\n");
50         printf("            -r          raw data file (not wav)\n");
51         printf("            -m          mono mode\n");
52         printf("            -s          stereo mode\n");
53         printf("            -b          8bits per sample (byte)\n");
54         printf("            -w          16bits per sample (word)\n");
55         printf("            -f          set replay refquency\n");
56         exit(1);
57 }
58
59 /*****************************************************************************/
60
61 int main(int argc, char *argv[])
62 {
63         char    *filename;
64         int     ofd, ifd, i, j, n;
65         int     freq, chans, bitspersample;
66         char    c;
67
68         /* Default to not set for now */
69         freq = 0;
70         chans = 0;
71         bitspersample = 0;
72
73         while ((c = getopt(argc, argv, "vrmswbf:")) > 0) {
74                 switch (c) {
75                 case 'v':
76                         verbose++;
77                         break;
78                 case 'f':
79                         freq = atoi(optarg);
80                         break;
81                 case 'r':
82                         raw++;
83                         break;
84                 case 's':
85                         chans = 2;
86                         break;
87                 case 'm':
88                         chans = 1;
89                         break;
90                 case 'w':
91                         bitspersample = 16;
92                         break;
93                 case 'b':
94                         bitspersample = 8;
95                         break;
96                 default:
97                         usage();
98                         break;
99                 }
100         }
101
102         if (optind >= argc)
103                 usage();
104
105         filename = argv[optind];
106         if ((ifd = open(filename, O_RDONLY)) < 1) {
107                 printf("ERROR: failed to wave file %s\n", filename);
108                 exit(1);
109         }
110         if ((ofd = open(DACDEVICE, O_RDWR)) < 1) {
111                 printf("ERROR: failed to open DAC device %s\n", DACDEVICE);
112                 exit(1);
113         }
114
115         if (!raw) {
116                 /* Parse wav header... */
117                 if ((n = read(ifd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
118                         printf("ERROR: failed to read(), errno=%d\n", errno);
119                         exit(1);
120                 }
121
122                 hdr.filesize = SWAPLONG(hdr.filesize);
123                 hdr.formattag = SWAPSHORT(hdr.formattag);
124                 hdr.channels = SWAPSHORT(hdr.channels);
125                 hdr.samplerate = SWAPLONG(hdr.samplerate);
126                 hdr.bytespersec = SWAPLONG(hdr.bytespersec);
127                 hdr.samplesize = SWAPSHORT(hdr.samplesize);
128                 hdr.bitspersample = SWAPSHORT(hdr.bitspersample);
129
130                 if (verbose) {
131                         printf("FILE=%s\n  Type=0x%x\n  File Length=%d\n",
132                                 filename, hdr.riffid, hdr.filesize);
133                         printf("  Channels=%d\n  Sample Rate=%d\n  Bytes Per "
134                                 "Second=%d\n  Sample Size=%d\n  "
135                                 "Bits per Sample=%d\n", hdr.channels,
136                                 hdr.samplerate, hdr.bytespersec,
137                                 hdr.samplesize, hdr.bitspersample);
138                 }
139         
140                 if (hdr.riffid != WAV_RIFFTYPE) {
141                         printf("ERROR: unknown file type, riffid=%x??\n",
142                                 hdr.riffid);
143                         exit(1);
144                 }
145                 if (hdr.waveid != WAV_WAVETYPE) {
146                         printf("ERROR: unknown file type, waveid=%x??\n",
147                                 hdr.waveid);
148                         exit(1);
149                 }
150                 if (hdr.fmtid != WAV_FMTTYPE) {
151                         printf("ERROR: unknown file type, fmtid=%x??\n",
152                                 hdr.fmtid);
153                         exit(1);
154                 }
155
156                 if (freq == 0)
157                         freq = hdr.samplerate;
158                 if (chans == 0)
159                         chans = hdr.channels;
160                 if (bitspersample == 0)
161                         bitspersample = hdr.bitspersample;
162         }
163
164         /* Set any remaining defaults if neccessary */
165         if (freq == 0)
166                 freq = 8000;
167         if (chans == 0)
168                 chans = 1;
169         if (bitspersample == 0)
170                 bitspersample = 8;
171
172         if (ioctl(ofd, SNDCTL_DSP_SPEED, &freq) < 0) {
173                 printf("ERROR: ioctl(SNDCTL_DSP_SPEED,freq) failed, "
174                         "errno=%d\n", errno);
175                 exit(1);
176         }
177         i = (chans == 2) ? 1 : 0;
178         if (ioctl(ofd, SNDCTL_DSP_STEREO, &i) < 0) {
179                 printf("ERROR: ioctl(SNDCTL_DSP_STEREO,0) failed, "
180                         "errno=%d\n", errno);
181                 exit(1);
182         }
183         i = (bitspersample == 16) ? AFMT_S16_LE : AFMT_U8;
184         if (ioctl(ofd, SNDCTL_DSP_SAMPLESIZE, &i) < 0) {
185                 printf("ERROR: ioctl(SNDCTL_DSP_SAMPLESIZE,8) failed, "
186                         "errno=%d\n", errno);
187                 exit(1);
188         }
189
190         /* Parse data header, and ignore... */
191         if ((n = read(ifd, &datahdr, sizeof(datahdr))) != sizeof(datahdr)) {
192                 printf("ERROR: failed to read(), errno=%d\n", errno);
193                 exit(1);
194         }
195
196 #if 1
197 printf("PLAYING at: freq=%d chans=%d bitspersample=%d\n", freq, chans, bitspersample);
198 #endif
199         /* Output data */
200         while ((n = read(ifd, buf, sizeof(buf))) > 0) {
201
202                 if ((hdr.bitspersample == 16) && (bitspersample == 8)) {
203                         /* Make audio track 8 bits only */
204                         for (i = 1, j = 0; (i < n); i += 2, j++)
205                                 buf[j] = buf[i];
206                         n = j;
207                 }
208                 if ((hdr.channels == 2) && (chans == 1)) {
209                         /* Make audio track single channel only */
210                         for (i = 2, j = 1; (i < n); i += 2, j++)
211                                 buf[j] = buf[i];
212                         n = j;
213                 }
214
215                 if (write(ofd, buf, n) != n) {
216                         printf("ERROR: write(%s) failed, errno=%d\n",
217                                 DACDEVICE, errno);
218                 }
219         }
220
221         close(ofd);
222         close(ifd);
223         exit(0);
224 }
225
226 /*****************************************************************************/