Merge pull request #13 from luar123/NETCONN
Fix dsp and add software volume mixer
This commit is contained in:
@@ -37,13 +37,15 @@ static uint32_t currentChunkDurationMs = 0;
|
||||
|
||||
static ptype_t bq[8];
|
||||
|
||||
static double dynamic_vol = 1.0;
|
||||
|
||||
int
|
||||
dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
{
|
||||
double dynamic_vol = 1.0;
|
||||
int16_t len = chunk_size / 4;
|
||||
int16_t valint;
|
||||
uint16_t i;
|
||||
volatile uint32_t *audio_tmp = (uint32_t *)audio; //volatile needed to ensure 32 bit access
|
||||
|
||||
if ((sbuffer0 == NULL) || (sbufout0 == NULL) || (sbuftmp0 == NULL))
|
||||
{
|
||||
@@ -57,6 +59,17 @@ dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
{
|
||||
case dspfStereo:
|
||||
{
|
||||
//set volume
|
||||
if (dynamic_vol != 1.0)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
audio_tmp[i] = ((uint32_t) (dynamic_vol
|
||||
* ((float)((int16_t)((audio_tmp[i] & 0xFFFF0000) >> 16)))) << 16)
|
||||
+ (uint32_t) (dynamic_vol
|
||||
* ((float)((int16_t)(audio_tmp[i] & 0xFFFF))));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -66,8 +79,7 @@ dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
sbuffer0[i] = dynamic_vol * 0.5
|
||||
* ((float)((int16_t) (audio[i * 4 + 1] << 8)
|
||||
+ audio[i * 4 + 0]))
|
||||
* ((float)((int16_t)(audio_tmp[i] & 0xFFFF)))
|
||||
/ 32768;
|
||||
}
|
||||
BIQUAD (sbuffer0, sbufout0, len, bq[6].coeffs, bq[6].w);
|
||||
@@ -75,17 +87,14 @@ dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
valint = (int16_t) (sbufout0[i] * 32768);
|
||||
|
||||
audio[i * 4 + 0] = (valint & 0x00ff);
|
||||
audio[i * 4 + 1] = ((valint & 0xff00) >> 8);
|
||||
audio_tmp[i] = (audio_tmp[i]&0xFFFF0000) + (uint32_t)valint;
|
||||
}
|
||||
|
||||
// channel 1
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
sbuffer0[i] = dynamic_vol * 0.5
|
||||
* ((float)((int16_t) (audio[i * 4 + 3] << 8)
|
||||
+ audio[i * 4 + 2]))
|
||||
* ((float)((int16_t)((audio_tmp[i] & 0xFFFF0000) >> 16)))
|
||||
/ 32768;
|
||||
}
|
||||
BIQUAD (sbuffer0, sbufout0, len, bq[7].coeffs, bq[7].w);
|
||||
@@ -93,8 +102,7 @@ dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
valint = (int16_t) (sbufout0[i] * 32768);
|
||||
audio[i * 4 + 2] = (valint & 0x00ff);
|
||||
audio[i * 4 + 3] = ((valint & 0xff00) >> 8);
|
||||
audio_tmp[i] = (audio_tmp[i]&0xFFFF) + ((uint32_t)valint << 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -105,8 +113,7 @@ dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
sbuffer0[i] = dynamic_vol * 0.5
|
||||
* ((float)((int16_t) (audio[i * 4 + 1] << 8)
|
||||
+ audio[i * 4 + 0]))
|
||||
* ((float)((int16_t)(audio_tmp[i] & 0xFFFF)))
|
||||
/ 32768;
|
||||
}
|
||||
BIQUAD (sbuffer0, sbuftmp0, len, bq[0].coeffs, bq[0].w);
|
||||
@@ -115,16 +122,14 @@ dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
valint = (int16_t) (sbufout0[i] * 32768);
|
||||
audio[i * 4 + 0] = (valint & 0x00ff);
|
||||
audio[i * 4 + 1] = ((valint & 0xff00) >> 8);
|
||||
audio_tmp[i] = (audio_tmp[i]&0xFFFF0000) + (uint32_t)valint;
|
||||
}
|
||||
|
||||
// Process audio ch1 HIGH PASS FILTER
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
sbuffer0[i] = dynamic_vol * 0.5
|
||||
* ((float)((int16_t) (audio[i * 4 + 3] << 8)
|
||||
+ audio[i * 4 + 2]))
|
||||
* ((float)((int16_t)((audio_tmp[i] & 0xFFFF0000) >> 16)))
|
||||
/ 32768;
|
||||
}
|
||||
BIQUAD (sbuffer0, sbuftmp0, len, bq[2].coeffs, bq[2].w);
|
||||
@@ -133,8 +138,7 @@ dsp_processor (char *audio, size_t chunk_size, dspFlows_t dspFlow)
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
valint = (int16_t) (sbufout0[i] * 32768);
|
||||
audio[i * 4 + 2] = (valint & 0x00ff);
|
||||
audio[i * 4 + 3] = ((valint & 0xff00) >> 8);
|
||||
audio_tmp[i] = (audio_tmp[i]&0xFFFF) + ((uint32_t)valint << 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -382,4 +386,14 @@ dsp_set_xoverfreq (uint8_t freqh, uint8_t freql, uint32_t samplerate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dsp_set_vol (double volume)
|
||||
{
|
||||
if (volume >= 0 && volume <= 1.0)
|
||||
{
|
||||
ESP_LOGI (TAG, "Set volume to %f", volume);
|
||||
dynamic_vol = volume;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -42,5 +42,6 @@ typedef struct pnode {
|
||||
void dsp_setup_flow(double freq, uint32_t samplerate, uint32_t chunkDurationMs);
|
||||
int dsp_processor(char *audio, size_t chunk_size, dspFlows_t dspFlow);
|
||||
void dsp_set_xoverfreq(uint8_t, uint8_t, uint32_t);
|
||||
void dsp_set_vol(double volume);
|
||||
|
||||
#endif /* _DSP_PROCESSOR_H_ */
|
||||
|
||||
@@ -19,18 +19,36 @@ menu "Snapcast Configuration"
|
||||
depends on !SNAPSERVER_USE_MDNS
|
||||
help
|
||||
Port of the snapserver to connect to.
|
||||
|
||||
config SNAPCLIENT_BUFF_LEN
|
||||
int "snapcast protocol buffer len"
|
||||
default 4000
|
||||
help
|
||||
Size of the snapclient protocol messages buffer (in bytes).
|
||||
|
||||
config SNAPCLIENT_NAME
|
||||
string "snapclient name"
|
||||
default "esp-snapclient"
|
||||
default "ESP32-Caster"
|
||||
help
|
||||
Name of the client to register the snapserver.
|
||||
|
||||
config SNAPCLIENT_USE_SOFT_VOL
|
||||
bool "Use software volume"
|
||||
default false
|
||||
depends on USE_DSP_PROCESSOR
|
||||
help
|
||||
Use software volume mixer instead of hardware mixer.
|
||||
|
||||
choice SNAPCLIENT_DSP_FLOW
|
||||
prompt "DSP flow"
|
||||
default SNAPCLIENT_DSP_FLOW_STEREO
|
||||
help
|
||||
Select the DSP flow to use.
|
||||
|
||||
config SNAPCLIENT_DSP_FLOW_STEREO
|
||||
bool "Stereo flow"
|
||||
|
||||
config SNAPCLIENT_DSP_FLOW_BASSBOOST
|
||||
bool "Bassboost flow"
|
||||
|
||||
config SNAPCLIENT_DSP_FLOW_BIAMP
|
||||
bool "Bi-Amp flow"
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
menu "SNTP Configuration"
|
||||
|
||||
63
main/main.c
63
main/main.c
@@ -101,8 +101,8 @@ static audio_board_handle_t board_handle = NULL;
|
||||
#define SNAPCAST_SERVER_HOST CONFIG_SNAPSERVER_HOST
|
||||
#define SNAPCAST_SERVER_PORT CONFIG_SNAPSERVER_PORT
|
||||
#endif
|
||||
#define SNAPCAST_BUFF_LEN CONFIG_SNAPCLIENT_BUFF_LEN
|
||||
#define SNAPCAST_CLIENT_NAME CONFIG_SNAPCLIENT_NAME
|
||||
#define SNAPCAST_USE_SOFT_VOL CONFIG_SNAPCLIENT_USE_SOFT_VOL
|
||||
|
||||
/* Logging tag */
|
||||
static const char *TAG = "SC";
|
||||
@@ -113,7 +113,15 @@ extern char mac_address[18];
|
||||
SemaphoreHandle_t timeSyncSemaphoreHandle = NULL;
|
||||
|
||||
#if CONFIG_USE_DSP_PROCESSOR
|
||||
uint8_t dspFlow = dspfStereo; // dspfBiamp; // dspfStereo; // dspfBassBoost;
|
||||
#if CONFIG_SNAPCLIENT_DSP_FLOW_STEREO
|
||||
dspFlows_t dspFlow = dspfStereo; // dspfBiamp; // dspfStereo; // dspfBassBoost;
|
||||
#endif
|
||||
#if CONFIG_SNAPCLIENT_DSP_FLOW_BASSBOOST
|
||||
dspFlows_t dspFlow = dspfBassBoost;
|
||||
#endif
|
||||
#if CONFIG_SNAPCLIENT_DSP_FLOW_BIAMP
|
||||
dspFlows_t dspFlow = dspfBiamp;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct flacData_s {
|
||||
@@ -722,7 +730,7 @@ static void http_get_task(void *pvParameters) {
|
||||
|
||||
// init hello message
|
||||
hello_message.mac = mac_address;
|
||||
hello_message.hostname = "ESP32-Caster";
|
||||
hello_message.hostname = SNAPCAST_CLIENT_NAME;
|
||||
hello_message.version = (char *)VERSION_STRING;
|
||||
hello_message.client_name = "libsnapcast";
|
||||
hello_message.os = "esp32";
|
||||
@@ -785,6 +793,7 @@ static void http_get_task(void *pvParameters) {
|
||||
uint32_t typedMsgLen = 0;
|
||||
uint32_t offset = 0;
|
||||
uint32_t tmpData = 0;
|
||||
int flow_drain_counter = 0;
|
||||
|
||||
#define BASE_MESSAGE_STATE 0
|
||||
#define TYPED_MESSAGE_STATE 1
|
||||
@@ -1405,6 +1414,20 @@ static void http_get_task(void *pvParameters) {
|
||||
endTime = esp_timer_get_time();
|
||||
|
||||
#if CONFIG_USE_DSP_PROCESSOR
|
||||
if (flow_drain_counter > 0) {
|
||||
flow_drain_counter--;
|
||||
double dynamic_vol = ((double)scSet.volume/100 / (20 - flow_drain_counter));
|
||||
if (flow_drain_counter == 0) {
|
||||
#if SNAPCAST_USE_SOFT_VOL
|
||||
dynamic_vol = 0;
|
||||
#else
|
||||
dynamic_vol = 1;
|
||||
#endif
|
||||
audio_hal_set_mute(board_handle->audio_hal,
|
||||
server_settings_message.muted);
|
||||
}
|
||||
dsp_set_vol(dynamic_vol);
|
||||
}
|
||||
dsp_setup_flow(500, scSet.sr, scSet.chkDur_ms);
|
||||
dsp_processor(pcmData->fragment->payload,
|
||||
pcmData->fragment->size, dspFlow);
|
||||
@@ -1443,6 +1466,20 @@ static void http_get_task(void *pvParameters) {
|
||||
}
|
||||
|
||||
#if CONFIG_USE_DSP_PROCESSOR
|
||||
if (flow_drain_counter > 0) {
|
||||
flow_drain_counter--;
|
||||
double dynamic_vol = ((double)scSet.volume/100 / (20 - flow_drain_counter));
|
||||
if (flow_drain_counter == 0) {
|
||||
#if SNAPCAST_USE_SOFT_VOL
|
||||
dynamic_vol = 0;
|
||||
#else
|
||||
dynamic_vol = 1;
|
||||
#endif
|
||||
audio_hal_set_mute(board_handle->audio_hal,
|
||||
server_settings_message.muted);
|
||||
}
|
||||
dsp_set_vol(dynamic_vol);
|
||||
}
|
||||
dsp_setup_flow(500, scSet.sr, scSet.chkDur_ms);
|
||||
dsp_processor(pcmData->fragment->payload,
|
||||
pcmData->fragment->size, dspFlow);
|
||||
@@ -1982,12 +2019,32 @@ static void http_get_task(void *pvParameters) {
|
||||
// Volume setting using ADF HAL
|
||||
// abstraction
|
||||
if (scSet.muted != server_settings_message.muted) {
|
||||
#if CONFIG_USE_DSP_PROCESSOR
|
||||
if (server_settings_message.muted) {
|
||||
flow_drain_counter = 20;
|
||||
}
|
||||
else {
|
||||
flow_drain_counter = 0;
|
||||
audio_hal_set_mute(board_handle->audio_hal,
|
||||
server_settings_message.muted);
|
||||
#if SNAPCAST_USE_SOFT_VOL
|
||||
dsp_set_vol((double)server_settings_message.volume/100);
|
||||
#else
|
||||
dsp_set_vol(1.0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
audio_hal_set_mute(board_handle->audio_hal,
|
||||
server_settings_message.muted);
|
||||
#endif
|
||||
}
|
||||
if (scSet.volume != server_settings_message.volume) {
|
||||
#if SNAPCAST_USE_SOFT_VOL
|
||||
dsp_set_vol((double)server_settings_message.volume/100);
|
||||
#else
|
||||
audio_hal_set_volume(board_handle->audio_hal,
|
||||
server_settings_message.volume);
|
||||
#endif
|
||||
}
|
||||
|
||||
scSet.cDacLat_ms = server_settings_message.latency;
|
||||
|
||||
Reference in New Issue
Block a user