Package list squeezelite / b3a18df
New upstream version 1.8 tony mancill 8 months ago
36 changed file(s) with 11230 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 Version 1.0 - 15/2/13
1 =====================
2 - initial release
3
4 Version 1.1 - 12/4/13
5 =====================
6
7 Minor changes
8 - add timeout on slimproto connection to detect dead server
9 - fix issue with clipping on windows by disabling portaudio dither
10 - silence alsa error messages on linux alsa builds unless debugging is enabled
11 - hide some additional error messages unless debuging is enabled so usb dacs produce less error messages when turned off and on
12
13 Version 1.2 - 6/7/13
14 ====================
15
16 Features
17 - support of upsampling via libsoxr
18
19 Minor changes
20 - command line option for setting the service address now requires "-s" before the server address
21 - fixes a bug where the channels could become swapped when using S16_LE ALSA output
22 - falls back to polling for a new server if one is not found for more than 30 seconds
23 - fixes play of wav/aiff local files when the LocalPlayer plugin is active
24
25 Version 1.3 - 6/10/13
26 =====================
27
28 Features
29 - support for wma/alac decode via ffmpeg library (requires compilation with -DFFMPEG)
30 - support for export of audio data to jivelite to enable visulizations on linux (requires compilation with -DVISEXPORT)
31
32 Minor changes
33 - support async as well as sync resampling rates
34 - support on/off of audio device with portaudio
35 - improved gapless support for aac/mad when skipping to mid track (based on patches from Wouter Ellenbroek)
36 - various bug fixes
37
38 Version 1.3.1 - 25/11/13
39 ========================
40
41 Minor changes
42 - support of compile time linking for distro packaging, uses -DLINKALL option
43
44 Version 1.4 28/12/13
45 ====================
46
47 Features
48 - native support of dsd playback to dop capable dac or via conversion to pcm and resampling
49 - support dop in flac playback to dop dacs
50 - support of output to stdout
51
52 Minor changes
53 - support of resampling only when sample rate is not natively supported
54 - fix problem with libmpg123 playback not playing to end of track
55 - add ablity for player name change to be stored locally in a file (to emulate hardware where name is stored on player)
56
57 Version 1.5 12/1/14
58 ===================
59
60 Minor changes
61 - add configurable delay for switch between pcm and dop
62 - allow visexport to work with jivelite running as any user
63 - bug fixes for dsf playback, for status progress on windows using wdm-ks output, and to avoid 100% cpu
64 - change some logging levels for slimproto to aid readability
65
66 Version 1.6 23/3/14
67 ===================
68
69 Minor changes
70 - add support for direct file playback on windows
71 - add configurable delay for switch between pcm sample rates
72 - support build on freebsd
73 - fix gapless playback on portaudio builds
74 - fix gapless playback for mp3 localfile case with tags at start of file
75
76 Version 1.6.1 22/4/14
77 =====================
78
79 Minor changes
80 - fix bug with PA version changing sample rate between tracks
81 - fix crash when skipping in ogg while resampling
82 - fix typo
83
84 Version 1.6.2 26/5/14
85 =====================
86
87 Minor changes
88 - fix XRUN on track change when resampling on low power cpus
89 - log command line to logfile when debugging enabled
90 - option to exclude codecs (-e)
91 - support parallel execution of libsoxr
92
93 Version 1.6.3 14/6/14
94 =====================
95
96 Minor changes
97 - reduce time to start track when playing local files
98 - disable use of OPENMP when RESAMPLE build option defined, add new option RESAMPLE_MP to enable it
99
100 Version 1.6.4 7/7/14
101 ====================
102
103 Minor changes
104 - improve synchronisation feedback accuracy
105
106 Version 1.6.5 21/11/14
107 ======================
108
109 Minor changes
110 - fix problem opening ALSA device if 44100 is not supported
111 - trap setting of hw player mac address
112
113 Version 1.7 1/1/15
114 ==================
115
116 Minor changes
117 - allow player modelname to be set at compile or run time
118 - workaround alsa drivers reporting very large number of available frames
119 - fix clicks on localfile playback of AIFF files
120 - add -P option to store process id in a file
121 - improve error messages for command line parsing
122
123 Version 1.7.1 10/1/15
124 =====================
125
126 Minor changes
127 - fix crash which could occur when resampling
128
129 Version 1.8 1/2/15
130 ==================
131
132 Features
133 - support for closing output device when idle with -C option
134 - support for basic IR input using LIRC on Linux
135 - support for volume adjustment or unmuting of alsa mixer
136 - support for inverting output polarity via LMS setting (requires recent 7.9 server)
0 Squeezelite - lightweight headless squeezebox emulator
1
2 (c) Adrian Smith 2012-2015, triode1@btinternet.com
3
4 Released under GPLv3 license:
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19
20 ---------------------------------------------------------------------
21
22 If built with DSD support, this software also includes code subject to the following license:
23
24 Copyright 2009, 2011 Sebastian Gesemann. All rights reserved.
25
26 Redistribution and use in source and binary forms, with or without modification, are
27 permitted provided that the following conditions are met:
28
29 1. Redistributions of source code must retain the above copyright notice, this list of
30 conditions and the following disclaimer.
31
32 2. Redistributions in binary form must reproduce the above copyright notice, this list
33 of conditions and the following disclaimer in the documentation and/or other materials
34 provided with the distribution.
35
36 THIS SOFTWARE IS PROVIDED BY SEBASTIAN GESEMANN ''AS IS'' AND ANY EXPRESS OR IMPLIED
37 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
38 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEBASTIAN GESEMANN OR
39 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
44 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45
46 The views and conclusions contained in the software and documentation are those of the
47 authors and should not be interpreted as representing official policies, either expressed
48 or implied, of Sebastian Gesemann.
0 # Cross compile support - create a Makefile which defines these three variables and then includes this Makefile...
1 CFLAGS ?= -Wall -fPIC -O2 $(OPTS)
2 LDFLAGS ?= -lasound -lpthread -lm -lrt
3 EXECUTABLE ?= squeezelite
4
5 # passing one or more of these in $(OPTS) enables optional feature inclusion
6 OPT_DSD = -DDSD
7 OPT_FF = -DFFMPEG
8 OPT_LINKALL = -DLINKALL
9 OPT_RESAMPLE= -DRESAMPLE
10 OPT_VIS = -DVISEXPORT
11 OPT_IR = -DIR
12
13 SOURCES = \
14 main.c slimproto.c buffer.c stream.c utils.c \
15 output.c output_alsa.c output_pa.c output_stdout.c output_pack.c decode.c \
16 flac.c pcm.c mad.c vorbis.c faad.c mpg.c
17
18 SOURCES_DSD = dsd.c dop.c dsd2pcm/dsd2pcm.c
19 SOURCES_FF = ffmpeg.c
20 SOURCES_RESAMPLE = process.c resample.c
21 SOURCES_VIS = output_vis.c
22 SOURCES_IR = ir.c
23
24 LINK_LINUX = -ldl
25
26 LINKALL = -lFLAC -lmad -lvorbisfile -lfaad -lmpg123
27 LINKALL_FF = -lavcodec -lavformat -lavutil
28 LINKALL_RESAMPLE = -lsoxr
29 LINKALL_IR = -llirc_client
30
31 DEPS = squeezelite.h slimproto.h
32
33 UNAME = $(shell uname -s)
34
35 # add optional sources
36 ifneq (,$(findstring $(OPT_DSD), $(CFLAGS)))
37 SOURCES += $(SOURCES_DSD)
38 endif
39 ifneq (,$(findstring $(OPT_FF), $(CFLAGS)))
40 SOURCES += $(SOURCES_FF)
41 endif
42 ifneq (,$(findstring $(OPT_RESAMPLE), $(CFLAGS)))
43 SOURCES += $(SOURCES_RESAMPLE)
44 endif
45 ifneq (,$(findstring $(OPT_VIS), $(CFLAGS)))
46 SOURCES += $(SOURCES_VIS)
47 endif
48 ifneq (,$(findstring $(OPT_IR), $(CFLAGS)))
49 SOURCES += $(SOURCES_IR)
50 endif
51
52 # add optional link options
53 ifneq (,$(findstring $(OPT_LINKALL), $(CFLAGS)))
54 LDFLAGS += $(LINKALL)
55 ifneq (,$(findstring $(OPT_FF), $(CFLAGS)))
56 LDFLAGS += $(LINKALL_FF)
57 endif
58 ifneq (,$(findstring $(OPT_RESAMPLE), $(CFLAGS)))
59 LDFLAGS += $(LINKALL_RESAMPLE)
60 endif
61 ifneq (,$(findstring $(OPT_IR), $(CFLAGS)))
62 LDFLAGS += $(LINKALL_IR)
63 endif
64 else
65 # if not LINKALL and linux add LINK_LINUX
66 ifeq ($(UNAME), Linux)
67 LDFLAGS += $(LINK_LINUX)
68 endif
69 endif
70
71 OBJECTS = $(SOURCES:.c=.o)
72
73 all: $(EXECUTABLE)
74
75 $(EXECUTABLE): $(OBJECTS)
76 $(CC) $(OBJECTS) $(LDFLAGS) -o $@
77
78 $(OBJECTS): $(DEPS)
79
80 .c.o:
81 $(CC) $(CFLAGS) $(CPPFLAGS) $< -c -o $@
82
83 clean:
84 rm -f $(OBJECTS) $(EXECUTABLE)
0 CPPFLAGS = -I/usr/local/include -I/usr/local/include/portaudio2
1 LDFLAGS = -L/usr/local/lib -L/usr/local/lib/portaudio2 -lportaudio -lpthread -lm
2
3 include Makefile
0 # OSX build - adjust -I to point to header files for codecs and portaudio
1 CFLAGS = -arch x86_64 -arch i386 -Wall -fPIC -O2 -I./include $(OPTS)
2 LDFLAGS = -arch x86_64 -arch i386 -lpthread libportaudio.a -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon
3
4 EXECUTABLE ?= squeezelite-osx
5
6 include Makefile
0 # Make with portaudio rather than direct alsa
1 OPTS += -DPORTAUDIO
2 LDFLAGS = -lportaudio -lpthread -ldl -lrt
3 EXECUTABLE = squeezelite-pa
4
5 include Makefile
0 OPTS = -DRESAMPLE
1
2 include Makefile
0 /*
1 * Squeezelite - lightweight headless squeezebox emulator
2 *
3 * (c) Adrian Smith 2012-2015, triode1@btinternet.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 // fifo bufffers
21
22 #define _GNU_SOURCE
23
24 #include "squeezelite.h"
25
26 // _* called with muxtex locked
27
28 inline unsigned _buf_used(struct buffer *buf) {
29 return buf->writep >= buf->readp ? buf->writep - buf->readp : buf->size - (buf->readp - buf->writep);
30 }
31
32 unsigned _buf_space(struct buffer *buf) {
33 return buf->size - _buf_used(buf) - 1; // reduce by one as full same as empty otherwise
34 }
35
36 unsigned _buf_cont_read(struct buffer *buf) {
37 return buf->writep >= buf->readp ? buf->writep - buf->readp : buf->wrap - buf->readp;
38 }
39
40 unsigned _buf_cont_write(struct buffer *buf) {
41 return buf->writep >= buf->readp ? buf->wrap - buf->writep : buf->readp - buf->writep;
42 }
43
44 void _buf_inc_readp(struct buffer *buf, unsigned by) {
45 buf->readp += by;
46 if (buf->readp >= buf->wrap) {
47 buf->readp -= buf->size;
48 }
49 }
50
51 void _buf_inc_writep(struct buffer *buf, unsigned by) {
52 buf->writep += by;
53 if (buf->writep >= buf->wrap) {
54 buf->writep -= buf->size;
55 }
56 }
57
58 void buf_flush(struct buffer *buf) {
59 mutex_lock(buf->mutex);
60 buf->readp = buf->buf;
61 buf->writep = buf->buf;
62 mutex_unlock(buf->mutex);
63 }
64
65 // adjust buffer to multiple of mod bytes so reading in multiple always wraps on frame boundary
66 void buf_adjust(struct buffer *buf, size_t mod) {
67 size_t size;
68 mutex_lock(buf->mutex);
69 size = ((unsigned)(buf->base_size / mod)) * mod;
70 buf->readp = buf->buf;
71 buf->writep = buf->buf;
72 buf->wrap = buf->buf + size;
73 buf->size = size;
74 mutex_unlock(buf->mutex);
75 }
76
77 // called with mutex locked to resize, does not retain contents, reverts to original size if fails
78 void _buf_resize(struct buffer *buf, size_t size) {
79 free(buf->buf);
80 buf->buf = malloc(size);
81 if (!buf->buf) {
82 size = buf->size;
83 buf->buf= malloc(size);
84 if (!buf->buf) {
85 size = 0;
86 }
87 }
88 buf->readp = buf->buf;
89 buf->writep = buf->buf;
90 buf->wrap = buf->buf + size;
91 buf->size = size;
92 buf->base_size = size;
93 }
94
95 void buf_init(struct buffer *buf, size_t size) {
96 buf->buf = malloc(size);
97 buf->readp = buf->buf;
98 buf->writep = buf->buf;
99 buf->wrap = buf->buf + size;
100 buf->size = size;
101 buf->base_size = size;
102 mutex_create_p(buf->mutex);
103 }
104
105 void buf_destroy(struct buffer *buf) {
106 if (buf->buf) {
107 free(buf->buf);
108 buf->buf = NULL;
109 buf->size = 0;
110 buf->base_size = 0;
111 mutex_destroy(buf->mutex);
112 }
113 }
0 /*
1 * Squeezelite - lightweight headless squeezebox emulator
2 *
3 * (c) Adrian Smith 2012-2015, triode1@btinternet.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 // decode thread
21
22 #include "squeezelite.h"
23
24 log_level loglevel;
25
26 extern struct buffer *streambuf;
27 extern struct buffer *outputbuf;
28 extern struct streamstate stream;
29 extern struct outputstate output;
30 extern struct processstate process;
31
32 struct decodestate decode;
33 struct codec *codecs[MAX_CODECS];
34 struct codec *codec;
35 static bool running = true;
36
37 #define LOCK_S mutex_lock(streambuf->mutex)
38 #define UNLOCK_S mutex_unlock(streambuf->mutex)
39 #define LOCK_O mutex_lock(outputbuf->mutex)
40 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
41 #define LOCK_D mutex_lock(decode.mutex);
42 #define UNLOCK_D mutex_unlock(decode.mutex);
43
44 #if PROCESS
45 #define IF_DIRECT(x) if (decode.direct) { x }
46 #define IF_PROCESS(x) if (!decode.direct) { x }
47 #define MAY_PROCESS(x) { x }
48 #else
49 #define IF_DIRECT(x) { x }
50 #define IF_PROCESS(x)
51 #define MAY_PROCESS(x)
52 #endif
53
54 static void *decode_thread() {
55
56 while (running) {
57 size_t bytes, space, min_space;
58 bool toend;
59 bool ran = false;
60
61 LOCK_S;
62 bytes = _buf_used(streambuf);
63 toend = (stream.state <= DISCONNECT);
64 UNLOCK_S;
65 LOCK_O;
66 space = _buf_space(outputbuf);
67 UNLOCK_O;
68
69 LOCK_D;
70
71 if (decode.state == DECODE_RUNNING && codec) {
72
73 LOG_SDEBUG("streambuf bytes: %u outputbuf space: %u", bytes, space);
74
75 IF_DIRECT(
76 min_space = codec->min_space;
77 );
78 IF_PROCESS(
79 min_space = process.max_out_frames * BYTES_PER_FRAME;
80 );
81
82 if (space > min_space && (bytes > codec->min_read_bytes || toend)) {
83
84 decode.state = codec->decode();
85
86 IF_PROCESS(
87 if (process.in_frames) {
88 process_samples();
89 }
90
91 if (decode.state == DECODE_COMPLETE) {
92 process_drain();
93 }
94 );
95
96 if (decode.state != DECODE_RUNNING) {
97
98 LOG_INFO("decode %s", decode.state == DECODE_COMPLETE ? "complete" : "error");
99
100 LOCK_O;
101 if (output.fade_mode) _checkfade(false);
102 UNLOCK_O;
103
104 wake_controller();
105 }
106
107 ran = true;
108 }
109 }
110
111 UNLOCK_D;
112
113 if (!ran) {
114 usleep(100000);
115 }
116 }
117
118 return 0;
119 }
120
121 static thread_type thread;
122
123 void decode_init(log_level level, const char *include_codecs, const char *exclude_codecs) {
124 int i;
125
126 loglevel = level;
127
128 LOG_INFO("init decode, include codecs: %s exclude codecs: %s", include_codecs ? include_codecs : "", exclude_codecs);
129
130 // register codecs
131 // dsf,dff,alc,wma,wmap,wmal,aac,spt,ogg,ogf,flc,aif,pcm,mp3
132 i = 0;
133 #if DSD
134 if (!strstr(exclude_codecs, "dsd") && (!include_codecs || strstr(include_codecs, "dsd"))) codecs[i++] = register_dsd();
135 #endif
136 #if FFMPEG
137 if (!strstr(exclude_codecs, "alac") && (!include_codecs || strstr(include_codecs, "alac"))) codecs[i++] = register_ff("alc");
138 if (!strstr(exclude_codecs, "wma") && (!include_codecs || strstr(include_codecs, "wma"))) codecs[i++] = register_ff("wma");
139 #endif
140 if (!strstr(exclude_codecs, "aac") && (!include_codecs || strstr(include_codecs, "aac"))) codecs[i++] = register_faad();
141 if (!strstr(exclude_codecs, "ogg") && (!include_codecs || strstr(include_codecs, "ogg"))) codecs[i++] = register_vorbis();
142 if (!strstr(exclude_codecs, "flac") && (!include_codecs || strstr(include_codecs, "flac"))) codecs[i++] = register_flac();
143 if (!strstr(exclude_codecs, "pcm") && (!include_codecs || strstr(include_codecs, "pcm"))) codecs[i++] = register_pcm();
144
145 // try mad then mpg for mp3 unless command line option passed
146 if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mad")) &&
147 (!include_codecs || strstr(include_codecs, "mp3") || strstr(include_codecs, "mad"))) codecs[i] = register_mad();
148 if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mpg")) && !codecs[i] &&
149 (!include_codecs || strstr(include_codecs, "mp3") || strstr(include_codecs, "mpg"))) codecs[i] = register_mpg();
150
151 mutex_create(decode.mutex);
152
153 #if LINUX || OSX || FREEBSD
154 pthread_attr_t attr;
155 pthread_attr_init(&attr);
156 pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + DECODE_THREAD_STACK_SIZE);
157 pthread_create(&thread, &attr, decode_thread, NULL);
158 pthread_attr_destroy(&attr);
159 #endif
160 #if WIN
161 thread = CreateThread(NULL, DECODE_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&decode_thread, NULL, 0, NULL);
162 #endif
163
164 decode.new_stream = true;
165 decode.state = DECODE_STOPPED;
166
167 MAY_PROCESS(
168 decode.direct = true;
169 decode.process = false;
170 );
171 }
172
173 void decode_close(void) {
174 LOG_INFO("close decode");
175 LOCK_D;
176 if (codec) {
177 codec->close();
178 codec = NULL;
179 }
180 running = false;
181 UNLOCK_D;
182 #if LINUX || OSX || FREEBSD
183 pthread_join(thread, NULL);
184 #endif
185 mutex_destroy(decode.mutex);
186 }
187
188 void decode_flush(void) {
189 LOG_INFO("decode flush");
190 LOCK_D;
191 decode.state = DECODE_STOPPED;
192 IF_PROCESS(
193 process_flush();
194 );
195 UNLOCK_D;
196 }
197
198 unsigned decode_newstream(unsigned sample_rate, unsigned supported_rates[]) {
199
200 // called with O locked to get sample rate for potentially processed output stream
201 // release O mutex during process_newstream as it can take some time
202
203 MAY_PROCESS(
204 if (decode.process) {
205 UNLOCK_O;
206 sample_rate = process_newstream(&decode.direct, sample_rate, supported_rates);
207 LOCK_O;
208 }
209 );
210
211 return sample_rate;
212 }
213
214 void codec_open(u8_t format, u8_t sample_size, u8_t sample_rate, u8_t channels, u8_t endianness) {
215 int i;
216
217 LOG_INFO("codec open: '%c'", format);
218
219 LOCK_D;
220
221 decode.new_stream = true;
222 decode.state = DECODE_STOPPED;
223
224 MAY_PROCESS(
225 decode.direct = true; // potentially changed within codec when processing enabled
226 );
227
228 // find the required codec
229 for (i = 0; i < MAX_CODECS; ++i) {
230
231 if (codecs[i] && codecs[i]->id == format) {
232
233 if (codec && codec != codecs[i]) {
234 LOG_INFO("closing codec: '%c'", codec->id);
235 codec->close();
236 }
237
238 codec = codecs[i];
239
240 codec->open(sample_size, sample_rate, channels, endianness);
241
242 decode.state = DECODE_READY;
243
244 UNLOCK_D;
245 return;
246 }
247 }
248
249 UNLOCK_D;
250
251 LOG_ERROR("codec not found");
252 }
253
+102
-0
dop.c less more
0 /*
1 * Squeezelite - lightweight headless squeezebox emulator
2 *
3 * (c) Adrian Smith 2012, 2013, triode1@btinternet.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 // DSP over PCM (DOP) specific functions
21
22 #include "squeezelite.h"
23
24 #if DSD
25
26 extern struct buffer *outputbuf;
27 extern struct outputstate output;
28
29 #define LOCK_O mutex_lock(outputbuf->mutex)
30 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
31
32 // check for 32 dop marker frames to see if this is dop in flac
33 // dop is always encoded in 24 bit samples with marker 0x0005xxxx or 0x00FAxxxx
34 bool is_flac_dop(u32_t *lptr, u32_t *rptr, frames_t frames) {
35 int matched = 0;
36 u32_t next = 0;
37
38 while (frames--) {
39 if (((*lptr & 0x00FF0000) == 0x00050000 && (*rptr & 0x00FF0000) == 0x00050000) ||
40 ((*lptr & 0x00FF0000) == 0x00FA0000 && (*rptr & 0x00FF0000) == 0x00FA0000)) {
41 if (*lptr >> 24 == next) {
42 matched++;
43 next = ( 0x05 + 0xFA ) - next;
44 } else {
45 next = *lptr >> 24;
46 matched = 1;
47 }
48 } else {
49 return false;
50 }
51 if (matched == 32) {
52 return true;
53 }
54
55 ++lptr; ++rptr;
56 }
57 return false;
58 }
59
60 // update the dop marker and potentially invert polarity for frames in the output buffer
61 // performaned on all output including silence to maintain marker phase consitency
62 void update_dop(u32_t *ptr, frames_t frames, bool invert) {
63 static u32_t marker = 0x05;
64 if (!invert) {
65 while (frames--) {
66 u32_t scaled_marker = marker << 24;
67 *ptr = (*ptr & 0x00FFFFFF) | scaled_marker;
68 ++ptr;
69 *ptr = (*ptr & 0x00FFFFFF) | scaled_marker;
70 ++ptr;
71 marker = ( 0x05 + 0xFA ) - marker;
72 }
73 } else {
74 while (frames--) {
75 u32_t scaled_marker = marker << 24;
76 *ptr = ((~(*ptr)) & 0x00FFFFFF) | scaled_marker;
77 ++ptr;
78 *ptr = ((~(*ptr)) & 0x00FFFFFF) | scaled_marker;
79 ++ptr;
80 marker = ( 0x05 + 0xFA ) - marker;
81 }
82 }
83 }
84
85 // fill silence buffer with 10101100 which represents dop silence
86 // leave marker zero it will be updated at output, leave lsb zero
87 void dop_silence_frames(u32_t *ptr, frames_t frames) {
88 while (frames--) {
89 *ptr++ = 0x00ACAC00;
90 *ptr++ = 0x00ACAC00;
91 }
92 }
93
94 void dop_init(bool enable, unsigned delay) {
95 LOCK_O;
96 output.has_dop = enable;
97 output.dop_delay = delay;
98 UNLOCK_O;
99 }
100
101 #endif // DSD
+628
-0
dsd.c less more
0 /*
1 * Squeezelite - lightweight headless squeezebox emulator
2 *
3 * (c) Adrian Smith 2012-2015, triode1@btinternet.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 // dsd support
21
22 #include "squeezelite.h"
23
24 #if DSD
25
26 // use dsd2pcm from Sebastian Gesemann for conversion to pcm:
27 #include "./dsd2pcm/dsd2pcm.h"
28
29 extern log_level loglevel;
30
31 extern struct buffer *streambuf;
32 extern struct buffer *outputbuf;
33 extern struct streamstate stream;
34 extern struct outputstate output;
35 extern struct decodestate decode;
36 extern struct processstate process;
37
38 #define LOCK_S mutex_lock(streambuf->mutex)
39 #define UNLOCK_S mutex_unlock(streambuf->mutex)
40 #define LOCK_O mutex_lock(outputbuf->mutex)
41 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
42 #if PROCESS
43 #define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
44 #define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
45 #define LOCK_O_not_direct if (!decode.direct) mutex_lock(outputbuf->mutex)
46 #define UNLOCK_O_not_direct if (!decode.direct) mutex_unlock(outputbuf->mutex)
47 #define IF_DIRECT(x) if (decode.direct) { x }
48 #define IF_PROCESS(x) if (!decode.direct) { x }
49 #else
50 #define LOCK_O_direct mutex_lock(outputbuf->mutex)
51 #define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
52 #define LOCK_O_not_direct
53 #define UNLOCK_O_not_direct
54 #define IF_DIRECT(x) { x }
55 #define IF_PROCESS(x)
56 #endif
57
58 #define BLOCK 4096 // expected size of dsd block
59 #define BLOCK_FRAMES BLOCK * BYTES_PER_FRAME
60 #define WRAP_BUF_SIZE 16
61
62 typedef enum { UNKNOWN=0, DSF, DSDIFF } dsd_type;
63
64 static bool dop = false; // local copy of output.has_dop to avoid holding output lock
65
66 struct dsd {
67 dsd_type type;
68 u32_t consume;
69 u32_t sample_rate;
70 u32_t channels;
71 u64_t sample_bytes;
72 u32_t block_size;
73 bool lsb_first;
74 dsd2pcm_ctx *dsd2pcm_ctx[2];
75 float *transfer[2];
76 };
77
78 static struct dsd *d;
79
80 static u64_t unpack64be(const u8_t *p) {
81 return
82 (u64_t)p[0] << 56 | (u64_t)p[1] << 48 | (u64_t)p[2] << 40 | (u64_t)p[3] << 32 |
83 (u64_t)p[4] << 24 | (u64_t)p[5] << 16 | (u64_t)p[6] << 8 | (u64_t)p[7];
84 }
85
86 static u64_t unpack64le(const u8_t *p) {
87 return
88 (u64_t)p[7] << 56 | (u64_t)p[6] << 48 | (u64_t)p[5] << 40 | (u64_t)p[4] << 32 |
89 (u64_t)p[3] << 24 | (u64_t)p[2] << 16 | (u64_t)p[1] << 8 | (u64_t)p[0];
90 }
91
92 static u32_t unpack32le(const u8_t *p) {
93 return
94 (u32_t)p[3] << 24 | (u32_t)p[2] << 16 | (u32_t)p[1] << 8 | (u32_t)p[0];
95 }
96
97 static int _read_header(void) {
98 unsigned bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
99 s32_t consume;
100
101 if (!d->type && bytes >= 4) {
102 if (!memcmp(streambuf->readp, "FRM8", 4)) {
103 d->type = DSDIFF;
104 } else if (!memcmp(streambuf->readp, "DSD ", 4)) {
105 d->type = DSF;
106 } else {
107 LOG_WARN("bad type");
108 return -1;
109 }
110 }
111
112 while (bytes >= 16) {
113 char id[5];
114 u64_t len = d->type == DSDIFF ? unpack64be(streambuf->readp + 4) : unpack64le(streambuf->readp + 4);
115 memcpy(id, streambuf->readp, 4);
116 id[4] = '\0';
117 consume = 0;
118
119 if (d->type == DSDIFF) {
120 if (!strcmp(id, "FRM8")) {
121 if (!memcmp(streambuf->readp + 12, "DSD ", 4)) {
122 consume = 16; // read into
123 } else {
124 LOG_WARN("bad dsdiff FRM8");
125 return -1;
126 }
127 }
128 if (!strcmp(id, "PROP") && !memcmp(streambuf->readp + 12, "SND ", 4)) {
129 consume = 16; // read into
130 }
131 if (!strcmp(id, "FVER")) {
132 LOG_INFO("DSDIFF version: %u.%u.%u.%u", *(streambuf->readp + 12), *(streambuf->readp + 13),
133 *(streambuf->readp + 14), *(streambuf->readp + 15));
134 }
135 if (!strcmp(id, "FS ")) {
136 d->sample_rate = unpackN((void *)(streambuf->readp + 12));
137 LOG_INFO("sample rate: %u", d->sample_rate);
138 }
139 if (!strcmp(id, "CHNL")) {
140 d->channels = unpackn((void *)(streambuf->readp + 12));
141 LOG_INFO("channels: %u", d->channels);
142 }
143 if (!strcmp(id, "DSD ")) {
144 LOG_INFO("found dsd len: " FMT_u64, len);
145 d->sample_bytes = len;
146 _buf_inc_readp(streambuf, 12);
147 bytes -= 12;
148 return 1; // got to the audio
149 }
150 }
151
152 if (d->type == DSF) {
153 if (!strcmp(id, "fmt ")) {
154 if (bytes >= len && bytes >= 52) {
155 u32_t version = unpack32le((void *)(streambuf->readp + 12));
156 u32_t format = unpack32le((void *)(streambuf->readp + 16));
157 LOG_INFO("DSF version: %u format: %u", version, format);
158 if (format != 0) {
159 LOG_WARN("only support DSD raw format");
160 return -1;
161 }
162 d->channels = unpack32le((void *)(streambuf->readp + 24));
163 d->sample_rate = unpack32le((void *)(streambuf->readp + 28));
164 d->lsb_first = (unpack32le((void *)(streambuf->readp + 32)) == 1);
165 d->sample_bytes = unpack64le((void *)(streambuf->readp + 36)) / 8;
166 d->block_size = unpack32le((void *)(streambuf->readp + 44));
167 LOG_INFO("channels: %u", d->channels);
168 LOG_INFO("sample rate: %u", d->sample_rate);
169 LOG_INFO("lsb first: %u", d->lsb_first);
170 LOG_INFO("sample bytes: " FMT_u64, d->sample_bytes);
171 LOG_INFO("block size: %u", d->block_size);
172 } else {
173 consume = -1; // come back later
174 }
175 }
176 if (!strcmp(id, "data")) {
177 LOG_INFO("found dsd len: " FMT_u64, len);
178 _buf_inc_readp(streambuf, 12);
179 bytes -= 12;
180 return 1; // got to the audio
181 }
182 }
183
184 // default to consuming whole chunk
185 if (!consume) {
186 consume = (s32_t)((d->type == DSDIFF) ? len + 12 : len);
187 }
188
189 if (bytes >= consume) {
190 LOG_DEBUG("id: %s len: " FMT_u64 " consume: %d", id, len, consume);
191 _buf_inc_readp(streambuf, consume);
192 bytes -= consume;
193 } else if (consume > 0) {
194 LOG_DEBUG("id: %s len: " FMT_u64 " consume: %d - partial consume: %u", id, len, consume, bytes);
195 _buf_inc_readp(streambuf, bytes);
196 d->consume = consume - bytes;
197 break;
198 } else {
199 break;
200 }
201 }
202
203 return 0;
204 }
205
206 static decode_state _decode_dsf(void) {
207
208 // samples in streambuf are interleaved on block basis
209 // we transfer whole blocks for all channels in one call and so itterate the while loop below to handle wraps
210
211 unsigned bytes = _buf_used(streambuf);
212 unsigned block_left = d->block_size;
213
214 unsigned bytes_per_frame = dop ? 2 : 1;
215
216 if (bytes < d->block_size * d->channels) {
217 LOG_INFO("stream too short"); // this can occur when scanning the track
218 return DECODE_COMPLETE;
219 }
220
221 IF_PROCESS(
222 process.in_frames = 0;
223 );
224
225 while (block_left) {
226
227 frames_t frames, out, count;
228 unsigned bytes_read;
229
230 u8_t *iptrl = (u8_t *)streambuf->readp;
231 u8_t *iptrr = (u8_t *)streambuf->readp + d->block_size;
232 u32_t *optr;
233
234 if (iptrr >= streambuf->wrap) {
235 iptrr -= streambuf->size;
236 }
237
238 bytes = min(block_left, min(streambuf->wrap - iptrl, streambuf->wrap - iptrr));
239
240 IF_DIRECT(
241 out = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
242 optr = (u32_t *)outputbuf->writep;
243 );
244 IF_PROCESS(
245 out = process.max_in_frames - process.in_frames;
246 optr = (u32_t *)(process.inbuf + process.in_frames * BYTES_PER_FRAME);
247 );
248
249 frames = min(bytes, d->sample_bytes) / bytes_per_frame;
250 if (frames == 0) {
251 if (dop && d->sample_bytes == 1 && bytes >= 2) {
252 // 1 byte left add a byte of silence and play
253 *(iptrl + 1) = *(iptrr + 1) = 0x69;
254 frames = 1;
255 } else {
256 // should not get here due to wrapping m/2 for dop should never result in 0 as header len is always even
257 LOG_INFO("frames got to zero");
258 return DECODE_COMPLETE;
259 }
260 }
261
262 frames = min(frames, out);
263 frames = min(frames, BLOCK);
264 bytes_read = frames * bytes_per_frame;
265
266 count = frames;
267
268 if (dop) {
269
270 if (d->channels == 1) {
271 if (d->lsb_first) {
272 while (count--) {
273 *(optr++) = dsd2pcm_bitreverse[*(iptrl)] << 16 | dsd2pcm_bitreverse[*(iptrl+1)] << 8;
274 *(optr++) = dsd2pcm_bitreverse[*(iptrl)] << 16 | dsd2pcm_bitreverse[*(iptrl+1)] << 8;
275 iptrl += 2;
276 }
277 } else {
278 while (count--) {
279 *(optr++) = *(iptrl) << 16 | *(iptrl+1) << 8;
280 *(optr++) = *(iptrl) << 16 | *(iptrl+1) << 8;
281 iptrl += 2;
282 }
283 }
284 } else {
285 if (d->lsb_first) {
286 while (count--) {
287 *(optr++) = dsd2pcm_bitreverse[*(iptrl)] << 16 | dsd2pcm_bitreverse[*(iptrl+1)] << 8;
288 *(optr++) = dsd2pcm_bitreverse[*(iptrr)] << 16 | dsd2pcm_bitreverse[*(iptrr+1)] << 8;
289 iptrl += 2;
290 iptrr += 2;
291 }
292 } else {
293 while (count--) {
294 *(optr++) = *(iptrl) << 16 | *(iptrl+1) << 8;
295 *(optr++) = *(iptrr) << 16 | *(iptrr+1) << 8;
296 iptrl += 2;
297 iptrr += 2;
298 }
299 }
300 }
301
302 } else {
303
304 if (d->channels == 1) {
305 float *iptrf = d->transfer[0];
306 dsd2pcm_translate(d->dsd2pcm_ctx[0], frames, iptrl, 1, d->lsb_first, iptrf, 1);
307 while (count--) {
308 double scaled = *iptrf++ * 0x7fffffff;
309 if (scaled > 2147483647.0) scaled = 2147483647.0;
310 if (scaled < -2147483648.0) scaled = -2147483648.0;
311 *optr++ = (s32_t)scaled;
312 *optr++ = (s32_t)scaled;
313 }
314 } else {
315 float *iptrfl = d->transfer[0];
316 float *iptrfr = d->transfer[1];
317 dsd2pcm_translate(d->dsd2pcm_ctx[0], frames, iptrl, 1, d->lsb_first, iptrfl, 1);
318 dsd2pcm_translate(d->dsd2pcm_ctx[1], frames, iptrr, 1, d->lsb_first, iptrfr, 1);
319 while (count--) {
320 double scaledl = *iptrfl++ * 0x7fffffff;
321 double scaledr = *iptrfr++ * 0x7fffffff;
322 if (scaledl > 2147483647.0) scaledl = 2147483647.0;
323 if (scaledl < -2147483648.0) scaledl = -2147483648.0;
324 if (scaledr > 2147483647.0) scaledr = 2147483647.0;
325 if (scaledr < -2147483648.0) scaledr = -2147483648.0;
326 *optr++ = (s32_t)scaledl;
327 *optr++ = (s32_t)scaledr;
328 }
329 }
330
331 }
332
333 _buf_inc_readp(streambuf, bytes_read);
334
335 block_left -= bytes_read;
336
337 if (d->sample_bytes > bytes_read) {
338 d->sample_bytes -= bytes_read;
339 } else {
340 LOG_INFO("end of track samples");
341 block_left = 0;
342 d->sample_bytes = 0;
343 }
344
345 IF_DIRECT(
346 _buf_inc_writep(outputbuf, frames * BYTES_PER_FRAME);
347 );
348 IF_PROCESS(
349 process.in_frames += frames;
350 );
351
352 LOG_SDEBUG("write %u frames", frames);
353 }
354
355 // skip the other channel blocks
356 // the right channel has already been read and is guarenteed to be in streambuf so can be skipped immediately
357 if (d->channels > 1) {
358 _buf_inc_readp(streambuf, d->block_size);
359 }
360 if (d->channels > 2) {
361 d->consume = d->block_size * (d->channels - 2);
362 }
363
364 return DECODE_RUNNING;
365 }
366
367 static decode_state _decode_dsdiff(void) {
368
369 // samples in streambuf are interleaved on byte per channel
370 // we process as little as necessary per call and only need to handle frames wrapping round streambuf
371
372 unsigned bytes_per_frame, bytes_read;
373 frames_t out, frames, count;
374 u8_t *iptr;
375 u32_t *optr;
376 u8_t tmp[WRAP_BUF_SIZE];
377
378 unsigned bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
379
380 IF_DIRECT(
381 out = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
382 );
383 IF_PROCESS(
384 out = process.max_in_frames;
385 );
386
387 if (dop) {
388 bytes_per_frame = d->channels * 2;
389 } else {
390 bytes_per_frame = d->channels;
391 out = min(out, BLOCK);
392 }
393
394 frames = min(min(bytes, d->sample_bytes) / bytes_per_frame, out);
395 bytes_read = frames * bytes_per_frame;
396
397 iptr = (u8_t *)streambuf->readp;
398
399 IF_DIRECT(
400 optr = (u32_t *)outputbuf->writep;
401 );
402 IF_PROCESS(
403 optr = (u32_t *)process.inbuf;
404 );
405
406 // handle wrap around end of streambuf and partial dop frame at end of stream
407 if (!frames && bytes < bytes_per_frame) {
408 memset(tmp, 0x69, WRAP_BUF_SIZE); // 0x69 = dsd silence
409 memcpy(tmp, streambuf->readp, bytes);
410 if (_buf_used(streambuf) > bytes_per_frame) {
411 memcpy(tmp + bytes, streambuf->buf, bytes_per_frame - bytes);
412 bytes_read = bytes_per_frame;
413 } else {
414 bytes_read = bytes;
415 }
416 iptr = tmp;
417 frames = 1;
418 }
419
420 count = frames;
421
422 if (dop) {
423
424 if (d->channels == 1) {
425 while (count--) {
426 *(optr++) = *(iptr) << 16 | *(iptr+1) << 8;
427 *(optr++) = *(iptr) << 16 | *(iptr+1) << 8;
428 iptr += bytes_per_frame;
429 }
430 } else {
431 while (count--) {
432 *(optr++) = *(iptr ) << 16 | *(iptr + d->channels) << 8;
433 *(optr++) = *(iptr+1) << 16 | *(iptr + d->channels + 1) << 8;
434 iptr += bytes_per_frame;
435 }
436 }
437
438 } else {
439
440 if (d->channels == 1) {
441 float *iptrf = d->transfer[0];
442 dsd2pcm_translate(d->dsd2pcm_ctx[0], frames, iptr, 1, 0, iptrf, 1);
443 while (count--) {
444 double scaled = *iptrf++ * 0x7fffffff;
445 if (scaled > 2147483647.0) scaled = 2147483647.0;
446 if (scaled < -2147483648.0) scaled = -2147483648.0;
447 *optr++ = (s32_t)scaled;
448 *optr++ = (s32_t)scaled;
449 }
450 } else {
451 float *iptrfl = d->transfer[0];
452 float *iptrfr = d->transfer[1];
453 dsd2pcm_translate(d->dsd2pcm_ctx[0], frames, iptr, d->channels, 0, iptrfl, 1);
454 dsd2pcm_translate(d->dsd2pcm_ctx[1], frames, iptr + 1, d->channels, 0, iptrfr, 1);
455 while (count--) {
456 double scaledl = *iptrfl++ * 0x7fffffff;
457 double scaledr = *iptrfr++ * 0x7fffffff;
458 if (scaledl > 2147483647.0) scaledl = 2147483647.0;
459 if (scaledl < -2147483648.0) scaledl = -2147483648.0;
460 if (scaledr > 2147483647.0) scaledr = 2147483647.0;
461 if (scaledr < -2147483648.0) scaledr = -2147483648.0;
462 *optr++ = (s32_t)scaledl;
463 *optr++ = (s32_t)scaledr;
464 }
465 }
466
467 }
468
469 _buf_inc_readp(streambuf, bytes_read);
470
471 if (d->sample_bytes > bytes_read) {
472 d->sample_bytes -= bytes_read;
473 } else {
474 LOG_INFO("end of track samples");
475 d->sample_bytes = 0;
476 }
477
478 IF_DIRECT(
479 _buf_inc_writep(outputbuf, frames * BYTES_PER_FRAME);
480 );
481 IF_PROCESS(
482 process.in_frames = frames;
483 );
484
485 LOG_SDEBUG("write %u frames", frames);
486
487 return DECODE_RUNNING;
488 }
489
490
491 static decode_state dsd_decode(void) {
492 decode_state ret;
493
494 LOCK_S;
495
496 if ((stream.state <= DISCONNECT && !_buf_used(streambuf)) || (!decode.new_stream && d->sample_bytes == 0)) {
497 UNLOCK_S;
498 return DECODE_COMPLETE;
499 }
500
501 if (d->consume) {
502 unsigned consume = min(d->consume, min(_buf_used(streambuf), _buf_cont_read(streambuf)));
503 LOG_DEBUG("consume: %u of %u", consume, d->consume);
504 _buf_inc_readp(streambuf, consume);
505 d->consume -= consume;
506 if (d->consume) {
507 UNLOCK_S;
508 return DECODE_RUNNING;
509 }
510 }
511
512 if (decode.new_stream) {
513 int r = _read_header();
514 if (r < 1) {
515 UNLOCK_S;
516 return DECODE_ERROR;
517 }
518 if (r == 0) {
519 UNLOCK_S;
520 return DECODE_RUNNING;
521 }
522 // otherwise got to start of audio
523
524 LOCK_O;
525
526 LOG_INFO("setting track_start");
527 output.track_start = outputbuf->writep;
528
529 dop = output.has_dop;
530
531 if (dop && d->sample_rate / 16 > output.supported_rates[0]) {
532 LOG_INFO("DOP sample rate too high for device - converting to PCM");
533 dop = false;
534 }
535
536 if (dop) {
537 LOG_INFO("DOP output");
538 output.next_dop = true;
539 output.next_sample_rate = d->sample_rate / 16;
540 output.fade = FADE_INACTIVE;
541 } else {
542 LOG_INFO("DSD to PCM output");
543 output.next_dop = false;
544 output.next_sample_rate = decode_newstream(d->sample_rate / 8, output.supported_rates);
545 if (output.fade_mode) _checkfade(true);
546 }
547
548 decode.new_stream = false;
549
550 UNLOCK_O;
551 }
552
553 LOCK_O_direct;
554
555 switch (d->type) {
556 case DSF:
557 ret = _decode_dsf();
558 break;
559 case DSDIFF:
560 ret = _decode_dsdiff();
561 break;
562 default:
563 ret = DECODE_ERROR;
564 }
565
566 UNLOCK_O_direct;
567 UNLOCK_S;
568
569 return ret;
570 }
571
572 static void dsd_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
573 d->type = UNKNOWN;
574
575 if (!d->dsd2pcm_ctx[0]) {
576 d->dsd2pcm_ctx[0] = dsd2pcm_init();
577 d->dsd2pcm_ctx[1] = dsd2pcm_init();
578 } else {
579 dsd2pcm_reset(d->dsd2pcm_ctx[0]);
580 dsd2pcm_reset(d->dsd2pcm_ctx[1]);
581 }
582 if (!d->transfer[1]) {
583 d->transfer[0] = malloc(sizeof(float) * BLOCK);
584 d->transfer[1] = malloc(sizeof(float) * BLOCK);
585 }
586 }
587
588 static void dsd_close(void) {
589 if (d->dsd2pcm_ctx[0]) {
590 dsd2pcm_destroy(d->dsd2pcm_ctx[0]);
591 dsd2pcm_destroy(d->dsd2pcm_ctx[1]);
592 d->dsd2pcm_ctx[0] = NULL;
593 d->dsd2pcm_ctx[1] = NULL;
594 }
595 if (d->transfer[0]) {
596 free(d->transfer[0]);
597 free(d->transfer[1]);
598 d->transfer[0] = NULL;
599 d->transfer[1] = NULL;
600 }
601 }
602
603 struct codec *register_dsd(void) {
604 static struct codec ret = {
605 'd', // id
606 "dsf,dff", // types
607 BLOCK * 2, // min read
608 BLOCK_FRAMES,// min space
609 dsd_open, // open
610 dsd_close, // close
611 dsd_decode, // decode
612 };
613
614 d = malloc(sizeof(struct dsd));
615 if (!d) {
616 return NULL;
617 }
618
619 memset(d, 0, sizeof(struct dsd));
620
621 dsd2pcm_precalc();
622
623 LOG_INFO("using dsd to decode dsf,dff");
624 return &ret;
625 }
626
627 #endif // DSD
0 Copyright 2009, 2011 Sebastian Gesemann. All rights reserved.
1
2 Redistribution and use in source and binary forms, with or without modification, are
3 permitted provided that the following conditions are met:
4
5 1. Redistributions of source code must retain the above copyright notice, this list of
6 conditions and the following disclaimer.
7
8 2. Redistributions in binary form must reproduce the above copyright notice, this list
9 of conditions and the following disclaimer in the documentation and/or other materials
10 provided with the distribution.
11
12 THIS SOFTWARE IS PROVIDED BY SEBASTIAN GESEMANN ''AS IS'' AND ANY EXPRESS OR IMPLIED
13 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
14 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEBASTIAN GESEMANN OR
15 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
16 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
19 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
20 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
22 The views and conclusions contained in the software and documentation are those of the
23 authors and should not be interpreted as representing official policies, either expressed
24 or implied, of Sebastian Gesemann.
0 /*
1
2 Copyright 2009, 2011 Sebastian Gesemann. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without modification, are
5 permitted provided that the following conditions are met:
6
7 1. Redistributions of source code must retain the above copyright notice, this list of
8 conditions and the following disclaimer.
9
10 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 of conditions and the following disclaimer in the documentation and/or other materials
12 provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY SEBASTIAN GESEMANN ''AS IS'' AND ANY EXPRESS OR IMPLIED
15 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEBASTIAN GESEMANN OR
17 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24 The views and conclusions contained in the software and documentation are those of the
25 authors and should not be interpreted as representing official policies, either expressed
26 or implied, of Sebastian Gesemann.
27
28 ----
29
30 Additions (c) Adrian Smith, 2013 under same licence terms:
31 - expose bitreverse array as dsd2pcm_bitreverse
32 - expose precalc function as dsd2pcm_precalc to allow it to be initalised
33
34 */
35
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include "dsd2pcm.h"
40
41 #define HTAPS 48 /* number of FIR constants */
42 #define FIFOSIZE 16 /* must be a power of two */
43 #define FIFOMASK (FIFOSIZE-1) /* bit mask for FIFO offsets */
44 #define CTABLES ((HTAPS+7)/8) /* number of "8 MACs" lookup tables */
45
46 #if FIFOSIZE*8 < HTAPS*2
47 #error "FIFOSIZE too small"
48 #endif
49
50 /*
51 * Properties of this 96-tap lowpass filter when applied on a signal
52 * with sampling rate of 44100*64 Hz:
53 *
54 * () has a delay of 17 microseconds.
55 *
56 * () flat response up to 48 kHz
57 *
58 * () if you downsample afterwards by a factor of 8, the
59 * spectrum below 70 kHz is practically alias-free.
60 *
61 * () stopband rejection is about 160 dB
62 *
63 * The coefficient tables ("ctables") take only 6 Kibi Bytes and
64 * should fit into a modern processor's fast cache.
65 */
66
67 /*
68 * The 2nd half (48 coeffs) of a 96-tap symmetric lowpass filter
69 */
70 static const double htaps[HTAPS] = {
71 0.09950731974056658,
72 0.09562845727714668,
73 0.08819647126516944,
74 0.07782552527068175,
75 0.06534876523171299,
76 0.05172629311427257,
77 0.0379429484910187,
78 0.02490921351762261,
79 0.0133774746265897,
80 0.003883043418804416,
81 -0.003284703416210726,
82 -0.008080250212687497,
83 -0.01067241812471033,
84 -0.01139427235000863,
85 -0.0106813877974587,
86 -0.009007905078766049,
87 -0.006828859761015335,
88 -0.004535184322001496,
89 -0.002425035959059578,
90 -0.0006922187080790708,
91 0.0005700762133516592,
92 0.001353838005269448,
93 0.001713709169690937,
94 0.001742046839472948,
95 0.001545601648013235,
96 0.001226696225277855,
97 0.0008704322683580222,
98 0.0005381636200535649,
99 0.000266446345425276,
100 7.002968738383528e-05,
101 -5.279407053811266e-05,
102 -0.0001140625650874684,
103 -0.0001304796361231895,
104 -0.0001189970287491285,
105 -9.396247155265073e-05,
106 -6.577634378272832e-05,
107 -4.07492895872535e-05,
108 -2.17407957554587e-05,
109 -9.163058931391722e-06,
110 -2.017460145032201e-06,
111 1.249721855219005e-06,
112 2.166655190537392e-06,
113 1.930520892991082e-06,
114 1.319400334374195e-06,
115 7.410039764949091e-07,
116 3.423230509967409e-07,
117 1.244182214744588e-07,
118 3.130441005359396e-08
119 };
120
121 static float ctables[CTABLES][256];
122 unsigned char dsd2pcm_bitreverse[256];
123 static int precalculated = 0;
124
125 void dsd2pcm_precalc(void)
126 {
127 int t, e, m, k;
128 double acc;
129 if (precalculated) return;
130 for (t=0, e=0; t<256; ++t) {
131 dsd2pcm_bitreverse[t] = e;
132 for (m=128; m && !((e^=m)&m); m>>=1)
133 ;
134 }
135 for (t=0; t<CTABLES; ++t) {
136 k = HTAPS - t*8;
137 if (k>8) k=8;
138 for (e=0; e<256; ++e) {
139 acc = 0.0;
140 for (m=0; m<k; ++m) {
141 acc += (((e >> (7-m)) & 1)*2-1) * htaps[t*8+m];
142 }
143 ctables[CTABLES-1-t][e] = (float)acc;
144 }
145 }
146 precalculated = 1;
147 }
148
149 struct dsd2pcm_ctx_s
150 {
151 unsigned char fifo[FIFOSIZE];
152 unsigned fifopos;
153 };
154
155 extern dsd2pcm_ctx* dsd2pcm_init()
156 {
157 dsd2pcm_ctx* ptr;
158 if (!precalculated) dsd2pcm_precalc();
159 ptr = (dsd2pcm_ctx*) malloc(sizeof(dsd2pcm_ctx));
160 if (ptr) dsd2pcm_reset(ptr);
161 return ptr;
162 }
163
164 extern void dsd2pcm_destroy(dsd2pcm_ctx* ptr)
165 {
166 free(ptr);
167 }
168
169 extern dsd2pcm_ctx* dsd2pcm_clone(dsd2pcm_ctx* ptr)
170 {
171 dsd2pcm_ctx* p2;
172 p2 = (dsd2pcm_ctx*) malloc(sizeof(dsd2pcm_ctx));
173 if (p2) {
174 memcpy(p2,ptr,sizeof(dsd2pcm_ctx));
175 }
176 return p2;
177 }
178
179 extern void dsd2pcm_reset(dsd2pcm_ctx* ptr)
180 {
181 int i;
182 for (i=0; i<FIFOSIZE; ++i)
183 ptr->fifo[i] = 0x69; /* my favorite silence pattern */
184 ptr->fifopos = 0;
185 /* 0x69 = 01101001
186 * This pattern "on repeat" makes a low energy 352.8 kHz tone
187 * and a high energy 1.0584 MHz tone which should be filtered
188 * out completely by any playback system --> silence
189 */
190 }
191
192 extern void dsd2pcm_translate(
193 dsd2pcm_ctx* ptr,
194 size_t samples,
195 const unsigned char *src, ptrdiff_t src_stride,
196 int lsbf,
197 float *dst, ptrdiff_t dst_stride)
198 {
199 unsigned ffp;
200 unsigned i;
201 unsigned bite1, bite2;
202 unsigned char* p;
203 double acc;
204 ffp = ptr->fifopos;
205 lsbf = lsbf ? 1 : 0;
206 while (samples-- > 0) {
207 bite1 = *src & 0xFFu;
208 if (lsbf) bite1 = dsd2pcm_bitreverse[bite1];
209 ptr->fifo[ffp] = bite1; src += src_stride;
210 p = ptr->fifo + ((ffp-CTABLES) & FIFOMASK);
211 *p = dsd2pcm_bitreverse[*p & 0xFF];
212 acc = 0;
213 for (i=0; i<CTABLES; ++i) {
214 bite1 = ptr->fifo[(ffp -i) & FIFOMASK] & 0xFF;
215 bite2 = ptr->fifo[(ffp-(CTABLES*2-1)+i) & FIFOMASK] & 0xFF;
216 acc += ctables[i][bite1] + ctables[i][bite2];
217 }
218 *dst = (float)acc; dst += dst_stride;
219 ffp = (ffp + 1) & FIFOMASK;
220 }
221 ptr->fifopos = ffp;
222 }
223
0 /*
1
2 Copyright 2009, 2011 Sebastian Gesemann. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without modification, are
5 permitted provided that the following conditions are met:
6
7 1. Redistributions of source code must retain the above copyright notice, this list of
8 conditions and the following disclaimer.
9
10 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 of conditions and the following disclaimer in the documentation and/or other materials
12 provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY SEBASTIAN GESEMANN ''AS IS'' AND ANY EXPRESS OR IMPLIED
15 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEBASTIAN GESEMANN OR
17 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24 The views and conclusions contained in the software and documentation are those of the
25 authors and should not be interpreted as representing official policies, either expressed
26 or implied, of Sebastian Gesemann.
27
28 ----
29
30 Marked additions (c) Adrian Smith, 2013 under same licence terms
31
32 */
33
34 #ifndef DSD2PCM_H_INCLUDED
35 #define DSD2PCM_H_INCLUDED
36
37 #include <stddef.h>
38 #include <string.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 struct dsd2pcm_ctx_s;
45
46 typedef struct dsd2pcm_ctx_s dsd2pcm_ctx;
47
48 /**
49 * initializes a "dsd2pcm engine" for one channel
50 * (precomputes tables and allocates memory)
51 *
52 * This is the only function that is not thread-safe in terms of the
53 * POSIX thread-safety definition because it modifies global state
54 * (lookup tables are computed during the first call)
55 */
56 extern dsd2pcm_ctx* dsd2pcm_init(void);
57
58 /**
59 * deinitializes a "dsd2pcm engine"
60 * (releases memory, don't forget!)
61 */
62 extern void dsd2pcm_destroy(dsd2pcm_ctx *ctx);
63
64 /**
65 * clones the context and returns a pointer to the
66 * newly allocated copy
67 */
68 extern dsd2pcm_ctx* dsd2pcm_clone(dsd2pcm_ctx *ctx);
69
70 /**
71 * resets the internal state for a fresh new stream
72 */
73 extern void dsd2pcm_reset(dsd2pcm_ctx *ctx);
74
75 /**
76 * "translates" a stream of octets to a stream of floats
77 * (8:1 decimation)
78 * @param ctx -- pointer to abstract context (buffers)
79 * @param samples -- number of octets/samples to "translate"
80 * @param src -- pointer to first octet (input)
81 * @param src_stride -- src pointer increment
82 * @param lsbitfirst -- bitorder, 0=msb first, 1=lsbfirst
83 * @param dst -- pointer to first float (output)
84 * @param dst_stride -- dst pointer increment
85 */
86 extern void dsd2pcm_translate(dsd2pcm_ctx *ctx,
87 size_t samples,
88 const unsigned char *src, ptrdiff_t src_stride,
89 int lsbitfirst,
90 float *dst, ptrdiff_t dst_stride);
91
92 /**
93 * Additions by Adrian Smith (c) 2013 for Squeezelite
94 */
95 extern unsigned char dsd2pcm_bitreverse[];
96
97 extern void dsd2pcm_precalc(void);
98 /**
99 * End of addition
100 */
101
102 #ifdef __cplusplus
103 } /* extern "C" */
104 #endif
105
106 #endif /* include guard DSD2PCM_H_INCLUDED */
107
0 /*
1 * Squeezelite - lightweight headless squeezebox emulator
2 *
3 * (c) Adrian Smith 2012-2015, triode1@btinternet.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 #include "squeezelite.h"
21
22 #include <neaacdec.h>
23
24 #define WRAPBUF_LEN 2048
25
26 struct chunk_table {
27 u32_t sample, offset;
28 };
29
30 struct faad {
31 NeAACDecHandle hAac;
32 u8_t type;
33 // following used for mp4 only
34 u32_t consume;
35 u32_t pos;
36 u32_t sample;
37 u32_t nextchunk;
38 void *stsc;
39 u32_t skip;
40 u64_t samples;
41 u64_t sttssamples;
42 bool empty;
43 struct chunk_table *chunkinfo;
44 // faad symbols to be dynamically loaded
45 #if !LINKALL
46 NeAACDecConfigurationPtr (* NeAACDecGetCurrentConfiguration)(NeAACDecHandle);
47 unsigned char (* NeAACDecSetConfiguration)(NeAACDecHandle, NeAACDecConfigurationPtr);
48 NeAACDecHandle (* NeAACDecOpen)(void);
49 void (* NeAACDecClose)(NeAACDecHandle);
50 long (* NeAACDecInit)(NeAACDecHandle, unsigned char *, unsigned long, unsigned long *, unsigned char *);
51 char (* NeAACDecInit2)(NeAACDecHandle, unsigned char *pBuffer, unsigned long, unsigned long *, unsigned char *);
52 void *(* NeAACDecDecode)(NeAACDecHandle, NeAACDecFrameInfo *, unsigned char *, unsigned long);
53 char *(* NeAACDecGetErrorMessage)(unsigned char);
54 #endif
55 };
56
57 static struct faad *a;
58
59 extern log_level loglevel;
60
61 extern struct buffer *streambuf;
62 extern struct buffer *outputbuf;
63 extern struct streamstate stream;
64 extern struct outputstate output;
65 extern struct decodestate decode;
66 extern struct processstate process;
67
68 #define LOCK_S mutex_lock(streambuf->mutex)
69 #define UNLOCK_S mutex_unlock(streambuf->mutex)
70 #define LOCK_O mutex_lock(outputbuf->mutex)
71 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
72 #if PROCESS
73 #define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
74 #define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
75 #define IF_DIRECT(x) if (decode.direct) { x }
76 #define IF_PROCESS(x) if (!decode.direct) { x }
77 #else
78 #define LOCK_O_direct mutex_lock(outputbuf->mutex)
79 #define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
80 #define IF_DIRECT(x) { x }
81 #define IF_PROCESS(x)
82 #endif
83
84 #if LINKALL
85 #define NEAAC(h, fn, ...) (NeAACDec ## fn)(__VA_ARGS__)
86 #else
87 #define NEAAC(h, fn, ...) (h)->NeAACDec##fn(__VA_ARGS__)
88 #endif
89
90 // minimal code for mp4 file parsing to extract audio config and find media data
91
92 // adapted from faad2/common/mp4ff
93 u32_t mp4_desc_length(u8_t **buf) {
94 u8_t b;
95 u8_t num_bytes = 0;
96 u32_t length = 0;
97
98 do {
99 b = **buf;
100 *buf += 1;
101 num_bytes++;
102 length = (length << 7) | (b & 0x7f);
103 } while ((b & 0x80) && num_bytes < 4);
104
105 return length;
106 }
107
108 // read mp4 header to extract config data
109 static int read_mp4_header(unsigned long *samplerate_p, unsigned char *channels_p) {
110 size_t bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
111 char type[5];
112 u32_t len;
113
114 while (bytes >= 8) {
115 // count trak to find the first playable one
116 static unsigned trak, play;
117 u32_t consume;
118
119 len = unpackN((u32_t *)streambuf->readp);
120 memcpy(type, streambuf->readp + 4, 4);
121 type[4] = '\0';
122
123 if (!strcmp(type, "moov")) {
124 trak = 0;
125 play = 0;
126 }
127 if (!strcmp(type, "trak")) {
128 trak++;
129 }
130
131 // extract audio config from within esds and pass to DecInit2
132 if (!strcmp(type, "esds") && bytes > len) {
133 unsigned config_len;
134 u8_t *ptr = streambuf->readp + 12;
135 if (*ptr++ == 0x03) {
136 mp4_desc_length(&ptr);
137 ptr += 4;
138 } else {
139 ptr += 3;
140 }
141 mp4_desc_length(&ptr);
142 ptr += 13;
143 if (*ptr++ != 0x05) {
144 LOG_WARN("error parsing esds");
145 return -1;
146 }
147 config_len = mp4_desc_length(&ptr);
148 if (NEAAC(a, Init2, a->hAac, ptr, config_len, samplerate_p, channels_p) == 0) {
149 LOG_DEBUG("playable aac track: %u", trak);
150 play = trak;
151 }
152 }
153
154 // extract the total number of samples from stts
155 if (!strcmp(type, "stts") && bytes > len) {
156 u32_t i;
157 u8_t *ptr = streambuf->readp + 12;
158 u32_t entries = unpackN((u32_t *)ptr);
159 ptr += 4;
160 for (i = 0; i < entries; ++i) {
161 u32_t count = unpackN((u32_t *)ptr);
162 u32_t size = unpackN((u32_t *)(ptr + 4));
163 a->sttssamples += count * size;
164 ptr += 8;
165 }
166 LOG_DEBUG("total number of samples contained in stts: " FMT_u64, a->sttssamples);
167 }
168
169 // stash sample to chunk info, assume it comes before stco
170 if (!strcmp(type, "stsc") && bytes > len && !a->chunkinfo) {
171 a->stsc = malloc(len - 12);
172 if (a->stsc == NULL) {
173 LOG_WARN("malloc fail");
174 return -1;
175 }
176 memcpy(a->stsc, streambuf->readp + 12, len - 12);
177 }
178
179 // build offsets table from stco and stored stsc
180 if (!strcmp(type, "stco") && bytes > len && play == trak) {
181 u32_t i;
182 // extract chunk offsets
183 u8_t *ptr = streambuf->readp + 12;
184 u32_t entries = unpackN((u32_t *)ptr);
185 ptr += 4;
186 a->chunkinfo = malloc(sizeof(struct chunk_table) * (entries + 1));
187 if (a->chunkinfo == NULL) {
188 LOG_WARN("malloc fail");
189 return -1;
190 }
191 for (i = 0; i < entries; ++i) {
192 a->chunkinfo[i].offset = unpackN((u32_t *)ptr);
193 a->chunkinfo[i].sample = 0;
194 ptr += 4;
195 }
196 a->chunkinfo[i].sample = 0;
197 a->chunkinfo[i].offset = 0;
198 // fill in first sample id for each chunk from stored stsc
199 if (a->stsc) {
200 u32_t stsc_entries = unpackN((u32_t *)a->stsc);
201 u32_t sample = 0;
202 u32_t last = 0, last_samples = 0;
203 u8_t *ptr = (u8_t *)a->stsc + 4;
204 while (stsc_entries--) {
205 u32_t first = unpackN((u32_t *)ptr);
206 u32_t samples = unpackN((u32_t *)(ptr + 4));
207 if (last) {
208 for (i = last - 1; i < first - 1; ++i) {
209 a->chunkinfo[i].sample = sample;
210 sample += last_samples;
211 }
212 }
213 if (stsc_entries == 0) {
214 for (i = first - 1; i < entries; ++i) {
215 a->chunkinfo[i].sample = sample;
216 sample += samples;
217 }
218 }
219 last = first;
220 last_samples = samples;
221 ptr += 12;
222 }
223 free(a->stsc);
224 a->stsc = NULL;
225 }
226 }
227
228 // found media data, advance to start of first chunk and return
229 if (!strcmp(type, "mdat")) {
230 _buf_inc_readp(streambuf, 8);
231 a->pos += 8;
232 bytes -= 8;
233 if (play) {
234 LOG_DEBUG("type: mdat len: %u pos: %u", len, a->pos);
235 if (a->chunkinfo && a->chunkinfo[0].offset > a->pos) {
236 u32_t skip = a->chunkinfo[0].offset - a->pos;
237 LOG_DEBUG("skipping: %u", skip);
238 if (skip <= bytes) {
239 _buf_inc_readp(streambuf, skip);
240 a->pos += skip;
241 } else {
242 a->consume = skip;
243 }
244 }
245 a->sample = a->nextchunk = 1;
246 return 1;
247 } else {
248 LOG_DEBUG("type: mdat len: %u, no playable track found", len);
249 return -1;
250 }
251 }
252
253 // parse key-value atoms within ilst ---- entries to get encoder padding within iTunSMPB entry for gapless
254 if (!strcmp(type, "----") && bytes > len) {
255 u8_t *ptr = streambuf->readp + 8;
256 u32_t remain = len - 8, size;
257 if (!memcmp(ptr + 4, "mean", 4) && (size = unpackN((u32_t *)ptr)) < remain) {
258 ptr += size; remain -= size;
259 }
260 if (!memcmp(ptr + 4, "name", 4) && (size = unpackN((u32_t *)ptr)) < remain && !memcmp(ptr + 12, "iTunSMPB", 8)) {
261 ptr += size; remain -= size;
262 }
263 if (!memcmp(ptr + 4, "data", 4) && remain > 16 + 48) {
264 // data is stored as hex strings: 0 start end samples
265 u32_t b, c; u64_t d;
266 if (sscanf((const char *)(ptr + 16), "%x %x %x " FMT_x64, &b, &b, &c, &d) == 4) {
267 LOG_DEBUG("iTunSMPB start: %u end: %u samples: " FMT_u64, b, c, d);
268 if (a->sttssamples && a->sttssamples < b + c + d) {
269 LOG_DEBUG("reducing samples as stts count is less");
270 d = a->sttssamples - (b + c);
271 }
272 a->skip = b;
273 a->samples = d;
274 }
275 }
276 }
277
278 // default to consuming entire box
279 consume = len;
280
281 // read into these boxes so reduce consume
282 if (!strcmp(type, "moov") || !strcmp(type, "trak") || !strcmp(type, "mdia") || !strcmp(type, "minf") || !strcmp(type, "stbl") ||
283 !strcmp(type, "udta") || !strcmp(type, "ilst")) {
284 consume = 8;
285 }
286 // special cases which mix mix data in the enclosing box which we want to read into
287 if (!strcmp(type, "stsd")) consume = 16;
288 if (!strcmp(type, "mp4a")) consume = 36;
289 if (!strcmp(type, "meta")) consume = 12;
290
291 // consume rest of box if it has been parsed (all in the buffer) or is not one we want to parse
292 if (bytes >= consume) {
293 LOG_DEBUG("type: %s len: %u consume: %u", type, len, consume);
294 _buf_inc_readp(streambuf, consume);
295 a->pos += consume;
296 bytes -= consume;
297 } else if ( !(!strcmp(type, "esds") || !strcmp(type, "stts") || !strcmp(type, "stsc") ||
298 !strcmp(type, "stco") || !strcmp(type, "----")) ) {
299 LOG_DEBUG("type: %s len: %u consume: %u - partial consume: %u", type, len, consume, bytes);
300 _buf_inc_readp(streambuf, bytes);
301 a->pos += bytes;
302 a->consume = consume - bytes;
303 break;
304 } else {
305 break;
306 }
307 }
308
309 return 0;
310 }
311
312 static decode_state faad_decode(void) {
313 size_t bytes_total;
314 size_t bytes_wrap;
315 NeAACDecFrameInfo info;
316 s32_t *iptr;
317 bool endstream;
318 frames_t frames;
319
320 LOCK_S;
321 bytes_total = _buf_used(streambuf);
322 bytes_wrap = min(bytes_total, _buf_cont_read(streambuf));
323
324 if (stream.state <= DISCONNECT && !bytes_total) {
325 UNLOCK_S;
326 return DECODE_COMPLETE;
327 }
328
329 if (a->consume) {
330 u32_t consume = min(a->consume, bytes_wrap);
331 LOG_DEBUG("consume: %u of %u", consume, a->consume);
332 _buf_inc_readp(streambuf, consume);
333 a->pos += consume;
334 a->consume -= consume;
335 UNLOCK_S;
336 return DECODE_RUNNING;
337 }
338
339 if (decode.new_stream) {
340 int found = 0;
341 static unsigned char channels;
342 static unsigned long samplerate;
343
344 if (a->type == '2') {
345
346 // adts stream - seek for header
347 while (bytes_wrap >= 2 && (*(streambuf->readp) != 0xFF || (*(streambuf->readp + 1) & 0xF6) != 0xF0)) {
348 _buf_inc_readp(streambuf, 1);
349 bytes_total--;
350 bytes_wrap--;
351 }
352
353 if (bytes_wrap >= 2) {
354 long n = NEAAC(a, Init, a->hAac, streambuf->readp, bytes_wrap, &samplerate, &channels);
355 if (n < 0) {
356 found = -1;
357 } else {
358 _buf_inc_readp(streambuf, n);
359 found = 1;
360 }
361 }
362
363 } else {
364
365 // mp4 - read header
366 found = read_mp4_header(&samplerate, &channels);
367 }
368
369 if (found == 1) {
370
371 LOG_INFO("samplerate: %u channels: %u", samplerate, channels);
372 bytes_total = _buf_used(streambuf);
373 bytes_wrap = min(bytes_total, _buf_cont_read(streambuf));
374
375 LOCK_O;
376 LOG_INFO("setting track_start");
377 output.next_sample_rate = decode_newstream(samplerate, output.supported_rates);
378 IF_DSD( output.next_dop = false; )
379 output.track_start = outputbuf->writep;
380 if (output.fade_mode) _checkfade(true);
381 decode.new_stream = false;
382 UNLOCK_O;
383
384 } else if (found == -1) {
385
386 LOG_WARN("error reading stream header");
387 UNLOCK_S;
388 return DECODE_ERROR;
389
390 } else {
391
392 // not finished header parsing come back next time
393 UNLOCK_S;
394 return DECODE_RUNNING;
395 }
396 }
397
398 if (bytes_wrap < WRAPBUF_LEN && bytes_total > WRAPBUF_LEN) {
399
400 // make a local copy of frames which may have wrapped round the end of streambuf
401 u8_t buf[WRAPBUF_LEN];
402 memcpy(buf, streambuf->readp, bytes_wrap);
403 memcpy(buf + bytes_wrap, streambuf->buf, WRAPBUF_LEN - bytes_wrap);
404
405 iptr = NEAAC(a, Decode, a->hAac, &info, buf, WRAPBUF_LEN);
406
407 } else {
408
409 iptr = NEAAC(a, Decode, a->hAac, &info, streambuf->readp, bytes_wrap);
410 }
411
412 if (info.error) {
413 LOG_WARN("error: %u %s", info.error, NEAAC(a, GetErrorMessage, info.error));
414 }
415
416 endstream = false;
417
418 // mp4 end of chunk - skip to next offset
419 if (a->chunkinfo && a->chunkinfo[a->nextchunk].offset && a->sample++ == a->chunkinfo[a->nextchunk].sample) {
420
421 if (a->chunkinfo[a->nextchunk].offset > a->pos) {
422 u32_t skip = a->chunkinfo[a->nextchunk].offset - a->pos;
423 if (skip != info.bytesconsumed) {
424 LOG_DEBUG("skipping to next chunk pos: %u consumed: %u != skip: %u", a->pos, info.bytesconsumed, skip);
425 }
426 if (bytes_total >= skip) {
427 _buf_inc_readp(streambuf, skip);
428 a->pos += skip;
429 } else {
430 a->consume = skip;
431 }
432 a->nextchunk++;
433 } else {
434 LOG_ERROR("error: need to skip backwards!");
435 endstream = true;
436 }
437
438 // adts and mp4 when not at end of chunk
439 } else if (info.bytesconsumed != 0) {
440
441 _buf_inc_readp(streambuf, info.bytesconsumed);
442 a->pos += info.bytesconsumed;
443
444 // error which doesn't advance streambuf - end
445 } else {
446 endstream = true;
447 }
448
449 UNLOCK_S;
450
451 if (endstream) {
452 LOG_WARN("unable to decode further");
453 return DECODE_ERROR;
454 }
455
456 if (!info.samples) {
457 a->empty = true;
458 return DECODE_RUNNING;
459 }
460
461 frames = info.samples / info.channels;
462
463 if (a->skip) {
464 u32_t skip;
465 if (a->empty) {
466 a->empty = false;
467 a->skip -= frames;
468 LOG_DEBUG("gapless: first frame empty, skipped %u frames at start", frames);
469 }
470 skip = min(frames, a->skip);
471 LOG_DEBUG("gapless: skipping %u frames at start", skip);
472 frames -= skip;
473 a->skip -= skip;
474 iptr += skip * info.channels;
475 }
476
477 if (a->samples) {
478 if (a->samples < frames) {
479 LOG_DEBUG("gapless: trimming %u frames from end", frames - a->samples);
480 frames = (frames_t)a->samples;
481 }
482 a->samples -= frames;
483 }
484
485 LOG_SDEBUG("write %u frames", frames);
486
487 LOCK_O_direct;
488
489 while (frames > 0) {
490 frames_t f;
491 frames_t count;
492 s32_t *optr;
493
494 IF_DIRECT(
495 f = _buf_cont_write(outputbuf) / BYTES_PER_FRAME;
496 optr = (s32_t *)outputbuf->writep;
497 );
498 IF_PROCESS(
499 f = process.max_in_frames;
500 optr = (s32_t *)process.inbuf;
501 );
502
503 f = min(f, frames);
504 count = f;
505
506 if (info.channels == 2) {
507 while (count--) {
508 *optr++ = *iptr++ << 8;
509 *optr++ = *iptr++ << 8;
510 }
511 } else if (info.channels == 1) {
512 while (count--) {
513 *optr++ = *iptr << 8;
514 *optr++ = *iptr++ << 8;
515 }
516 } else {
517 LOG_WARN("unsupported number of channels");
518 }
519
520 frames -= f;
521
522 IF_DIRECT(
523 _buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
524 );
525 IF_PROCESS(
526 process.in_frames = f;
527 if (frames) LOG_ERROR("unhandled case");
528 );
529 }
530
531 UNLOCK_O_direct;
532
533 return DECODE_RUNNING;
534 }
535
536 static void faad_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
537 NeAACDecConfigurationPtr conf;
538
539 LOG_INFO("opening %s stream", size == '2' ? "adts" : "mp4");
540
541 a->type = size;
542 a->pos = a->consume = a->sample = a->nextchunk = 0;
543
544 if (a->chunkinfo) {
545 free(a->chunkinfo);
546 }
547 if (a->stsc) {
548 free(a->stsc);
549 }
550 a->chunkinfo = NULL;
551 a->stsc = NULL;
552 a->skip = 0;
553 a->samples = 0;
554 a->sttssamples = 0;
555 a->empty = false;
556
557 if (a->hAac) {
558 NEAAC(a, Close, a->hAac);
559 }
560 a->hAac = NEAAC(a, Open);
561
562 conf = NEAAC(a, GetCurrentConfiguration, a->hAac);
563
564 conf->outputFormat = FAAD_FMT_24BIT;
565 conf->downMatrix = 1;
566
567 if (!NEAAC(a, SetConfiguration, a->hAac, conf)) {
568 LOG_WARN("error setting config");
569 };
570 }
571
572 static void faad_close(void) {
573 NEAAC(a, Close, a->hAac);
574 a->hAac = NULL;
575 if (a->chunkinfo) {
576 free(a->chunkinfo);
577 a->chunkinfo = NULL;
578 }
579 if (a->stsc) {
580 free(a->stsc);
581 a->stsc = NULL;
582 }
583 }
584
585 static bool load_faad() {
586 #if !LINKALL
587 void *handle = dlopen(LIBFAAD, RTLD_NOW);
588 char *err;
589
590 if (!handle) {
591 LOG_INFO("dlerror: %s", dlerror());
592 return false;
593 }
594
595 a->NeAACDecGetCurrentConfiguration = dlsym(handle, "NeAACDecGetCurrentConfiguration");
596 a->NeAACDecSetConfiguration = dlsym(handle, "NeAACDecSetConfiguration");
597 a->NeAACDecOpen = dlsym(handle, "NeAACDecOpen");
598 a->NeAACDecClose = dlsym(handle, "NeAACDecClose");
599 a->NeAACDecInit = dlsym(handle, "NeAACDecInit");
600 a->NeAACDecInit2 = dlsym(handle, "NeAACDecInit2");
601 a->NeAACDecDecode = dlsym(handle, "NeAACDecDecode");
602 a->NeAACDecGetErrorMessage = dlsym(handle, "NeAACDecGetErrorMessage");
603
604 if ((err = dlerror()) != NULL) {
605 LOG_INFO("dlerror: %s", err);
606 return false;
607 }
608
609 LOG_INFO("loaded "LIBFAAD"");
610 #endif
611
612 return true;
613 }
614
615 struct codec *register_faad(void) {
616 static struct codec ret = {
617 'a', // id
618 "aac", // types
619 WRAPBUF_LEN, // min read
620 20480, // min space
621 faad_open, // open
622 faad_close, // close
623 faad_decode, // decode
624 };
625
626 a = malloc(sizeof(struct faad));
627 if (!a) {
628 return NULL;
629 }
630
631 a->hAac = NULL;
632 a->chunkinfo = NULL;
633 a->stsc = NULL;
634
635 if (!load_faad()) {
636 return NULL;
637 }
638
639 LOG_INFO("using faad to decode aac");
640 return &ret;
641 }
0 /*
1 * Squeezelite - lightweight headless squeezebox emulator
2 *
3 * (c) Adrian Smith 2012-2015, triode1@btinternet.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 #include "squeezelite.h"
21
22 #if FFMPEG
23
24 #include <libavformat/avformat.h>
25 #include <libavcodec/avcodec.h>
26
27 #define READ_SIZE 4096 * 4 // this is large enough to ensure ffmpeg always gets new data when decode is called
28 #define WRITE_SIZE 256 * 1024 // FIXME - make smaller, but still to absorb max wma output
29
30 // FIXME - do we need to align these params as per ffmpeg on i386?
31 #define attribute_align_arg
32
33 struct ff_s {
34 // state for ffmpeg decoder
35 bool wma;
36 u8_t wma_mmsh;
37 u8_t wma_playstream;
38 u8_t wma_metadatastream;
39 u8_t *readbuf;
40 bool end_of_stream;
41 AVInputFormat *input_format;
42 AVFormatContext *formatC;
43 AVCodecContext *codecC;
44 AVFrame *frame;
45 AVPacket *avpkt;
46 unsigned mmsh_bytes_left;
47 unsigned mmsh_bytes_pad;
48 unsigned mmsh_packet_len;
49 #if !LINKALL
50 // ffmpeg symbols to be dynamically loaded from libavcodec
51 unsigned (* avcodec_version)(void);
52 AVCodec * (* avcodec_find_decoder)(int);
53 int attribute_align_arg (* avcodec_open2)(AVCodecContext *, const AVCodec *, AVDictionary **);
54 AVFrame * (* avcodec_alloc_frame)(void);
55 void (* avcodec_free_frame)(AVFrame **);
56 int attribute_align_arg (* avcodec_decode_audio4)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
57 // ffmpeg symbols to be dynamically loaded from libavformat
58 unsigned (* avformat_version)(void);
59 AVFormatContext * (* avformat_alloc_context)(void);
60 void (* avformat_free_context)(AVFormatContext *);
61 int (* avformat_open_input)(AVFormatContext **, const char *, AVInputFormat *, AVDictionary **);
62 int (* avformat_find_stream_info)(AVFormatContext *, AVDictionary **);
63 AVIOContext * (* avio_alloc_context)(unsigned char *, int, int, void *,
64 int (*read_packet)(void *, uint8_t *, int), int (*write_packet)(void *, uint8_t *, int), int64_t (*seek)(void *, int64_t, int));
65 void (* av_init_packet)(AVPacket *);
66 void (* av_free_packet)(AVPacket *);
67 int (* av_read_frame)(AVFormatContext *, AVPacket *);
68 AVInputFormat * (* av_find_input_format)(const char *);
69 void (* av_register_all)(void);
70 // ffmpeg symbols to be dynamically loaded from libavutil
71 unsigned (* avutil_version)(void);
72 void (* av_log_set_callback)(void (*)(void*, int, const char*, va_list));
73 void (* av_log_set_level)(int);
74 int (* av_strerror)(int, char *, size_t);
75 void * (* av_malloc)(size_t);
76 void (* av_freep)(void *);
77 #endif
78 };
79
80 static struct ff_s *ff;
81
82 extern log_level loglevel;
83
84 extern struct buffer *streambuf;
85 extern struct buffer *outputbuf;
86 extern struct streamstate stream;
87 extern struct outputstate output;
88 extern struct decodestate decode;
89 extern struct processstate process;
90
91 #define LOCK_S mutex_lock(streambuf->mutex)
92 #define UNLOCK_S mutex_unlock(streambuf->mutex)
93 #define LOCK_O mutex_lock(outputbuf->mutex)
94 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
95 #if PROCESS
96 #define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
97 #define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
98 #define IF_DIRECT(x) if (decode.direct) { x }
99 #define IF_PROCESS(x) if (!decode.direct) { x }
100 #else
101 #define LOCK_O_direct mutex_lock(outputbuf->mutex)
102 #define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
103 #define IF_DIRECT(x) { x }
104 #define IF_PROCESS(x)
105 #endif
106
107 #if LINKALL
108 #define AV(h, fn, ...) (av_ ## fn)(__VA_ARGS__)
109 #define AVIO(h, fn, ...) (avio_ ## fn)(__VA_ARGS__)
110 #define AVCODEC(h, fn, ...) (avcodec_ ## fn)(__VA_ARGS__)
111 #define AVFORMAT(h, fn, ...) (avformat_ ## fn)(__VA_ARGS__)
112 #else
113 #define AV(h, fn, ...) (h)->av_##fn(__VA_ARGS__)
114 #define AVIO(h, fn, ...) (h)->avio_##fn(__VA_ARGS__)
115 #define AVCODEC(h, fn, ...) (h)->avcodec_##fn(__VA_ARGS__)
116 #define AVFORMAT(h, fn, ...) (h)->avformat_##fn(__VA_ARGS__)
117 #endif
118
119
120 // our own version of useful error function not included in earlier ffmpeg versions
121 static char *av__err2str(errnum) {
122 static char buf[64];
123 AV(ff, strerror, errnum, buf, 64);
124 return buf;
125 }
126
127 // parser to extract asf data packet length from asf header
128 const u8_t header_guid[16] = { 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C };
129 const u8_t file_props_guid[16] = { 0xA1, 0xDC, 0xAB, 0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 };
130
131 static int _parse_packlen(void) {
132 int bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
133 u8_t *ptr = streambuf->readp;
134 int remain = 1;
135
136 while (bytes >= 24 && remain > 0) {
137 u32_t len = *(ptr+16) | *(ptr+17) << 8 | *(ptr+18) << 16 | *(ptr+19) << 24; // assume msb 32 bits are 0
138 if (!memcmp(ptr, header_guid, 16) && bytes >= 30) {
139 ptr += 30;
140 bytes -= 30;
141 remain = len - 30;
142 continue;
143 }
144 if (!memcmp(ptr, file_props_guid, 16) && len == 104) {
145 u32_t packlen = *(ptr+92) | *(ptr+93) << 8 | *(ptr+94) << 16 | *(ptr+95) << 24;
146 LOG_INFO("asf packet len: %u", packlen);
147 return packlen;
148 }
149 ptr += len;
150 bytes -= len;
151 remain -= len;
152 }
153
154 LOG_WARN("could not parse packet length");
155 return 0;
156 }
157
158 static int _read_data(void *opaque, u8_t *buffer, int buf_size) {
159 size_t bytes;
160
161 LOCK_S;
162
163 bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
164 ff->end_of_stream = (stream.state <= DISCONNECT && bytes == 0);
165 bytes = min(bytes, buf_size);
166
167 // for chunked wma extract asf header and data frames from framing structure
168 // pad asf data frames to size of packet extracted from asf header
169 if (ff->wma_mmsh) {
170 unsigned chunk_type = 0, chunk_len = 0;
171
172 if (ff->mmsh_bytes_left) {
173 // bytes remaining from previous frame
174 if (bytes >= ff->mmsh_bytes_left) {
175 bytes = ff->mmsh_bytes_left;
176 ff->mmsh_bytes_left = 0;
177 } else {
178 ff->mmsh_bytes_left -= bytes;
179 }
180 } else if (ff->mmsh_bytes_pad) {
181 // add padding for previous frame
182 bytes = min(ff->mmsh_bytes_pad, buf_size);
183 memset(buffer, 0, bytes);
184 ff->mmsh_bytes_pad -= bytes;
185 UNLOCK_S;
186 return bytes;
187 } else if (bytes >= 12) {
188 // new chunk header
189 chunk_type = (*(streambuf->readp) & 0x7f) | *(streambuf->readp + 1) << 8;
190 chunk_len = *(streambuf->readp + 2) | *(streambuf->readp + 3) << 8;
191 _buf_inc_readp(streambuf, 12);
192 bytes -= 12;
193 } else if (_buf_used(streambuf) >= 12) {
194 // new chunk header split over end of streambuf, read in two
195 u8_t header[12];
196 memcpy(header, streambuf->readp, bytes);
197 _buf_inc_readp(streambuf, bytes);
198 memcpy(header + bytes, streambuf->readp, 12 - bytes);
199 _buf_inc_readp(streambuf, 12 - bytes);
200 chunk_type = (header[0] & 0x7f) | header[1] << 8;
201 chunk_len = header[2] | header[3] << 8;
202 bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
203 bytes = min(bytes, buf_size);
204 } else {
205 // should not get here...
206 LOG_ERROR("chunk parser stalled bytes: %u %u", bytes, _buf_used(streambuf));
207 UNLOCK_S;
208 return 0;
209 }
210
211 if (chunk_type && chunk_len) {
212 if (chunk_type == 0x4824) {
213 // asf header - parse packet length
214 ff->mmsh_packet_len = _parse_packlen();
215 ff->mmsh_bytes_pad = 0;
216 } else if (chunk_type == 0x4424 && ff->mmsh_packet_len) {
217 // asf data packet - add padding
218 ff->mmsh_bytes_pad = ff->mmsh_packet_len - chunk_len + 8;
219 } else {
220 LOG_INFO("unknown chunk: %04x", chunk_type);
221 // other packet - no padding
222 ff->mmsh_bytes_pad = 0;
223 }
224
225 if (chunk_len - 8 <= bytes) {
226 bytes = chunk_len - 8;
227 ff->mmsh_bytes_left = 0;
228 } else {
229 ff->mmsh_bytes_left = chunk_len - 8 - bytes;
230 }
231 }
232
233 }
234
235 memcpy(buffer, streambuf->readp, bytes);
236
237 _buf_inc_readp(streambuf, bytes);
238
239 if (ff->mmsh_bytes_pad && bytes + ff->mmsh_bytes_pad < buf_size) {
240 memset(buffer + bytes, 0, ff->mmsh_bytes_pad);
241 bytes += ff->mmsh_bytes_pad;
242 ff->mmsh_bytes_pad = 0;
243 }
244
245 UNLOCK_S;
246
247 return bytes;
248 }
249
250 static decode_state ff_decode(void) {
251 int r, len, got_frame;
252 AVPacket pkt_c;
253 s32_t *optr = NULL;
254
255 if (decode.new_stream) {
256
257 AVIOContext *avio;
258 AVStream *av_stream;
259 AVCodec *codec;
260 int o;
261 int audio_stream = -1;
262
263 ff->mmsh_bytes_left = ff->mmsh_bytes_pad = ff->mmsh_packet_len = 0;
264
265 if (!ff->readbuf) {
266 ff->readbuf = AV(ff, malloc, READ_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
267 }
268
269 avio = AVIO(ff, alloc_context, ff->readbuf, READ_SIZE, 0, NULL, _read_data, NULL, NULL);
270 avio->seekable = 0;
271
272 ff->formatC = AVFORMAT(ff, alloc_context);
273 if (ff->formatC == NULL) {
274 LOG_ERROR("null context");
275 return DECODE_ERROR;
276 }
277
278 ff->formatC->pb = avio;
279 ff->formatC->flags |= AVFMT_FLAG_CUSTOM_IO | AVFMT_FLAG_NOPARSE;
280
281 o = AVFORMAT(ff, open_input, &ff->formatC, "", ff->input_format, NULL);
282 if (o < 0) {
283 LOG_WARN("avformat_open_input: %d %s", o, av__err2str(o));
284 return DECODE_ERROR;
285 }
286
287 LOG_INFO("format: name:%s lname:%s", ff->formatC->iformat->name, ff->formatC->iformat->long_name);
288
289 o = AVFORMAT(ff, find_stream_info, ff->formatC, NULL);
290 if (o < 0) {
291 LOG_WARN("avformat_find_stream_info: %d %s", o, av__err2str(o));
292 return DECODE_ERROR;
293 }
294
295 if (ff->wma && ff->wma_playstream < ff->formatC->nb_streams) {
296 if (ff->formatC->streams[ff->wma_playstream]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
297 LOG_INFO("using wma stream sent from server: %i", ff->wma_playstream);
298 audio_stream = ff->wma_playstream;
299 }
300 }
301
302 if (audio_stream == -1) {
303 int i;
304 for (i = 0; i < ff->formatC->nb_streams; ++i) {
305 if (ff->formatC->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
306 audio_stream = i;
307 LOG_INFO("found stream: %i", i);
308 break;
309 }
310 }
311 }
312
313 if (audio_stream == -1) {
314 LOG_WARN("no audio stream found");
315 return DECODE_ERROR;
316 }
317
318 av_stream = ff->formatC->streams[audio_stream];
319
320 ff->codecC = av_stream->codec;
321
322 codec = AVCODEC(ff, find_decoder, ff->codecC->codec_id);
323
324 AVCODEC(ff, open2, ff->codecC, codec, NULL);
325
326 ff->frame = AVCODEC(ff, alloc_frame);
327
328 ff->avpkt = AV(ff, malloc, sizeof(AVPacket));
329 if (ff->avpkt == NULL) {
330 LOG_ERROR("can't allocate avpkt");
331 return DECODE_ERROR;
332 }
333
334 AV(ff, init_packet, ff->avpkt);
335 ff->avpkt->data = NULL;
336 ff->avpkt->size = 0;
337
338 LOCK_O;
339 LOG_INFO("setting track_start");
340 output.next_sample_rate = decode_newstream(ff->codecC->sample_rate, output.supported_rates);
341 IF_DSD( output.next_dop = false; )
342 output.track_start = outputbuf->writep;
343 if (output.fade_mode) _checkfade(true);
344 decode.new_stream = false;
345 UNLOCK_O;
346 }
347
348 got_frame = 0;
349
350 if ((r = AV(ff, read_frame, ff->formatC, ff->avpkt)) < 0) {
351 if (r == AVERROR_EOF) {
352 if (ff->end_of_stream) {
353 LOG_INFO("decode complete");
354 return DECODE_COMPLETE;
355 } else {
356 LOG_INFO("codec end of file");
357 }
358 } else {
359 LOG_ERROR("av_read_frame error: %i %s", r, av__err2str(r));
360 }
361 return DECODE_RUNNING;
362 }
363
364 // clone packet as we are adjusting it
365 pkt_c = *ff->avpkt;
366
367 IF_PROCESS(
368 optr = (s32_t *)process.inbuf;
369 process.in_frames = 0;
370 );
371
372 while (pkt_c.size > 0 || got_frame) {
373
374 len = AVCODEC(ff, decode_audio4, ff->codecC, ff->frame, &got_frame, &pkt_c);
375 if (len < 0) {
376 LOG_ERROR("avcodec_decode_audio4 error: %i %s", len, av__err2str(len));
377 return DECODE_RUNNING;
378 }
379
380 pkt_c.data += len;
381 pkt_c.size -= len;
382
383 if (got_frame) {
384
385 s16_t *iptr16 = (s16_t *)ff->frame->data[0];
386 s32_t *iptr32 = (s32_t *)ff->frame->data[0];
387 s16_t *iptr16l = (s16_t *)ff->frame->data[0];
388 s16_t *iptr16r = (s16_t *)ff->frame->data[1];
389 s32_t *iptr32l = (s32_t *)ff->frame->data[0];
390 s32_t *iptr32r = (s32_t *)ff->frame->data[1];
391 float *iptrfl = (float *)ff->frame->data[0];
392 float *iptrfr = (float *)ff->frame->data[1];
393
394 frames_t frames = ff->frame->nb_samples;
395
396 LOG_SDEBUG("got audio channels: %u samples: %u format: %u", ff->codecC->channels, ff->frame->nb_samples,
397 ff->codecC->sample_fmt);
398
399 LOCK_O_direct;
400
401 while (frames > 0) {
402 frames_t count;
403 frames_t f;
404
405 IF_DIRECT(
406 optr = (s32_t *)outputbuf->writep;
407 f = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
408 f = min(f, frames);
409 );
410
411 IF_PROCESS(
412 if (process.in_frames + frames > process.max_in_frames) {
413 LOG_WARN("exceeded process buffer size - dropping frames");
414 break;
415 }
416 f = frames;
417 );
418
419 count = f;
420
421 if (ff->codecC->channels == 2) {
422 if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16) {
423 while (count--) {
424 *optr++ = *iptr16++ << 16;
425 *optr++ = *iptr16++ << 16;
426 }
427 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32) {
428 while (count--) {
429 *optr++ = *iptr32++;
430 *optr++ = *iptr32++;
431 }
432 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16P) {
433 while (count--) {
434 *optr++ = *iptr16l++ << 16;
435 *optr++ = *iptr16r++ << 16;
436 }
437 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32P) {
438 while (count--) {
439 *optr++ = *iptr32l++;
440 *optr++ = *iptr32r++;
441 }
442 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_FLTP) {
443 while (count--) {
444 double scaledl = *iptrfl++ * 0x7fffffff;
445 double scaledr = *iptrfr++ * 0x7fffffff;
446 if (scaledl > 2147483647.0) scaledl = 2147483647.0;
447 if (scaledl < -2147483648.0) scaledl = -2147483648.0;
448 if (scaledr > 2147483647.0) scaledr = 2147483647.0;
449 if (scaledr < -2147483648.0) scaledr = -2147483648.0;
450 *optr++ = (s32_t)scaledl;
451 *optr++ = (s32_t)scaledr;
452 }
453 } else {
454 LOG_WARN("unsupported sample format: %u", ff->codecC->sample_fmt);
455 }
456 } else if (ff->codecC->channels == 1) {
457 if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16) {
458 while (count--) {
459 *optr++ = *iptr16 << 16;
460 *optr++ = *iptr16++ << 16;
461 }
462 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32) {
463 while (count--) {
464 *optr++ = *iptr32;
465 *optr++ = *iptr32++;
466 }
467 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16P) {
468 while (count--) {
469 *optr++ = *iptr16l << 16;
470 *optr++ = *iptr16l++ << 16;
471 }
472 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32P) {
473 while (count--) {
474 *optr++ = *iptr32l;
475 *optr++ = *iptr32l++;
476 }
477 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_FLTP) {
478 while (count--) {
479 double scaled = *iptrfl++ * 0x7fffffff;
480 if (scaled > 2147483647.0) scaled = 2147483647.0;
481 if (scaled < -2147483648.0) scaled = -2147483648.0;
482 *optr++ = (s32_t)scaled;
483 *optr++ = (s32_t)scaled;
484 }
485 } else {
486 LOG_WARN("unsupported sample format: %u", ff->codecC->sample_fmt);
487 }
488 } else {
489 LOG_WARN("unsupported number of channels");
490 }
491
492 frames -= f;
493
494 IF_DIRECT(
495 _buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
496 );
497
498 IF_PROCESS(
499 process.in_frames += f;
500 );
501 }
502
503 UNLOCK_O_direct;
504 }
505 }
506
507 AV(ff, free_packet, ff->avpkt);
508
509 return DECODE_RUNNING;
510 }
511
512 static void _free_ff_data(void) {
513 if (ff->formatC) {
514 if (ff->formatC->pb) AV(ff, freep, &ff->formatC->pb);
515 AVFORMAT(ff, free_context, ff->formatC);
516 ff->formatC = NULL;
517 }
518
519 if (ff->frame) {
520 // ffmpeg version dependant free function
521 #if !LINKALL
522 ff->avcodec_free_frame ? AVCODEC(ff, free_frame, &ff->frame) : AV(ff, freep, &ff->frame);
523 #elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,28,0)
524 AVCODEC(ff, free_frame, &ff->frame);
525 #else
526 AV(ff, freep, &ff->frame);
527 #endif
528 ff->frame = NULL;
529 }
530
531 if (ff->avpkt) {
532 AV(ff, free_packet, ff->avpkt);
533 AV(ff, freep, &ff->avpkt);
534 ff->avpkt = NULL;
535 }
536 }
537
538 static void ff_open_wma(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
539 _free_ff_data();
540
541 ff->input_format = AV(ff, find_input_format, "asf");
542 if (ff->input_format == NULL) {
543 LOG_ERROR("asf format not supported by ffmpeg library");
544 }
545
546 ff->wma = true;
547 ff->wma_mmsh = size - '0';
548 ff->wma_playstream = rate - 1;
549 ff->wma_metadatastream = chan != '?' ? chan : 0;
550
551 LOG_INFO("open wma chunking: %u playstream: %u metadatastream: %u", ff->wma_mmsh, ff->wma_playstream, ff->wma_metadatastream);
552 }
553
554 static void ff_open_alac(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
555 _free_ff_data();
556
557 ff->input_format = AV(ff, find_input_format, "mp4");
558 if (ff->input_format == NULL) {
559 LOG_ERROR("mp4 format not supported by ffmpeg library");
560 }
561
562 ff->wma = false;
563 ff->wma_mmsh = 0;
564
565 LOG_INFO("open alac");
566 }
567
568 static void ff_close(void) {
569 _free_ff_data();
570
571 if (ff->readbuf) {
572 AV(ff, freep, &ff->readbuf);
573 ff->readbuf = NULL;
574 }
575 }
576
577 static bool load_ff() {
578 #if !LINKALL
579 void *handle_codec = NULL, *handle_format = NULL, *handle_util = NULL;
580 char name[30];
581 char *err;
582
583 // we try to load the ffmpeg library version which matches the header file we are compiled with as structs differ between versions
584
585 sprintf(name, LIBAVCODEC, LIBAVCODEC_VERSION_MAJOR);
586 handle_codec = dlopen(name, RTLD_NOW);
587 if (!handle_codec) {
588 LOG_INFO("dlerror: %s", dlerror());
589 return false;
590 }
591
592 sprintf(name, LIBAVFORMAT, LIBAVFORMAT_VERSION_MAJOR);
593 handle_format = dlopen(name, RTLD_NOW);
594 if (!handle_format) {
595 LOG_INFO("dlerror: %s", dlerror());
596 return false;
597 }
598
599 sprintf(name, LIBAVUTIL, LIBAVUTIL_VERSION_MAJOR);
600 handle_util = dlopen(name, RTLD_NOW);
601 if (!handle_util) {
602 LOG_INFO("dlerror: %s", dlerror());
603 return false;
604 }
605
606 ff->avcodec_version = dlsym(handle_codec, "avcodec_version");
607 ff->avcodec_find_decoder = dlsym(handle_codec, "avcodec_find_decoder");
608 ff->avcodec_open2 = dlsym(handle_codec, "avcodec_open2");
609 ff->avcodec_alloc_frame = dlsym(handle_codec, "avcodec_alloc_frame");
610 ff->avcodec_free_frame = dlsym(handle_codec, "avcodec_free_frame");
611 ff->avcodec_decode_audio4 = dlsym(handle_codec, "avcodec_decode_audio4");
612 ff->av_init_packet = dlsym(handle_codec, "av_init_packet");
613 ff->av_free_packet = dlsym(handle_codec, "av_free_packet");
614
615 if ((err = dlerror()) != NULL) {
616 LOG_INFO("dlerror: %s", err);
617 return false;
618 }
619
620 LOG_INFO("loaded "LIBAVCODEC" (%u.%u.%u)", LIBAVCODEC_VERSION_MAJOR, ff->avcodec_version() >> 16, (ff->avcodec_version() >> 8) & 0xff, ff->avcodec_version() & 0xff);
621
622 ff->avformat_version = dlsym(handle_format, "avformat_version");
623 ff->avformat_alloc_context = dlsym(handle_format, "avformat_alloc_context");
624 ff->avformat_free_context = dlsym(handle_format, "avformat_free_context");
625 ff->avformat_open_input = dlsym(handle_format, "avformat_open_input");
626 ff->avformat_find_stream_info = dlsym(handle_format, "avformat_find_stream_info");
627 ff->avio_alloc_context = dlsym(handle_format, "avio_alloc_context");
628 ff->av_read_frame = dlsym(handle_format, "av_read_frame");
629 ff->av_find_input_format= dlsym(handle_format, "av_find_input_format");
630 ff->av_register_all = dlsym(handle_format, "av_register_all");
631
632 if ((err = dlerror()) != NULL) {
633 LOG_INFO("dlerror: %s", err);
634 return false;
635 }
636
637 LOG_INFO("loaded "LIBAVFORMAT" (%u.%u.%u)", LIBAVFORMAT_VERSION_MAJOR, ff->avformat_version() >> 16, (ff->avformat_version() >> 8) & 0xff, ff->avformat_version() & 0xff);
638
639 ff->avutil_version = dlsym(handle_util, "avutil_version");
640 ff->av_log_set_callback = dlsym(handle_util, "av_log_set_callback");
641 ff->av_log_set_level = dlsym(handle_util, "av_log_set_level");
642 ff->av_strerror = dlsym(handle_util, "av_strerror");
643 ff->av_malloc = dlsym(handle_util, "av_malloc");
644 ff->av_freep = dlsym(handle_util, "av_freep");
645
646 if ((err = dlerror()) != NULL) {
647 LOG_INFO("dlerror: %s", err);
648 return false;
649 }
650
651 LOG_INFO("loaded "LIBAVUTIL" (%u.%u.%u)", LIBAVUTIL_VERSION_MAJOR, ff->avutil_version() >> 16, (ff->avutil_version() >> 8) & 0xff, ff->avutil_version() & 0xff);
652
653 #endif
654
655 return true;
656 }
657
658 static int ff_log_level = 0;
659
660 void av_err_callback(void *avcl, int level, const char *fmt, va_list vl) {
661 if (level > ff_log_level) return;
662 fprintf(stderr, "%s ffmpeg: ", logtime());
663 vfprintf(stderr, fmt, vl);
664 fflush(stderr);
665 }
666
667 static bool registered = false;
668
669 struct codec *register_ff(const char *codec) {
670 if (!registered) {
671
672 ff = malloc(sizeof(struct ff_s));
673 if (!ff) {
674 return NULL;
675 }
676
677 memset(ff, 0, sizeof(struct ff_s));
678
679 if (!load_ff()) {
680 return NULL;
681 }
682
683 switch (loglevel) {
684 case lERROR:
685 ff_log_level = AV_LOG_ERROR; break;
686 case lWARN:
687 ff_log_level = AV_LOG_WARNING; break;
688 case lINFO:
689 ff_log_level = AV_LOG_INFO; break;
690 case lDEBUG:
691 ff_log_level = AV_LOG_VERBOSE; break;
692 default: break;
693 }
694
695 AV(ff, log_set_callback, av_err_callback);
696
697 AV(ff, register_all);
698
699 registered = true;
700 }
701
702 if (!strcmp(codec, "wma")) {
703
704 static struct codec ret = {
705 'w', // id
706 "wma,wmap,wmal", // types
707 READ_SIZE, // min read
708 WRITE_SIZE, // min space
709 ff_open_wma, // open
710 ff_close, // close
711 ff_decode, // decode
712 };
713
714 LOG_INFO("using ffmpeg to decode wma,wmap,wmal");
715 return &ret;
716 }
717
718 if (!strcmp(codec, "alc")) {
719
720 static struct codec ret = {
721 'l', // id
722 "alc", // types
723 READ_SIZE, // min read
724 WRITE_SIZE, // min space
725 ff_open_alac,// open
726 ff_close, // close
727 ff_decode, // decode
728 };
729
730 LOG_INFO("using ffmpeg to decode alc");
731 return &ret;
732 }
733
734