From 16fe532dc8260bb7a01135a3897fddb04f04dc5c Mon Sep 17 00:00:00 2001 From: Philippe G Date: Mon, 27 Jul 2020 14:24:06 -0700 Subject: [PATCH] opus & vorbis fix when using resampling --- components/display/core/gds.h | 10 ++++---- components/squeezelite/opus.c | 34 ++++++++++++++++------------ components/squeezelite/squeezelite.h | 8 +++---- components/squeezelite/vorbis.c | 25 +++++++++++--------- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/components/display/core/gds.h b/components/display/core/gds.h index bfbc29e4..29f3e8c7 100644 --- a/components/display/core/gds.h +++ b/components/display/core/gds.h @@ -5,11 +5,11 @@ #include /* NOTE for drivers: - The build-in DrawPixel(Fast), DrawCBR and ClearWindow are optimized for 1 bit - and 4 bits screen depth. For any other type of screen, DrawCBR and ClearWindow - default to use DrawPixel, which is very sub-optimal. For such other depth, you - must supply the DrawPixelFast. The built-in 1 bit depth function are only for - screen with vertical framing (1 byte = 8 lines). For example SSD1326 in + The build-in DrawPixel(Fast), DrawCBR and ClearWindow have optimized for 1 bit + and 4 bits grayscale screen depth and 8, 16, 24 color. For any other type of screen, + DrawCBR and ClearWindow default to use DrawPixel, which is very sub-optimal. For + other depth, you must supply the DrawPixelFast. The built-in 1 bit depth function + are only for screen with vertical framing (1 byte = 8 lines). For example SSD1326 in monochrome mode is not such type of screen, SH1106 and SSD1306 are */ diff --git a/components/squeezelite/opus.c b/components/squeezelite/opus.c index f20ebe42..45e3037c 100644 --- a/components/squeezelite/opus.c +++ b/components/squeezelite/opus.c @@ -30,7 +30,9 @@ * thread has a higher priority. Using an interim buffer where opus decoder writes the output is not great from * an efficiency (one extra memory copy) point of view, but it allows the lock to not be kept for too long */ +#if EMBEDDED #define FRAME_BUF 2048 +#endif #if BYTES_PER_FRAME == 4 #define ALIGN(n) (n) @@ -151,16 +153,14 @@ static decode_state opus_decompress(void) { LOG_INFO("setting track_start"); } -#if !FRAME_BUF - LOCK_O_direct; -#endif - #if FRAME_BUF IF_DIRECT( frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME; + frames = min(frames, FRAME_BUF); write_buf = u->write_buf; ); #else + LOCK_O_direct; IF_DIRECT( frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME; write_buf = outputbuf->writep; @@ -171,10 +171,6 @@ static decode_state opus_decompress(void) { write_buf = process.inbuf; ); -#if FRAME_BUF - frames = min(frames, FRAME_BUF); -#endif - // write the decoded frames into outputbuf then unpack them (they are 16 bits) n = OP(u, read, u->of, (opus_int16*) write_buf, frames * channels, NULL); @@ -190,15 +186,21 @@ static decode_state opus_decompress(void) { frames = n; count = frames * channels; - iptr = (s16_t *)write_buf + count; - optr = (ISAMPLE_T *) outputbuf->writep + frames * 2; - + // work backward to unpack samples (if needed) + iptr = (s16_t *) write_buf + count; + optr = (ISAMPLE_T *) write_buf + frames * 2; + if (channels == 2) { #if BYTES_PER_FRAME == 4 - memcpy(outputbuf->writep, write_buf, frames * BYTES_PER_FRAME); +#if FRAME_BUF + // copy needed only when DIRECT and FRAME_BUF + IF_DIRECT( + memcpy(outputbuf->writep, write_buf, frames * BYTES_PER_FRAME); + ) +#endif #else while (count--) { - *--optr = *--iptr << 16; + *--optr = ALIGN(*--iptr); } #endif } else if (channels == 1) { @@ -298,8 +300,8 @@ struct codec *register_opus(void) { static struct codec ret = { 'u', // id "ops", // types - 4096, // min read - 20480, // min space + 4*1024, // min read + 32*1024, // min space opus_open, // open opus_close, // close opus_decompress, // decode @@ -311,7 +313,9 @@ struct codec *register_opus(void) { } u->of = NULL; +#if FRAME_BUF u->write_buf = NULL; +#endif if (!load_opus()) { return NULL; diff --git a/components/squeezelite/squeezelite.h b/components/squeezelite/squeezelite.h index fe75b94b..2831a80f 100644 --- a/components/squeezelite/squeezelite.h +++ b/components/squeezelite/squeezelite.h @@ -387,9 +387,6 @@ typedef BOOL bool; #endif -typedef u32_t frames_t; -typedef int sockfd; - // logging typedef enum { lERROR = 0, lWARN, lINFO, lDEBUG, lSDEBUG } log_level; @@ -401,7 +398,10 @@ void logprint(const char *fmt, ...); #define LOG_INFO(fmt, ...) if (loglevel >= lINFO) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__) #define LOG_DEBUG(fmt, ...) if (loglevel >= lDEBUG) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__) #define LOG_SDEBUG(fmt, ...) if (loglevel >= lSDEBUG) logprint("%s %s:%d " fmt "\n", logtime(), __FUNCTION__, __LINE__, ##__VA_ARGS__) - + +typedef uint32_t frames_t; +typedef int sockfd; + #if EMBEDDED #include "embedded.h" #endif diff --git a/components/squeezelite/vorbis.c b/components/squeezelite/vorbis.c index 8baa12e1..6ade8b84 100644 --- a/components/squeezelite/vorbis.c +++ b/components/squeezelite/vorbis.c @@ -29,7 +29,9 @@ * thread has a higher priority. Using an interim buffer where vorbis decoder writes the output is not great from * an efficiency (one extra memory copy) point of view, but it allows the lock to not be kept for too long */ +#if EMBEDDED #define FRAME_BUF 2048 +#endif #if BYTES_PER_FRAME == 4 #define ALIGN(n) (n) @@ -183,16 +185,14 @@ static decode_state vorbis_decode(void) { } } -#if !FRAME_BUF - LOCK_O_direct; -#endif - #if FRAME_BUF IF_DIRECT( frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME; + frames = min(frames, FRAME_BUF); write_buf = v->write_buf; ); #else + LOCK_O_direct; IF_DIRECT( frames = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME; write_buf = outputbuf->writep; @@ -203,9 +203,6 @@ static decode_state vorbis_decode(void) { write_buf = process.inbuf; ); -#if FRAME_BUF - frames = min(frames, FRAME_BUF); -#endif bytes = frames * 2 * channels; // samples returned are 16 bits // write the decoded frames into outputbuf even though they are 16 bits per sample, then unpack them @@ -237,15 +234,21 @@ static decode_state vorbis_decode(void) { frames = n / 2 / channels; count = frames * channels; - iptr = (s16_t *)write_buf + count; - optr = (ISAMPLE_T *) outputbuf->writep + frames * 2; + // work backward to unpack samples (if needed) + iptr = (s16_t *) write_buf + count; + optr = (ISAMPLE_T *) write_buf + frames * 2; if (channels == 2) { #if BYTES_PER_FRAME == 4 - memcpy(outputbuf->writep, write_buf, frames * BYTES_PER_FRAME); +#if FRAME_BUF + // copy needed only when DIRECT and FRAME_BUF + IF_DIRECT( + memcpy(outputbuf->writep, write_buf, frames * BYTES_PER_FRAME); + ) +#endif #else while (count--) { - *--optr = *--iptr << 16; + *--optr = ALIGN(*--iptr); } #endif } else if (channels == 1) {