diff --git a/Makefile.i386 b/Makefile.i386 index 6e58824..c2ff131 100644 --- a/Makefile.i386 +++ b/Makefile.i386 @@ -1,7 +1,7 @@ -# OSX 10.5 Intel 32-bit -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 +# OSX 10.7 Intel 32-bit +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 -LDFLAGS = -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5.sdk -arch i386 -mmacosx-version-min=10.5 -L./lib +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 LDADD = -lportaudio -lpthread -ldl -lm -framework CoreVideo -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon diff --git a/Makefile.m1 b/Makefile.m1 new file mode 100644 index 0000000..0c132a4 --- /dev/null +++ b/Makefile.m1 @@ -0,0 +1,8 @@ +# OSX 11.0+ arm64 only +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/MacOSX11.1.sdk -mmacosx-version-min=11.0 + +LDFLAGS = -arch arm64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk -mmacosx-version-min=11.0 -L./libm1 + +LDADD = -lportaudio -lpthread -ldl -lm -framework CoreVideo -framework VideoDecodeAcceleration -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon + +include Makefile diff --git a/Makefile.x86_64 b/Makefile.x86_64 index 0289a11..18e4d2b 100644 --- a/Makefile.x86_64 +++ b/Makefile.x86_64 @@ -1,5 +1,5 @@ # OSX 10.7+ 64-bit only -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 +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 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 diff --git a/alac.c b/alac.c index b8b524b..6de2640 100644 --- a/alac.c +++ b/alac.c @@ -120,8 +120,15 @@ // extract audio config from within alac if (!strcmp(type, "alac") && bytes > len) { u8_t *ptr = streambuf->readp + 36; - l->decoder = alac_create_decoder(len - 36, ptr, &l->sample_size, &l->sample_rate, &l->channels); - l->play = l->trak; + unsigned int block_size; + l->play = l->trak; + l->decoder = alac_create_decoder(len - 36, ptr, &l->sample_size, &l->sample_rate, &l->channels, &block_size); + l->writebuf = malloc(block_size + 256); + LOG_INFO("allocated write buffer of %u bytes", block_size); + if (!l->writebuf) { + LOG_ERROR("allocation failed"); + return -1; + } } // extract the total number of samples from stts @@ -376,10 +383,9 @@ // need to create a buffer with contiguous data if (bytes < block_size) { - u8_t *buffer = malloc(block_size); - memcpy(buffer, streambuf->readp, bytes); - memcpy(buffer + bytes, streambuf->buf, block_size - bytes); - iptr = buffer; + iptr = malloc(block_size); + memcpy(iptr, streambuf->readp, bytes); + memcpy(iptr + bytes, streambuf->buf, block_size - bytes); } else iptr = streambuf->readp; if (!alac_to_pcm(l->decoder, iptr, l->writebuf, 2, &frames)) { @@ -474,6 +480,7 @@ } } else if (l->sample_size == 16) { u16_t *_iptr = (u16_t*) iptr; + iptr += count * 4; while (count--) { *optr++ = ALIGN16(*_iptr++); *optr++ = ALIGN16(*_iptr++); @@ -486,6 +493,7 @@ } } else if (l->sample_size == 32) { u32_t *_iptr = (u32_t*) iptr; + iptr += count * 8; while (count--) { *optr++ = ALIGN32(*_iptr++); *optr++ = ALIGN32(*_iptr++); @@ -511,27 +519,17 @@ return DECODE_RUNNING; } -static void alac_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) { - if (l->decoder) alac_delete_decoder(l->decoder); - else l->writebuf = malloc(BLOCK_SIZE * 2); - +static void alac_close(void) { + if (l->decoder) alac_delete_decoder(l->decoder); + if (l->writebuf) free(l->writebuf); if (l->chunkinfo) free(l->chunkinfo); if (l->block_size) free(l->block_size); if (l->stsc) free(l->stsc); - l->decoder = l->chunkinfo = l->stsc = l->block_size = NULL; - l->skip = 0; - l->samples = l->sttssamples = 0; - l->empty = false; - l->pos = l->consume = l->sample = l->nextchunk = 0; + memset(l, 0, sizeof(struct alac)); } -static void alac_close(void) { - if (l->decoder) alac_delete_decoder(l->decoder); - if (l->chunkinfo) free(l->chunkinfo); - if (l->block_size) free(l->block_size); - if (l->stsc) free(l->stsc); - l->decoder = l->chunkinfo = l->stsc = l->block_size = NULL; - free(l->writebuf); +static void alac_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) { + alac_close(); } struct codec *register_alac(void) { @@ -544,14 +542,10 @@ alac_close, // close alac_decode, // decode }; - - l = malloc(sizeof(struct alac)); - if (!l) { - return NULL; - } - - l->decoder = l->chunkinfo = l->stsc = l->block_size = NULL; - + + l = calloc(1, sizeof(struct alac)); + if (!l) return NULL; + LOG_INFO("using alac to decode alc"); return &ret; } diff --git a/alac_wrapper.cpp b/alac_wrapper.cpp index 427b9b4..35c6842 100644 --- a/alac_wrapper.cpp +++ b/alac_wrapper.cpp @@ -32,7 +32,7 @@ /*----------------------------------------------------------------------------*/ extern "C" struct alac_codec_s *alac_create_decoder(int magic_cookie_size, unsigned char *magic_cookie, unsigned char *sample_size, unsigned *sample_rate, - unsigned char *channels) { + unsigned char *channels, unsigned int *block_size) { struct alac_codec_s *codec = (struct alac_codec_s*) malloc(sizeof(struct alac_codec_s)); codec->Decoder = new ALACDecoder; @@ -43,7 +43,7 @@ *sample_size = codec->Decoder->mConfig.bitDepth; codec->frames_per_packet = codec->Decoder->mConfig.frameLength; - codec->block_size = codec->frames_per_packet * (*channels) * (*sample_size) / 8; + *block_size = codec->block_size = codec->frames_per_packet * (*channels) * (*sample_size) / 8; return codec; } diff --git a/alac_wrapper.h b/alac_wrapper.h index 5f01483..d37692f 100644 --- a/alac_wrapper.h +++ b/alac_wrapper.h @@ -28,7 +28,7 @@ struct alac_codec_s *alac_create_decoder(int magic_cookie_size, unsigned char *magic_cookie, unsigned char *sample_size, unsigned *sample_rate, - unsigned char *channels); + unsigned char *channels, unsigned int *block_size); void alac_delete_decoder(struct alac_codec_s *codec); bool alac_to_pcm(struct alac_codec_s *codec, unsigned char* input, unsigned char *output, char channels, unsigned *out_frames); diff --git a/buffer.c b/buffer.c index 125661f..0fd2b05 100644 --- a/buffer.c +++ b/buffer.c @@ -27,7 +27,10 @@ // _* called with muxtex locked -inline unsigned _buf_used(struct buffer *buf) { +#if !WIN +inline +#endif +unsigned _buf_used(struct buffer *buf) { return buf->writep >= buf->readp ? buf->writep - buf->readp : buf->size - (buf->readp - buf->writep); } diff --git a/debian/changelog b/debian/changelog index 7c636db..f938d8b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +squeezelite (1.9+git20210513.556de56-1) UNRELEASED; urgency=low + + * New upstream snapshot. + + -- Debian Janitor Tue, 17 Aug 2021 16:54:25 -0000 + squeezelite (1.9+git20210102.78fef68-3) unstable; urgency=medium * Upload to unstable. diff --git a/ir.c b/ir.c index a2aedd1..922ea64 100644 --- a/ir.c +++ b/ir.c @@ -133,6 +133,7 @@ { "KEY_DOWN", 0x7689b04f, true }, { "KEY_HOME", 0x768922dd, false }, { "KEY_MEDIA_REPEAT", 0x768938c7, false }, + { "KEY_AGAIN", 0x768938c7, false }, // { "KEY_TITLE", 0x76897887, false }, // Now Playing // { "KEY_TITLE", 0x7689a25d, false }, // Now Playing // { "KEY_TEXT", 0x7689f807, false }, // Size diff --git a/main.c b/main.c index 2b736db..dcb5748 100644 --- a/main.c +++ b/main.c @@ -139,9 +139,7 @@ #if LINUX || FREEBSD || SUN " -z \t\t\tDaemonize\n" #endif -#if RESAMPLE " -Z \t\tReport rate to server in helo as the maximum sample rate we can support\n" -#endif " -t \t\t\tLicense terms\n" " -? \t\t\tDisplay this help text\n" "\n" @@ -350,16 +348,9 @@ while (optind < argc && strlen(argv[optind]) >= 2 && argv[optind][0] == '-') { char *opt = argv[optind] + 1; - if (strstr("oabcCdefmMnNpPrs" + if (strstr("oabcCdefmMnNpPrsZ" #if ALSA "UVO" -#endif -/* - * only allow '-Z ' override of maxSampleRate - * reported by client if built with the capability to resample! - */ -#if RESAMPLE - "Z" #endif , opt) && optind < argc - 1) { optarg = argv[optind + 1]; @@ -526,6 +517,9 @@ case 'N': namefile = optarg; break; + case 'Z': + maxSampleRate = atoi(optarg); + break; case 'W': pcm_check_header = true; break; @@ -556,9 +550,6 @@ } else { resample = ""; } - break; - case 'Z': - maxSampleRate = atoi(optarg); break; #endif #if DSD diff --git a/opus.c b/opus.c index 1e1792c..ee75476 100644 --- a/opus.c +++ b/opus.c @@ -189,7 +189,12 @@ // work backward to unpack samples (if needed) iptr = (s16_t *) write_buf + count; - optr = (ISAMPLE_T *) write_buf + frames * 2; + IF_DIRECT( + optr = (ISAMPLE_T *) outputbuf->writep + frames * 2; + ) + IF_PROCESS( + optr = (ISAMPLE_T *) write_buf + frames * 2; + ) if (channels == 2) { #if BYTES_PER_FRAME == 4 diff --git a/output.c b/output.c index 7d3fce1..99d4cc4 100644 --- a/output.c +++ b/output.c @@ -47,6 +47,7 @@ frames_t frames, size; bool silence; + u8_t flags = output.channels; s32_t cross_gain_in = 0, cross_gain_out = 0; s32_t *cross_ptr = NULL; @@ -59,7 +60,7 @@ silence = false; // start when threshold met - if (output.state == OUTPUT_BUFFER && frames > output.threshold * output.next_sample_rate / 10 && frames > output.start_frames) { + if (output.state == OUTPUT_BUFFER && (frames * BYTES_PER_FRAME) > output.threshold * output.next_sample_rate / 10 && frames > output.start_frames) { output.state = OUTPUT_RUNNING; LOG_INFO("start buffer frames: %u", frames); wake_controller(); @@ -256,8 +257,14 @@ } out_frames = !silence ? min(size, cont_frames) : size; - - wrote = output.write_cb(out_frames, silence, gainL, gainR, cross_gain_in, cross_gain_out, &cross_ptr); + + IF_DSD( + if (output.outfmt != PCM) { + flags = 0; + } + ) + + wrote = output.write_cb(out_frames, silence, gainL, gainR, flags, cross_gain_in, cross_gain_out, &cross_ptr); if (wrote <= 0) { frames -= size; diff --git a/output_alsa.c b/output_alsa.c index aa663cd..125a737 100644 --- a/output_alsa.c +++ b/output_alsa.c @@ -547,7 +547,7 @@ return 0; } -static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _write_frames(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) { const snd_pcm_channel_area_t *areas; @@ -594,17 +594,14 @@ outputptr = alsa.mmap ? (areas[0].addr + (areas[0].first + offset * areas[0].step) / 8) : alsa.write_buf; - _scale_and_pack_frames(outputptr, inputptr, out_frames, gainL, gainR, output.format); + _scale_and_pack_frames(outputptr, inputptr, out_frames, gainL, gainR, flags, output.format); } else { outputptr = (void *)inputptr; if (!silence) { - - if (gainL != FIXED_ONE || gainR!= FIXED_ONE) { - _apply_gain(outputbuf, out_frames, gainL, gainR); - } + _apply_gain(outputbuf, out_frames, gainL, gainR, flags); } } @@ -676,11 +673,9 @@ #if GPIO // Wake up amp if (gpio_active) { - ampstate = 1; relay(1); } if (power_script != NULL) { - ampstate = 1; relay_script(1); } #endif @@ -810,11 +805,9 @@ #if GPIO // Put Amp to Sleep if (gpio_active){ - ampstate = 0; relay(0); } if (power_script != NULL ){ - ampstate = 0; relay_script(0); } #endif diff --git a/output_pa.c b/output_pa.c index 8729f81..96b135d 100644 --- a/output_pa.c +++ b/output_pa.c @@ -448,7 +448,7 @@ static u8_t *optr; -static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _write_frames(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) { if (!silence) { @@ -458,7 +458,7 @@ } if (gainL != FIXED_ONE || gainR!= FIXED_ONE) { - _apply_gain(outputbuf, out_frames, gainL, gainR); + _apply_gain(outputbuf, out_frames, gainL, gainR, flags); } IF_DSD( diff --git a/output_pack.c b/output_pack.c index 7043f6f..fa855ed 100644 --- a/output_pack.c +++ b/output_pack.c @@ -43,7 +43,32 @@ return (s32_t)(f * 65536.0F); } -void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format) { +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) { + // in-place copy input samples if mono/combined is used (never happens with DSD active) + if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) { + s32_t *ptr = inputptr; + frames_t count = cnt; + while (count--) { + // use 64 bits integer for purists but should really not care + *ptr = *(ptr + 1) = ((s64_t) *ptr + (s64_t) *(ptr + 1)) / 2; + ptr += 2; + } + } else if (flags & MONO_RIGHT) { + s32_t *ptr = inputptr + 1; + frames_t count = cnt; + while (count--) { + *(ptr - 1) = *ptr; + ptr += 2; + } + } else if (flags & MONO_LEFT) { + s32_t *ptr = inputptr; + frames_t count = cnt; + while (count--) { + *(ptr + 1) = *ptr; + ptr += 2; + } + } + switch(format) { #if DSD case U32_LE: @@ -353,13 +378,36 @@ #if !WIN inline #endif -void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) { - s32_t *ptrL = (s32_t *)(void *)outputbuf->readp; - s32_t *ptrR = (s32_t *)(void *)outputbuf->readp + 1; - while (count--) { - *ptrL = gain(gainL, *ptrL); - *ptrR = gain(gainR, *ptrR); - ptrL += 2; - ptrR += 2; +void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR, u8_t flags) { + if (gainL == FIXED_ONE && gainR == FIXED_ONE && !(flags & (MONO_LEFT | MONO_RIGHT))) { + return; + } else if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) { + ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp; + ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1; + while (count--) { + *ptrL = *ptrR = (gain(gainL, *ptrL) + gain(gainR, *ptrR)) / 2; + ptrL += 2; ptrR += 2; + } + + } else if (flags & MONO_RIGHT) { + ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1; + while (count--) { + *(ptr - 1) = *ptr = gain(gainR, *ptr); + ptr += 2; + } + } else if (flags & MONO_LEFT) { + ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp; + while (count--) { + *(ptr + 1) = *ptr = gain(gainL, *ptr); + ptr += 2; + } + } else { + ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp; + ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1; + while (count--) { + *ptrL = gain(gainL, *ptrL); + *ptrR = gain(gainR, *ptrR); + ptrL += 2; ptrR += 2; + } } } diff --git a/output_pulse.c b/output_pulse.c index 69e194d..274380d 100644 --- a/output_pulse.c +++ b/output_pulse.c @@ -362,8 +362,9 @@ d->default_sink_name = strdup(l->name); if (!d->userdef_rates) { - d->rates[0] = l->sample_spec.rate; - } + d->rates[0] = PA_RATE_MAX; + } + output.default_sample_rate = l->sample_spec.rate; *d->sample_spec = l->sample_spec; } @@ -386,7 +387,7 @@ return true; } -static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _write_frames(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) { pa_stream_write(pulse.stream, silence ? silencebuf : outputbuf->readp, out_frames * BYTES_PER_FRAME, (pa_free_cb_t)NULL, 0, PA_SEEK_RELATIVE); return (int)out_frames; diff --git a/output_stdout.c b/output_stdout.c index 640a883..036f700 100644 --- a/output_stdout.c +++ b/output_stdout.c @@ -45,7 +45,7 @@ static unsigned buffill; static int bytes_per_frame; -static int _stdout_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, +static int _stdout_write_frames(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) { u8_t *obuf; @@ -75,7 +75,7 @@ } ) - _scale_and_pack_frames(buf + buffill * bytes_per_frame, (s32_t *)(void *)obuf, out_frames, gainL, gainR, output.format); + _scale_and_pack_frames(buf + buffill * bytes_per_frame, (s32_t *)(void *)obuf, out_frames, gainL, gainR, flags, output.format); buffill += out_frames; diff --git a/slimproto.c b/slimproto.c index edc6bff..d81f512 100644 --- a/slimproto.c +++ b/slimproto.c @@ -120,7 +120,7 @@ } static void sendHELO(bool reconnect, const char *fixed_cap, const char *var_cap, u8_t mac[6]) { - #define BASE_CAP "Model=squeezelite,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Firmware=" VERSION + #define BASE_CAP "Model=squeezelite,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Balance=1,Firmware=" VERSION #define SSL_CAP "CanHTTPS=1" const char *base_cap; struct HELO_packet pkt; @@ -380,7 +380,8 @@ output.fade_mode = strm->transition_type - '0'; output.fade_secs = strm->transition_period; output.invert = (strm->flags & 0x03) == 0x03; - LOG_DEBUG("set fade mode: %u", output.fade_mode); + output.channels = (strm->flags & 0x0c) >> 2; + LOG_DEBUG("set fade mode: %u, channels: %u, invert: %u", output.fade_mode, output.channels, output.invert); UNLOCK_O; } break; @@ -875,7 +876,11 @@ LOCK_O; snprintf(fixed_cap, FIXED_CAP_LEN, ",ModelName=%s,MaxSampleRate=%u", modelname ? modelname : MODEL_NAME_STRING, +#if RESAMPLE ((maxSampleRate > 0) ? maxSampleRate : output.supported_rates[0])); +#else + ((maxSampleRate > 0 && maxSampleRate < output.supported_rates[0]) ? maxSampleRate : output.supported_rates[0])); +#endif for (i = 0; i < MAX_CODECS; i++) { if (codecs[i] && codecs[i]->id && strlen(fixed_cap) < FIXED_CAP_LEN - 10) { diff --git a/squeezelite.h b/squeezelite.h index fd89073..c86392c 100644 --- a/squeezelite.h +++ b/squeezelite.h @@ -25,8 +25,8 @@ // make may define: PORTAUDIO, SELFPIPE, RESAMPLE, RESAMPLE_MP, VISEXPORT, GPIO, IR, DSD, LINKALL to influence build #define MAJOR_VERSION "1.9" -#define MINOR_VERSION "8" -#define MICRO_VERSION "1317" +#define MINOR_VERSION "9" +#define MICRO_VERSION "1386" #if defined(CUSTOM_VERSION) #define VERSION "v" MAJOR_VERSION "." MINOR_VERSION "-" MICRO_VERSION STR(CUSTOM_VERSION) @@ -615,12 +615,15 @@ typedef enum { FADE_UP = 1, FADE_DOWN, FADE_CROSS } fade_dir; typedef enum { FADE_NONE = 0, FADE_CROSSFADE, FADE_IN, FADE_OUT, FADE_INOUT } fade_mode; +#define MONO_RIGHT 0x02 +#define MONO_LEFT 0x01 #define MAX_SUPPORTED_SAMPLERATES 18 #define TEST_RATES = { 768000, 705600, 384000, 352800, 192000, 176400, 96000, 88200, 48000, 44100, 32000, 24000, 22500, 16000, 12000, 11025, 8000, 0 } struct outputstate { output_state state; output_format format; + u8_t channels; const char *device; #if ALSA unsigned buffer; @@ -632,7 +635,7 @@ unsigned latency; int pa_hostapi_option; #endif - 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); + 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); unsigned start_frames; unsigned frames_played; unsigned frames_played_dmp;// frames played at the point delay is measured @@ -716,9 +719,9 @@ void output_close_stdout(void); // output_pack.c -void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format); +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); void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr); -void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR); +void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR, u8_t flags); s32_t gain(s32_t gain, s32_t sample); s32_t to_gain(float f); @@ -759,16 +762,15 @@ struct codec *register_opus(void); #endif -//gpio.c +// gpio.c #if GPIO -void relay( int state); +void relay(int state); void relay_script(int state); int gpio_pin; bool gpio_active_low; bool gpio_active; char *power_script; -// my amp state -int ampstate; + #if RPI #define PI_INPUT 0 #define PI_OUTPUT 1 diff --git a/stream.c b/stream.c index fc3cf4c..2e784c5 100644 --- a/stream.c +++ b/stream.c @@ -107,16 +107,22 @@ unsigned try = 0; ssize_t n; + int error; while (len) { n = _send(ssl, fd, ptr, len, MSG_NOSIGNAL); if (n <= 0) { - if (n < 0 && _last_error() == ERROR_WOULDBLOCK && try < 10) { - LOG_SDEBUG("retrying (%d) writing to socket", ++try); + error = _last_error(); +#if WIN + if (n < 0 && (error == ERROR_WOULDBLOCK || error == WSAENOTCONN) && try < 10) { +#else + if (n < 0 && error == ERROR_WOULDBLOCK && try < 10) { +#endif + LOG_DEBUG("retrying (%d) writing to socket", ++try); usleep(1000); continue; } - LOG_INFO("failed writing to socket: %s", strerror(last_error())); + LOG_WARN("failed writing to socket: %s", strerror(last_error())); stream.disconnect = LOCAL_DISCONNECT; stream.state = DISCONNECT; wake_controller(); @@ -395,7 +401,7 @@ n = _recv(ssl, fd, streambuf->writep, space, 0); if (n == 0) { - LOG_INFO("end of stream"); + LOG_INFO("end of stream (%u bytes)", stream.bytes); _disconnect(DISCONNECT, DISCONNECT_OK); } if (n < 0 && _last_error() != ERROR_WOULDBLOCK) { @@ -557,7 +563,10 @@ *host = '\0'; p = strcasestr(header,"Host:"); - if (p) sscanf(p, "Host:%255[^:]", host); + if (p) { + sscanf(p, "Host:%255s", host); + if ((p = strchr(host, ':')) != NULL) *p = '\0'; + } port = ntohs(port); sock = connect_socket(use_ssl || port == 443); diff --git a/utils.c b/utils.c index ecaf02c..9b06476 100644 --- a/utils.c +++ b/utils.c @@ -489,7 +489,7 @@ } #endif -#if WIN && USE_SSL +#if WIN char *strcasestr(const char *haystack, const char *needle) { size_t length_needle; size_t length_haystack; diff --git a/vorbis.c b/vorbis.c index 50f02b6..c6883d7 100644 --- a/vorbis.c +++ b/vorbis.c @@ -236,7 +236,12 @@ // work backward to unpack samples (if needed) iptr = (s16_t *) write_buf + count; - optr = (ISAMPLE_T *) write_buf + frames * 2; + IF_DIRECT( + optr = (ISAMPLE_T *) outputbuf->writep + frames * 2; + ) + IF_PROCESS( + optr = (ISAMPLE_T *) write_buf + frames * 2; + ) if (channels == 2) { #if BYTES_PER_FRAME == 4