New upstream snapshot.
Debian Janitor
5 months ago
4 | 4 | EXECUTABLE ?= squeezelite |
5 | 5 | |
6 | 6 | # passing one or more of these in $(OPTS) enables optional feature inclusion |
7 | OPT_DSD = -DDSD | |
8 | OPT_FF = -DFFMPEG | |
9 | OPT_ALAC = -DALAC | |
10 | OPT_LINKALL = -DLINKALL | |
11 | OPT_RESAMPLE= -DRESAMPLE | |
12 | OPT_VIS = -DVISEXPORT | |
13 | OPT_IR = -DIR | |
14 | OPT_GPIO = -DGPIO | |
15 | OPT_RPI = -DRPI | |
16 | OPT_NO_FAAD = -DNO_FAAD | |
17 | OPT_SSL = -DUSE_SSL | |
18 | OPT_NOSSLSYM= -DNO_SSLSYM | |
19 | OPT_OPUS = -DOPUS | |
20 | OPT_PORTAUDIO = -DPORTAUDIO | |
7 | OPT_DSD = -DDSD | |
8 | OPT_FF = -DFFMPEG | |
9 | OPT_ALAC = -DALAC | |
10 | OPT_LINKALL = -DLINKALL | |
11 | OPT_RESAMPLE = -DRESAMPLE | |
12 | OPT_VIS = -DVISEXPORT | |
13 | OPT_IR = -DIR | |
14 | OPT_GPIO = -DGPIO | |
15 | OPT_RPI = -DRPI | |
16 | OPT_NO_FAAD = -DNO_FAAD | |
17 | OPT_NO_MAD = -DNO_MAD | |
18 | OPT_NO_MPG123 = -DNO_MPG123 | |
19 | OPT_SSL = -DUSE_SSL | |
20 | OPT_NOSSLSYM = -DNO_SSLSYM | |
21 | OPT_OPUS = -DOPUS | |
22 | OPT_PORTAUDIO = -DPORTAUDIO | |
21 | 23 | OPT_PULSEAUDIO = -DPULSEAUDIO |
22 | 24 | |
23 | 25 | SOURCES = \ |
24 | 26 | main.c slimproto.c buffer.c stream.c utils.c \ |
25 | 27 | output.c output_alsa.c output_pa.c output_stdout.c output_pack.c output_pulse.c decode.c \ |
26 | flac.c pcm.c mad.c vorbis.c mpg.c | |
28 | flac.c pcm.c vorbis.c | |
27 | 29 | |
28 | 30 | SOURCES_DSD = dsd.c dop.c dsd2pcm/dsd2pcm.c |
29 | 31 | SOURCES_FF = ffmpeg.c |
36 | 38 | SOURCES_FAAD = faad.c |
37 | 39 | SOURCES_SSL = sslsym.c |
38 | 40 | SOURCES_OPUS = opus.c |
41 | SOURCES_MAD = mad.c | |
42 | SOURCES_MPG123 = mpg.c | |
39 | 43 | |
40 | 44 | LINK_LINUX = -ldl |
41 | 45 | LINK_ALSA = -lasound |
44 | 48 | LINK_SSL = -lssl -lcrypto |
45 | 49 | LINK_ALAC = -lalac |
46 | 50 | |
47 | LINKALL = -lmad -lmpg123 -lFLAC -lvorbisfile -lvorbis -logg | |
51 | LINKALL = -lFLAC -lvorbisfile -lvorbis -logg | |
48 | 52 | LINKALL_FF = -lavformat -lavcodec -lavutil |
49 | 53 | LINKALL_RESAMPLE = -lsoxr |
50 | 54 | LINKALL_IR = -llirc_client |
51 | 55 | LINKALL_FAAD = -lfaad |
52 | 56 | LINKALL_OPUS = -lopusfile -lopus |
57 | LINKALL_MAD = -lmad | |
58 | LINKALL_MPG123 = -lmpg123 | |
53 | 59 | |
54 | 60 | DEPS = squeezelite.h slimproto.h |
55 | 61 | |
97 | 103 | ifneq (,$(findstring $(OPT_SSL), $(OPTS))) |
98 | 104 | SOURCES += $(SOURCES_SSL) |
99 | 105 | endif |
106 | ifeq (,$(findstring $(OPT_NO_MAD), $(OPTS))) | |
107 | SOURCES += $(SOURCES_MAD) | |
108 | endif | |
109 | ifeq (,$(findstring $(OPT_NO_MPG123), $(OPTS))) | |
110 | SOURCES += $(SOURCES_MPG123) | |
111 | endif | |
100 | 112 | |
101 | 113 | # add optional link options |
102 | 114 | ifneq (,$(findstring $(OPT_LINKALL), $(OPTS))) |
118 | 130 | endif |
119 | 131 | ifneq (,$(findstring $(OPT_SSL), $(OPTS))) |
120 | 132 | LDADD += $(LINK_SSL) |
133 | endif | |
134 | ifeq (,$(findstring $(OPT_NO_MAD), $(OPTS))) | |
135 | LDADD += $(LINKALL_MAD) | |
136 | endif | |
137 | ifeq (,$(findstring $(OPT_NO_MPG123), $(OPTS))) | |
138 | LDADD += $(LINKALL_MPG123) | |
121 | 139 | endif |
122 | 140 | else |
123 | 141 | # if not LINKALL and linux add LINK_LINUX |
0 | # OSX 10.5 Intel 32-bit | |
1 | OPTS = -DPORTAUDIO -DALAC -DOPUS -DRESAMPLE -DGPIO -DLINKALL -DVISEXPORT -DDSD -DUSE_SSL -I./include -I./include/opus -I./include/alac -O2 -I./include -isysroot /Developer/SDKs/MacOSX10.5.sdk -arch i386 | |
0 | # OSX 10.7 Intel 32-bit | |
1 | OPTS = -DPORTAUDIO -DALAC -DOPUS -DRESAMPLE -DLINKALL -DVISEXPORT -DDSD -DUSE_SSL -I./include -I./include/opus -I./include/alac -I./include -O3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -arch i386 -mmacosx-version-min=10.7 | |
2 | 2 | |
3 | LDFLAGS = -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5.sdk -arch i386 -mmacosx-version-min=10.5 -L./lib | |
3 | LDFLAGS = -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -arch i386 -mmacosx-version-min=10.7 -L./lib | |
4 | 4 | |
5 | 5 | LDADD = -lportaudio -lpthread -ldl -lm -framework CoreVideo -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon |
6 | 6 |
0 | # OSX 11.0+ arm64 only | |
1 | OPTS = -DPORTAUDIO -DALAC -DOPUS -DRESAMPLE -DLINKALL -DVISEXPORT -DDSD -DUSE_SSL -I./includem1 -I./includem1/opus -I./includem1/alac -arch arm64 -O3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -mmacosx-version-min=11.0 | |
2 | ||
3 | LDFLAGS = -arch arm64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -mmacosx-version-min=11.0 -L./libm1 | |
4 | ||
5 | LDADD = -lportaudio -lpthread -ldl -lm -framework CoreVideo -framework VideoDecodeAcceleration -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon | |
6 | ||
7 | include Makefile |
0 | 0 | # OSX 10.7+ 64-bit only |
1 | OPTS = -DPORTAUDIO -DALAC -DOPUS -DRESAMPLE -DGPIO -DLINKALL -DVISEXPORT -DDSD -DUSE_SSL -I./include64 -I./include64/opus -I./include64/alac -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -arch x86_64 -mmacosx-version-min=10.7 | |
1 | OPTS = -DPORTAUDIO -DALAC -DOPUS -DRESAMPLE -DLINKALL -DVISEXPORT -DDSD -DUSE_SSL -I./include64 -I./include64/opus -I./include64/alac -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -arch x86_64 -mmacosx-version-min=10.7 | |
2 | 2 | |
3 | 3 | LDFLAGS = -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -arch x86_64 -mmacosx-version-min=10.7 -L./lib64 |
4 | 4 |
119 | 119 | // extract audio config from within alac |
120 | 120 | if (!strcmp(type, "alac") && bytes > len) { |
121 | 121 | u8_t *ptr = streambuf->readp + 36; |
122 | l->decoder = alac_create_decoder(len - 36, ptr, &l->sample_size, &l->sample_rate, &l->channels); | |
123 | l->play = l->trak; | |
122 | unsigned int block_size; | |
123 | l->play = l->trak; | |
124 | l->decoder = alac_create_decoder(len - 36, ptr, &l->sample_size, &l->sample_rate, &l->channels, &block_size); | |
125 | l->writebuf = malloc(block_size + 256); | |
126 | LOG_INFO("allocated write buffer of %u bytes", block_size); | |
127 | if (!l->writebuf) { | |
128 | LOG_ERROR("allocation failed"); | |
129 | return -1; | |
130 | } | |
124 | 131 | } |
125 | 132 | |
126 | 133 | // extract the total number of samples from stts |
375 | 382 | |
376 | 383 | // need to create a buffer with contiguous data |
377 | 384 | if (bytes < block_size) { |
378 | u8_t *buffer = malloc(block_size); | |
379 | memcpy(buffer, streambuf->readp, bytes); | |
380 | memcpy(buffer + bytes, streambuf->buf, block_size - bytes); | |
381 | iptr = buffer; | |
385 | iptr = malloc(block_size); | |
386 | memcpy(iptr, streambuf->readp, bytes); | |
387 | memcpy(iptr + bytes, streambuf->buf, block_size - bytes); | |
382 | 388 | } else iptr = streambuf->readp; |
383 | 389 | |
384 | 390 | if (!alac_to_pcm(l->decoder, iptr, l->writebuf, 2, &frames)) { |
473 | 479 | } |
474 | 480 | } else if (l->sample_size == 16) { |
475 | 481 | u16_t *_iptr = (u16_t*) iptr; |
482 | iptr += count * 4; | |
476 | 483 | while (count--) { |
477 | 484 | *optr++ = ALIGN16(*_iptr++); |
478 | 485 | *optr++ = ALIGN16(*_iptr++); |
485 | 492 | } |
486 | 493 | } else if (l->sample_size == 32) { |
487 | 494 | u32_t *_iptr = (u32_t*) iptr; |
495 | iptr += count * 8; | |
488 | 496 | while (count--) { |
489 | 497 | *optr++ = ALIGN32(*_iptr++); |
490 | 498 | *optr++ = ALIGN32(*_iptr++); |
510 | 518 | return DECODE_RUNNING; |
511 | 519 | } |
512 | 520 | |
513 | static void alac_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) { | |
514 | if (l->decoder) alac_delete_decoder(l->decoder); | |
515 | else l->writebuf = malloc(BLOCK_SIZE * 2); | |
516 | ||
521 | static void alac_close(void) { | |
522 | if (l->decoder) alac_delete_decoder(l->decoder); | |
523 | if (l->writebuf) free(l->writebuf); | |
517 | 524 | if (l->chunkinfo) free(l->chunkinfo); |
518 | 525 | if (l->block_size) free(l->block_size); |
519 | 526 | if (l->stsc) free(l->stsc); |
520 | l->decoder = l->chunkinfo = l->stsc = l->block_size = NULL; | |
521 | l->skip = 0; | |
522 | l->samples = l->sttssamples = 0; | |
523 | l->empty = false; | |
524 | l->pos = l->consume = l->sample = l->nextchunk = 0; | |
527 | memset(l, 0, sizeof(struct alac)); | |
525 | 528 | } |
526 | 529 | |
527 | static void alac_close(void) { | |
528 | if (l->decoder) alac_delete_decoder(l->decoder); | |
529 | if (l->chunkinfo) free(l->chunkinfo); | |
530 | if (l->block_size) free(l->block_size); | |
531 | if (l->stsc) free(l->stsc); | |
532 | l->decoder = l->chunkinfo = l->stsc = l->block_size = NULL; | |
533 | free(l->writebuf); | |
530 | static void alac_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) { | |
531 | alac_close(); | |
534 | 532 | } |
535 | 533 | |
536 | 534 | struct codec *register_alac(void) { |
543 | 541 | alac_close, // close |
544 | 542 | alac_decode, // decode |
545 | 543 | }; |
546 | ||
547 | l = malloc(sizeof(struct alac)); | |
548 | if (!l) { | |
549 | return NULL; | |
550 | } | |
551 | ||
552 | l->decoder = l->chunkinfo = l->stsc = l->block_size = NULL; | |
553 | ||
544 | ||
545 | l = calloc(1, sizeof(struct alac)); | |
546 | if (!l) return NULL; | |
547 | ||
554 | 548 | LOG_INFO("using alac to decode alc"); |
555 | 549 | return &ret; |
556 | 550 | } |
31 | 31 | /*----------------------------------------------------------------------------*/ |
32 | 32 | extern "C" struct alac_codec_s *alac_create_decoder(int magic_cookie_size, unsigned char *magic_cookie, |
33 | 33 | unsigned char *sample_size, unsigned *sample_rate, |
34 | unsigned char *channels) { | |
34 | unsigned char *channels, unsigned int *block_size) { | |
35 | 35 | struct alac_codec_s *codec = (struct alac_codec_s*) malloc(sizeof(struct alac_codec_s)); |
36 | 36 | |
37 | 37 | codec->Decoder = new ALACDecoder; |
42 | 42 | *sample_size = codec->Decoder->mConfig.bitDepth; |
43 | 43 | |
44 | 44 | codec->frames_per_packet = codec->Decoder->mConfig.frameLength; |
45 | codec->block_size = codec->frames_per_packet * (*channels) * (*sample_size) / 8; | |
45 | *block_size = codec->block_size = codec->frames_per_packet * (*channels) * (*sample_size) / 8; | |
46 | 46 | |
47 | 47 | return codec; |
48 | 48 | } |
27 | 27 | |
28 | 28 | struct alac_codec_s *alac_create_decoder(int magic_cookie_size, unsigned char *magic_cookie, |
29 | 29 | unsigned char *sample_size, unsigned *sample_rate, |
30 | unsigned char *channels); | |
30 | unsigned char *channels, unsigned int *block_size); | |
31 | 31 | void alac_delete_decoder(struct alac_codec_s *codec); |
32 | 32 | bool alac_to_pcm(struct alac_codec_s *codec, unsigned char* input, |
33 | 33 | unsigned char *output, char channels, unsigned *out_frames); |
0 | 0 | # Contributor: Carl Chave <online@chave.us> |
1 | 1 | # Maintainer: Ralph Irving <ralph.irving@gmail.com> |
2 | 2 | pkgname=squeezelite |
3 | pkgver=1.9.7.1273 | |
4 | pkgrel=1 | |
3 | pkgver=1.9.9.1401 | |
4 | pkgrel=0 | |
5 | 5 | pkgdesc="Lightweight headless squeezebox player for Logitech Media Server" |
6 | 6 | url="https://github.com/ralph-irving/squeezelite" |
7 | 7 | arch="all" |
8 | 8 | license="GPL-3.0-or-later3" |
9 | 9 | options="!check" # No test suite |
10 | depends="flac alsa-lib faad2 mpg123 libvorbis libmad soxr openssl opusfile libalac" | |
11 | makedepends="flac-dev alsa-lib-dev faad2-dev mpg123-dev libvorbis-dev libmad-dev soxr-dev openssl-dev opusfile-dev opus-dev libalac-dev" | |
10 | depends="flac alsa-lib faad2-libs mpg123-libs libvorbis libmad soxr openssl opusfile libalac lirc" | |
11 | makedepends="flac-dev alsa-lib-dev faad2-dev mpg123-dev libvorbis-dev libmad-dev soxr-dev openssl-dev opusfile-dev opus-dev libalac-dev lirc-dev" | |
12 | 12 | install="$pkgname.pre-install" |
13 | 13 | subpackages="$pkgname-doc $pkgname-openrc" |
14 | 14 | source="$pkgname-$pkgver.zip::https://github.com/ralph-irving/squeezelite/archive/master.zip load-libtremor-first.patch $pkgname.confd $pkgname.initd" |
16 | 16 | |
17 | 17 | build() { |
18 | 18 | cd "$builddir" |
19 | make OPTS="-DRESAMPLE -DDSD -DGPIO -DVISEXPORT -DUSE_SSL -DNO_SSLSYM -DOPUS -DALAC -I/usr/include/opus -I/usr/include/alac" | |
19 | make OPTS="-DRESAMPLE -DDSD -DGPIO -DVISEXPORT -DUSE_SSL -DNO_SSLSYM -DOPUS -DALAC -DIR -I/usr/include/opus -I/usr/include/alac" | |
20 | 20 | gcc -Os -fomit-frame-pointer -fcommon -s -o find_servers tools/find_servers.c |
21 | 21 | gcc -Os -fomit-frame-pointer -fcommon -s -o alsacap tools/alsacap.c -lasound |
22 | 22 | } |
6 | 6 | arch="all" |
7 | 7 | subpackages="$pkgname-doc $pkgname-dev" |
8 | 8 | license="Apache 2.0" |
9 | makedepends="git autoconf automake make tar" | |
9 | makedepends="git autoconf automake libtool make tar" | |
10 | 10 | source="fix-arm-segfault.patch \ |
11 | 11 | alac-version.patch" |
12 | 12 | |
44 | 44 | install -Dm644 LICENSE "$pkgdir"/usr/share/licenses/$pkgname/COPYING |
45 | 45 | } |
46 | 46 | |
47 | sha512sums="e72b13714476170108844b84c0043dc06d2ff2e8c9b651a7ad1571d148fc5567aca48048646d16fb82630d6972a31b9328f04e522972b297d1cf8e804785867f fix-arm-segfault.patch | |
47 | sha512sums="271d4c5184c7f48ac79c8f8f9f3bc39f7f970b4d98acda792e40450b687f211094b4dcaea23e034d4deb7ea78713b95e691db9c09fbf31b1be59b6d525ef11a8 fix-arm-segfault.patch | |
48 | 48 | 093379f79b5dc9f5b8aa45826d61738b088d78305a7d514df33851ae34d02ee9034a8ecddf2558fcb1bf4daaf64c620ea4411521908cfc748e31fd0a2d50bbf7 alac-version.patch" |
26 | 26 | |
27 | 27 | // _* called with muxtex locked |
28 | 28 | |
29 | inline unsigned _buf_used(struct buffer *buf) { | |
29 | #if !WIN | |
30 | inline | |
31 | #endif | |
32 | unsigned _buf_used(struct buffer *buf) { | |
30 | 33 | return buf->writep >= buf->readp ? buf->writep - buf->readp : buf->size - (buf->readp - buf->writep); |
31 | 34 | } |
32 | 35 |
0 | squeezelite (1.9+git20221015.ca44fc6-1) UNRELEASED; urgency=low | |
1 | ||
2 | * New upstream snapshot. | |
3 | ||
4 | -- Debian Janitor <janitor@jelmer.uk> Tue, 18 Oct 2022 03:41:15 -0000 | |
5 | ||
0 | 6 | squeezelite (1.9+git20210102.78fef68-3) unstable; urgency=medium |
1 | 7 | |
2 | 8 | * Upload to unstable. |
182 | 182 | if (!strstr(exclude_codecs, "pcm") && (!include_codecs || (order_codecs = strstr(include_codecs, "pcm")))) |
183 | 183 | sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_pcm()); |
184 | 184 | |
185 | #if !defined(NO_MAD) && !defined(NO_MPG123) | |
185 | 186 | // try mad then mpg for mp3 unless command line option passed |
186 | 187 | if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mad")) && |
187 | 188 | (!include_codecs || (order_codecs = strstr(include_codecs, "mp3")) || (order_codecs = strstr(include_codecs, "mad")))) |
189 | 190 | else if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mpg")) && |
190 | 191 | (!include_codecs || (order_codecs = strstr(include_codecs, "mp3")) || (order_codecs = strstr(include_codecs, "mpg")))) |
191 | 192 | sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_mpg()); |
193 | #elif !defined(NO_MAD) | |
194 | if (!strstr(exclude_codecs, "mp3") && (!include_codecs || (order_codecs = strstr(include_codecs, "mp3")))) | |
195 | sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_mad()); | |
196 | #elif !defined(NO_MPG123) | |
197 | if (!strstr(exclude_codecs, "mp3") && (!include_codecs || (order_codecs = strstr(include_codecs, "mp3")))) | |
198 | sort_codecs((include_codecs ? order_codecs - include_codecs : i), register_mpg()); | |
199 | #endif | |
192 | 200 | |
193 | 201 | LOG_DEBUG("include codecs: %s exclude codecs: %s", include_codecs ? include_codecs : "", exclude_codecs); |
194 | 202 |
53 | 53 | unsigned (* avcodec_version)(void); |
54 | 54 | AVCodec * (* avcodec_find_decoder)(int); |
55 | 55 | int attribute_align_arg (* avcodec_open2)(AVCodecContext *, const AVCodec *, AVDictionary **); |
56 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) | |
57 | 56 | AVFrame * (* av_frame_alloc)(void); |
58 | 57 | void (* av_frame_free)(AVFrame **); |
59 | #else | |
60 | AVFrame * (* avcodec_alloc_frame)(void); | |
61 | void (* avcodec_free_frame)(AVFrame **); | |
62 | #endif | |
63 | int attribute_align_arg (* avcodec_decode_audio4)(AVCodecContext *, AVFrame *, int *, const AVPacket *); | |
58 | int attribute_align_arg (* avcodec_send_packet)(AVCodecContext *, const AVPacket *); | |
59 | int attribute_align_arg (* avcodec_receive_frame)(AVCodecContext *, AVFrame *); | |
64 | 60 | AVCodecContext * (* avcodec_alloc_context3)(const AVCodec *); |
65 | 61 | void (* avcodec_free_context)(AVCodecContext **); |
66 | 62 | int (* avcodec_parameters_to_context)(AVCodecContext *, const AVCodecParameters *); |
72 | 68 | int (* avformat_find_stream_info)(AVFormatContext *, AVDictionary **); |
73 | 69 | AVIOContext * (* avio_alloc_context)(unsigned char *, int, int, void *, |
74 | 70 | int (*read_packet)(void *, uint8_t *, int), int (*write_packet)(void *, uint8_t *, int), int64_t (*seek)(void *, int64_t, int)); |
71 | AVPacket * (* av_packet_alloc)(void); | |
72 | #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,133,100) | |
75 | 73 | void (* av_init_packet)(AVPacket *); |
76 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57,24,102) | |
74 | #endif | |
77 | 75 | void (* av_packet_unref)(AVPacket *); |
78 | #else | |
79 | void (* av_free_packet)(AVPacket *); | |
80 | #endif | |
81 | 76 | int (* av_read_frame)(AVFormatContext *, AVPacket *); |
82 | 77 | AVInputFormat * (* av_find_input_format)(const char *); |
78 | #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58,9,100) | |
83 | 79 | void (* av_register_all)(void); |
80 | #endif | |
84 | 81 | // ffmpeg symbols to be dynamically loaded from libavutil |
85 | 82 | unsigned (* avutil_version)(void); |
86 | 83 | void (* av_log_set_callback)(void (*)(void*, int, const char*, va_list)); |
262 | 259 | } |
263 | 260 | |
264 | 261 | static decode_state ff_decode(void) { |
265 | int r, len, got_frame; | |
266 | AVPacket pkt_c; | |
262 | int r; | |
267 | 263 | s32_t *optr = NULL; |
268 | 264 | |
269 | 265 | if (decode.new_stream) { |
350 | 346 | |
351 | 347 | AVCODEC(ff, open2, ff->codecC, codec, NULL); |
352 | 348 | |
353 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) | |
354 | 349 | ff->frame = AV(ff, frame_alloc); |
355 | #else | |
356 | ff->frame = AVCODEC(ff, alloc_frame); | |
357 | #endif | |
358 | ||
359 | ff->avpkt = AV(ff, malloc, sizeof(AVPacket)); | |
350 | ff->avpkt = AV(ff, packet_alloc); | |
360 | 351 | if (ff->avpkt == NULL) { |
361 | 352 | LOG_ERROR("can't allocate avpkt"); |
362 | 353 | return DECODE_ERROR; |
363 | 354 | } |
364 | 355 | |
365 | AV(ff, init_packet, ff->avpkt); | |
366 | ff->avpkt->data = NULL; | |
367 | ff->avpkt->size = 0; | |
356 | #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,133,100) | |
357 | AV(ff, init_packet, ff->avpkt); // on older ffmpeg, this still is needed to e.g. set ->pos to -1 | |
358 | #endif | |
368 | 359 | |
369 | 360 | LOCK_O; |
370 | 361 | LOG_INFO("setting track_start"); |
375 | 366 | decode.new_stream = false; |
376 | 367 | UNLOCK_O; |
377 | 368 | } |
378 | ||
379 | got_frame = 0; | |
380 | 369 | |
381 | 370 | if ((r = AV(ff, read_frame, ff->formatC, ff->avpkt)) < 0) { |
382 | 371 | if (r == AVERROR_EOF) { |
392 | 381 | return DECODE_RUNNING; |
393 | 382 | } |
394 | 383 | |
395 | // clone packet as we are adjusting it | |
396 | pkt_c = *ff->avpkt; | |
397 | ||
398 | 384 | IF_PROCESS( |
399 | 385 | optr = (s32_t *)process.inbuf; |
400 | 386 | process.in_frames = 0; |
401 | 387 | ); |
402 | 388 | |
403 | while (pkt_c.size > 0 || got_frame) { | |
404 | ||
405 | len = AVCODEC(ff, decode_audio4, ff->codecC, ff->frame, &got_frame, &pkt_c); | |
406 | if (len < 0) { | |
407 | LOG_ERROR("avcodec_decode_audio4 error: %i %s", len, av__err2str(len)); | |
408 | break; // exit loop, free the packet, and continue decoding | |
409 | } | |
410 | ||
411 | pkt_c.data += len; | |
412 | pkt_c.size -= len; | |
413 | ||
414 | if (got_frame) { | |
415 | ||
389 | if ((r = AVCODEC(ff, send_packet, ff->codecC, ff->avpkt)) < 0) { | |
390 | AV(ff, packet_unref, ff->avpkt); | |
391 | ||
392 | if (r == AVERROR_EOF) { | |
393 | LOG_DEBUG("av_send_packet reports eof"); | |
394 | return DECODE_COMPLETE; | |
395 | } else { | |
396 | LOG_ERROR("av_send_packet error: %i %s", r, av__err2str(r)); | |
397 | ||
398 | // EAGAIN is treated as an unrecoverable error here since all pending output frames are processed below | |
399 | if (r == AVERROR(EAGAIN) || r == AVERROR(EINVAL) || r == AVERROR(ENOMEM)) | |
400 | return DECODE_ERROR; | |
401 | ||
402 | // retain existing behavior (continue decoding) for legitimate decoding errors | |
403 | return DECODE_RUNNING; | |
404 | } | |
405 | } else { | |
406 | // a single input packet can lead to multiple output frames - process all of them | |
407 | while ((r = AVCODEC(ff, receive_frame, ff->codecC, ff->frame)) >= 0) { | |
416 | 408 | s16_t *iptr16 = (s16_t *)ff->frame->data[0]; |
417 | 409 | s32_t *iptr32 = (s32_t *)ff->frame->data[0]; |
418 | 410 | s16_t *iptr16l = (s16_t *)ff->frame->data[0]; |
535 | 527 | } |
536 | 528 | } |
537 | 529 | |
538 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57,24,102) | |
539 | 530 | AV(ff, packet_unref, ff->avpkt); |
540 | #else | |
541 | AV(ff, free_packet, ff->avpkt); | |
542 | #endif | |
531 | ||
532 | if (r == AVERROR(EAGAIN)) { | |
533 | // EAGAIN is expected if there are no more pending frames | |
534 | } else if (r == AVERROR_EOF) { | |
535 | LOG_DEBUG("av_receive_frame reports eof"); | |
536 | return DECODE_COMPLETE; | |
537 | } else { | |
538 | LOG_ERROR("av_receive_frame error: %i %s", r, av__err2str(r)); | |
539 | ||
540 | if (r == AVERROR(EINVAL)) | |
541 | return DECODE_ERROR; | |
542 | ||
543 | // retain existing behavior (continue decoding) for legitimate decoding errors | |
544 | } | |
543 | 545 | |
544 | 546 | return DECODE_RUNNING; |
545 | 547 | } |
564 | 566 | } |
565 | 567 | |
566 | 568 | if (ff->frame) { |
567 | // ffmpeg version dependant free function | |
568 | #if !LINKALL | |
569 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) | |
570 | ff->av_frame_free ? AV(ff, frame_free, &ff->frame) : AV(ff, freep, &ff->frame); | |
571 | #else | |
572 | ff->avcodec_free_frame ? AVCODEC(ff, free_frame, &ff->frame) : AV(ff, freep, &ff->frame); | |
573 | #endif | |
574 | #elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,28,0) | |
575 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) | |
576 | 569 | AV(ff, frame_free, &ff->frame); |
577 | #else | |
578 | AVCODEC(ff, free_frame, &ff->frame); | |
579 | #endif | |
580 | #else | |
581 | AV(ff, freep, &ff->frame); | |
582 | #endif | |
583 | 570 | ff->frame = NULL; |
584 | 571 | } |
585 | 572 | |
586 | 573 | if (ff->avpkt) { |
587 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57,24,102) | |
588 | 574 | AV(ff, packet_unref, ff->avpkt); |
589 | #else | |
590 | AV(ff, free_packet, ff->avpkt); | |
591 | #endif | |
592 | 575 | AV(ff, freep, &ff->avpkt); |
593 | 576 | ff->avpkt = NULL; |
594 | 577 | } |
660 | 643 | ff->avcodec_version = dlsym(handle_codec, "avcodec_version"); |
661 | 644 | ff->avcodec_find_decoder = dlsym(handle_codec, "avcodec_find_decoder"); |
662 | 645 | ff->avcodec_open2 = dlsym(handle_codec, "avcodec_open2"); |
663 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) | |
664 | 646 | ff->av_frame_alloc = dlsym(handle_codec, "av_frame_alloc"); |
665 | 647 | ff->av_frame_free = dlsym(handle_codec, "av_frame_free"); |
666 | #else | |
667 | ff->avcodec_alloc_frame = dlsym(handle_codec, "avcodec_alloc_frame"); | |
668 | ff->avcodec_free_frame = dlsym(handle_codec, "avcodec_free_frame"); | |
669 | #endif | |
670 | ff->avcodec_decode_audio4 = dlsym(handle_codec, "avcodec_decode_audio4"); | |
648 | ff->avcodec_send_packet = dlsym(handle_codec, "avcodec_send_packet"); | |
649 | ff->avcodec_receive_frame = dlsym(handle_codec, "avcodec_receive_frame"); | |
671 | 650 | ff->avcodec_alloc_context3 = dlsym(handle_format, "avcodec_alloc_context3"); |
672 | 651 | ff->avcodec_free_context = dlsym(handle_format, "avcodec_free_context"); |
673 | 652 | ff->avcodec_parameters_to_context = dlsym(handle_format, "avcodec_parameters_to_context"); |
653 | ff->av_packet_alloc = dlsym(handle_codec, "av_packet_alloc"); | |
654 | #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,133,100) | |
674 | 655 | ff->av_init_packet = dlsym(handle_codec, "av_init_packet"); |
675 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57,24,102) | |
656 | #endif | |
676 | 657 | ff->av_packet_unref = dlsym(handle_codec, "av_packet_unref"); |
677 | #else | |
678 | ff->av_free_packet = dlsym(handle_codec, "av_free_packet"); | |
679 | #endif | |
680 | 658 | |
681 | 659 | if ((err = dlerror()) != NULL) { |
682 | 660 | LOG_INFO("dlerror: %s", err); |
693 | 671 | ff->avio_alloc_context = dlsym(handle_format, "avio_alloc_context"); |
694 | 672 | ff->av_read_frame = dlsym(handle_format, "av_read_frame"); |
695 | 673 | ff->av_find_input_format= dlsym(handle_format, "av_find_input_format"); |
674 | #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58,9,100) | |
696 | 675 | ff->av_register_all = dlsym(handle_format, "av_register_all"); |
676 | #endif | |
697 | 677 | |
698 | 678 | if ((err = dlerror()) != NULL) { |
699 | 679 | LOG_INFO("dlerror: %s", err); |
760 | 740 | |
761 | 741 | AV(ff, log_set_callback, av_err_callback); |
762 | 742 | |
743 | #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58,9,100) | |
763 | 744 | AV(ff, register_all); |
764 | ||
745 | #endif | |
746 | ||
765 | 747 | registered = true; |
766 | 748 | } |
767 | 749 | |
769 | 751 | |
770 | 752 | static struct codec ret = { |
771 | 753 | 'w', // id |
772 | "wma,wmap", // types | |
754 | "wma,wmap,wmal", // types | |
773 | 755 | READ_SIZE, // min read |
774 | 756 | WRITE_SIZE, // min space |
775 | 757 | ff_open_wma, // open |
777 | 759 | ff_decode, // decode |
778 | 760 | }; |
779 | 761 | |
780 | LOG_INFO("using ffmpeg to decode wma,wmap"); | |
762 | LOG_INFO("using ffmpeg to decode wma,wmap,wmal"); | |
781 | 763 | return &ret; |
782 | 764 | } |
783 | 765 |
122 | 122 | |
123 | 123 | *want = bytes; |
124 | 124 | |
125 | // if there's nothing in the stream buffer, libFLAC will continuously call this function as quickly as possible. slow it down. | |
126 | if (!bytes && !end) | |
127 | usleep(1000); | |
128 | ||
125 | 129 | return end ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; |
126 | 130 | } |
127 | 131 |
132 | 132 | { "KEY_DOWN", 0x7689b04f, true }, |
133 | 133 | { "KEY_HOME", 0x768922dd, false }, |
134 | 134 | { "KEY_MEDIA_REPEAT", 0x768938c7, false }, |
135 | { "KEY_AGAIN", 0x768938c7, false }, | |
135 | 136 | // { "KEY_TITLE", 0x76897887, false }, // Now Playing |
136 | 137 | // { "KEY_TITLE", 0x7689a25d, false }, // Now Playing |
137 | 138 | // { "KEY_TEXT", 0x7689f807, false }, // Size |
27 | 27 | |
28 | 28 | #define TITLE "Squeezelite " VERSION ", Copyright 2012-2015 Adrian Smith, 2015-2021 Ralph Irving." |
29 | 29 | |
30 | #define CODECS_BASE "flac,pcm,mp3,ogg" | |
30 | #define CODECS_BASE "flac,pcm,ogg" | |
31 | 31 | #if NO_FAAD |
32 | 32 | #define CODECS_AAC "" |
33 | 33 | #else |
50 | 50 | #else |
51 | 51 | #define CODECS_DSD "" |
52 | 52 | #endif |
53 | #define CODECS_MP3 " (mad,mpg for specific mp3 codec)" | |
53 | #if !defined(NO_MAD) && !defined(NO_MPG123) | |
54 | #define CODECS_MP3 ",mp3 (mad,mpg for specific mp3 codec)" | |
55 | #elif defined(NO_MAD) && defined(NO_MPG123) | |
56 | #define CODECS_MP3 "" | |
57 | #else | |
58 | #define CODECS_MP3 ",mp3" | |
59 | #endif | |
54 | 60 | |
55 | 61 | #define CODECS CODECS_BASE CODECS_AAC CODECS_FF CODECS_OPUS CODECS_DSD CODECS_MP3 |
56 | 62 | |
138 | 144 | #if LINUX || FREEBSD || SUN |
139 | 145 | " -z \t\t\tDaemonize\n" |
140 | 146 | #endif |
141 | #if RESAMPLE | |
142 | 147 | " -Z <rate>\t\tReport rate to server in helo as the maximum sample rate we can support\n" |
143 | #endif | |
144 | 148 | " -t \t\t\tLicense terms\n" |
145 | 149 | " -? \t\t\tDisplay this help text\n" |
146 | 150 | "\n" |
221 | 225 | #endif |
222 | 226 | #if NO_SSLSYM |
223 | 227 | " NO_SSLSYM" |
228 | #endif | |
229 | #if NO_MPG123 | |
230 | " NO_MPG123" | |
231 | #endif | |
232 | #if NO_MAD | |
233 | " NO_MAD" | |
224 | 234 | #endif |
225 | 235 | #if LINKALL |
226 | 236 | " LINKALL" |
349 | 359 | |
350 | 360 | while (optind < argc && strlen(argv[optind]) >= 2 && argv[optind][0] == '-') { |
351 | 361 | char *opt = argv[optind] + 1; |
352 | if (strstr("oabcCdefmMnNpPrs" | |
362 | if (strstr("oabcCdefmMnNpPrsZ" | |
353 | 363 | #if ALSA |
354 | 364 | "UVO" |
355 | #endif | |
356 | /* | |
357 | * only allow '-Z <rate>' override of maxSampleRate | |
358 | * reported by client if built with the capability to resample! | |
359 | */ | |
360 | #if RESAMPLE | |
361 | "Z" | |
362 | 365 | #endif |
363 | 366 | , opt) && optind < argc - 1) { |
364 | 367 | optarg = argv[optind + 1]; |
525 | 528 | case 'N': |
526 | 529 | namefile = optarg; |
527 | 530 | break; |
531 | case 'Z': | |
532 | maxSampleRate = atoi(optarg); | |
533 | break; | |
528 | 534 | case 'W': |
529 | 535 | pcm_check_header = true; |
530 | 536 | break; |
555 | 561 | } else { |
556 | 562 | resample = ""; |
557 | 563 | } |
558 | break; | |
559 | case 'Z': | |
560 | maxSampleRate = atoi(optarg); | |
561 | 564 | break; |
562 | 565 | #endif |
563 | 566 | #if DSD |
188 | 188 | |
189 | 189 | // work backward to unpack samples (if needed) |
190 | 190 | iptr = (s16_t *) write_buf + count; |
191 | optr = (ISAMPLE_T *) write_buf + frames * 2; | |
191 | IF_DIRECT( | |
192 | optr = (ISAMPLE_T *) outputbuf->writep + frames * 2; | |
193 | ) | |
194 | IF_PROCESS( | |
195 | optr = (ISAMPLE_T *) write_buf + frames * 2; | |
196 | ) | |
192 | 197 | |
193 | 198 | if (channels == 2) { |
194 | 199 | #if BYTES_PER_FRAME == 4 |
224 | 229 | if (stream.state <= DISCONNECT) { |
225 | 230 | LOG_INFO("partial decode"); |
226 | 231 | UNLOCK_O_direct; |
227 | UNLOCK_S; | |
228 | 232 | return DECODE_COMPLETE; |
229 | 233 | } else { |
230 | 234 | LOG_INFO("no frame decoded"); |
46 | 46 | |
47 | 47 | frames_t frames, size; |
48 | 48 | bool silence; |
49 | u8_t flags = output.channels; | |
49 | 50 | |
50 | 51 | s32_t cross_gain_in = 0, cross_gain_out = 0; s32_t *cross_ptr = NULL; |
51 | 52 | |
58 | 59 | silence = false; |
59 | 60 | |
60 | 61 | // start when threshold met |
61 | if (output.state == OUTPUT_BUFFER && frames > output.threshold * output.next_sample_rate / 10 && frames > output.start_frames) { | |
62 | if (output.state == OUTPUT_BUFFER && (frames * BYTES_PER_FRAME) > output.threshold * output.next_sample_rate / 10 && frames > output.start_frames) { | |
62 | 63 | output.state = OUTPUT_RUNNING; |
63 | 64 | LOG_INFO("start buffer frames: %u", frames); |
64 | 65 | wake_controller(); |
255 | 256 | } |
256 | 257 | |
257 | 258 | out_frames = !silence ? min(size, cont_frames) : size; |
258 | ||
259 | wrote = output.write_cb(out_frames, silence, gainL, gainR, cross_gain_in, cross_gain_out, &cross_ptr); | |
259 | ||
260 | IF_DSD( | |
261 | if (output.outfmt != PCM) { | |
262 | flags = 0; | |
263 | } | |
264 | ) | |
265 | ||
266 | wrote = output.write_cb(out_frames, silence, gainL, gainR, flags, cross_gain_in, cross_gain_out, &cross_ptr); | |
260 | 267 | |
261 | 268 | if (wrote <= 0) { |
262 | 269 | frames -= size; |
383 | 390 | output.idle_to = (u32_t) idle; |
384 | 391 | |
385 | 392 | /* Skip test_open for stdout, set default sample rates */ |
386 | if ( output.device[0] == '-' ) { | |
393 | if ( output.device[0] == '-' || user_rates ) { | |
387 | 394 | for (i = 0; i < MAX_SUPPORTED_SAMPLERATES; ++i) { |
388 | 395 | output.supported_rates[i] = rates[i]; |
389 | 396 | } |
392 | 399 | if (!test_open(output.device, output.supported_rates, user_rates)) { |
393 | 400 | LOG_ERROR("unable to open output device: %s", output.device); |
394 | 401 | exit(0); |
395 | } | |
396 | } | |
397 | ||
398 | if (user_rates) { | |
399 | for (i = 0; i < MAX_SUPPORTED_SAMPLERATES; ++i) { | |
400 | output.supported_rates[i] = rates[i]; | |
401 | 402 | } |
402 | 403 | } |
403 | 404 |
296 | 296 | if (snd_pcm_hw_params_test_rate(pcm, hw_params, ref[i], 0) == 0) { |
297 | 297 | rates[ind++] = ref[i]; |
298 | 298 | } |
299 | else { | |
300 | LOG_DEBUG("sample rate %u not supported", ref[i]); | |
301 | } | |
299 | 302 | } |
300 | 303 | } |
301 | 304 | |
546 | 549 | return 0; |
547 | 550 | } |
548 | 551 | |
549 | static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, | |
552 | static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, | |
550 | 553 | s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr) { |
551 | 554 | |
552 | 555 | const snd_pcm_channel_area_t *areas; |
593 | 596 | |
594 | 597 | outputptr = alsa.mmap ? (areas[0].addr + (areas[0].first + offset * areas[0].step) / 8) : alsa.write_buf; |
595 | 598 | |
596 | _scale_and_pack_frames(outputptr, inputptr, out_frames, gainL, gainR, output.format); | |
599 | _scale_and_pack_frames(outputptr, inputptr, out_frames, gainL, gainR, flags, output.format); | |
597 | 600 | |
598 | 601 | } else { |
599 | 602 | |
600 | 603 | outputptr = (void *)inputptr; |
601 | 604 | |
602 | 605 | if (!silence) { |
603 | ||
604 | if (gainL != FIXED_ONE || gainR!= FIXED_ONE) { | |
605 | _apply_gain(outputbuf, out_frames, gainL, gainR); | |
606 | } | |
606 | _apply_gain(outputbuf, out_frames, gainL, gainR, flags); | |
607 | 607 | } |
608 | 608 | } |
609 | 609 | |
675 | 675 | #if GPIO |
676 | 676 | // Wake up amp |
677 | 677 | if (gpio_active) { |
678 | ampstate = 1; | |
679 | 678 | relay(1); |
680 | 679 | } |
681 | 680 | if (power_script != NULL) { |
682 | ampstate = 1; | |
683 | 681 | relay_script(1); |
684 | 682 | } |
685 | 683 | #endif |
809 | 807 | #if GPIO |
810 | 808 | // Put Amp to Sleep |
811 | 809 | if (gpio_active){ |
812 | ampstate = 0; | |
813 | 810 | relay(0); |
814 | 811 | } |
815 | 812 | if (power_script != NULL ){ |
816 | ampstate = 0; | |
817 | 813 | relay_script(0); |
818 | 814 | } |
819 | 815 | #endif |
213 | 213 | #endif |
214 | 214 | switch (err) { |
215 | 215 | case paInvalidSampleRate: |
216 | LOG_DEBUG("sample rate %u not supported", ref[i]); | |
216 | 217 | continue; |
217 | 218 | #if WIN |
218 | 219 | #ifndef PA18API |
447 | 448 | |
448 | 449 | static u8_t *optr; |
449 | 450 | |
450 | static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, | |
451 | static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, | |
451 | 452 | s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr) { |
452 | 453 | |
453 | 454 | if (!silence) { |
457 | 458 | } |
458 | 459 | |
459 | 460 | if (gainL != FIXED_ONE || gainR!= FIXED_ONE) { |
460 | _apply_gain(outputbuf, out_frames, gainL, gainR); | |
461 | _apply_gain(outputbuf, out_frames, gainL, gainR, flags); | |
461 | 462 | } |
462 | 463 | |
463 | 464 | IF_DSD( |
42 | 42 | return (s32_t)(f * 65536.0F); |
43 | 43 | } |
44 | 44 | |
45 | void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format) { | |
45 | void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, u8_t flags, output_format format) { | |
46 | // in-place copy input samples if mono/combined is used (never happens with DSD active) | |
47 | if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) { | |
48 | s32_t *ptr = inputptr; | |
49 | frames_t count = cnt; | |
50 | while (count--) { | |
51 | // use 64 bits integer for purists but should really not care | |
52 | *ptr = *(ptr + 1) = ((s64_t) *ptr + (s64_t) *(ptr + 1)) / 2; | |
53 | ptr += 2; | |
54 | } | |
55 | } else if (flags & MONO_RIGHT) { | |
56 | s32_t *ptr = inputptr + 1; | |
57 | frames_t count = cnt; | |
58 | while (count--) { | |
59 | *(ptr - 1) = *ptr; | |
60 | ptr += 2; | |
61 | } | |
62 | } else if (flags & MONO_LEFT) { | |
63 | s32_t *ptr = inputptr; | |
64 | frames_t count = cnt; | |
65 | while (count--) { | |
66 | *(ptr + 1) = *ptr; | |
67 | ptr += 2; | |
68 | } | |
69 | } | |
70 | ||
46 | 71 | switch(format) { |
47 | 72 | #if DSD |
48 | 73 | case U32_LE: |
352 | 377 | #if !WIN |
353 | 378 | inline |
354 | 379 | #endif |
355 | void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) { | |
356 | s32_t *ptrL = (s32_t *)(void *)outputbuf->readp; | |
357 | s32_t *ptrR = (s32_t *)(void *)outputbuf->readp + 1; | |
358 | while (count--) { | |
359 | *ptrL = gain(gainL, *ptrL); | |
360 | *ptrR = gain(gainR, *ptrR); | |
361 | ptrL += 2; | |
362 | ptrR += 2; | |
380 | void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR, u8_t flags) { | |
381 | if (gainL == FIXED_ONE && gainR == FIXED_ONE && !(flags & (MONO_LEFT | MONO_RIGHT))) { | |
382 | return; | |
383 | } else if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) { | |
384 | ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp; | |
385 | ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1; | |
386 | while (count--) { | |
387 | *ptrL = *ptrR = (gain(gainL, *ptrL) + gain(gainR, *ptrR)) / 2; | |
388 | ptrL += 2; ptrR += 2; | |
389 | } | |
390 | ||
391 | } else if (flags & MONO_RIGHT) { | |
392 | ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1; | |
393 | while (count--) { | |
394 | *(ptr - 1) = *ptr = gain(gainR, *ptr); | |
395 | ptr += 2; | |
396 | } | |
397 | } else if (flags & MONO_LEFT) { | |
398 | ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp; | |
399 | while (count--) { | |
400 | *(ptr + 1) = *ptr = gain(gainL, *ptr); | |
401 | ptr += 2; | |
402 | } | |
403 | } else { | |
404 | ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp; | |
405 | ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1; | |
406 | while (count--) { | |
407 | *ptrL = gain(gainL, *ptrL); | |
408 | *ptrR = gain(gainR, *ptrR); | |
409 | ptrL += 2; ptrR += 2; | |
410 | } | |
363 | 411 | } |
364 | 412 | } |
361 | 361 | d->default_sink_name = strdup(l->name); |
362 | 362 | |
363 | 363 | if (!d->userdef_rates) { |
364 | d->rates[0] = l->sample_spec.rate; | |
365 | } | |
364 | d->rates[0] = PA_RATE_MAX; | |
365 | } | |
366 | output.default_sample_rate = l->sample_spec.rate; | |
366 | 367 | |
367 | 368 | *d->sample_spec = l->sample_spec; |
368 | 369 | } |
385 | 386 | return true; |
386 | 387 | } |
387 | 388 | |
388 | static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, | |
389 | static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, | |
389 | 390 | s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr) { |
390 | 391 | pa_stream_write(pulse.stream, silence ? silencebuf : outputbuf->readp, out_frames * BYTES_PER_FRAME, (pa_free_cb_t)NULL, 0, PA_SEEK_RELATIVE); |
391 | 392 | return (int)out_frames; |
44 | 44 | static unsigned buffill; |
45 | 45 | static int bytes_per_frame; |
46 | 46 | |
47 | static int _stdout_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, | |
47 | static int _stdout_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, | |
48 | 48 | s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr) { |
49 | 49 | |
50 | 50 | u8_t *obuf; |
74 | 74 | } |
75 | 75 | ) |
76 | 76 | |
77 | _scale_and_pack_frames(buf + buffill * bytes_per_frame, (s32_t *)(void *)obuf, out_frames, gainL, gainR, output.format); | |
77 | _scale_and_pack_frames(buf + buffill * bytes_per_frame, (s32_t *)(void *)obuf, out_frames, gainL, gainR, flags, output.format); | |
78 | 78 | |
79 | 79 | buffill += out_frames; |
80 | 80 |
62 | 62 | #define MAX_DECODE_FRAMES 4096 |
63 | 63 | |
64 | 64 | static u32_t sample_rates[] = { |
65 | 11025, 22050, 32000, 44100, 48000, 8000, 12000, 16000, 24000, 96000, 88200, 176400, 192000, 352800, 384000, 705600, 768000 | |
65 | 11025, 22050, 32000, 44100, 48000, 8000, 12000, 16000, 24000, 96000, 88200, 176400, 192000, 352800, 384000, 705600, 768000, 1411200, 1536000 | |
66 | 66 | }; |
67 | 67 | |
68 | 68 | static u32_t sample_rate; |
119 | 119 | } |
120 | 120 | |
121 | 121 | static void sendHELO(bool reconnect, const char *fixed_cap, const char *var_cap, u8_t mac[6]) { |
122 | #define BASE_CAP "Model=squeezelite,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Firmware=" VERSION | |
122 | #define BASE_CAP "Model=squeezelite,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Balance=1,Firmware=" VERSION | |
123 | 123 | #define SSL_CAP "CanHTTPS=1" |
124 | 124 | const char *base_cap; |
125 | 125 | struct HELO_packet pkt; |
379 | 379 | output.fade_mode = strm->transition_type - '0'; |
380 | 380 | output.fade_secs = strm->transition_period; |
381 | 381 | output.invert = (strm->flags & 0x03) == 0x03; |
382 | LOG_DEBUG("set fade mode: %u", output.fade_mode); | |
382 | output.channels = (strm->flags & 0x0c) >> 2; | |
383 | LOG_DEBUG("set fade mode: %u, channels: %u, invert: %u", output.fade_mode, output.channels, output.invert); | |
383 | 384 | UNLOCK_O; |
384 | 385 | } |
385 | 386 | break; |
874 | 875 | |
875 | 876 | LOCK_O; |
876 | 877 | snprintf(fixed_cap, FIXED_CAP_LEN, ",ModelName=%s,MaxSampleRate=%u", modelname ? modelname : MODEL_NAME_STRING, |
878 | #if RESAMPLE | |
877 | 879 | ((maxSampleRate > 0) ? maxSampleRate : output.supported_rates[0])); |
880 | #else | |
881 | ((maxSampleRate > 0 && maxSampleRate < output.supported_rates[0]) ? maxSampleRate : output.supported_rates[0])); | |
882 | #endif | |
878 | 883 | |
879 | 884 | for (i = 0; i < MAX_CODECS; i++) { |
880 | 885 | if (codecs[i] && codecs[i]->id && strlen(fixed_cap) < FIXED_CAP_LEN - 10) { |
24 | 24 | // make may define: PORTAUDIO, SELFPIPE, RESAMPLE, RESAMPLE_MP, VISEXPORT, GPIO, IR, DSD, LINKALL to influence build |
25 | 25 | |
26 | 26 | #define MAJOR_VERSION "1.9" |
27 | #define MINOR_VERSION "8" | |
28 | #define MICRO_VERSION "1317" | |
27 | #define MINOR_VERSION "9" | |
28 | #define MICRO_VERSION "1411" | |
29 | 29 | |
30 | 30 | #if defined(CUSTOM_VERSION) |
31 | 31 | #define VERSION "v" MAJOR_VERSION "." MINOR_VERSION "-" MICRO_VERSION STR(CUSTOM_VERSION) |
614 | 614 | typedef enum { FADE_UP = 1, FADE_DOWN, FADE_CROSS } fade_dir; |
615 | 615 | typedef enum { FADE_NONE = 0, FADE_CROSSFADE, FADE_IN, FADE_OUT, FADE_INOUT } fade_mode; |
616 | 616 | |
617 | #define MAX_SUPPORTED_SAMPLERATES 18 | |
618 | #define TEST_RATES = { 768000, 705600, 384000, 352800, 192000, 176400, 96000, 88200, 48000, 44100, 32000, 24000, 22500, 16000, 12000, 11025, 8000, 0 } | |
617 | #define MONO_RIGHT 0x02 | |
618 | #define MONO_LEFT 0x01 | |
619 | #define MAX_SUPPORTED_SAMPLERATES 20 | |
620 | #define TEST_RATES = { 1536000, 1411200, 768000, 705600, 384000, 352800, 192000, 176400, 96000, 88200, 48000, 44100, 32000, 24000, 22500, 16000, 12000, 11025, 8000, 0 } | |
619 | 621 | |
620 | 622 | struct outputstate { |
621 | 623 | output_state state; |
622 | 624 | output_format format; |
625 | u8_t channels; | |
623 | 626 | const char *device; |
624 | 627 | #if ALSA |
625 | 628 | unsigned buffer; |
631 | 634 | unsigned latency; |
632 | 635 | int pa_hostapi_option; |
633 | 636 | #endif |
634 | int (* write_cb)(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr); | |
637 | int (* write_cb)(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, u8_t flags, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr); | |
635 | 638 | unsigned start_frames; |
636 | 639 | unsigned frames_played; |
637 | 640 | unsigned frames_played_dmp;// frames played at the point delay is measured |
715 | 718 | void output_close_stdout(void); |
716 | 719 | |
717 | 720 | // output_pack.c |
718 | void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format); | |
721 | void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, u8_t flags, output_format format); | |
719 | 722 | void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr); |
720 | void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR); | |
723 | void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR, u8_t flags); | |
721 | 724 | s32_t gain(s32_t gain, s32_t sample); |
722 | 725 | s32_t to_gain(float f); |
723 | 726 | |
758 | 761 | struct codec *register_opus(void); |
759 | 762 | #endif |
760 | 763 | |
761 | //gpio.c | |
764 | // gpio.c | |
762 | 765 | #if GPIO |
763 | void relay( int state); | |
766 | void relay(int state); | |
764 | 767 | void relay_script(int state); |
765 | 768 | int gpio_pin; |
766 | 769 | bool gpio_active_low; |
767 | 770 | bool gpio_active; |
768 | 771 | char *power_script; |
769 | // my amp state | |
770 | int ampstate; | |
772 | ||
771 | 773 | #if RPI |
772 | 774 | #define PI_INPUT 0 |
773 | 775 | #define PI_OUTPUT 1 |
129 | 129 | <Tool |
130 | 130 | Name="VCLinkerTool" |
131 | 131 | AdditionalOptions="/NODEFAULTLIB:LIBCMT" |
132 | AdditionalDependencies="ws2_32.lib lib\portaudio.lib lib\libogg.lib lib\libvorbisfile.lib lib\libvorbis.lib lib\libmad.lib lib\libFLAC.lib lib\libfaad.lib lib\libmpg123.lib lib\libsoxr.lib lib\libavformat.a lib\libavcodec.a lib\libavutil.a lib\ssleay32.lib lib\libeay32.lib lib\opus.lib lib\opusfile.lib" | |
132 | AdditionalDependencies="ws2_32.lib crypt32.lib lib\portaudio.lib lib\libogg.lib lib\libvorbisfile.lib lib\libvorbis.lib lib\libmad.lib lib\libFLAC.lib lib\libfaad.lib lib\libmpg123.lib lib\libsoxr.lib lib\libavformat.a lib\libavcodec.a lib\libavutil.a lib\ssleay32.lib lib\libeay32.lib lib\opus.lib lib\opusfile.lib" | |
133 | 133 | OutputFile="$(OutDir)\$(ProjectName)-ffmpeg.exe" |
134 | 134 | LinkIncremental="1" |
135 | 135 | ModuleDefinitionFile="" |
50 | 50 | struct streamstate stream; |
51 | 51 | |
52 | 52 | #if USE_SSL |
53 | #if WIN | |
54 | #define _last_error() WSAGetLastError() | |
55 | #define ERROR_WOULDBLOCK WSAEWOULDBLOCK | |
56 | #else | |
53 | 57 | #define _last_error() ERROR_WOULDBLOCK |
54 | ||
58 | #endif | |
55 | 59 | static SSL_CTX *SSLctx; |
56 | 60 | SSL *ssl; |
57 | 61 | |
106 | 110 | |
107 | 111 | unsigned try = 0; |
108 | 112 | ssize_t n; |
113 | int error; | |
109 | 114 | |
110 | 115 | while (len) { |
111 | 116 | n = _send(ssl, fd, ptr, len, MSG_NOSIGNAL); |
112 | 117 | if (n <= 0) { |
113 | if (n < 0 && _last_error() == ERROR_WOULDBLOCK && try < 10) { | |
114 | LOG_SDEBUG("retrying (%d) writing to socket", ++try); | |
118 | error = _last_error(); | |
119 | #if WIN | |
120 | if (n < 0 && (error == ERROR_WOULDBLOCK || error == WSAENOTCONN) && try < 10) { | |
121 | #else | |
122 | if (n < 0 && error == ERROR_WOULDBLOCK && try < 10) { | |
123 | #endif | |
124 | LOG_DEBUG("retrying (%d) writing to socket", ++try); | |
115 | 125 | usleep(1000); |
116 | 126 | continue; |
117 | 127 | } |
118 | LOG_INFO("failed writing to socket: %s", strerror(last_error())); | |
128 | LOG_WARN("failed writing to socket: %s", strerror(last_error())); | |
119 | 129 | stream.disconnect = LOCAL_DISCONNECT; |
120 | 130 | stream.state = DISCONNECT; |
121 | 131 | wake_controller(); |
386 | 396 | // stream body into streambuf |
387 | 397 | } else { |
388 | 398 | int n; |
399 | int error; | |
389 | 400 | |
390 | 401 | space = min(_buf_space(streambuf), _buf_cont_write(streambuf)); |
391 | 402 | if (stream.meta_interval) { |
394 | 405 | |
395 | 406 | n = _recv(ssl, fd, streambuf->writep, space, 0); |
396 | 407 | if (n == 0) { |
397 | LOG_INFO("end of stream"); | |
408 | LOG_INFO("end of stream (%u bytes)", stream.bytes); | |
398 | 409 | _disconnect(DISCONNECT, DISCONNECT_OK); |
399 | 410 | } |
400 | if (n < 0 && _last_error() != ERROR_WOULDBLOCK) { | |
401 | LOG_INFO("error reading: %s", strerror(last_error())); | |
402 | _disconnect(DISCONNECT, REMOTE_DISCONNECT); | |
411 | if (n < 0) { | |
412 | error = _last_error(); | |
413 | if (error != ERROR_WOULDBLOCK) { | |
414 | LOG_INFO("error reading: %s (%d)", strerror(error), error); | |
415 | _disconnect(DISCONNECT, REMOTE_DISCONNECT); | |
416 | } | |
403 | 417 | } |
404 | 418 | |
405 | 419 | if (n > 0) { |
556 | 570 | |
557 | 571 | *host = '\0'; |
558 | 572 | p = strcasestr(header,"Host:"); |
559 | if (p) sscanf(p, "Host:%255[^:]", host); | |
573 | if (p) { | |
574 | sscanf(p, "Host:%255s", host); | |
575 | if ((p = strchr(host, ':')) != NULL) *p = '\0'; | |
576 | } | |
560 | 577 | |
561 | 578 | port = ntohs(port); |
562 | 579 | sock = connect_socket(use_ssl || port == 443); |
488 | 488 | } |
489 | 489 | #endif |
490 | 490 | |
491 | #if WIN && USE_SSL | |
491 | #if WIN | |
492 | 492 | char *strcasestr(const char *haystack, const char *needle) { |
493 | 493 | size_t length_needle; |
494 | 494 | size_t length_haystack; |
235 | 235 | |
236 | 236 | // work backward to unpack samples (if needed) |
237 | 237 | iptr = (s16_t *) write_buf + count; |
238 | optr = (ISAMPLE_T *) write_buf + frames * 2; | |
238 | IF_DIRECT( | |
239 | optr = (ISAMPLE_T *) outputbuf->writep + frames * 2; | |
240 | ) | |
241 | IF_PROCESS( | |
242 | optr = (ISAMPLE_T *) write_buf + frames * 2; | |
243 | ) | |
239 | 244 | |
240 | 245 | if (channels == 2) { |
241 | 246 | #if BYTES_PER_FRAME == 4 |