mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 13:07:03 +03:00
mono channels with inversion - release
This commit is contained in:
@@ -254,10 +254,7 @@ frames_t _output_frames(frames_t avail) {
|
|||||||
|
|
||||||
out_frames = !silence ? min(size, cont_frames) : size;
|
out_frames = !silence ? min(size, cont_frames) : size;
|
||||||
|
|
||||||
if (output.channels & 0x01) gainR |= MONO_FLAG;
|
wrote = output.write_cb(out_frames, silence, gainL, gainR, output.channels, cross_gain_in, cross_gain_out, &cross_ptr);
|
||||||
if (output.channels & 0x02) gainL |= MONO_FLAG;
|
|
||||||
|
|
||||||
wrote = output.write_cb(out_frames, silence, gainL, gainR, cross_gain_in, cross_gain_out, &cross_ptr);
|
|
||||||
|
|
||||||
if (wrote <= 0) {
|
if (wrote <= 0) {
|
||||||
frames -= size;
|
frames -= size;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ static uint8_t *btout;
|
|||||||
static frames_t oframes;
|
static frames_t oframes;
|
||||||
static bool stats;
|
static bool stats;
|
||||||
|
|
||||||
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, ISAMPLE_T **cross_ptr);
|
s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
|
||||||
|
|
||||||
#define DECLARE_ALL_MIN_MAX \
|
#define DECLARE_ALL_MIN_MAX \
|
||||||
@@ -79,7 +79,7 @@ void output_close_bt(void) {
|
|||||||
equalizer_close();
|
equalizer_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
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, ISAMPLE_T **cross_ptr) {
|
s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
|
||||||
|
|
||||||
assert(btout != NULL);
|
assert(btout != NULL);
|
||||||
@@ -90,7 +90,7 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g
|
|||||||
_apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
|
_apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
_apply_gain(outputbuf, out_frames, gainL, gainR);
|
_apply_gain(outputbuf, out_frames, gainL, gainR, flags);
|
||||||
|
|
||||||
#if BYTES_PER_FRAME == 4
|
#if BYTES_PER_FRAME == 4
|
||||||
memcpy(btout + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME);
|
memcpy(btout + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME);
|
||||||
@@ -112,7 +112,7 @@ static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t g
|
|||||||
memcpy(btout + oframes * BYTES_PER_FRAME, buf, out_frames * BYTES_PER_FRAME);
|
memcpy(btout + oframes * BYTES_PER_FRAME, buf, out_frames * BYTES_PER_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
output_visu_export(btout + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, ((gainL & ~MONO_FLAG) + (gainR & ~MONO_FLAG)) / 2);
|
output_visu_export(btout + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, (gainL + gainR) / 2);
|
||||||
|
|
||||||
oframes += out_frames;
|
oframes += out_frames;
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ static struct {
|
|||||||
|
|
||||||
DECLARE_ALL_MIN_MAX;
|
DECLARE_ALL_MIN_MAX;
|
||||||
|
|
||||||
static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
|
static int _i2s_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, ISAMPLE_T **cross_ptr);
|
s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
|
||||||
static void *output_thread_i2s(void *arg);
|
static void *output_thread_i2s(void *arg);
|
||||||
static void output_thread_i2s_stats(void *arg);
|
static void output_thread_i2s_stats(void *arg);
|
||||||
@@ -398,20 +398,20 @@ bool output_volume_i2s(unsigned left, unsigned right) {
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Write frames to the output buffer
|
* Write frames to the output buffer
|
||||||
*/
|
*/
|
||||||
static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
|
static int _i2s_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, ISAMPLE_T **cross_ptr) {
|
s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
|
||||||
if (!silence) {
|
if (!silence) {
|
||||||
if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
|
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);
|
_apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
_apply_gain(outputbuf, out_frames, gainL, gainR);
|
_apply_gain(outputbuf, out_frames, gainL, gainR, flags);
|
||||||
memcpy(obuf + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME);
|
memcpy(obuf + oframes * BYTES_PER_FRAME, outputbuf->readp, out_frames * BYTES_PER_FRAME);
|
||||||
} else {
|
} else {
|
||||||
memcpy(obuf + oframes * BYTES_PER_FRAME, silencebuf, out_frames * BYTES_PER_FRAME);
|
memcpy(obuf + oframes * BYTES_PER_FRAME, silencebuf, out_frames * BYTES_PER_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
output_visu_export(obuf + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, ((gainL & ~MONO_FLAG) + (gainR & ~MONO_FLAG)) / 2);
|
output_visu_export(obuf + oframes * BYTES_PER_FRAME, out_frames, output.current_sample_rate, silence, (gainL + gainR) / 2);
|
||||||
oframes += out_frames;
|
oframes += out_frames;
|
||||||
|
|
||||||
return out_frames;
|
return out_frames;
|
||||||
|
|||||||
@@ -43,29 +43,26 @@ s32_t to_gain(float f) {
|
|||||||
return (s32_t)(f * 65536.0F);
|
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)
|
// in-place copy input samples if mono/combined is used (never happens with DSD active)
|
||||||
if ((gainR & MONO_FLAG) && (gainL & MONO_FLAG)) {
|
if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) {
|
||||||
s32_t *ptr = inputptr;
|
s32_t *ptr = inputptr;
|
||||||
frames_t count = cnt;
|
frames_t count = cnt;
|
||||||
gainL &= ~MONO_FLAG; gainR &= ~MONO_FLAG;
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
// use 64 bits integer for purists but should really not care
|
// use 64 bits integer for purists but should really not care
|
||||||
*ptr = *(ptr + 1) = ((s64_t) *ptr + (s64_t) *(ptr + 1)) / 2;
|
*ptr = *(ptr + 1) = ((s64_t) *ptr + (s64_t) *(ptr + 1)) / 2;
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
} else if (gainL & MONO_FLAG) {
|
} else if (flags & MONO_RIGHT) {
|
||||||
s32_t *ptr = inputptr + 1;
|
s32_t *ptr = inputptr + 1;
|
||||||
frames_t count = cnt;
|
frames_t count = cnt;
|
||||||
gainL &= ~MONO_FLAG;
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
*(ptr - 1) = *ptr;
|
*(ptr - 1) = *ptr;
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
} else if (gainR & MONO_FLAG) {
|
} else if (flags & MONO_LEFT) {
|
||||||
s32_t *ptr = inputptr;
|
s32_t *ptr = inputptr;
|
||||||
frames_t count = cnt;
|
frames_t count = cnt;
|
||||||
gainR &= ~MONO_FLAG;
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
*(ptr + 1) = *ptr;
|
*(ptr + 1) = *ptr;
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
@@ -383,24 +380,24 @@ void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gai
|
|||||||
#if !WIN
|
#if !WIN
|
||||||
inline
|
inline
|
||||||
#endif
|
#endif
|
||||||
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) {
|
||||||
if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
|
if (gainL == FIXED_ONE && gainR == FIXED_ONE && !(flags & (MONO_LEFT | MONO_RIGHT))) {
|
||||||
return;
|
return;
|
||||||
} if ((gainR & MONO_FLAG) && (gainL & MONO_FLAG)) {
|
} else if ((flags & MONO_LEFT) && (flags & MONO_RIGHT)) {
|
||||||
ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
|
ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
|
||||||
ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
|
ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
|
||||||
gainL &= ~MONO_FLAG; gainR &= ~MONO_FLAG;
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
*ptrL = *ptrR = (gain(gainL, *ptrL) + gain(gainR, *ptrR)) / 2;
|
*ptrL = *ptrR = (gain(gainL, *ptrL) + gain(gainR, *ptrR)) / 2;
|
||||||
ptrL += 2; ptrR += 2;
|
ptrL += 2; ptrR += 2;
|
||||||
}
|
}
|
||||||
} else if (gainL & MONO_FLAG) {
|
|
||||||
|
} else if (flags & MONO_RIGHT) {
|
||||||
ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
|
ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
*(ptr - 1) = *ptr = gain(gainR, *ptr);
|
*(ptr - 1) = *ptr = gain(gainR, *ptr);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
} else if (gainR & MONO_FLAG) {
|
} else if (flags & MONO_LEFT) {
|
||||||
ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
|
ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
*(ptr + 1) = *ptr = gain(gainL, *ptr);
|
*(ptr + 1) = *ptr = gain(gainL, *ptr);
|
||||||
|
|||||||
@@ -472,7 +472,6 @@ void _wake_create(event_event*);
|
|||||||
#define MAX_SILENCE_FRAMES 2048
|
#define MAX_SILENCE_FRAMES 2048
|
||||||
|
|
||||||
#define FIXED_ONE 0x10000
|
#define FIXED_ONE 0x10000
|
||||||
#define MONO_FLAG 0x20000
|
|
||||||
|
|
||||||
#ifndef BYTES_PER_FRAME
|
#ifndef BYTES_PER_FRAME
|
||||||
#define BYTES_PER_FRAME 8
|
#define BYTES_PER_FRAME 8
|
||||||
@@ -655,6 +654,8 @@ typedef enum { FADE_INACTIVE = 0, FADE_DUE, FADE_ACTIVE } fade_state;
|
|||||||
typedef enum { FADE_UP = 1, FADE_DOWN, FADE_CROSS } fade_dir;
|
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;
|
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 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 }
|
#define TEST_RATES = { 768000, 705600, 384000, 352800, 192000, 176400, 96000, 88200, 48000, 44100, 32000, 24000, 22500, 16000, 12000, 11025, 8000, 0 }
|
||||||
|
|
||||||
@@ -675,7 +676,7 @@ struct outputstate {
|
|||||||
unsigned latency;
|
unsigned latency;
|
||||||
int pa_hostapi_option;
|
int pa_hostapi_option;
|
||||||
#endif
|
#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, ISAMPLE_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, ISAMPLE_T **cross_ptr);
|
||||||
unsigned start_frames;
|
unsigned start_frames;
|
||||||
unsigned frames_played;
|
unsigned frames_played;
|
||||||
unsigned frames_played_dmp;// frames played at the point delay is measured
|
unsigned frames_played_dmp;// frames played at the point delay is measured
|
||||||
@@ -758,9 +759,9 @@ void output_close_stdout(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// output_pack.c
|
// 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, ISAMPLE_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);
|
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 gain(s32_t gain, s32_t sample);
|
||||||
s32_t to_gain(float f);
|
s32_t to_gain(float f);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user