Blame


1 3baa2617 2022-02-16 op /*
2 3baa2617 2022-02-16 op * Copyright (c) 2022 Omar Polo <op@openbsd.org>
3 3baa2617 2022-02-16 op *
4 3baa2617 2022-02-16 op * Permission to use, copy, modify, and distribute this software for any
5 3baa2617 2022-02-16 op * purpose with or without fee is hereby granted, provided that the above
6 3baa2617 2022-02-16 op * copyright notice and this permission notice appear in all copies.
7 3baa2617 2022-02-16 op *
8 3baa2617 2022-02-16 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 3baa2617 2022-02-16 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 3baa2617 2022-02-16 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 3baa2617 2022-02-16 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 3baa2617 2022-02-16 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 3baa2617 2022-02-16 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 3baa2617 2022-02-16 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 3baa2617 2022-02-16 op */
16 3baa2617 2022-02-16 op
17 3baa2617 2022-02-16 op #include <sys/mman.h>
18 3baa2617 2022-02-16 op #include <sys/stat.h>
19 3baa2617 2022-02-16 op #include <sys/types.h>
20 3baa2617 2022-02-16 op #include <sys/queue.h>
21 3baa2617 2022-02-16 op #include <sys/uio.h>
22 3baa2617 2022-02-16 op
23 3baa2617 2022-02-16 op #include <err.h>
24 3baa2617 2022-02-16 op #include <event.h>
25 3baa2617 2022-02-16 op #include <fcntl.h>
26 bb3f279f 2022-02-16 op #include <limits.h>
27 3baa2617 2022-02-16 op #include <sndio.h>
28 3baa2617 2022-02-16 op #include <stdio.h>
29 3baa2617 2022-02-16 op #include <stdint.h>
30 3baa2617 2022-02-16 op #include <imsg.h>
31 3baa2617 2022-02-16 op #include <unistd.h>
32 3baa2617 2022-02-16 op
33 3baa2617 2022-02-16 op #include <mad.h>
34 3baa2617 2022-02-16 op
35 3baa2617 2022-02-16 op #include "amused.h"
36 3baa2617 2022-02-16 op
37 3baa2617 2022-02-16 op struct mad_stream mad_stream;
38 3baa2617 2022-02-16 op struct mad_frame mad_frame;
39 3baa2617 2022-02-16 op struct mad_synth mad_synth;
40 3baa2617 2022-02-16 op
41 3baa2617 2022-02-16 op struct buffer {
42 3baa2617 2022-02-16 op const void *start;
43 3baa2617 2022-02-16 op size_t length;
44 3baa2617 2022-02-16 op int sample_rate;
45 18596703 2022-02-18 op int channels;
46 3baa2617 2022-02-16 op };
47 3baa2617 2022-02-16 op
48 3baa2617 2022-02-16 op static enum mad_flow
49 3baa2617 2022-02-16 op input(void *d, struct mad_stream *stream)
50 3baa2617 2022-02-16 op {
51 3baa2617 2022-02-16 op struct buffer *buffer = d;
52 3baa2617 2022-02-16 op
53 3baa2617 2022-02-16 op if (buffer->length == 0)
54 3baa2617 2022-02-16 op return MAD_FLOW_STOP;
55 3baa2617 2022-02-16 op
56 3baa2617 2022-02-16 op printf("decode time! start=%p, len=%zu\n", buffer->start, buffer->length);
57 3baa2617 2022-02-16 op mad_stream_buffer(stream, buffer->start, buffer->length);
58 3baa2617 2022-02-16 op buffer->length = 0;
59 3baa2617 2022-02-16 op buffer->sample_rate = 0;
60 18596703 2022-02-18 op buffer->channels = 0;
61 3baa2617 2022-02-16 op return MAD_FLOW_CONTINUE;
62 3baa2617 2022-02-16 op }
63 3baa2617 2022-02-16 op
64 3baa2617 2022-02-16 op /* scale a mad sample to 16 bits */
65 3baa2617 2022-02-16 op static inline int
66 3baa2617 2022-02-16 op scale(mad_fixed_t sample)
67 3baa2617 2022-02-16 op {
68 3baa2617 2022-02-16 op /* round */
69 3baa2617 2022-02-16 op sample += (1L << (MAD_F_FRACBITS - 16));
70 3baa2617 2022-02-16 op
71 3baa2617 2022-02-16 op /* clip */
72 3baa2617 2022-02-16 op if (sample >= MAD_F_ONE)
73 3baa2617 2022-02-16 op sample = MAD_F_ONE - 1;
74 3baa2617 2022-02-16 op else if (sample < -MAD_F_ONE)
75 3baa2617 2022-02-16 op sample -= MAD_F_ONE;
76 3baa2617 2022-02-16 op
77 3baa2617 2022-02-16 op /* quantize */
78 3baa2617 2022-02-16 op return sample >> (MAD_F_FRACBITS + 1 - 16);
79 3baa2617 2022-02-16 op }
80 3baa2617 2022-02-16 op
81 3baa2617 2022-02-16 op static enum mad_flow
82 3baa2617 2022-02-16 op output(void *data, const struct mad_header *header, struct mad_pcm *pcm)
83 3baa2617 2022-02-16 op {
84 3baa2617 2022-02-16 op static uint8_t buf[BUFSIZ];
85 3baa2617 2022-02-16 op size_t len;
86 3baa2617 2022-02-16 op struct buffer *buffer = data;
87 3baa2617 2022-02-16 op int nsamples, i;
88 3baa2617 2022-02-16 op uint16_t sample;
89 3baa2617 2022-02-16 op const mad_fixed_t *leftch, *rightch;
90 3baa2617 2022-02-16 op
91 3baa2617 2022-02-16 op if (player_shouldstop())
92 3baa2617 2022-02-16 op return MAD_FLOW_STOP;
93 3baa2617 2022-02-16 op
94 3baa2617 2022-02-16 op nsamples = pcm->length;
95 3baa2617 2022-02-16 op leftch = pcm->samples[0];
96 3baa2617 2022-02-16 op rightch = pcm->samples[1];
97 3baa2617 2022-02-16 op
98 18596703 2022-02-18 op if (buffer->sample_rate != pcm->samplerate ||
99 18596703 2022-02-18 op buffer->channels != pcm->channels) {
100 3baa2617 2022-02-16 op buffer->sample_rate = pcm->samplerate;
101 18596703 2022-02-18 op buffer->channels = pcm->channels;
102 18596703 2022-02-18 op if (player_setup(pcm->samplerate, pcm->channels) == -1)
103 3baa2617 2022-02-16 op err(1, "player_setrate");
104 3baa2617 2022-02-16 op }
105 3baa2617 2022-02-16 op
106 3baa2617 2022-02-16 op for (i = 0, len = 0; i < nsamples; ++i) {
107 3baa2617 2022-02-16 op if (len+4 >= sizeof(buf)) {
108 3baa2617 2022-02-16 op sio_write(hdl, buf, len);
109 3baa2617 2022-02-16 op /* fwrite(buf, 1, len, stdout); */
110 3baa2617 2022-02-16 op len = 0;
111 3baa2617 2022-02-16 op }
112 3baa2617 2022-02-16 op
113 3baa2617 2022-02-16 op sample = scale(*leftch++);
114 3baa2617 2022-02-16 op buf[len++] = sample & 0xff;
115 3baa2617 2022-02-16 op buf[len++] = (sample >> 8) & 0xff;
116 3baa2617 2022-02-16 op
117 18596703 2022-02-18 op if (pcm->channels == 2) {
118 18596703 2022-02-18 op sample = scale(*rightch++);
119 18596703 2022-02-18 op buf[len++] = sample & 0xff;
120 18596703 2022-02-18 op buf[len++] = (sample >> 8) & 0xff;
121 18596703 2022-02-18 op }
122 3baa2617 2022-02-16 op }
123 3baa2617 2022-02-16 op
124 3baa2617 2022-02-16 op if (len != 0)
125 3baa2617 2022-02-16 op /* fwrite(buf, 1, len, stdout); */
126 3baa2617 2022-02-16 op sio_write(hdl, buf, len);
127 3baa2617 2022-02-16 op
128 3baa2617 2022-02-16 op return MAD_FLOW_CONTINUE;
129 3baa2617 2022-02-16 op }
130 3baa2617 2022-02-16 op
131 3baa2617 2022-02-16 op static enum mad_flow
132 3baa2617 2022-02-16 op error(void *d, struct mad_stream *stream, struct mad_frame *frame)
133 3baa2617 2022-02-16 op {
134 3baa2617 2022-02-16 op struct buffer *buffer = d;
135 3baa2617 2022-02-16 op
136 3baa2617 2022-02-16 op warnx("decoding error 0x%04x (%s) at byte offset %zu",
137 3baa2617 2022-02-16 op stream->error, mad_stream_errorstr(stream),
138 3baa2617 2022-02-16 op stream->this_frame - (const unsigned char *)buffer->start);
139 3baa2617 2022-02-16 op
140 3baa2617 2022-02-16 op return MAD_FLOW_CONTINUE;
141 3baa2617 2022-02-16 op }
142 3baa2617 2022-02-16 op
143 3baa2617 2022-02-16 op static int
144 3baa2617 2022-02-16 op decode(void *m, size_t len)
145 3baa2617 2022-02-16 op {
146 3baa2617 2022-02-16 op struct buffer buffer;
147 3baa2617 2022-02-16 op struct mad_decoder decoder;
148 3baa2617 2022-02-16 op int result;
149 3baa2617 2022-02-16 op
150 3baa2617 2022-02-16 op /* initialize our private message structure; */
151 3baa2617 2022-02-16 op buffer.start = m;
152 3baa2617 2022-02-16 op buffer.length = len;
153 3baa2617 2022-02-16 op
154 3baa2617 2022-02-16 op /* configure input, output and error functions */
155 3baa2617 2022-02-16 op mad_decoder_init(&decoder, &buffer, input, 0 /* header */,
156 3baa2617 2022-02-16 op 0 /* filter */, output, error, 0 /* message */);
157 3baa2617 2022-02-16 op
158 3baa2617 2022-02-16 op /* start decoding */
159 3baa2617 2022-02-16 op result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
160 3baa2617 2022-02-16 op
161 3baa2617 2022-02-16 op /* release the decoder */
162 3baa2617 2022-02-16 op mad_decoder_finish(&decoder);
163 3baa2617 2022-02-16 op
164 3baa2617 2022-02-16 op return result;
165 3baa2617 2022-02-16 op }
166 3baa2617 2022-02-16 op
167 3baa2617 2022-02-16 op void
168 3baa2617 2022-02-16 op play_mp3(int fd)
169 3baa2617 2022-02-16 op {
170 3baa2617 2022-02-16 op struct stat stat;
171 3baa2617 2022-02-16 op void *m;
172 3baa2617 2022-02-16 op
173 3baa2617 2022-02-16 op if (fstat(fd, &stat) == -1)
174 3baa2617 2022-02-16 op err(1, "fstat");
175 3baa2617 2022-02-16 op warnx("file size %lld", stat.st_size);
176 3baa2617 2022-02-16 op
177 3baa2617 2022-02-16 op m = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
178 3baa2617 2022-02-16 op if (m == MAP_FAILED)
179 3baa2617 2022-02-16 op err(1, "mmap");
180 3baa2617 2022-02-16 op
181 3baa2617 2022-02-16 op decode(m, stat.st_size);
182 3baa2617 2022-02-16 op munmap(m, stat.st_size);
183 3baa2617 2022-02-16 op }