1 #ifndef lint
2 static char rcsid[] =
3 "$Id: encode_sun.c,v 1.3 1997/03/25 15:21:27 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_sun.h"
19
check_sunaudio(char * audio_file)20 sun_header_t *check_sunaudio(char *audio_file)
21 {
22 int fd;
23 static sun_header_t header;
24
25 if ((fd = open(audio_file, O_RDONLY)) < 0) {
26 warn("%s", audio_file);
27 return (sun_header_t*)FAIL;
28 }
29 if (read(fd, &header, SUNAUDIO_HDR_SIZE) < 0) {
30 warn("%s", audio_file);
31 return NULL;
32 }
33
34 header.magic = htonl(header.magic);
35 if (header.magic != SUNAUDIO_MAGIC)
36 return NULL;
37
38 header.head_length = htonl(header.head_length);
39 if (header.head_length > SUNAUDIO_HDR_SIZE) {
40 size_t infosize = header.head_length - SUNAUDIO_HDR_SIZE;
41 if ((header.infop = malloc(infosize)) == NULL) {
42 warn("%s", "malloc");
43 return (sun_header_t*)FAIL;
44 }
45 if (read(fd, header.infop, infosize) < 0) {
46 warn("%s", audio_file);
47 return (sun_header_t*)FAIL;
48 }
49 } else {
50 header.infop = NULL;
51 }
52 close(fd);
53
54 header.head_length = header.head_length;
55 header.data_length = htonl(header.data_length);
56 header.data_format = htonl(header.data_format);
57 header.sample_rate = htonl(header.sample_rate);
58 header.channels = htonl(header.channels);
59 switch (header.data_format) {
60 case SUNAUDIO_ENCODING_MULAW_8:
61 header.data_format = AFMT_MU_LAW;
62 break;
63 case SUNAUDIO_ENCODING_LINEAR_8:
64 case SUNAUDIO_ENCODING_LINEAR_16:
65 case SUNAUDIO_ENCODING_LINEAR_24:
66 case SUNAUDIO_ENCODING_LINEAR_32:
67 header.data_format = AFMT_S16_LE;
68 break;
69 case SUNAUDIO_ENCODING_FLOAT:
70 case SUNAUDIO_ENCODING_DOUBLE:
71 header.data_format = AFMT_MU_LAW;
72 break;
73 default:
74 warn("%s: Unknown format", header.data_format);
75 return (sun_header_t*)FAIL;
76 }
77 return &header;
78 }
79
print_sun_header(sun_header_t * headp)80 void print_sun_header(sun_header_t *headp)
81 {
82 printf(" magic = %d\n", headp->magic);
83 printf("headerlength = %d\n", headp->head_length);
84 printf(" data_length = %d\n", headp->data_length);
85 printf(" data_format = %d\n", headp->data_format);
86 printf(" sample_rate = %d\n", headp->sample_rate);
87 printf(" channels = %d\n", headp->channels);
88 if (headp->infop != NULL)
89 printf(" info = %s\n", headp->infop);
90 }
91
play_sunaudio(char * audio_file,sun_header_t * headp,arg_params_t * params)92 int play_sunaudio(char *audio_file, sun_header_t *headp, arg_params_t *params)
93 {
94 unsigned char *bufp;
95 int stat;
96 int devfd, filefd;
97 char *device;
98
99 if (f_extra)
100 print_sun_header(headp);
101
102 if (params->device == NULL)
103 device = DEV_DSP;
104 else
105 device = params->device;
106
107 if (headp->infop != NULL)
108 free(headp->infop);
109
110 if (headp->data_length == SUNAUDIO_UNKNOWN_SIZE)
111 headp->data_length = 4096;
112
113 if ((devfd = open(device, O_WRONLY)) < 0)
114 err(1, "%s", device);
115
116 if (f_hasdsp && ioctl(devfd, SNDCTL_DSP_SETFMT, &headp->data_format) < 0) {
117 warn("%s", device);
118 stat = FAIL; goto failplay0;
119 }
120 if ((filefd = open(audio_file, O_RDONLY)) < 0) {
121 warn("%s", audio_file);
122 stat = FAIL; goto failplay0;
123 }
124 if ((bufp = (char*)malloc(headp->data_length)) == NULL) {
125 warn("%s", "malloc");
126 stat = FAIL; goto failplay1;
127 }
128
129 intr = FALSE;
130 signal(SIGINT, intr_play);
131
132 if ((stat = read(filefd, bufp, headp->head_length)) < 0) {
133 warn("%s", audio_file); goto failplay2;
134 }
135
136 if (!intr && (stat = read(filefd, bufp, headp->data_length)) < 0) {
137 warn("%s", audio_file); goto failplay2;
138 }
139 if (!intr && (stat = write(devfd, bufp, stat)) < 0) {
140 warn("%s", audio_file); goto failplay2;
141 }
142
143 failplay2:
144 free(bufp);
145 failplay1:
146 close(filefd);
147 failplay0:
148 close(devfd);
149
150 return stat;
151 }
152