Integrate DigiRadioFinale DSP program: exclusive source mux, real
Bass Boost1/SPhat1 enhancement blocks Replaces the 74-parameter ADAU1701 program with the new 224-parameter SigmaStudio export. The new netlist has no mixer -- MX1 is an exclusive selector (DC1) passing through exactly one of three stereo pairs (radio/bluetooth/beep) instead of blending them with independent gains. core::MixSource/MixerState are gone; core::ActiveSource plus IDsp::selectSource() replace applyMixer()/setInputVolume() throughout the driver/service/API stack. AudioProfile.mixer -> activeSource; the HTTP "mixer" JSON object -> a single "active_source" string. DC1 turned out to need a raw 32-bit integer (0/1/2), not the 5.23 fixpoint its compiled TYPE_DC1 macro implies -- confirmed live by writing both encodings and listening for which one actually switched sources. Documented in Adau1701Driver::selectSource() and adau1701::paramSourceIndex(). Bass Boost1 and SPhat1 are real ADI algorithm blocks in this revision, so core::applyEnhancementsToEq() (the old EQ-band-overwrite hack for bass/stereo enhancement) is deleted; IDsp::setBassBoostLevel()/ setStereoSpreadLevel() scale each block's compiled coefficients toward identity/unity instead. Confirmed live: Bass Boost audible on real program content (not a static test tone -- the algorithm is dynamics- based), Stereo Spread audible but subtle. The EQ "locked" flag from 2026-08-24 (enhancements silently overwriting manually-set bands) no longer applies to bands 1-5. A full sweep of all 223 non-DC1 named parameters (writing each back to its own compiled default) completed with zero failures, confirming the whole new address space is reachable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,28 @@
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x6C , 0xAC ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x7F , 0xFC , 0xB9 ,
|
||||
0x00 , 0x7F , 0xFC , 0xB9 ,
|
||||
0x00 , 0x7F , 0xFC , 0xB9 ,
|
||||
0x00 , 0x7F , 0xFC , 0xB9 ,
|
||||
0x01 , 0x41 , 0x85 , 0x7F ,
|
||||
0x00 , 0x09 , 0x0F , 0xCC ,
|
||||
0x00 , 0x09 , 0x0F , 0xCC ,
|
||||
0x00 , 0x06 , 0x6A , 0x4A ,
|
||||
0x00 , 0x04 , 0x8A , 0xA7 ,
|
||||
0x00 , 0x03 , 0x37 , 0x18 ,
|
||||
0x00 , 0x02 , 0x46 , 0xB5 ,
|
||||
0x00 , 0x01 , 0x9C , 0x86 ,
|
||||
0x00 , 0x01 , 0x24 , 0x0C ,
|
||||
0x00 , 0x00 , 0xCE , 0xC1 ,
|
||||
0x00 , 0x00 , 0x92 , 0x5F ,
|
||||
0x00 , 0x00 , 0x67 , 0x9F ,
|
||||
0x00 , 0x00 , 0x49 , 0x5C ,
|
||||
0x00 , 0x00 , 0xDA , 0xD7 ,
|
||||
0x00 , 0x02 , 0xFD , 0x86 ,
|
||||
0x00 , 0x0A , 0x75 , 0xDE ,
|
||||
0x00 , 0x24 , 0x97 , 0x68 ,
|
||||
0x00 , 0x7E , 0xDA , 0x4D ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
@@ -10,31 +32,113 @@
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x0F , 0xB9 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x09 , 0x60 ,
|
||||
0x00 , 0x00 , 0x00 , 0xB6 ,
|
||||
0x00 , 0x00 , 0x4E , 0xB0 ,
|
||||
0x00 , 0x00 , 0x01 , 0xE0 ,
|
||||
0x00 , 0x00 , 0x07 , 0x1C ,
|
||||
0x00 , 0x00 , 0x4E , 0xB0 ,
|
||||
0x00 , 0x00 , 0x01 , 0xE0 ,
|
||||
0x00 , 0x00 , 0x07 , 0x1C ,
|
||||
0x00 , 0x00 , 0x4E , 0xB0 ,
|
||||
0x00 , 0x00 , 0x01 , 0xE0 ,
|
||||
0x00 , 0x00 , 0x07 , 0x1C ,
|
||||
0x00 , 0x00 , 0x4E , 0xB0 ,
|
||||
0x00 , 0x00 , 0x01 , 0xE0 ,
|
||||
0x00 , 0x00 , 0x07 , 0x1C ,
|
||||
0x00 , 0x7F , 0xC3 , 0x65 ,
|
||||
0x0F , 0x00 , 0x79 , 0x35 ,
|
||||
0x00 , 0x7F , 0xC3 , 0x65 ,
|
||||
0x00 , 0xFF , 0x86 , 0xAE ,
|
||||
0x0F , 0x80 , 0x79 , 0x19 ,
|
||||
0x00 , 0x7F , 0xE6 , 0x6F ,
|
||||
0x0F , 0x01 , 0xD7 , 0xBF ,
|
||||
0x00 , 0x7E , 0x47 , 0xC2 ,
|
||||
0x00 , 0xFE , 0x28 , 0x41 ,
|
||||
0x0F , 0x81 , 0xD1 , 0xCF ,
|
||||
0x00 , 0x80 , 0x0B , 0x93 ,
|
||||
0x0F , 0x06 , 0x4A , 0x08 ,
|
||||
0x00 , 0x79 , 0xF5 , 0x34 ,
|
||||
0x00 , 0xF9 , 0xB5 , 0xF8 ,
|
||||
0x0F , 0x85 , 0xFF , 0x39 ,
|
||||
0x00 , 0x7F , 0x5D , 0x86 ,
|
||||
0x0F , 0x14 , 0xBB , 0x22 ,
|
||||
0x00 , 0x6E , 0x7D , 0xEA ,
|
||||
0x00 , 0xEB , 0x44 , 0xDE ,
|
||||
0x0F , 0x92 , 0x24 , 0x90 ,
|
||||
0x00 , 0x80 , 0x52 , 0x5D ,
|
||||
0x0F , 0x3C , 0xC4 , 0x90 ,
|
||||
0x00 , 0x55 , 0x01 , 0xAB ,
|
||||
0x00 , 0xC3 , 0x3B , 0x70 ,
|
||||
0x0F , 0xAA , 0xAB , 0xF8 ,
|
||||
0x00 , 0x82 , 0x2B , 0x9A ,
|
||||
0x0F , 0x98 , 0xC2 , 0xB2 ,
|
||||
0x00 , 0x34 , 0x93 , 0x0C ,
|
||||
0x00 , 0x67 , 0x3D , 0x4E ,
|
||||
0x0F , 0xC9 , 0x41 , 0x5A ,
|
||||
0x00 , 0x02 , 0xC4 , 0x78 ,
|
||||
0x00 , 0x05 , 0x88 , 0xEF ,
|
||||
0x00 , 0x02 , 0xC4 , 0x78 ,
|
||||
0x00 , 0xC5 , 0x84 , 0xFE ,
|
||||
0xFF , 0xAF , 0x69 , 0x23 ,
|
||||
0x00 , 0x65 , 0x86 , 0xF7 ,
|
||||
0xFF , 0x34 , 0xF2 , 0x12 ,
|
||||
0x00 , 0x65 , 0x86 , 0xF7 ,
|
||||
0x00 , 0xC5 , 0x84 , 0xFE ,
|
||||
0xFF , 0xAF , 0x69 , 0x23 ,
|
||||
0x00 , 0xA6 , 0x66 , 0x66 ,
|
||||
0x00 , 0x73 , 0x33 , 0x33 ,
|
||||
0x00 , 0x6D , 0x66 , 0xD6 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x75 , 0x69 , 0x4C ,
|
||||
0x00 , 0x5A , 0x9D , 0xF8 ,
|
||||
0x00 , 0x45 , 0xEF , 0xFF ,
|
||||
0x00 , 0x35 , 0xFA , 0x27 ,
|
||||
0x00 , 0x29 , 0xA8 , 0xBB ,
|
||||
0x00 , 0x20 , 0x26 , 0xF3 ,
|
||||
0x00 , 0x06 , 0x4A , 0x36 ,
|
||||
0x00 , 0x00 , 0x01 , 0x6C ,
|
||||
0x00 , 0x00 , 0x5D , 0xC0 ,
|
||||
0x00 , 0x08 , 0x0D , 0x6A ,
|
||||
0x00 , 0x02 , 0x78 , 0x8C ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
@@ -42,6 +146,52 @@
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||
0x00 , 0x01 , 0x01 , 0x5C ,
|
||||
0x00 , 0x00 , 0x01 , 0x64 ,
|
||||
0x00 , 0x00 , 0x02 , 0xC8 ,
|
||||
0x00 , 0x00 , 0x01 , 0x64 ,
|
||||
0x00 , 0xFD , 0xA1 , 0x53 ,
|
||||
0x0F , 0x82 , 0x59 , 0x1D ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x28 , 0xDA , 0x08 ,
|
||||
0x00 , 0x29 , 0x53 , 0x21 ,
|
||||
0x00 , 0x2A , 0xC6 , 0xE7 ,
|
||||
0x00 , 0x2C , 0x47 , 0xBE ,
|
||||
0x00 , 0x2D , 0xD6 , 0x1B ,
|
||||
0x00 , 0x2F , 0x72 , 0x77 ,
|
||||
0x00 , 0x31 , 0x1D , 0x52 ,
|
||||
0x00 , 0x32 , 0xD7 , 0x2C ,
|
||||
0x00 , 0x34 , 0xA0 , 0x8E ,
|
||||
0x00 , 0x36 , 0x7A , 0x02 ,
|
||||
0x00 , 0x00 , 0x06 , 0xD3 ,
|
||||
0x00 , 0x00 , 0x4E , 0xB0 ,
|
||||
0x00 , 0x00 , 0x01 , 0xE0 ,
|
||||
0x00 , 0x00 , 0x07 , 0x1C ,
|
||||
0x00 , 0x00 , 0x4E , 0xB0 ,
|
||||
0x00 , 0x00 , 0x01 , 0xE0 ,
|
||||
0x00 , 0x00 , 0x07 , 0x1C ,
|
||||
0x0F , 0xFE , 0x2B , 0xE3 ,
|
||||
0x00 , 0x22 , 0xBE , 0x2C ,
|
||||
0x0F , 0xEA , 0xAA , 0xAB ,
|
||||
@@ -872,154 +1022,4 @@
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* File: C:\Users\mikbi\Documents\Allegati\Desktop\DigiRadio\DigiRadioModificato\DigiRadio_IC_1_REG.h
|
||||
* File: C:\Users\mikbi\Documents\Allegati\Desktop\Sigmastudio\DigiRadioFinale_IC_1_REG.h
|
||||
*
|
||||
* Created: Friday, August 7, 2026 3:19:11 AM
|
||||
* Description: DigiRadio:IC 1 control register definitions.
|
||||
* Created: Tuesday, August 25, 2026 8:11:05 PM
|
||||
* Description: DigiRadioFinale:IC 1 control register definitions.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
@@ -16,8 +16,8 @@
|
||||
*
|
||||
* Copyright ©2026 Analog Devices, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef __DIGIRADIO_IC_1_REG_H__
|
||||
#define __DIGIRADIO_IC_1_REG_H__
|
||||
#ifndef __DIGIRADIOFINALE_IC_1_REG_H__
|
||||
#define __DIGIRADIOFINALE_IC_1_REG_H__
|
||||
|
||||
|
||||
/* InterfaceRegister0 - Registers (IC 1) */
|
||||
|
||||
@@ -17,77 +17,125 @@
|
||||
<NetList>
|
||||
<IC name=" IC 1 " type="DSPSigma100">
|
||||
<Schematic>
|
||||
<Algorithm name="ICSigma100In1" friendlyname="170x\140x input " cell="Input1 " location="{X=-15, Y=104} " Growth="10 " GrowthB="0 " FS="48000">
|
||||
<Link pin="O_C33_A0_P3_out" dir="out" link="Link0" />
|
||||
<Link pin="O_C33_A0_P4_out" dir="out" link="Link1" />
|
||||
<Link pin="O_C33_A0_P5_out" dir="out" link="Link2" />
|
||||
<Link pin="O_C33_A0_P6_out" dir="out" link="Link3" />
|
||||
<Algorithm name="ICSigma100In1" friendlyname="170x\140x input " cell="Input1 " location="{X=-71, Y=184.3228} " Growth="10 " GrowthB="0 " FS="48000">
|
||||
<Link pin="O_C33_A0_P3_out" dir="out" link="Link4" />
|
||||
<Link pin="O_C33_A0_P4_out" dir="out" link="Link5" />
|
||||
<Link pin="O_C33_A0_P5_out" dir="out" link="Link6" />
|
||||
<Link pin="O_C33_A0_P6_out" dir="out" link="Link7" />
|
||||
</Algorithm>
|
||||
<Algorithm name="BeepAlg1" friendlyname="Beep - variable gain " cell="Beep1 " location="{X=30, Y=459} " Growth="0 " GrowthB="0 " FS="48000">
|
||||
<Link pin="O_C0_A0_P1_out" dir="out" link="Link15" />
|
||||
<Algorithm name="BeepAlg1" friendlyname="Beep - variable gain " cell="Beep1 " location="{X=136, Y=723.2243} " Growth="0 " GrowthB="0 " FS="48000">
|
||||
<Link pin="O_C0_A0_P1_out" dir="out" link="Link16" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS1" friendlyname="Gain (no slew) " cell="Si4674 " location="{X=168, Y=5} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C63_A0_P1_in" dir="in" link="Link0" />
|
||||
<Link pin="O_C63_A0_P2_out" dir="out" link="Link4" />
|
||||
<Algorithm name="DCInpAlg1" friendlyname="dc Input " cell="DC1 " location="{X=609, Y=89.22221} " Growth="0 " GrowthB="0 " FS="48000">
|
||||
<Link pin="O_C216_A0_P1_out" dir="out" link="Link19" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS2" friendlyname="Gain (no slew) " cell="Si4674 " location="{X=168, Y=5} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C63_A1_P1_in" dir="in" link="Link1" />
|
||||
<Link pin="O_C63_A1_P2_out" dir="out" link="Link5" />
|
||||
<Algorithm name="DCBlockAlgDoublePrec1" friendlyname="DC Blocking " cell="DCB1 " location="{X=101, Y=61.38417} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C67_A0_P1_in" dir="in" link="Link4" />
|
||||
<Link pin="O_C67_A0_P2_out" dir="out" link="Link2" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS3" friendlyname="Gain (no slew) " cell="ESP32 " location="{X=166, Y=196} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C75_A0_P1_in" dir="in" link="Link2" />
|
||||
<Link pin="O_C75_A0_P2_out" dir="out" link="Link6" />
|
||||
<Algorithm name="DCBlockAlgDoublePrec2" friendlyname="DC Blocking " cell="DCB2 " location="{X=104, Y=138.3348} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C72_A0_P1_in" dir="in" link="Link5" />
|
||||
<Link pin="O_C72_A0_P2_out" dir="out" link="Link3" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS4" friendlyname="Gain (no slew) " cell="ESP32 " location="{X=166, Y=196} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C75_A1_P1_in" dir="in" link="Link3" />
|
||||
<Link pin="O_C75_A1_P2_out" dir="out" link="Link7" />
|
||||
<Algorithm name="DCBlockAlgDoublePrec4" friendlyname="DC Blocking " cell="DCB4 " location="{X=103, Y=323.756} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C91_A0_P1_in" dir="in" link="Link6" />
|
||||
<Link pin="O_C91_A0_P2_out" dir="out" link="Link10" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS7" friendlyname="Gain (no slew) " cell="Single 1 " location="{X=188, Y=404} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C4_A0_P1_in" dir="in" link="Link15" />
|
||||
<Link pin="O_C4_A0_P2_out" dir="out" link="Link16" />
|
||||
<Algorithm name="DCBlockAlgDoublePrec3" friendlyname="DC Blocking " cell="DCB3 " location="{X=92, Y=505.472} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C81_A0_P1_in" dir="in" link="Link7" />
|
||||
<Link pin="O_C81_A0_P2_out" dir="out" link="Link11" />
|
||||
</Algorithm>
|
||||
<Algorithm name="SingleCtrlSplit1" friendlyname="Splitter Single " cell="S Splitter1 " location="{X=289, Y=440} " Growth="2 " GrowthB="0">
|
||||
<Algorithm name="SingleCtrlSplit1" friendlyname="Splitter Single " cell="S Splitter1 " location="{X=332, Y=704.3125} " Growth="2 " GrowthB="0">
|
||||
<Link pin="I_C9_A0_P1_in" dir="in" link="Link16" />
|
||||
<Link pin="O_C9_A0_P2_out" dir="out" link="Link17" />
|
||||
<Link pin="O_C9_A0_P3_out" dir="out" link="Link18" />
|
||||
</Algorithm>
|
||||
<Algorithm name="StereoMixerAlg1" friendlyname="Stereo Mixer " cell="St Mixer1 " location="{X=464, Y=112} " Growth="3 " GrowthB="0">
|
||||
<Link pin="I_C84_A0_P3_in" dir="in" link="Link4" />
|
||||
<Link pin="I_C84_A0_P4_in" dir="in" link="Link5" />
|
||||
<Link pin="I_C84_A0_P5_in" dir="in" link="Link6" />
|
||||
<Link pin="I_C84_A0_P6_in" dir="in" link="Link7" />
|
||||
<Link pin="I_C84_A0_P7_in" dir="in" link="Link17" />
|
||||
<Link pin="I_C84_A0_P8_in" dir="in" link="Link18" />
|
||||
<Link pin="O_C84_A0_P1_out" dir="out" link="Link8" />
|
||||
<Link pin="O_C84_A0_P2_out" dir="out" link="Link9" />
|
||||
<Algorithm name="TwoChannelSingleDetectAlgFix1" friendlyname="Stereo RMS (Post Gain) " cell="Compressor1 " location="{X=187, Y=-4.364594} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C106_A0_P1_in" dir="in" link="Link2" />
|
||||
<Link pin="I_C106_A0_P2_in" dir="in" link="Link3" />
|
||||
<Link pin="O_C106_A0_P3_out" dir="out" link="Link8" />
|
||||
<Link pin="O_C106_A0_P4_out" dir="out" link="Link9" />
|
||||
</Algorithm>
|
||||
<Algorithm name="PEQ1Chan1" friendlyname="PEQ1Chan - Double Precision " cell="Param EQ1 " location="{X=585, Y=153} " Growth="2 " GrowthB="0">
|
||||
<Link pin="I_C125_A0_P1_in" dir="in" link="Link8" />
|
||||
<Link pin="I_C125_A0_P3_in" dir="in" link="Link9" />
|
||||
<Link pin="O_C125_A0_P2_out" dir="out" link="Link10" />
|
||||
<Link pin="O_C125_A0_P4_out" dir="out" link="Link11" />
|
||||
<Algorithm name="SingleBandLevelDet3" friendlyname="Single Band " cell="1 X RTA3 " location="{X=352, Y=296} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C155_A0_P1_in" dir="in" link="Link10" />
|
||||
<Link pin="O_C155_A0_P2_out" dir="out" link="Link14" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS5" friendlyname="Gain (no slew) " cell="Multiple 1 " location="{X=711, Y=85} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C138_A0_P1_in" dir="in" link="Link10" />
|
||||
<Link pin="O_C138_A0_P2_out" dir="out" link="Link12" />
|
||||
<Algorithm name="SingleBandLevelDet4" friendlyname="Single Band " cell="1 X RTA4 " location="{X=355, Y=469} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C158_A0_P1_in" dir="in" link="Link11" />
|
||||
<Link pin="O_C158_A0_P2_out" dir="out" link="Link15" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS6" friendlyname="Gain (no slew) " cell="Multiple 1 " location="{X=711, Y=85} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C138_A1_P1_in" dir="in" link="Link11" />
|
||||
<Link pin="O_C138_A1_P2_out" dir="out" link="Link13" />
|
||||
<Algorithm name="SingleBandLevelDet1" friendlyname="Single Band " cell="1 X RTA1 " location="{X=350, Y=-73} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C149_A0_P1_in" dir="in" link="Link8" />
|
||||
<Link pin="O_C149_A0_P2_out" dir="out" link="Link12" />
|
||||
</Algorithm>
|
||||
<Algorithm name="limiterAlg1" friendlyname="Limiter with Indicator " cell="Limiter 1 " location="{X=844, Y=37} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C169_A0_P1_in" dir="in" link="Link12" />
|
||||
<Link pin="O_C169_A0_P2_out" dir="out" link="Link19" />
|
||||
<Algorithm name="SingleBandLevelDet2" friendlyname="Single Band " cell="1 X RTA2 " location="{X=344, Y=112} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C152_A0_P1_in" dir="in" link="Link9" />
|
||||
<Link pin="O_C152_A0_P2_out" dir="out" link="Link13" />
|
||||
</Algorithm>
|
||||
<Algorithm name="limiterAlg2" friendlyname="Limiter with Indicator " cell="Limiter 2 " location="{X=848, Y=186} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C174_A0_P1_in" dir="in" link="Link13" />
|
||||
<Link pin="O_C174_A0_P2_out" dir="out" link="Link14" />
|
||||
<Algorithm name="DCinputmux_stereo_Alg1" friendlyname="Stereo " cell="MX1 " location="{X=730, Y=222.1111} " Growth="3 " GrowthB="0">
|
||||
<Link pin="I_C174_A0_P3_in" dir="in" link="Link19" />
|
||||
<Link pin="I_C174_A0_P4_in" dir="in" link="Link12" />
|
||||
<Link pin="I_C174_A0_P5_in" dir="in" link="Link13" />
|
||||
<Link pin="I_C174_A0_P6_in" dir="in" link="Link14" />
|
||||
<Link pin="I_C174_A0_P7_in" dir="in" link="Link15" />
|
||||
<Link pin="I_C174_A0_P8_in" dir="in" link="Link17" />
|
||||
<Link pin="I_C174_A0_P9_in" dir="in" link="Link18" />
|
||||
<Link pin="O_C174_A0_P1_out" dir="out" link="Link20" />
|
||||
<Link pin="O_C174_A0_P2_out" dir="out" link="Link21" />
|
||||
</Algorithm>
|
||||
<Algorithm name="ICSigma100Out2" friendlyname="170x\140x output " cell="Output2 " location="{X=1003, Y=202} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C185_A0_P1_in" dir="in" link="Link14" />
|
||||
<Algorithm name="PEQ1Chan1" friendlyname="PEQ1Chan - Double Precision " cell="Param EQ1 " location="{X=820, Y=211.9035} " Growth="2 " GrowthB="0">
|
||||
<Link pin="I_C125_A0_P1_in" dir="in" link="Link20" />
|
||||
<Link pin="I_C125_A0_P3_in" dir="in" link="Link21" />
|
||||
<Link pin="O_C125_A0_P2_out" dir="out" link="Link22" />
|
||||
<Link pin="O_C125_A0_P4_out" dir="out" link="Link23" />
|
||||
</Algorithm>
|
||||
<Algorithm name="ICSigma100Out1" friendlyname="170x\140x output " cell="Output1 " location="{X=1009.037, Y=52} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C183_A0_P1_in" dir="in" link="Link19" />
|
||||
<Algorithm name="SuperPhatAlg1" friendlyname="Super Bass " cell="SPhat1 " location="{X=921, Y=196} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C227_A0_P1_in" dir="in" link="Link22" />
|
||||
<Link pin="I_C227_A0_P2_in" dir="in" link="Link23" />
|
||||
<Link pin="O_C227_A0_P3_out" dir="out" link="Link24" />
|
||||
<Link pin="O_C227_A0_P4_out" dir="out" link="Link25" />
|
||||
</Algorithm>
|
||||
<Algorithm name="EQ1940DualS1" friendlyname="2 Channel - Single Precision " cell="Gen Filter1 " location="{X=1037, Y=197} " Growth="1 " GrowthB="0">
|
||||
<Link pin="I_C232_A0_P1_in" dir="in" link="Link24" />
|
||||
<Link pin="I_C232_A0_P2_in" dir="in" link="Link25" />
|
||||
<Link pin="O_C232_A0_P3_out" dir="out" link="Link26" />
|
||||
<Link pin="O_C232_A0_P4_out" dir="out" link="Link27" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS5" friendlyname="Gain (no slew) " cell="Multiple 1 " location="{X=1214, Y=149.7451} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C138_A0_P1_in" dir="in" link="Link26" />
|
||||
<Link pin="O_C138_A0_P2_out" dir="out" link="Link33" />
|
||||
</Algorithm>
|
||||
<Algorithm name="Gain1940AlgNS6" friendlyname="Gain (no slew) " cell="Multiple 1 " location="{X=1214, Y=149.7451} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C138_A1_P1_in" dir="in" link="Link27" />
|
||||
<Link pin="O_C138_A1_P2_out" dir="out" link="Link32" />
|
||||
</Algorithm>
|
||||
<Algorithm name="BassBAlg_stereo1" friendlyname="Stereo Dynamic Bass Boost " cell="Bass Boost1 " location="{X=1394, Y=131.4268} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C263_A0_P1_in" dir="in" link="Link33" />
|
||||
<Link pin="I_C263_A0_P2_in" dir="in" link="Link32" />
|
||||
<Link pin="O_C263_A0_P3_out" dir="out" link="Link31" />
|
||||
<Link pin="O_C263_A0_P4_out" dir="out" link="Link30" />
|
||||
</Algorithm>
|
||||
<Algorithm name="SingleBandLevelDet6" friendlyname="Single Band " cell="1 X RTA2_2 " location="{X=1676, Y=243} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C252_A0_P1_in" dir="in" link="Link30" />
|
||||
<Link pin="O_C252_A0_P2_out" dir="out" link="Link28" />
|
||||
</Algorithm>
|
||||
<Algorithm name="SingleBandLevelDet5" friendlyname="Single Band " cell="1 X RTA1_2 " location="{X=1676, Y=68} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C249_A0_P1_in" dir="in" link="Link31" />
|
||||
<Link pin="O_C249_A0_P2_out" dir="out" link="Link29" />
|
||||
</Algorithm>
|
||||
<Algorithm name="limiterAlg2" friendlyname="Limiter with Indicator " cell="Limiter 2 " location="{X=1800, Y=269.5105} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C29_A0_P1_in" dir="in" link="Link28" />
|
||||
<Link pin="O_C29_A0_P2_out" dir="out" link="Link1" />
|
||||
</Algorithm>
|
||||
<Algorithm name="limiterAlg1" friendlyname="Limiter with Indicator " cell="Limiter 1 " location="{X=1803, Y=90.51053} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C169_A0_P1_in" dir="in" link="Link29" />
|
||||
<Link pin="O_C169_A0_P2_out" dir="out" link="Link0" />
|
||||
</Algorithm>
|
||||
<Algorithm name="ICSigma100Out1" friendlyname="170x\140x output " cell="Output1 " location="{X=1958, Y=107.0044} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C183_A0_P1_in" dir="in" link="Link0" />
|
||||
</Algorithm>
|
||||
<Algorithm name="ICSigma100Out2" friendlyname="170x\140x output " cell="Output2 " location="{X=1955, Y=285.5105} " Growth="0 " GrowthB="0">
|
||||
<Link pin="I_C48_A0_P1_in" dir="in" link="Link1" />
|
||||
</Algorithm>
|
||||
</Schematic>
|
||||
</IC>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* File: defines.h
|
||||
*
|
||||
* Created: Friday, August 7, 2026 3:19:11 AM
|
||||
* Description: DigiRadio IC default download data definitions.
|
||||
* Created: Tuesday, August 25, 2026 8:11:05 PM
|
||||
* Description: DigiRadioFinale IC default download data definitions.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
|
||||
@@ -19,11 +19,9 @@ idf_component_register(
|
||||
"src/EqBandIndex.cpp"
|
||||
"src/BiquadCoefficients.cpp"
|
||||
"src/BiquadDesign.cpp"
|
||||
"src/MixerState.cpp"
|
||||
"src/EqProfile.cpp"
|
||||
"src/EnhanceLevel.cpp"
|
||||
"src/AudioEnhancements.cpp"
|
||||
"src/EnhancementsDesign.cpp"
|
||||
"src/AudioProfile.cpp"
|
||||
"src/AudioProfileJson.cpp"
|
||||
"src/Bt1035At.cpp"
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file ActiveSource.hpp
|
||||
* @brief ADAU1701 MX1 input source selector.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace core {
|
||||
|
||||
/**
|
||||
* @brief ActiveSource — the one stereo pair MX1 currently passes through.
|
||||
*
|
||||
* @dname ActiveSource
|
||||
* @return n/a (type)
|
||||
* @pubstate n/a
|
||||
*
|
||||
* The DigiRadioFinale SigmaStudio revision (2026-08-25) replaced St Mixer1
|
||||
* (which combined Si4684 + ESP32 + Beep simultaneously, each at its own
|
||||
* gain) with MX1, a DC-controlled exclusive mux: only one of the three
|
||||
* stereo pairs reaches Param EQ1 at a time, selected by the DC1 cell.
|
||||
* Per-source gain trims (the old Si4674/ESP32 cells) no longer exist —
|
||||
* level is controlled solely by Master Volume and the EQ, downstream of
|
||||
* the selected source.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
enum class ActiveSource {
|
||||
Radio, ///< Si4684 tuner (FM/DAB), MX1 pair index 0.
|
||||
Bluetooth, ///< ESP32 I2S input, MX1 pair index 1.
|
||||
Beep, ///< Internal test tone, MX1 pair index 2.
|
||||
};
|
||||
|
||||
// DC1 is a raw 32-bit integer index (0/1/2), not the 5.23 fixpoint its
|
||||
// compiled TYPE_DC1/VALUE_DC1 macros would suggest -- confirmed live
|
||||
// 2026-08-25 (see adau1701::paramSourceIndex() and Adau1701Driver::
|
||||
// selectSource()).
|
||||
|
||||
} // namespace core
|
||||
@@ -17,19 +17,20 @@
|
||||
namespace core {
|
||||
|
||||
/**
|
||||
* @brief AudioEnhancements — psychoacoustic EQ overlays (0–100 each).
|
||||
* @brief AudioEnhancements — dedicated-block enhancement levels (0–100).
|
||||
*
|
||||
* @dname AudioEnhancements
|
||||
* @return n/a (type)
|
||||
* @pubstate Mapped to PEQ bands at runtime (manual chapter sigmastudio).
|
||||
* No dedicated SigmaStudio blocks; see \c applyEnhancementsToEq.
|
||||
* @pubstate Applied via IDsp::setStereoSpreadLevel/setBassBoostLevel, which
|
||||
* scale the SPhat1/Bass Boost1 SigmaStudio blocks toward their
|
||||
* compiled response; does not touch EqProfile.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
struct AudioEnhancements {
|
||||
EnhanceLevel stereo; ///< Stereo depth / presence (PEQ bands 3–5).
|
||||
EnhanceLevel bass; ///< Bass emphasis (PEQ bands 1–2).
|
||||
EnhanceLevel stereo; ///< Stereo spread (SPhat1 spatializer).
|
||||
EnhanceLevel bass; ///< Bass boost intensity (Bass Boost1).
|
||||
|
||||
/**
|
||||
* @brief factoryDefault — both enhancements off.
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/ActiveSource.hpp"
|
||||
#include "core/AudioEnhancements.hpp"
|
||||
#include "core/EqProfile.hpp"
|
||||
#include "core/GainDb.hpp"
|
||||
#include "core/MixerState.hpp"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace core {
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
struct AudioProfile {
|
||||
MixerState mixer; ///< Input and stereo-mixer gains.
|
||||
ActiveSource activeSource; ///< Which MX1 pair reaches Param EQ1.
|
||||
EqProfile eq; ///< Six-band parametric EQ.
|
||||
GainDb masterLeft; ///< Multiple 1 master volume, left.
|
||||
GainDb masterRight; ///< Multiple 1 master volume, right.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* @file EnhancementsDesign.hpp
|
||||
* @brief Map enhancement levels onto Param EQ1 bands (host-testable).
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/AudioEnhancements.hpp"
|
||||
#include "core/EqProfile.hpp"
|
||||
|
||||
namespace core {
|
||||
|
||||
/**
|
||||
* @brief applyEnhancementsToEq — merge enhancement overlays into an EQ profile.
|
||||
*
|
||||
* @dname applyEnhancementsToEq
|
||||
* @param base User EQ settings (bands not touched stay unchanged).
|
||||
* @param enhancements Stereo and bass levels (0 = use base band only).
|
||||
* @return EqProfile with affected PEQ bands updated for safeload.
|
||||
* @pubstate none
|
||||
*
|
||||
* Stereo (bands 3–5): slight 1\,kHz cut plus 3/8\,kHz lift for depth.
|
||||
* Bass (bands 1–2): 100\,Hz and 400\,Hz peaking boost.
|
||||
* Band 0 (high-pass) is never modified.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] EqProfile applyEnhancementsToEq(
|
||||
const EqProfile& base, const AudioEnhancements& enhancements) noexcept;
|
||||
|
||||
} // namespace core
|
||||
@@ -12,13 +12,13 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/ActiveSource.hpp"
|
||||
#include "core/AudioProfile.hpp"
|
||||
#include "core/DspError.hpp"
|
||||
#include "core/EnhanceLevel.hpp"
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/FrequencyHz.hpp"
|
||||
#include "core/GainDb.hpp"
|
||||
#include "core/MixSource.hpp"
|
||||
#include "core/MixerState.hpp"
|
||||
#include "core/EqProfile.hpp"
|
||||
|
||||
#include <expected>
|
||||
@@ -56,18 +56,18 @@ public:
|
||||
const AudioProfile& profile) = 0;
|
||||
|
||||
/**
|
||||
* @brief applyMixer — safeload input and stereo-mixer gains.
|
||||
* @brief selectSource — safeload MX1's DC1 control to pick one source.
|
||||
*
|
||||
* @dname applyMixer
|
||||
* @param mixer Per-source and St Mixer1 levels.
|
||||
* @dname selectSource
|
||||
* @param source Which stereo pair MX1 passes through to Param EQ1.
|
||||
* @return Ok on success, or DspError.
|
||||
* @pubstate writes ADAU1701 parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] virtual std::expected<void, DspError> applyMixer(
|
||||
const MixerState& mixer) = 0;
|
||||
[[nodiscard]] virtual std::expected<void, DspError> selectSource(
|
||||
ActiveSource source) = 0;
|
||||
|
||||
/**
|
||||
* @brief applyEq — safeload all six PEQ bands.
|
||||
@@ -83,22 +83,6 @@ public:
|
||||
[[nodiscard]] virtual std::expected<void, DspError> applyEq(
|
||||
const EqProfile& eq) = 0;
|
||||
|
||||
/**
|
||||
* @brief setInputVolume — safeload one input path (Si4684 or ESP32).
|
||||
*
|
||||
* @dname setInputVolume
|
||||
* @param source Tuner or ESP32 I2S path.
|
||||
* @param left Left channel gain.
|
||||
* @param right Right channel gain.
|
||||
* @return Ok on success, or DspError.
|
||||
* @pubstate writes ADAU1701 parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] virtual std::expected<void, DspError> setInputVolume(
|
||||
MixSource source, GainDb left, GainDb right) = 0;
|
||||
|
||||
/**
|
||||
* @brief setMasterVolume — safeload Multiple 1 master output gain.
|
||||
*
|
||||
@@ -146,6 +130,42 @@ public:
|
||||
[[nodiscard]] virtual std::expected<void, DspError> setBeepEnabled(
|
||||
bool enabled) = 0;
|
||||
|
||||
/**
|
||||
* @brief setBassBoostLevel — scale Bass Boost1 toward its compiled
|
||||
* curve.
|
||||
*
|
||||
* @dname setBassBoostLevel
|
||||
* @param level 0 = flat bypass, 100 = the full SigmaStudio-tuned
|
||||
* Dynamic Bass Boost response.
|
||||
* @return Ok on success, or DspError.
|
||||
* @pubstate writes ADAU1701 parameter RAM via safeload. Linearly
|
||||
* interpolates the compiled crossover filter and 33-point
|
||||
* compander curve toward identity/unity; BASSFREQUENCY and
|
||||
* the time constant are left at their tuned defaults.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] virtual std::expected<void, DspError> setBassBoostLevel(
|
||||
EnhanceLevel level) = 0;
|
||||
|
||||
/**
|
||||
* @brief setStereoSpreadLevel — scale SPhat1's stereo spread amount.
|
||||
*
|
||||
* @dname setStereoSpreadLevel
|
||||
* @param level 0 = no added spread, 100 = the full SigmaStudio-tuned
|
||||
* SuperPhat spread.
|
||||
* @return Ok on success, or DspError.
|
||||
* @pubstate writes ADAU1701 parameter RAM via safeload. Scales
|
||||
* SPREAD1/SPREAD2 linearly; the crossover filter and
|
||||
* compander curve are left at their tuned defaults.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] virtual std::expected<void, DspError> setStereoSpreadLevel(
|
||||
EnhanceLevel level) = 0;
|
||||
|
||||
/**
|
||||
* @brief writeRawParam — safeload any named Parameter RAM cell.
|
||||
*
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* @file MixSource.hpp
|
||||
* @brief ADAU1701 input path selector for per-source volume control.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace core {
|
||||
|
||||
/**
|
||||
* @brief MixSource — Si4684 tuner or ESP32 I2S input on the ADAU1701.
|
||||
*
|
||||
* @dname MixSource
|
||||
* @return n/a (type)
|
||||
* @pubstate n/a
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
enum class MixSource {
|
||||
Si4684,
|
||||
Esp32,
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
* @file MixerState.hpp
|
||||
* @brief ADAU1701 input and stereo-mixer gain snapshot.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/GainDb.hpp"
|
||||
|
||||
namespace core {
|
||||
|
||||
/**
|
||||
* @brief MixerState — per-source and St Mixer1 levels for the ADAU1701.
|
||||
*
|
||||
* @dname MixerState
|
||||
* @return n/a (type)
|
||||
* @pubstate Immutable snapshot applied by AudioService via IDsp.
|
||||
*
|
||||
* Maps to SigmaStudio modules Si4674, ESP32, and St Mixer1.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
struct MixerState {
|
||||
GainDb si4684Left; ///< Si4674 volume control, left channel.
|
||||
GainDb si4684Right; ///< Si4674 volume control, right channel.
|
||||
GainDb esp32Left; ///< ESP32 volume control, left channel.
|
||||
GainDb esp32Right; ///< ESP32 volume control, right channel.
|
||||
GainDb mixLeft; ///< St Mixer1 ST0 (Si4684) input level.
|
||||
GainDb mixRight; ///< St Mixer1 ST1 (ESP32) input level.
|
||||
|
||||
/**
|
||||
* @brief factoryDefault — unity gains on all paths.
|
||||
*
|
||||
* @dname factoryDefault
|
||||
* @return MixerState with 0 dB on every control.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] static MixerState factoryDefault() noexcept;
|
||||
|
||||
/**
|
||||
* @brief radioFirst — Si4684 path open, ESP32 path muted.
|
||||
*
|
||||
* @dname radioFirst
|
||||
* @return MixerState for FM/DAB tuner audio to the Bose I2S chain.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-05
|
||||
*/
|
||||
[[nodiscard]] static MixerState radioFirst() noexcept;
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
@@ -19,7 +19,7 @@ AudioProfile AudioProfile::factoryDefault() noexcept
|
||||
{
|
||||
const GainDb unity = GainDb::zero();
|
||||
return AudioProfile{
|
||||
.mixer = MixerState::factoryDefault(),
|
||||
.activeSource = ActiveSource::Radio,
|
||||
.eq = EqProfile::factoryDefault(),
|
||||
.masterLeft = unity,
|
||||
.masterRight = unity,
|
||||
|
||||
@@ -92,35 +92,48 @@ namespace {
|
||||
return GainDb::tryFromDb(db);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<MixerState, ParseError> parseMixerJson(
|
||||
[[nodiscard]] std::string_view activeSourceName(ActiveSource source) noexcept
|
||||
{
|
||||
switch (source) {
|
||||
case ActiveSource::Radio:
|
||||
return "radio";
|
||||
case ActiveSource::Bluetooth:
|
||||
return "bluetooth";
|
||||
case ActiveSource::Beep:
|
||||
return "beep";
|
||||
}
|
||||
return "radio";
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<ActiveSource, ParseError> parseActiveSourceJson(
|
||||
std::string_view json)
|
||||
{
|
||||
const std::size_t mixerStart = json.find("\"mixer\"");
|
||||
if (mixerStart == std::string_view::npos) {
|
||||
constexpr std::string_view kKey = "\"active_source\"";
|
||||
const std::size_t needlePos = json.find(kKey);
|
||||
if (needlePos == std::string_view::npos) {
|
||||
return std::unexpected(ParseError::MissingField);
|
||||
}
|
||||
const std::string_view mixer = json.substr(mixerStart);
|
||||
|
||||
const auto si4684Left = parseGainField(mixer, "si4684_left_db");
|
||||
const auto si4684Right = parseGainField(mixer, "si4684_right_db");
|
||||
const auto esp32Left = parseGainField(mixer, "esp32_left_db");
|
||||
const auto esp32Right = parseGainField(mixer, "esp32_right_db");
|
||||
const auto mixLeft = parseGainField(mixer, "mix_left_db");
|
||||
const auto mixRight = parseGainField(mixer, "mix_right_db");
|
||||
|
||||
if (!si4684Left || !si4684Right || !esp32Left || !esp32Right || !mixLeft
|
||||
|| !mixRight) {
|
||||
const std::size_t quoteStart = json.find('"', needlePos + kKey.size());
|
||||
if (quoteStart == std::string_view::npos) {
|
||||
return std::unexpected(ParseError::MissingField);
|
||||
}
|
||||
const std::size_t quoteEnd = json.find('"', quoteStart + 1U);
|
||||
if (quoteEnd == std::string_view::npos) {
|
||||
return std::unexpected(ParseError::MissingField);
|
||||
}
|
||||
const std::string_view value =
|
||||
json.substr(quoteStart + 1U, quoteEnd - quoteStart - 1U);
|
||||
|
||||
return MixerState{
|
||||
.si4684Left = *si4684Left,
|
||||
.si4684Right = *si4684Right,
|
||||
.esp32Left = *esp32Left,
|
||||
.esp32Right = *esp32Right,
|
||||
.mixLeft = *mixLeft,
|
||||
.mixRight = *mixRight,
|
||||
};
|
||||
if (value == "radio") {
|
||||
return ActiveSource::Radio;
|
||||
}
|
||||
if (value == "bluetooth") {
|
||||
return ActiveSource::Bluetooth;
|
||||
}
|
||||
if (value == "beep") {
|
||||
return ActiveSource::Beep;
|
||||
}
|
||||
return std::unexpected(ParseError::MissingField);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<EqProfile, ParseError> parseEqJson(
|
||||
@@ -207,14 +220,8 @@ namespace {
|
||||
std::string serializeAudioProfileJson(const AudioProfile& profile)
|
||||
{
|
||||
std::ostringstream out;
|
||||
const auto& m = profile.mixer;
|
||||
out << "{\"mixer\":{"
|
||||
<< "\"si4684_left_db\":" << m.si4684Left.value() << ','
|
||||
<< "\"si4684_right_db\":" << m.si4684Right.value() << ','
|
||||
<< "\"esp32_left_db\":" << m.esp32Left.value() << ','
|
||||
<< "\"esp32_right_db\":" << m.esp32Right.value() << ','
|
||||
<< "\"mix_left_db\":" << m.mixLeft.value() << ','
|
||||
<< "\"mix_right_db\":" << m.mixRight.value() << "},"
|
||||
out << "{\"active_source\":\"" << activeSourceName(profile.activeSource)
|
||||
<< "\","
|
||||
<< "\"master\":{"
|
||||
<< "\"left_db\":" << profile.masterLeft.value() << ','
|
||||
<< "\"right_db\":" << profile.masterRight.value() << "},"
|
||||
@@ -223,19 +230,13 @@ std::string serializeAudioProfileJson(const AudioProfile& profile)
|
||||
// Per-band "locked" flag, added 2026-08-24: band 0 is a fixed high-pass
|
||||
// Adau1701Driver::applyEq() never safeloads (SigmaStudio band 1, ST0 in
|
||||
// the compiled program -- whatever gain_db/center_hz/q is stored/sent
|
||||
// for it has zero audible effect, always). Bands 1-2 are overwritten by
|
||||
// core::applyEnhancementsToEq() with formula-derived values whenever
|
||||
// bass_level > 0; bands 3-5 likewise whenever stereo_level > 0 -- a
|
||||
// manual edit to those bands is silently inaudible while the
|
||||
// corresponding enhancement is active. This was previously
|
||||
// undiscoverable from the API response (GET echoed back the stored,
|
||||
// inert value with no indication it wasn't what was actually playing);
|
||||
// "locked":true now tells a client to grey out that slider instead of
|
||||
// letting the user "fix" a value that can't take effect.
|
||||
const bool bassLocks = profile.enhancements.bass.value() > 0U;
|
||||
const bool stereoLocks = profile.enhancements.stereo.value() > 0U;
|
||||
// for it has zero audible effect, always). Since the 2026-08-25
|
||||
// DigiRadioFinale revision, bass/stereo enhancement drive the dedicated
|
||||
// Bass Boost1/SPhat1 blocks directly instead of overwriting EQ bands,
|
||||
// so bands 1-5 are no longer locked by enhancement levels -- only
|
||||
// band 0 remains permanently inert.
|
||||
const bool locked[EqBandIndex::kBandCount] = {
|
||||
true, bassLocks, bassLocks, stereoLocks, stereoLocks, stereoLocks,
|
||||
true, false, false, false, false, false,
|
||||
};
|
||||
|
||||
const auto& bands = profile.eq.bands();
|
||||
@@ -263,9 +264,9 @@ std::expected<AudioProfile, ParseError> parseAudioProfileJson(
|
||||
return std::unexpected(ParseError::InvalidJson);
|
||||
}
|
||||
|
||||
const auto mixer = parseMixerJson(json);
|
||||
if (!mixer) {
|
||||
return std::unexpected(mixer.error());
|
||||
const auto activeSource = parseActiveSourceJson(json);
|
||||
if (!activeSource) {
|
||||
return std::unexpected(activeSource.error());
|
||||
}
|
||||
|
||||
const auto eq = parseEqJson(json);
|
||||
@@ -290,7 +291,7 @@ std::expected<AudioProfile, ParseError> parseAudioProfileJson(
|
||||
}
|
||||
|
||||
return AudioProfile{
|
||||
.mixer = *mixer,
|
||||
.activeSource = *activeSource,
|
||||
.eq = *eq,
|
||||
.masterLeft = *masterLeft,
|
||||
.masterRight = *masterRight,
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/**
|
||||
* @file EnhancementsDesign.cpp
|
||||
* @brief Enhancement-to-EQ mapping implementation.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#include "core/EnhancementsDesign.hpp"
|
||||
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/FrequencyHz.hpp"
|
||||
#include "core/GainDb.hpp"
|
||||
|
||||
namespace core {
|
||||
|
||||
namespace {
|
||||
|
||||
void setBand(EqProfile& profile, std::uint8_t index, GainDb gain,
|
||||
FrequencyHz center, float q) noexcept
|
||||
{
|
||||
const auto band = EqBandIndex::tryFromIndex(index);
|
||||
if (!band) {
|
||||
return;
|
||||
}
|
||||
profile.setBand(*band, EqBandSettings{
|
||||
.gain = gain,
|
||||
.center = center,
|
||||
.q = q,
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] GainDb gainFromDb(float db) noexcept
|
||||
{
|
||||
return *GainDb::tryFromDb(db);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EqProfile applyEnhancementsToEq(const EqProfile& base,
|
||||
const AudioEnhancements& enhancements) noexcept
|
||||
{
|
||||
EqProfile profile = base;
|
||||
|
||||
if (enhancements.bass.value() > 0U) {
|
||||
const float t = enhancements.bass.fraction();
|
||||
setBand(profile, 1U, gainFromDb(9.0F * t),
|
||||
*FrequencyHz::tryFromHz(100U), 0.9F);
|
||||
setBand(profile, 2U, gainFromDb(3.0F * t),
|
||||
*FrequencyHz::tryFromHz(400U), 1.0F);
|
||||
}
|
||||
|
||||
if (enhancements.stereo.value() > 0U) {
|
||||
const float t = enhancements.stereo.fraction();
|
||||
setBand(profile, 3U, gainFromDb(-1.5F * t),
|
||||
*FrequencyHz::tryFromHz(1000U), 1.0F);
|
||||
setBand(profile, 4U, gainFromDb(2.0F * t),
|
||||
*FrequencyHz::tryFromHz(3000U), 1.0F);
|
||||
setBand(profile, 5U, gainFromDb(4.0F * t),
|
||||
*FrequencyHz::tryFromHz(8000U), 1.0F);
|
||||
}
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* @file MixerState.cpp
|
||||
* @brief MixerState factory defaults.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
#include "core/MixerState.hpp"
|
||||
|
||||
namespace core {
|
||||
|
||||
MixerState MixerState::factoryDefault() noexcept
|
||||
{
|
||||
const GainDb unity = GainDb::zero();
|
||||
return MixerState{
|
||||
.si4684Left = unity,
|
||||
.si4684Right = unity,
|
||||
.esp32Left = unity,
|
||||
.esp32Right = unity,
|
||||
.mixLeft = unity,
|
||||
.mixRight = unity,
|
||||
};
|
||||
}
|
||||
|
||||
MixerState MixerState::radioFirst() noexcept
|
||||
{
|
||||
const GainDb unity = GainDb::zero();
|
||||
const GainDb muted = *GainDb::tryFromDb(GainDb::kMinDb);
|
||||
return MixerState{
|
||||
.si4684Left = unity,
|
||||
.si4684Right = unity,
|
||||
.esp32Left = muted,
|
||||
.esp32Right = muted,
|
||||
.mixLeft = unity,
|
||||
.mixRight = muted,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
@@ -31,11 +31,9 @@ add_library(digiradio_core STATIC
|
||||
"${CORE_SRC_DIR}/EqBandIndex.cpp"
|
||||
"${CORE_SRC_DIR}/BiquadCoefficients.cpp"
|
||||
"${CORE_SRC_DIR}/BiquadDesign.cpp"
|
||||
"${CORE_SRC_DIR}/MixerState.cpp"
|
||||
"${CORE_SRC_DIR}/EqProfile.cpp"
|
||||
"${CORE_SRC_DIR}/EnhanceLevel.cpp"
|
||||
"${CORE_SRC_DIR}/AudioEnhancements.cpp"
|
||||
"${CORE_SRC_DIR}/EnhancementsDesign.cpp"
|
||||
"${CORE_SRC_DIR}/AudioProfile.cpp"
|
||||
"${CORE_SRC_DIR}/AudioProfileJson.cpp"
|
||||
"${CORE_SRC_DIR}/Bt1035At.cpp"
|
||||
@@ -110,10 +108,6 @@ add_executable(audio_profile_json_test audio_profile_json_test.cpp)
|
||||
target_link_libraries(audio_profile_json_test PRIVATE digiradio_core)
|
||||
add_test(NAME audio_profile_json_test COMMAND audio_profile_json_test)
|
||||
|
||||
add_executable(enhancements_design_test enhancements_design_test.cpp)
|
||||
target_link_libraries(enhancements_design_test PRIVATE digiradio_core)
|
||||
add_test(NAME enhancements_design_test COMMAND enhancements_design_test)
|
||||
|
||||
add_executable(station_service_test station_service_test.cpp)
|
||||
target_include_directories(station_service_test PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/host_stubs"
|
||||
|
||||
@@ -69,6 +69,23 @@ namespace {
|
||||
std::cerr << "enhancements round-trip mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (parsed->activeSource != core::ActiveSource::Radio) {
|
||||
std::cerr << "default active_source mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
profile.activeSource = core::ActiveSource::Bluetooth;
|
||||
const std::string json3 = core::serializeAudioProfileJson(profile);
|
||||
if (json3.find(R"("active_source":"bluetooth")") == std::string::npos) {
|
||||
std::cerr << "active_source serialization mismatch: " << json3 << '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const auto parsed3 = core::parseAudioProfileJson(json3);
|
||||
if (!parsed3 || parsed3->activeSource != core::ActiveSource::Bluetooth) {
|
||||
std::cerr << "active_source round-trip mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/**
|
||||
* @file enhancements_design_test.cpp
|
||||
* @brief Host tests for enhancement-to-EQ mapping.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
#include "core/AudioEnhancements.hpp"
|
||||
#include "core/EnhanceLevel.hpp"
|
||||
#include "core/EnhancementsDesign.hpp"
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/EqProfile.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] bool nearlyEqual(float a, float b) noexcept
|
||||
{
|
||||
return std::fabs(a - b) < 0.01F;
|
||||
}
|
||||
|
||||
[[nodiscard]] int runBassMappingTest()
|
||||
{
|
||||
const auto level = core::EnhanceLevel::tryFromLevel(100U);
|
||||
if (!level) {
|
||||
std::cerr << "level setup failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
core::AudioEnhancements enhancements = core::AudioEnhancements::factoryDefault();
|
||||
enhancements.bass = *level;
|
||||
|
||||
const core::EqProfile base = core::EqProfile::factoryDefault();
|
||||
const core::EqProfile effective =
|
||||
core::applyEnhancementsToEq(base, enhancements);
|
||||
|
||||
const auto band1 = core::EqBandIndex::tryFromIndex(1U);
|
||||
const auto band2 = core::EqBandIndex::tryFromIndex(2U);
|
||||
if (!band1 || !band2) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!nearlyEqual(effective.band(*band1).gain.value(), 9.0F)
|
||||
|| !nearlyEqual(effective.band(*band2).gain.value(), 3.0F)) {
|
||||
std::cerr << "bass mapping mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] int runStereoMappingTest()
|
||||
{
|
||||
const auto level = core::EnhanceLevel::tryFromLevel(50U);
|
||||
if (!level) {
|
||||
std::cerr << "level setup failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
core::AudioEnhancements enhancements = core::AudioEnhancements::factoryDefault();
|
||||
enhancements.stereo = *level;
|
||||
|
||||
const core::EqProfile base = core::EqProfile::factoryDefault();
|
||||
const core::EqProfile effective =
|
||||
core::applyEnhancementsToEq(base, enhancements);
|
||||
|
||||
const auto band3 = core::EqBandIndex::tryFromIndex(3U);
|
||||
const auto band4 = core::EqBandIndex::tryFromIndex(4U);
|
||||
const auto band5 = core::EqBandIndex::tryFromIndex(5U);
|
||||
if (!band3 || !band4 || !band5) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!nearlyEqual(effective.band(*band3).gain.value(), -0.75F)
|
||||
|| !nearlyEqual(effective.band(*band4).gain.value(), 1.0F)
|
||||
|| !nearlyEqual(effective.band(*band5).gain.value(), 2.0F)) {
|
||||
std::cerr << "stereo mapping mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] int runOffLeavesBaseTest()
|
||||
{
|
||||
const core::EqProfile base = core::EqProfile::factoryDefault();
|
||||
const core::AudioEnhancements off = core::AudioEnhancements::factoryDefault();
|
||||
const core::EqProfile effective = core::applyEnhancementsToEq(base, off);
|
||||
|
||||
const auto band1 = core::EqBandIndex::tryFromIndex(1U);
|
||||
if (!band1) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!nearlyEqual(effective.band(*band1).gain.value(),
|
||||
base.band(*band1).gain.value())) {
|
||||
std::cerr << "off should leave base unchanged\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
if (runBassMappingTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (runStereoMappingTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (runOffLeavesBaseTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -40,8 +40,8 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> applyMixer(
|
||||
const core::MixerState&) override
|
||||
[[nodiscard]] std::expected<void, core::DspError> selectSource(
|
||||
core::ActiveSource) override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
@@ -52,12 +52,6 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setInputVolume(
|
||||
core::MixSource, core::GainDb, core::GainDb) override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setMasterVolume(
|
||||
core::GainDb, core::GainDb) override
|
||||
{
|
||||
@@ -76,6 +70,18 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setBassBoostLevel(
|
||||
core::EnhanceLevel) override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setStereoSpreadLevel(
|
||||
core::EnhanceLevel) override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> writeRawParam(
|
||||
unsigned, float) override
|
||||
{
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
#include "adau1701/Adau1701Error.hpp"
|
||||
|
||||
#include "core/AudioProfile.hpp"
|
||||
#include "core/EnhanceLevel.hpp"
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/EqProfile.hpp"
|
||||
#include "core/FrequencyHz.hpp"
|
||||
#include "core/GainDb.hpp"
|
||||
#include "core/IDspProgramSource.hpp"
|
||||
#include "core/MixSource.hpp"
|
||||
#include "core/MixerState.hpp"
|
||||
#include "core/ActiveSource.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
@@ -144,18 +144,18 @@ public:
|
||||
const core::AudioProfile& profile);
|
||||
|
||||
/**
|
||||
* @brief applyMixer — safeload input and stereo-mixer gains.
|
||||
* @brief selectSource — safeload DC1 to pick MX1's active input pair.
|
||||
*
|
||||
* @dname applyMixer
|
||||
* @param mixer Per-source and St Mixer1 levels.
|
||||
* @dname selectSource
|
||||
* @param source Which stereo pair MX1 passes through.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> applyMixer(
|
||||
const core::MixerState& mixer);
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> selectSource(
|
||||
core::ActiveSource source);
|
||||
|
||||
/**
|
||||
* @brief applyEq — safeload all six PEQ bands.
|
||||
@@ -171,22 +171,6 @@ public:
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> applyEq(
|
||||
const core::EqProfile& eq);
|
||||
|
||||
/**
|
||||
* @brief setInputVolume — safeload one input path gain.
|
||||
*
|
||||
* @dname setInputVolume
|
||||
* @param source Si4684 or ESP32 I2S path.
|
||||
* @param left Left channel gain.
|
||||
* @param right Right channel gain.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right);
|
||||
|
||||
/**
|
||||
* @brief setMasterVolume — safeload Multiple 1 master output gain.
|
||||
*
|
||||
@@ -234,6 +218,35 @@ public:
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> setBeepEnabled(
|
||||
bool enabled);
|
||||
|
||||
/**
|
||||
* @brief setBassBoostLevel — scale Bass Boost1 toward its compiled
|
||||
* curve.
|
||||
*
|
||||
* @dname setBassBoostLevel
|
||||
* @param level 0 = flat bypass, 100 = full compiled response.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> setBassBoostLevel(
|
||||
core::EnhanceLevel level);
|
||||
|
||||
/**
|
||||
* @brief setStereoSpreadLevel — scale SPhat1's stereo spread amount.
|
||||
*
|
||||
* @dname setStereoSpreadLevel
|
||||
* @param level 0 = no spread, 100 = full compiled spread.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> setStereoSpreadLevel(
|
||||
core::EnhanceLevel level);
|
||||
|
||||
/**
|
||||
* @brief writeRawParam — safeload any named Parameter RAM cell.
|
||||
*
|
||||
|
||||
@@ -45,15 +45,12 @@ public:
|
||||
[[nodiscard]] std::expected<void, core::DspError> applyProfile(
|
||||
const core::AudioProfile& profile) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> applyMixer(
|
||||
const core::MixerState& mixer) override;
|
||||
[[nodiscard]] std::expected<void, core::DspError> selectSource(
|
||||
core::ActiveSource source) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> applyEq(
|
||||
const core::EqProfile& eq) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setMasterVolume(
|
||||
core::GainDb left, core::GainDb right) override;
|
||||
|
||||
@@ -64,6 +61,12 @@ public:
|
||||
[[nodiscard]] std::expected<void, core::DspError> setBeepEnabled(
|
||||
bool enabled) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setBassBoostLevel(
|
||||
core::EnhanceLevel level) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setStereoSpreadLevel(
|
||||
core::EnhanceLevel level) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> writeRawParam(
|
||||
unsigned address, float value) override;
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
#include "DigiRadio_IC_1_PARAM.h"
|
||||
|
||||
#include "core/ActiveSource.hpp"
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/MixSource.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -39,39 +39,30 @@ namespace adau1701 {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief paramAddrInputLeft — left volume address for an input source.
|
||||
* @brief paramSourceIndex — MX1 pair index written to DC1 for a source.
|
||||
*
|
||||
* @dname paramAddrInputLeft
|
||||
* @param source Si4684 or ESP32 path.
|
||||
* @return Parameter RAM address for the left channel gain cell.
|
||||
* @dname paramSourceIndex
|
||||
* @param source Which stereo pair MX1 should pass through.
|
||||
* @return 0 (Radio), 1 (Bluetooth), or 2 (Beep) -- confirmed live
|
||||
* 2026-08-25 against real hardware (see
|
||||
* docs/adau1701-sigmastudio-analysis.md).
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] inline unsigned paramAddrInputLeft(core::MixSource source) noexcept
|
||||
[[nodiscard]] inline unsigned paramSourceIndex(
|
||||
core::ActiveSource source) noexcept
|
||||
{
|
||||
return source == core::MixSource::Si4684
|
||||
? static_cast<unsigned>(ADDR_SI4674)
|
||||
: static_cast<unsigned>(ADDR_ESP32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief paramAddrInputRight — right volume address for an input source.
|
||||
*
|
||||
* @dname paramAddrInputRight
|
||||
* @param source Si4684 or ESP32 path.
|
||||
* @return Parameter RAM address for the right channel gain cell.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] inline unsigned paramAddrInputRight(core::MixSource source) noexcept
|
||||
{
|
||||
return source == core::MixSource::Si4684
|
||||
? static_cast<unsigned>(ADDR_SI4674_1)
|
||||
: static_cast<unsigned>(ADDR_ESP32_1);
|
||||
switch (source) {
|
||||
case core::ActiveSource::Radio:
|
||||
return 0U;
|
||||
case core::ActiveSource::Bluetooth:
|
||||
return 1U;
|
||||
case core::ActiveSource::Beep:
|
||||
return 2U;
|
||||
}
|
||||
return 0U;
|
||||
}
|
||||
|
||||
} // namespace adau1701
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Generated from Firmware/ADAU1701-Firmware/DigiRadio_IC_1_PARAM.h (the
|
||||
* SigmaStudio export). Regenerate by re-running the extraction over that
|
||||
* file if the SigmaStudio project's cell list changes; entries here must
|
||||
* stay in sync with the ADDR_* constants used by
|
||||
* SigmaStudio export, "DigiRadioFinale" revision, captured 2026-08-25).
|
||||
* Regenerate by re-running the extraction over that file if the SigmaStudio
|
||||
* project's cell list changes; entries here must stay in sync with the
|
||||
* ADDR_* constants used by
|
||||
* components/drivers/adau1701/src/Adau1701Driver.cpp's replayProgram().
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-18
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -39,83 +40,239 @@ struct Adau1701ParamEntry {
|
||||
* @pubstate Read-only; see file header for regeneration instructions.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-18
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
inline constexpr std::array<Adau1701ParamEntry, 74> kAdau1701ParamTable = {{
|
||||
inline constexpr std::array<Adau1701ParamEntry, 230> kAdau1701ParamTable = {{
|
||||
{"BEEP1_ENABLE", 0},
|
||||
{"BEEP1_KICK", 1},
|
||||
{"BEEP1_BEEP_FREQ", 2},
|
||||
{"SI4674", 3},
|
||||
{"SI4674_1", 4},
|
||||
{"ESP32", 5},
|
||||
{"ESP32_1", 6},
|
||||
{"SINGLE1", 7},
|
||||
{"DC1", 3},
|
||||
{"DCB1_POLE", 4},
|
||||
{"DCB2_POLE", 5},
|
||||
{"DCB4_POLE", 6},
|
||||
{"DCB3_POLE", 7},
|
||||
{"SSPLITTER1", 8},
|
||||
{"STMIXER1_ST0_VOLUME", 9},
|
||||
{"STMIXER1_ST1_VOLUME", 10},
|
||||
{"STMIXER1_ST2_VOLUME", 11},
|
||||
{"PARAMEQ1_ST0_B0", 12},
|
||||
{"PARAMEQ1_ST0_B1", 13},
|
||||
{"PARAMEQ1_ST0_B2", 14},
|
||||
{"PARAMEQ1_ST0_A0", 15},
|
||||
{"PARAMEQ1_ST0_A1", 16},
|
||||
{"PARAMEQ1_ST1_B0", 17},
|
||||
{"PARAMEQ1_ST1_B1", 18},
|
||||
{"PARAMEQ1_ST1_B2", 19},
|
||||
{"PARAMEQ1_ST1_A0", 20},
|
||||
{"PARAMEQ1_ST1_A1", 21},
|
||||
{"PARAMEQ1_ST2_B0", 22},
|
||||
{"PARAMEQ1_ST2_B1", 23},
|
||||
{"PARAMEQ1_ST2_B2", 24},
|
||||
{"PARAMEQ1_ST2_A0", 25},
|
||||
{"PARAMEQ1_ST2_A1", 26},
|
||||
{"PARAMEQ1_ST3_B0", 27},
|
||||
{"PARAMEQ1_ST3_B1", 28},
|
||||
{"PARAMEQ1_ST3_B2", 29},
|
||||
{"PARAMEQ1_ST3_A0", 30},
|
||||
{"PARAMEQ1_ST3_A1", 31},
|
||||
{"PARAMEQ1_ST4_B0", 32},
|
||||
{"PARAMEQ1_ST4_B1", 33},
|
||||
{"PARAMEQ1_ST4_B2", 34},
|
||||
{"PARAMEQ1_ST4_A0", 35},
|
||||
{"PARAMEQ1_ST4_A1", 36},
|
||||
{"PARAMEQ1_ST5_B0", 37},
|
||||
{"PARAMEQ1_ST5_B1", 38},
|
||||
{"PARAMEQ1_ST5_B2", 39},
|
||||
{"PARAMEQ1_ST5_A0", 40},
|
||||
{"PARAMEQ1_ST5_A1", 41},
|
||||
{"MULTIPLE1", 42},
|
||||
{"MULTIPLE1_1", 43},
|
||||
{"LIMITER1_S1", 44},
|
||||
{"LIMITER1_INT1", 45},
|
||||
{"LIMITER1_S2", 46},
|
||||
{"LIMITER1_INT2", 47},
|
||||
{"LIMITER1_S3", 48},
|
||||
{"LIMITER1_INT3", 49},
|
||||
{"LIMITER1_S4", 50},
|
||||
{"LIMITER1_INT4", 51},
|
||||
{"LIMITER1_C1", 52},
|
||||
{"LIMITER1_C2", 53},
|
||||
{"LIMITER1_C3", 54},
|
||||
{"LIMITER1_THRESHOLD", 55},
|
||||
{"LIMITER1_RMS", 56},
|
||||
{"LIMITER1_DECAY", 57},
|
||||
{"LIMITER1_DECAYCOMPLEMENT", 58},
|
||||
{"LIMITER2_S1", 59},
|
||||
{"LIMITER2_INT1", 60},
|
||||
{"LIMITER2_S2", 61},
|
||||
{"LIMITER2_INT2", 62},
|
||||
{"LIMITER2_S3", 63},
|
||||
{"LIMITER2_INT3", 64},
|
||||
{"LIMITER2_S4", 65},
|
||||
{"LIMITER2_INT4", 66},
|
||||
{"LIMITER2_C1", 67},
|
||||
{"LIMITER2_C2", 68},
|
||||
{"LIMITER2_C3", 69},
|
||||
{"LIMITER2_THRESHOLD", 70},
|
||||
{"LIMITER2_RMS", 71},
|
||||
{"LIMITER2_DECAY", 72},
|
||||
{"LIMITER2_DECAYCOMPLEMENT", 73},
|
||||
{"COMPRESSOR1_0", 9},
|
||||
{"COMPRESSOR1_1", 10},
|
||||
{"COMPRESSOR1_2", 11},
|
||||
{"COMPRESSOR1_3", 12},
|
||||
{"COMPRESSOR1_4", 13},
|
||||
{"COMPRESSOR1_5", 14},
|
||||
{"COMPRESSOR1_6", 15},
|
||||
{"COMPRESSOR1_7", 16},
|
||||
{"COMPRESSOR1_8", 17},
|
||||
{"COMPRESSOR1_9", 18},
|
||||
{"COMPRESSOR1_10", 19},
|
||||
{"COMPRESSOR1_11", 20},
|
||||
{"COMPRESSOR1_12", 21},
|
||||
{"COMPRESSOR1_13", 22},
|
||||
{"COMPRESSOR1_14", 23},
|
||||
{"COMPRESSOR1_15", 24},
|
||||
{"COMPRESSOR1_16", 25},
|
||||
{"COMPRESSOR1_17", 26},
|
||||
{"COMPRESSOR1_18", 27},
|
||||
{"COMPRESSOR1_19", 28},
|
||||
{"COMPRESSOR1_20", 29},
|
||||
{"COMPRESSOR1_21", 30},
|
||||
{"COMPRESSOR1_22", 31},
|
||||
{"COMPRESSOR1_23", 32},
|
||||
{"COMPRESSOR1_24", 33},
|
||||
{"COMPRESSOR1_25", 34},
|
||||
{"COMPRESSOR1_26", 35},
|
||||
{"COMPRESSOR1_27", 36},
|
||||
{"COMPRESSOR1_28", 37},
|
||||
{"COMPRESSOR1_29", 38},
|
||||
{"COMPRESSOR1_30", 39},
|
||||
{"COMPRESSOR1_31", 40},
|
||||
{"COMPRESSOR1_32", 41},
|
||||
{"COMPRESSOR1_33", 42},
|
||||
{"COMPRESSOR1_RMS", 43},
|
||||
{"COMPRESSOR1_POST_GAIN", 44},
|
||||
{"COMPRESSOR1_HOLD", 45},
|
||||
{"COMPRESSOR1_DECAY", 46},
|
||||
{"1XRTA3_TCONST", 47},
|
||||
{"1XRTA3_HOLD", 48},
|
||||
{"1XRTA3_DECAY", 49},
|
||||
{"1XRTA3", 2074},
|
||||
{"1XRTA4_TCONST", 50},
|
||||
{"1XRTA4_HOLD", 51},
|
||||
{"1XRTA4_DECAY", 52},
|
||||
{"1XRTA4", 2074},
|
||||
{"1XRTA1_TCONST", 53},
|
||||
{"1XRTA1_HOLD", 54},
|
||||
{"1XRTA1_DECAY", 55},
|
||||
{"1XRTA1", 2074},
|
||||
{"1XRTA2_TCONST", 56},
|
||||
{"1XRTA2_HOLD", 57},
|
||||
{"1XRTA2_DECAY", 58},
|
||||
{"1XRTA2", 2074},
|
||||
{"PARAMEQ1_ST0_B0", 59},
|
||||
{"PARAMEQ1_ST0_B1", 60},
|
||||
{"PARAMEQ1_ST0_B2", 61},
|
||||
{"PARAMEQ1_ST0_A0", 62},
|
||||
{"PARAMEQ1_ST0_A1", 63},
|
||||
{"PARAMEQ1_ST1_B0", 64},
|
||||
{"PARAMEQ1_ST1_B1", 65},
|
||||
{"PARAMEQ1_ST1_B2", 66},
|
||||
{"PARAMEQ1_ST1_A0", 67},
|
||||
{"PARAMEQ1_ST1_A1", 68},
|
||||
{"PARAMEQ1_ST2_B0", 69},
|
||||
{"PARAMEQ1_ST2_B1", 70},
|
||||
{"PARAMEQ1_ST2_B2", 71},
|
||||
{"PARAMEQ1_ST2_A0", 72},
|
||||
{"PARAMEQ1_ST2_A1", 73},
|
||||
{"PARAMEQ1_ST3_B0", 74},
|
||||
{"PARAMEQ1_ST3_B1", 75},
|
||||
{"PARAMEQ1_ST3_B2", 76},
|
||||
{"PARAMEQ1_ST3_A0", 77},
|
||||
{"PARAMEQ1_ST3_A1", 78},
|
||||
{"PARAMEQ1_ST4_B0", 79},
|
||||
{"PARAMEQ1_ST4_B1", 80},
|
||||
{"PARAMEQ1_ST4_B2", 81},
|
||||
{"PARAMEQ1_ST4_A0", 82},
|
||||
{"PARAMEQ1_ST4_A1", 83},
|
||||
{"PARAMEQ1_ST5_B0", 84},
|
||||
{"PARAMEQ1_ST5_B1", 85},
|
||||
{"PARAMEQ1_ST5_B2", 86},
|
||||
{"PARAMEQ1_ST5_A0", 87},
|
||||
{"PARAMEQ1_ST5_A1", 88},
|
||||
{"SPHAT1_B0LO0", 89},
|
||||
{"SPHAT1_B0LO1", 90},
|
||||
{"SPHAT1_B0LO2", 91},
|
||||
{"SPHAT1_B0LO3", 92},
|
||||
{"SPHAT1_B0LO4", 93},
|
||||
{"SPHAT1_B0LO5", 94},
|
||||
{"SPHAT1_B0LO6", 95},
|
||||
{"SPHAT1_B0LO7", 96},
|
||||
{"SPHAT1_B0LO8", 97},
|
||||
{"SPHAT1_B0LO9", 98},
|
||||
{"SPHAT1_GAINHI", 99},
|
||||
{"SPHAT1_GAINLO", 100},
|
||||
{"SPHAT1_GAININV", 101},
|
||||
{"SPHAT1_COMP_BASE0", 102},
|
||||
{"SPHAT1_COMP_BASE1", 103},
|
||||
{"SPHAT1_COMP_BASE2", 104},
|
||||
{"SPHAT1_COMP_BASE3", 105},
|
||||
{"SPHAT1_COMP_BASE4", 106},
|
||||
{"SPHAT1_COMP_BASE5", 107},
|
||||
{"SPHAT1_COMP_BASE6", 108},
|
||||
{"SPHAT1_COMP_BASE7", 109},
|
||||
{"SPHAT1_COMP_BASE8", 110},
|
||||
{"SPHAT1_COMP_BASE9", 111},
|
||||
{"SPHAT1_COMP_BASE10", 112},
|
||||
{"SPHAT1_COMP_BASE11", 113},
|
||||
{"SPHAT1_COMP_BASE12", 114},
|
||||
{"SPHAT1_COMP_BASE13", 115},
|
||||
{"SPHAT1_COMP_BASE14", 116},
|
||||
{"SPHAT1_COMP_BASE15", 117},
|
||||
{"SPHAT1_COMP_BASE16", 118},
|
||||
{"SPHAT1_COMP_BASE17", 119},
|
||||
{"SPHAT1_COMP_BASE18", 120},
|
||||
{"SPHAT1_COMP_BASE19", 121},
|
||||
{"SPHAT1_COMP_BASE20", 122},
|
||||
{"SPHAT1_COMP_BASE21", 123},
|
||||
{"SPHAT1_COMP_BASE22", 124},
|
||||
{"SPHAT1_COMP_BASE23", 125},
|
||||
{"SPHAT1_COMP_BASE24", 126},
|
||||
{"SPHAT1_COMP_BASE25", 127},
|
||||
{"SPHAT1_COMP_BASE26", 128},
|
||||
{"SPHAT1_COMP_BASE27", 129},
|
||||
{"SPHAT1_COMP_BASE28", 130},
|
||||
{"SPHAT1_COMP_BASE29", 131},
|
||||
{"SPHAT1_COMP_BASE30", 132},
|
||||
{"SPHAT1_COMP_BASE31", 133},
|
||||
{"SPHAT1_COMP_BASE32", 134},
|
||||
{"SPHAT1_COMP_BASE33", 135},
|
||||
{"SPHAT1_RMS", 136},
|
||||
{"SPHAT1_DECAY", 137},
|
||||
{"SPHAT1_HOLD", 138},
|
||||
{"SPHAT1_SPREAD1", 139},
|
||||
{"SPHAT1_SPREAD2", 140},
|
||||
{"GENFILTER1_ST0_B0", 141},
|
||||
{"GENFILTER1_ST0_B1", 142},
|
||||
{"GENFILTER1_ST0_B2", 143},
|
||||
{"GENFILTER1_ST0_A1", 144},
|
||||
{"GENFILTER1_ST0_A2", 145},
|
||||
{"MULTIPLE1", 146},
|
||||
{"MULTIPLE1_1", 147},
|
||||
{"BASSBOOST1_BASSFREQUENCY", 148},
|
||||
{"BASSBOOST1_B0", 149},
|
||||
{"BASSBOOST1_B1", 150},
|
||||
{"BASSBOOST1_B2", 151},
|
||||
{"BASSBOOST1_A1", 152},
|
||||
{"BASSBOOST1_A2", 153},
|
||||
{"BASSBOOST1_TABLE0", 154},
|
||||
{"BASSBOOST1_TABLE1", 155},
|
||||
{"BASSBOOST1_TABLE2", 156},
|
||||
{"BASSBOOST1_TABLE3", 157},
|
||||
{"BASSBOOST1_TABLE4", 158},
|
||||
{"BASSBOOST1_TABLE5", 159},
|
||||
{"BASSBOOST1_TABLE6", 160},
|
||||
{"BASSBOOST1_TABLE7", 161},
|
||||
{"BASSBOOST1_TABLE8", 162},
|
||||
{"BASSBOOST1_TABLE9", 163},
|
||||
{"BASSBOOST1_TABLE10", 164},
|
||||
{"BASSBOOST1_TABLE11", 165},
|
||||
{"BASSBOOST1_TABLE12", 166},
|
||||
{"BASSBOOST1_TABLE13", 167},
|
||||
{"BASSBOOST1_TABLE14", 168},
|
||||
{"BASSBOOST1_TABLE15", 169},
|
||||
{"BASSBOOST1_TABLE16", 170},
|
||||
{"BASSBOOST1_TABLE17", 171},
|
||||
{"BASSBOOST1_TABLE18", 172},
|
||||
{"BASSBOOST1_TABLE19", 173},
|
||||
{"BASSBOOST1_TABLE20", 174},
|
||||
{"BASSBOOST1_TABLE21", 175},
|
||||
{"BASSBOOST1_TABLE22", 176},
|
||||
{"BASSBOOST1_TABLE23", 177},
|
||||
{"BASSBOOST1_TABLE24", 178},
|
||||
{"BASSBOOST1_TABLE25", 179},
|
||||
{"BASSBOOST1_TABLE26", 180},
|
||||
{"BASSBOOST1_TABLE27", 181},
|
||||
{"BASSBOOST1_TABLE28", 182},
|
||||
{"BASSBOOST1_TABLE29", 183},
|
||||
{"BASSBOOST1_TABLE30", 184},
|
||||
{"BASSBOOST1_TABLE31", 185},
|
||||
{"BASSBOOST1_TABLE32", 186},
|
||||
{"BASSBOOST1_TIMECONSTANT", 187},
|
||||
{"1XRTA2_2_TCONST", 188},
|
||||
{"1XRTA2_2_HOLD", 189},
|
||||
{"1XRTA2_2_DECAY", 190},
|
||||
{"1XRTA2_2", 2074},
|
||||
{"1XRTA1_2_TCONST", 191},
|
||||
{"1XRTA1_2_HOLD", 192},
|
||||
{"1XRTA1_2_DECAY", 193},
|
||||
{"1XRTA1_2", 2074},
|
||||
{"LIMITER2_S1", 194},
|
||||
{"LIMITER2_INT1", 195},
|
||||
{"LIMITER2_S2", 196},
|
||||
{"LIMITER2_INT2", 197},
|
||||
{"LIMITER2_S3", 198},
|
||||
{"LIMITER2_INT3", 199},
|
||||
{"LIMITER2_S4", 200},
|
||||
{"LIMITER2_INT4", 201},
|
||||
{"LIMITER2_C1", 202},
|
||||
{"LIMITER2_C2", 203},
|
||||
{"LIMITER2_C3", 204},
|
||||
{"LIMITER2_THRESHOLD", 205},
|
||||
{"LIMITER2_RMS", 206},
|
||||
{"LIMITER2_DECAY", 207},
|
||||
{"LIMITER2_DECAYCOMPLEMENT", 208},
|
||||
{"LIMITER1_S1", 209},
|
||||
{"LIMITER1_INT1", 210},
|
||||
{"LIMITER1_S2", 211},
|
||||
{"LIMITER1_INT2", 212},
|
||||
{"LIMITER1_S3", 213},
|
||||
{"LIMITER1_INT3", 214},
|
||||
{"LIMITER1_S4", 215},
|
||||
{"LIMITER1_INT4", 216},
|
||||
{"LIMITER1_C1", 217},
|
||||
{"LIMITER1_C2", 218},
|
||||
{"LIMITER1_C3", 219},
|
||||
{"LIMITER1_THRESHOLD", 220},
|
||||
{"LIMITER1_RMS", 221},
|
||||
{"LIMITER1_DECAY", 222},
|
||||
{"LIMITER1_DECAYCOMPLEMENT", 223},
|
||||
}};
|
||||
|
||||
/**
|
||||
@@ -127,7 +284,7 @@ inline constexpr std::array<Adau1701ParamEntry, 74> kAdau1701ParamTable = {{
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-08-18
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] inline std::optional<unsigned> findAdau1701ParamAddress(
|
||||
std::string_view name) noexcept
|
||||
|
||||
@@ -358,18 +358,22 @@ namespace adau1701
|
||||
return safeloadFixpoint(paramAddr, core::gainDbToLinearFixpoint(gain));
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right)
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::selectSource(
|
||||
core::ActiveSource source)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready)
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
if (auto result = safeloadGain(paramAddrInputLeft(source), left); !result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return safeloadGain(paramAddrInputRight(source), right);
|
||||
// MX1 (DCinputmux_stereo) reads DC1 as a raw 32-bit integer pair
|
||||
// index (0/1/2), NOT the 5.23 fixpoint conversion its compiled
|
||||
// TYPE_DC1/VALUE_DC1 macros would suggest -- confirmed live
|
||||
// 2026-08-25 (a 5.23-encoded write left the source unchanged; the
|
||||
// raw integer switched Radio/Bluetooth/Beep correctly). 0=Radio,
|
||||
// 1=Bluetooth (ESP32), 2=Beep, per paramSourceIndex().
|
||||
const auto index =
|
||||
static_cast<std::int32_t>(paramSourceIndex(source));
|
||||
return safeloadFixpoint(static_cast<unsigned>(ADDR_DC1), index);
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setMasterVolume(
|
||||
@@ -387,45 +391,6 @@ namespace adau1701
|
||||
return safeloadGain(static_cast<unsigned>(ADDR_MULTIPLE1_1), right);
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::applyMixer(
|
||||
const core::MixerState &mixer)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready)
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
if (auto result = setInputVolume(core::MixSource::Si4684, mixer.si4684Left,
|
||||
mixer.si4684Right);
|
||||
!result)
|
||||
{
|
||||
ESP_LOGW(kTag, "applyMixer: si4684 input safeload failed");
|
||||
return result;
|
||||
}
|
||||
if (auto result = setInputVolume(core::MixSource::Esp32, mixer.esp32Left,
|
||||
mixer.esp32Right);
|
||||
!result)
|
||||
{
|
||||
ESP_LOGW(kTag, "applyMixer: esp32 input safeload failed");
|
||||
return result;
|
||||
}
|
||||
if (auto result =
|
||||
safeloadGain(static_cast<unsigned>(ADDR_STMIXER1_ST0_VOLUME),
|
||||
mixer.mixLeft);
|
||||
!result)
|
||||
{
|
||||
ESP_LOGW(kTag, "applyMixer: st0 safeload failed");
|
||||
return result;
|
||||
}
|
||||
if (auto result = safeloadGain(
|
||||
static_cast<unsigned>(ADDR_STMIXER1_ST1_VOLUME), mixer.mixRight);
|
||||
!result)
|
||||
{
|
||||
ESP_LOGW(kTag, "applyMixer: st1 safeload failed");
|
||||
return result;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setEqBand(
|
||||
core::EqBandIndex band, core::GainDb gain, core::FrequencyHz center, float q)
|
||||
{
|
||||
@@ -487,6 +452,103 @@ namespace adau1701
|
||||
return safeloadFixpoint(static_cast<unsigned>(ADDR_BEEP1_KICK), value);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// Compiled SigmaStudio defaults for Bass Boost1's crossover filter
|
||||
// and 33-point compander curve (DigiRadioFinale_IC_1_PARAM.h,
|
||||
// 2026-08-25 export). setBassBoostLevel() interpolates from these
|
||||
// toward an identity/unity bypass as level goes from 100 to 0 --
|
||||
// ADI's Dynamic Bass Boost algorithm internals aren't documented,
|
||||
// so this is a linear blend of the known-good compiled curve, not
|
||||
// a re-derivation of the algorithm's own math.
|
||||
constexpr float kBassBoostB0 = 4.24433093514364e-05F;
|
||||
constexpr float kBassBoostB1 = 8.48866187028728e-05F;
|
||||
constexpr float kBassBoostB2 = 4.24433093514364e-05F;
|
||||
constexpr float kBassBoostA1 = 1.98148576456209F;
|
||||
constexpr float kBassBoostA2 = -0.981655537799498F;
|
||||
constexpr float kBassBoostTable[33] = {
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.319153785510076F, 0.319153785510076F, 0.319153785510076F,
|
||||
0.322849412171264F, 0.334195040026114F, 0.345939377826122F,
|
||||
0.358096437102636F, 0.370680721782576F, 0.383707245492279F,
|
||||
0.39719154946944F, 0.411149721104522F, 0.425598413133743F,
|
||||
};
|
||||
|
||||
constexpr float kSpreadSpread1 = 0.0629093159447337F;
|
||||
constexpr float kSpreadSpread2 = 0.0193038143874401F;
|
||||
|
||||
[[nodiscard]] float towardIdentity(float compiled, float identity,
|
||||
float level) noexcept
|
||||
{
|
||||
return identity + (compiled - identity) * level;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setBassBoostLevel(
|
||||
core::EnhanceLevel level)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready)
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
const float t = level.fraction();
|
||||
unsigned addrs[5U];
|
||||
int values[5U];
|
||||
addrs[0] = static_cast<unsigned>(ADDR_BASSBOOST1_B0);
|
||||
addrs[1] = static_cast<unsigned>(ADDR_BASSBOOST1_B1);
|
||||
addrs[2] = static_cast<unsigned>(ADDR_BASSBOOST1_B2);
|
||||
addrs[3] = static_cast<unsigned>(ADDR_BASSBOOST1_A1);
|
||||
addrs[4] = static_cast<unsigned>(ADDR_BASSBOOST1_A2);
|
||||
values[0] = core::floatToFixpoint823(towardIdentity(kBassBoostB0, 1.0F, t));
|
||||
values[1] = core::floatToFixpoint823(towardIdentity(kBassBoostB1, 0.0F, t));
|
||||
values[2] = core::floatToFixpoint823(towardIdentity(kBassBoostB2, 0.0F, t));
|
||||
values[3] = core::floatToFixpoint823(towardIdentity(kBassBoostA1, 0.0F, t));
|
||||
values[4] = core::floatToFixpoint823(towardIdentity(kBassBoostA2, 0.0F, t));
|
||||
if (sigma_safeload_block(5U, addrs, values) != 0)
|
||||
{
|
||||
return std::unexpected(Adau1701Error::SafeloadFailed);
|
||||
}
|
||||
|
||||
for (unsigned i = 0U; i < 33U; ++i)
|
||||
{
|
||||
const unsigned addr =
|
||||
static_cast<unsigned>(ADDR_BASSBOOST1_TABLE0) + i;
|
||||
const std::int32_t value = core::floatToFixpoint823(
|
||||
towardIdentity(kBassBoostTable[i], 1.0F, t));
|
||||
if (auto result = safeloadFixpoint(addr, value); !result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setStereoSpreadLevel(
|
||||
core::EnhanceLevel level)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready)
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
const float t = level.fraction();
|
||||
if (auto result = safeloadFixpoint(
|
||||
static_cast<unsigned>(ADDR_SPHAT1_SPREAD1),
|
||||
core::floatToFixpoint823(kSpreadSpread1 * t));
|
||||
!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return safeloadFixpoint(
|
||||
static_cast<unsigned>(ADDR_SPHAT1_SPREAD2),
|
||||
core::floatToFixpoint823(kSpreadSpread2 * t));
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::writeRawParam(
|
||||
unsigned address, float value)
|
||||
{
|
||||
@@ -535,7 +597,7 @@ namespace adau1701
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
if (auto result = applyMixer(profile.mixer); !result)
|
||||
if (auto result = selectSource(profile.activeSource); !result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@@ -543,7 +605,17 @@ namespace adau1701
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return setMasterVolume(profile.masterLeft, profile.masterRight);
|
||||
if (auto result = setMasterVolume(profile.masterLeft, profile.masterRight);
|
||||
!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (auto result = setBassBoostLevel(profile.enhancements.bass);
|
||||
!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return setStereoSpreadLevel(profile.enhancements.stereo);
|
||||
}
|
||||
|
||||
} // namespace adau1701
|
||||
|
||||
@@ -43,10 +43,10 @@ std::expected<void, core::DspError> Adau1701Dsp::applyProfile(
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::applyMixer(
|
||||
const core::MixerState& mixer)
|
||||
std::expected<void, core::DspError> Adau1701Dsp::selectSource(
|
||||
core::ActiveSource source)
|
||||
{
|
||||
if (auto result = driver_.applyMixer(mixer); !result) {
|
||||
if (auto result = driver_.selectSource(source); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
@@ -61,15 +61,6 @@ std::expected<void, core::DspError> Adau1701Dsp::applyEq(
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right)
|
||||
{
|
||||
if (auto result = driver_.setInputVolume(source, left, right); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::setMasterVolume(
|
||||
core::GainDb left, core::GainDb right)
|
||||
{
|
||||
@@ -97,6 +88,24 @@ std::expected<void, core::DspError> Adau1701Dsp::setBeepEnabled(bool enabled)
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::setBassBoostLevel(
|
||||
core::EnhanceLevel level)
|
||||
{
|
||||
if (auto result = driver_.setBassBoostLevel(level); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::setStereoSpreadLevel(
|
||||
core::EnhanceLevel level)
|
||||
{
|
||||
if (auto result = driver_.setStereoSpreadLevel(level); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::writeRawParam(
|
||||
unsigned address, float value)
|
||||
{
|
||||
|
||||
@@ -12,16 +12,15 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/ActiveSource.hpp"
|
||||
#include "core/AudioProfile.hpp"
|
||||
#include "core/DspError.hpp"
|
||||
#include "core/EnhanceLevel.hpp"
|
||||
#include "core/EnhancementsDesign.hpp"
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/FrequencyHz.hpp"
|
||||
#include "core/GainDb.hpp"
|
||||
#include "core/IAudioProfileStore.hpp"
|
||||
#include "core/IDsp.hpp"
|
||||
#include "core/MixSource.hpp"
|
||||
#include "core/StoreError.hpp"
|
||||
|
||||
#include <expected>
|
||||
@@ -106,22 +105,19 @@ public:
|
||||
const core::AudioProfile& profile, bool persist);
|
||||
|
||||
/**
|
||||
* @brief setInputVolume — update one input path and apply live.
|
||||
* @brief selectSource — switch MX1's active input pair and apply live.
|
||||
*
|
||||
* @dname setInputVolume
|
||||
* @param source Si4684 or ESP32 path.
|
||||
* @param left Left gain.
|
||||
* @param right Right gain.
|
||||
* @dname selectSource
|
||||
* @param source Which stereo pair MX1 should pass through.
|
||||
* @param persist When true and store is set, write NVS.
|
||||
* @return Ok on success, or StoreError wrapping DspError/IoFailed.
|
||||
* @pubstate updates profile_.mixer and safeloads.
|
||||
* @pubstate updates profile_.activeSource and safeloads.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
* @date 2026-08-25
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, core::StoreError> setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right,
|
||||
bool persist);
|
||||
[[nodiscard]] std::expected<void, core::StoreError> selectSource(
|
||||
core::ActiveSource source, bool persist);
|
||||
|
||||
/**
|
||||
* @brief setMasterVolume — update master output and apply live.
|
||||
@@ -239,9 +235,6 @@ private:
|
||||
[[nodiscard]] std::expected<void, core::StoreError> applyProfileToDsp(
|
||||
const core::AudioProfile& profile);
|
||||
|
||||
[[nodiscard]] std::expected<void, core::StoreError> applyEffectiveEq(
|
||||
bool persist);
|
||||
|
||||
core::IDsp& dsp_;
|
||||
core::IAudioProfileStore* store_;
|
||||
core::AudioProfile profile_;
|
||||
|
||||
@@ -21,15 +21,6 @@ namespace {
|
||||
|
||||
constexpr char kTag[] = "AudioService";
|
||||
|
||||
[[nodiscard]] core::AudioProfile profileForHardware(
|
||||
const core::AudioProfile& profile) noexcept
|
||||
{
|
||||
core::AudioProfile hardware = profile;
|
||||
hardware.eq =
|
||||
core::applyEnhancementsToEq(profile.eq, profile.enhancements);
|
||||
return hardware;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AudioService::AudioService(core::IDsp& dsp, core::IAudioProfileStore* store)
|
||||
@@ -81,28 +72,13 @@ std::expected<void, core::StoreError> AudioService::persistProfile() const
|
||||
std::expected<void, core::StoreError> AudioService::applyProfileToDsp(
|
||||
const core::AudioProfile& profile)
|
||||
{
|
||||
const core::AudioProfile hardware = profileForHardware(profile);
|
||||
if (auto applied = dsp_.applyProfile(hardware); !applied) {
|
||||
if (auto applied = dsp_.applyProfile(profile); !applied) {
|
||||
ESP_LOGW(kTag, "applyProfileToDsp: DSP safeload failed");
|
||||
return std::unexpected(core::StoreError::IoFailed);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::StoreError> AudioService::applyEffectiveEq(
|
||||
bool persist)
|
||||
{
|
||||
const core::EqProfile effective = core::applyEnhancementsToEq(
|
||||
profile_.eq, profile_.enhancements);
|
||||
if (auto applied = dsp_.applyEq(effective); !applied) {
|
||||
return std::unexpected(core::StoreError::IoFailed);
|
||||
}
|
||||
if (persist) {
|
||||
return persistProfile();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::StoreError> AudioService::applyProfile(
|
||||
const core::AudioProfile& profile, bool persist)
|
||||
{
|
||||
@@ -116,21 +92,13 @@ std::expected<void, core::StoreError> AudioService::applyProfile(
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::StoreError> AudioService::setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right, bool persist)
|
||||
std::expected<void, core::StoreError> AudioService::selectSource(
|
||||
core::ActiveSource source, bool persist)
|
||||
{
|
||||
if (auto applied = dsp_.setInputVolume(source, left, right); !applied) {
|
||||
if (auto applied = dsp_.selectSource(source); !applied) {
|
||||
return std::unexpected(core::StoreError::IoFailed);
|
||||
}
|
||||
|
||||
if (source == core::MixSource::Si4684) {
|
||||
profile_.mixer.si4684Left = left;
|
||||
profile_.mixer.si4684Right = right;
|
||||
} else {
|
||||
profile_.mixer.esp32Left = left;
|
||||
profile_.mixer.esp32Right = right;
|
||||
}
|
||||
|
||||
profile_.activeSource = source;
|
||||
if (persist) {
|
||||
return persistProfile();
|
||||
}
|
||||
@@ -155,10 +123,10 @@ std::expected<void, core::StoreError> AudioService::applyRadioFirstMix(
|
||||
bool persist)
|
||||
{
|
||||
const core::GainDb unity = core::GainDb::zero();
|
||||
profile_.mixer = core::MixerState::radioFirst();
|
||||
profile_.activeSource = core::ActiveSource::Radio;
|
||||
profile_.masterLeft = unity;
|
||||
profile_.masterRight = unity;
|
||||
if (auto applied = dsp_.applyMixer(profile_.mixer); !applied) {
|
||||
if (auto applied = dsp_.selectSource(profile_.activeSource); !applied) {
|
||||
return std::unexpected(core::StoreError::IoFailed);
|
||||
}
|
||||
if (auto master = dsp_.setMasterVolume(unity, unity); !master) {
|
||||
@@ -179,21 +147,39 @@ std::expected<void, core::StoreError> AudioService::setEqBand(
|
||||
.center = center,
|
||||
.q = q,
|
||||
});
|
||||
return applyEffectiveEq(persist);
|
||||
if (auto applied = dsp_.applyEq(profile_.eq); !applied) {
|
||||
return std::unexpected(core::StoreError::IoFailed);
|
||||
}
|
||||
if (persist) {
|
||||
return persistProfile();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::StoreError> AudioService::setStereoEnhance(
|
||||
core::EnhanceLevel level, bool persist)
|
||||
{
|
||||
if (auto applied = dsp_.setStereoSpreadLevel(level); !applied) {
|
||||
return std::unexpected(core::StoreError::IoFailed);
|
||||
}
|
||||
profile_.enhancements.stereo = level;
|
||||
return applyEffectiveEq(persist);
|
||||
if (persist) {
|
||||
return persistProfile();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::StoreError> AudioService::setBassEnhance(
|
||||
core::EnhanceLevel level, bool persist)
|
||||
{
|
||||
if (auto applied = dsp_.setBassBoostLevel(level); !applied) {
|
||||
return std::unexpected(core::StoreError::IoFailed);
|
||||
}
|
||||
profile_.enhancements.bass = level;
|
||||
return applyEffectiveEq(persist);
|
||||
if (persist) {
|
||||
return persistProfile();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> AudioService::setBeepEnabled(bool enabled)
|
||||
|
||||
Reference in New Issue
Block a user