1 #ifndef lint
2 static char rcsid[] =
3 "$Id: encode_riff.c,v 1.10 1997/03/25 15:21:09 tommy Exp $";
4 #endif
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <fcntl.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <signal.h>
12 #include <err.h>
13 #include <arpa/inet.h>
14
15 #include <sys/soundcard.h>
16
17 #include "play.h"
18 #include "encode_riff.h"
19
check_riff(char * audio_file)20 riff_header_t *check_riff(char *audio_file)
21 {
22 int fd, stat;
23 static riff_header_t header;
24
25 if ((fd = open(audio_file, O_RDONLY)) < 0) {
26 warn("%s", audio_file);
27 return (riff_header_t*)FAIL;
28 }
29 if (read(fd, &header, sizeof(header)) < 0) {
30 warn("%s", audio_file);
31 stat = NULL; goto checkfail;
32 }
33
34 header.magic = htonl(header.magic);
35 if (header.magic == RIFF_MAGIC) {
36 header.chunk_data = htonl(header.chunk_data);
37 header.chunk_type = htonl(header.chunk_type);
38 if (header.chunk_type != RIFF_TYPE) {
39 fprintf(stderr, "%s: missing \"WAVE\"\n", myname, audio_file);
40 stat = FAIL; goto checkfail;
41 }
42 header.chunk_format = htonl(header.chunk_format) >> 8;
43 if ((header.chunk_format) != RIFF_FORMAT) {
44 fprintf(stderr, "%s: missing \"fmt\"\n", audio_file);
45 stat = FAIL; goto checkfail;
46 }
47 return &header;
48 }
49 stat = NULL;
50
51 checkfail:
52 close(fd);
53 return (riff_header_t*)stat;
54 }
55
print_riff_header(riff_header_t * headp)56 void print_riff_header(riff_header_t *headp)
57 {
58 printf(" magic = %d\n", headp->magic);
59 printf(" length = %d\n", headp->length);
60 printf(" chunk_type = %d\n", headp->chunk_type);
61 printf("chunk_format = %x\n", headp->chunk_format);
62 printf("chunk_length = %d\n", headp->chunk_length);
63 printf(" format = %d\n", headp->format);
64 printf(" chanells = %d\n", headp->channels);
65 printf(" sample_rate = %d\n", headp->sample_rate);
66 printf(" speed = %d\n", headp->speed);
67 printf(" sample_size = %d\n", headp->sample_size);
68 printf(" precision = %d\n", headp->precision);
69 printf(" chunk_data = %d\n", headp->chunk_data);
70 printf(" data_length = %d\n", headp->data_length);
71 }
72
play_riff(char * audio_file,riff_header_t * headerp,arg_params_t * params)73 int play_riff(char *audio_file, riff_header_t *headerp, arg_params_t *params)
74 {
75 char *bufp;
76 char *device;
77 int devfd, filefd;
78 int stat, len, buf_size, format = 0, data_length;
79
80 if (!f_hasdsp) {
81 fprintf(stderr, "%s: %s: needs DSP for play\n", myname, audio_file);
82 return FAIL;
83 }
84 if (f_extra)
85 print_riff_header(headerp);
86
87 switch (headerp->precision) {
88 case 8:
89 format = AFMT_U8;
90 break;
91 case 16:
92 format = AFMT_S16_LE;
93 break;
94 default:
95 break;
96 }
97
98 if (params->device == NULL)
99 device = DEV_DSP;
100 else
101 device = params->device;
102
103 if ((data_length = headerp->data_length) < 16)
104 data_length = headerp->length - sizeof(riff_header_t);
105
106 if ((devfd = open(device, O_WRONLY)) < 0)
107 err(1, "%s", device);
108
109 if (ioctl(devfd, SNDCTL_DSP_GETBLKSIZE, &buf_size) < 0) {
110 warn("%s", device);
111 stat = FAIL; goto failplay0;
112 }
113 #if 0
114 /* this (at least under fbsd) means that you want to set play format
115 * to headerp->sample_size which is a nonsense */
116 if (ioctl(devfd, SNDCTL_DSP_SAMPLESIZE, &headerp->sample_size) < 0) {
117 #endif
118 if (ioctl(devfd, SNDCTL_DSP_SAMPLESIZE, &format) < 0) {
119 warn("%s", device);
120 stat = FAIL; goto failplay0;
121 }
122 if (ioctl(devfd, SNDCTL_DSP_SPEED, &headerp->speed) < 0) {
123 warn("%s", device);
124 stat = FAIL; goto failplay0;
125 }
126 if (ioctl(devfd, SOUND_PCM_WRITE_RATE, &headerp->sample_rate) < 0) {
127 warn("%s", device);
128 stat = FAIL; goto failplay0;
129 }
130 if (headerp->channels > 1) {
131 int ch = headerp->channels;
132 if (ioctl(devfd, SNDCTL_DSP_STEREO, &ch) < 0) {
133 warn("%s", device);
134 stat = FAIL; goto failplay0;
135 }
136 }
137 if (ioctl(devfd, SNDCTL_DSP_SYNC, NULL) < 0) {
138 warn("%s", device);
139 stat = FAIL; goto failplay0;
140 }
141
142 if ((filefd = open(audio_file, O_RDONLY)) < 0) {
143 warn("%s", audio_file);
144 stat = FAIL; goto failplay0;
145 }
146 if ((bufp = (char*)malloc((size_t)buf_size)) == NULL) {
147 warn("malloc");
148 stat = FAIL; goto failplay1;
149 }
150 if ((stat = read(filefd, bufp, sizeof(riff_header_t))) < 0) {
151 warn("%s", audio_file);
152 stat = FAIL; goto failplay2;
153 }
154
155 len = data_length;
156
157 intr = FALSE;
158 signal(SIGINT, intr_play);
159
160 while (len > 0) {
161 if (intr)
162 break;
163 if ((stat = read(filefd, bufp, buf_size)) < 0) {
164 warn("read");
165 stat = FAIL; goto failplay2;
166 }
167 /* printf("len = %10d, len = %10d\n", stat, len); */
168 stat = (len < stat)? len : stat;
169 if (write(devfd, bufp, stat) < 0) {
170 warn("write");
171 stat = FAIL; goto failplay2;
172 }
173 len -= stat;
174 }
175 stat = SUCCESS;
176
177 failplay2:
178 free(bufp);
179 failplay1:
180 close(filefd);
181 failplay0:
182 close(devfd);
183
184 return stat;
185 }
186