From b53c14a2b568d7581173470b2b2298d077a1f9f9 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Sun, 26 May 2019 22:58:38 -0700 Subject: [PATCH] update --- main/output.c | 4 +-- main/output_dac.c | 88 ++++++++++++++++++++++++++++++++-------------- main/output_pack.c | 17 ++++++--- main/squeezelite.h | 2 +- 4 files changed, 76 insertions(+), 35 deletions(-) diff --git a/main/output.c b/main/output.c index a68cbab4..622b3d21 100644 --- a/main/output.c +++ b/main/output.c @@ -48,7 +48,7 @@ frames_t _output_frames(frames_t avail) { frames_t frames, size; bool silence; - s32_t cross_gain_in = 0, cross_gain_out = 0; s32_t *cross_ptr = NULL; + s32_t cross_gain_in = 0, cross_gain_out = 0; ISAMPLE_T *cross_ptr = NULL; s32_t gainL = output.current_replay_gain ? gain(output.gainL, output.current_replay_gain) : output.gainL; s32_t gainR = output.current_replay_gain ? gain(output.gainR, output.current_replay_gain) : output.gainR; @@ -242,7 +242,7 @@ frames_t _output_frames(frames_t avail) { gainL = output.gainL; gainR = output.gainR; if (output.invert) { gainL = -gainL; gainR = -gainR; } - cross_ptr = (s32_t *)(output.fade_end + cur_f * BYTES_PER_FRAME); + cross_ptr = (ISAMPLE_T *)(output.fade_end + cur_f * BYTES_PER_FRAME); } else { LOG_INFO("unable to continue crossfade - too few samples"); output.fade = FADE_INACTIVE; diff --git a/main/output_dac.c b/main/output_dac.c index 0a42bcfb..44952bfe 100644 --- a/main/output_dac.c +++ b/main/output_dac.c @@ -10,6 +10,10 @@ static bool running = true; extern struct outputstate output; extern struct buffer *outputbuf; +#if REPACK && BYTES_PER_FRAMES == 4 +#error "REPACK is not compatible with BYTES_PER_FRAME=4" +#endif + #define LOCK mutex_lock(outputbuf->mutex) #define UNLOCK mutex_unlock(outputbuf->mutex) @@ -17,33 +21,34 @@ extern struct buffer *outputbuf; extern u8_t *silencebuf; -// buffer to hold output data so we can block on writing outside of output lock, allocated on init -static u8_t *buf; -static unsigned buffill; +static u8_t *optr; static int bytes_per_frame; static thread_type thread; static int _dac_write_frames(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); + s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); static void *output_thread(); -void set_volume(unsigned left, unsigned right) {} +void set_volume(unsigned left, unsigned right) { + LOG_DEBUG("setting internal gain left: %u right: %u", left, right); + LOCK; + output.gainL = left; + output.gainR = right; + UNLOCK; +} void output_init_dac(log_level level, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) { loglevel = level; LOG_INFO("init output DAC"); - - buf = malloc(FRAME_BLOCK * BYTES_PER_FRAME); - if (!buf) { - LOG_ERROR("unable to malloc buf"); - return; - } - buffill = 0; - + memset(&output, 0, sizeof(output)); +#if BYTES_PER_FRAME == 4 + output.format = S16_LE; +#else output.format = S32_LE; +#endif output.start_frames = FRAME_BLOCK * 2; output.write_cb = &_dac_write_frames; output.rate_delay = rate_delay; @@ -82,38 +87,65 @@ void output_close_dac(void) { running = false; UNLOCK; - free(buf); - output_close_common(); } static int _dac_write_frames(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) { + s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) { u8_t *obuf; - + if (!silence) { if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) { _apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr); } - - obuf = outputbuf->readp; + +#if !REPACK + if (gainL != FIXED_ONE || gainR!= FIXED_ONE) { + _apply_gain(outputbuf, out_frames, gainL, gainR); + } + + IF_DSD( + if (output.outfmt == DOP) { + update_dop((u32_t *) outputbuf->readp, out_frames, output.invert); + } else if (output.outfmt != PCM && output.invert) + dsd_invert((u32_t *) outputbuf->readp, out_frames); + ) + + memcpy(optr, outputbuf->readp, out_frames * BYTES_PER_FRAME); +#else + obuf = outputbuf->readp; +#endif } else { obuf = silencebuf; +#if !REPACK + IF_DSD( + if (output.outfmt != PCM) { + obuf = silencebuf_dsd; + update_dop((u32_t *) obuf, out_frames, false); // don't invert silence + } + ) + + memcpy(optr, obuf, out_frames * BYTES_PER_FRAME); +#endif } - _scale_and_pack_frames(buf + buffill * bytes_per_frame, (s32_t *)(void *)obuf, out_frames, gainL, gainR, output.format); - - buffill += out_frames; +#if REPACK + _scale_and_pack_frames(optr, (s32_t *)(void *)obuf, out_frames, gainL, gainR, output.format); +#endif return (int)out_frames; } static void *output_thread() { + // buffer to hold output data so we can block on writing outside of output lock, allocated on init + u8_t *obuf = malloc(FRAME_BLOCK * BYTES_PER_FRAME); + unsigned frames = 0; +#if REPACK LOCK; switch (output.format) { @@ -129,6 +161,7 @@ static void *output_thread() { } UNLOCK; +#endif while (running) { @@ -144,14 +177,15 @@ static void *output_thread() { output.updated = gettime_ms(); output.frames_played_dmp = output.frames_played; - _output_frames(FRAME_BLOCK); + optr = obuf + frames * bytes_per_frame; + frames += _output_frames(FRAME_BLOCK); UNLOCK; - if (buffill) { - // do something ... - usleep((buffill * 1000 * 1000) / output.current_sample_rate); - buffill = 0; + if (frames) { + // do something with some of these frames... + usleep((frames * 1000 * 1000) / output.current_sample_rate); + frames = 0; } else { usleep((FRAME_BLOCK * 1000 * 1000) / output.current_sample_rate); } diff --git a/main/output_pack.c b/main/output_pack.c index bbffc577..e2bfc798 100644 --- a/main/output_pack.c +++ b/main/output_pack.c @@ -23,8 +23,14 @@ #include "squeezelite.h" +#if BYTES_PER_FRAM == 4 +#define MAX_VAL16 0x7fffffffLL #define MAX_SCALESAMPLE 0x7fffffffffffLL #define MIN_SCALESAMPLE -MAX_SCALESAMPLE +#else +#define MAX_SCALESAMPLE 0x7fffffffffffLL +#define MIN_SCALESAMPLE -MAX_SCALESAMPLE +#endif // inlining these on windows prevents them being linkable... #if !WIN @@ -338,11 +344,11 @@ void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_ #if !WIN inline #endif -void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr) { - s32_t *ptr = (s32_t *)(void *)outputbuf->readp; +void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) { + ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp; frames_t count = out_frames * 2; while (count--) { - if (*cross_ptr > (s32_t *)outputbuf->wrap) { + if (*cross_ptr > (ISAMPLE_T *)outputbuf->wrap) { *cross_ptr -= outputbuf->size / BYTES_PER_FRAME * 2; } *ptr = gain(cross_gain_out, *ptr) + gain(cross_gain_in, **cross_ptr); @@ -354,8 +360,8 @@ void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gai 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; + 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); @@ -363,3 +369,4 @@ void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t ga ptrR += 2; } } + diff --git a/main/squeezelite.h b/main/squeezelite.h index 5261ebfc..18b23194 100644 --- a/main/squeezelite.h +++ b/main/squeezelite.h @@ -733,7 +733,7 @@ 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 _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_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR); s32_t gain(s32_t gain, s32_t sample); s32_t to_gain(float f);