Skip to content

Commit

Permalink
Audio refactoring, filters and I2SConfig (#19662)
Browse files Browse the repository at this point in the history
  • Loading branch information
s-hadinger authored Oct 3, 2023
1 parent e32c39f commit 473a8ee
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 125 deletions.
16 changes: 16 additions & 0 deletions lib/libesp32/berry_tasmota/src/be_i2s_audio_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ BE_FUNC_CTYPE_DECLARE(be_audio_input_i2s_get_channels, "i", ".");
extern float be_audio_input_i2s_get_gain(void* in);
BE_FUNC_CTYPE_DECLARE(be_audio_input_i2s_get_gain, "f", ".");

// AudioInputI2S.get_dc_offset() -> float
extern int be_audio_input_i2s_get_dc_offset(void* in);
BE_FUNC_CTYPE_DECLARE(be_audio_input_i2s_get_dc_offset, "i", ".");

// AudioInputI2S.get_lowpass_alpha() -> float
extern float be_audio_input_i2s_get_lowpass_alpha(void* in);
BE_FUNC_CTYPE_DECLARE(be_audio_input_i2s_get_lowpass_alpha, "f", ".");

// AudioInputI2S.set_lowpass_alpha(alpha:float) -> bool
extern int be_audio_input_i2s_set_lowpass_alpha(void* in, float alpha);
BE_FUNC_CTYPE_DECLARE(be_audio_input_i2s_set_lowpass_alpha, "b", ".f");

#include "be_fixed_be_class_AudioOutputI2S.h"
#include "be_fixed_be_class_AudioGenerator.h"
#include "be_fixed_be_class_AudioGeneratorWAV.h"
Expand Down Expand Up @@ -202,6 +214,10 @@ class be_class_AudioInputI2S (scope: global, name: AudioInputI2S, strings: weak)
get_gain, ctype_func(be_audio_input_i2s_get_gain)
set_gain, ctype_func(be_audio_input_set_gain)
get_dc_offset, ctype_func(be_audio_input_i2s_get_dc_offset)
get_lowpass_alpha, ctype_func(be_audio_input_i2s_get_lowpass_alpha)
set_lowpass_alpha, ctype_func(be_audio_input_i2s_set_lowpass_alpha)
}
@const_object_info_end */
Expand Down
5 changes: 5 additions & 0 deletions tasmota/include/i18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,11 @@
#define D_CMND_PING "Ping"
#define D_JSON_PING "Ping"

// Commands xdrv_42_audio - I2S Audio
#define D_PRFX_I2S "I2S"
#define D_JSON_I2S_CONFIG "Config"


// Commands xdrv_52_berry.ino - Berry scripting language
#define D_PRFX_BR "Br"
#define D_CMND_BR_RUN ""
Expand Down
39 changes: 23 additions & 16 deletions tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_0_config_idf51.ino
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ enum : int8_t {
};

#define I2S_SLOTS 2
#define AUDIO_SETTINGS_VERSION 1

typedef struct{
struct{
uint8_t version = 0; // B00
uint8_t version = AUDIO_SETTINGS_VERSION; // B00

// runtime options, will be saved but ignored on setting read
bool duplex = 0; // B01 - depends on GPIO setting and SOC caps, DIN and DOUT on same port in GPIO means -> try to use duplex if possible
Expand All @@ -81,7 +82,8 @@ typedef struct{
bool mclk_inv[I2S_SLOTS] = {0}; // B05-06 - invert mclk
bool bclk_inv[I2S_SLOTS] = {0}; // B07-08 - invert bclk
bool ws_inv[I2S_SLOTS] = {0}; // B09-0A - invert ws
uint8_t spare[5]; // B0B-0F
uint8_t mp3_preallocate = 0; // B0B - will be ignored without PS-RAM
uint8_t spare[4]; // B0C-0F
} sys;
struct {
uint32_t sample_rate = 16000; // B00-03
Expand All @@ -91,26 +93,31 @@ typedef struct{
uint8_t slot_config = I2S_SLOT_MSB;// B07 - slot configuration MSB = 0, PCM = 1, PHILIPS = 2
uint8_t channels = 2; // B08 - mono/stereo - 1 is added for both
bool apll = 1; // B09 - will be ignored on unsupported SOC's
// device specific
uint8_t mp3_preallocate = 0; // B0A - preallocate MP3 buffer for mp3 playing
uint8_t codec = 0; // B0B - S3 box only, unused for now
uint8_t spare[4]; // B0C-0F
uint8_t spare[6]; // B0A-0F
} tx;
struct {
uint32_t sample_rate = 16000; // B00-03
uint8_t gain = 30; // B04
uint8_t mode = I2S_MODE_PDM; // B05 - I2S mode standard, PDM, TDM, DAC
uint8_t slot_mask = I2S_SLOT_NOCHANGE;// B06 - slot mask
uint8_t slot_config = I2S_SLOT_MSB;// B07 - slot configuration MSB = 0, PCM = 1, PHILIPS = 2
uint8_t channels = 1; // B08 - mono/stereo - 1 is added for both
bool apll = 1; // B09 - will be ignored on unsupported SOC's
// device specific
uint8_t codec = 0; // B0A - S3 box only, unused for now
uint8_t mp3_preallocate = 0; // B0B - will be ignored without PS-RAM
uint8_t spare[4]; // B0C-0F
uint16_t gain = 30 * 16; // B04-05 - in Q12.4
uint8_t mode = I2S_MODE_PDM; // B06 - I2S mode standard, PDM, TDM, DAC
uint8_t slot_mask = I2S_SLOT_NOCHANGE;// B07 - slot mask
uint8_t slot_config = I2S_SLOT_MSB;// B08 - slot configuration MSB = 0, PCM = 1, PHILIPS = 2
uint8_t channels = 1; // B09 - mono/stereo - 1 is added for both
// filters
uint16_t dc_filter_alpha = 0b0111111011111111; // B0A-B0B - DC_block filter = (1-2^(-7)) Q32:1.31, or `0` if disabled
// low pass filter
// See: https://en.wikipedia.org/wiki/Low-pass_filter#Simple_infinite_impulse_response_filter
// For 3000Hz low pass filter, RC = 0.0000530786
// dt = 1/16000 = 0.0000625
// alpha = dt / (RC + dt) = 0.540757545
// alpha = (b) 0.100010100110111 = 0x4537
uint16_t lowpass_alpha = 0b0100010100110111; // B0C-B0D - lowpass filter = 3000Hz for 16000Hz sample rate
bool apll = 1; // B0E - will be ignored on unsupported SOC's
uint8_t spare[1]; // B0F
} rx;
} tI2SSettings;

static_assert(sizeof(tI2SSettings) == 48, "tI2SSettings Size is not correct");

typedef union {
uint8_t data;
struct {
Expand Down
Loading

0 comments on commit 473a8ee

Please sign in to comment.