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 , 0x00 , 0x00 ,
|
||||||
0x00 , 0x00 , 0x6C , 0xAC ,
|
0x00 , 0x00 , 0x6C , 0xAC ,
|
||||||
0x00 , 0x80 , 0x00 , 0x00 ,
|
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 ,
|
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 , 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 ,
|
0x00 , 0x7F , 0xC3 , 0x65 ,
|
||||||
0x0F , 0x00 , 0x79 , 0x35 ,
|
0x0F , 0x00 , 0x79 , 0x35 ,
|
||||||
0x00 , 0x7F , 0xC3 , 0x65 ,
|
0x00 , 0x7F , 0xC3 , 0x65 ,
|
||||||
0x00 , 0xFF , 0x86 , 0xAE ,
|
0x00 , 0xFF , 0x86 , 0xAE ,
|
||||||
0x0F , 0x80 , 0x79 , 0x19 ,
|
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 , 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 , 0x00 , 0x00 , 0x00 ,
|
|
||||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
|
||||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
|
||||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
|
||||||
0x00 , 0x80 , 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 , 0x00 , 0x00 , 0x00 ,
|
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
0x00 , 0x80 , 0x00 , 0x00 ,
|
||||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
0x00 , 0x80 , 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 , 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 , 0x80 , 0x00 , 0x00 ,
|
||||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||||
0x00 , 0x00 , 0x00 , 0x00 ,
|
0x00 , 0x00 , 0x00 , 0x00 ,
|
||||||
@@ -42,6 +146,52 @@
|
|||||||
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 , 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 ,
|
0x0F , 0xFE , 0x2B , 0xE3 ,
|
||||||
0x00 , 0x22 , 0xBE , 0x2C ,
|
0x00 , 0x22 , 0xBE , 0x2C ,
|
||||||
0x0F , 0xEA , 0xAA , 0xAB ,
|
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 ,
|
|
||||||
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
|
* Created: Tuesday, August 25, 2026 8:11:05 PM
|
||||||
* Description: DigiRadio:IC 1 control register definitions.
|
* Description: DigiRadioFinale:IC 1 control register definitions.
|
||||||
*
|
*
|
||||||
* This software is distributed in the hope that it will be useful,
|
* This software is distributed in the hope that it will be useful,
|
||||||
* but is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
* but is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
*
|
*
|
||||||
* Copyright ©2026 Analog Devices, Inc. All rights reserved.
|
* Copyright ©2026 Analog Devices, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#ifndef __DIGIRADIO_IC_1_REG_H__
|
#ifndef __DIGIRADIOFINALE_IC_1_REG_H__
|
||||||
#define __DIGIRADIO_IC_1_REG_H__
|
#define __DIGIRADIOFINALE_IC_1_REG_H__
|
||||||
|
|
||||||
|
|
||||||
/* InterfaceRegister0 - Registers (IC 1) */
|
/* InterfaceRegister0 - Registers (IC 1) */
|
||||||
|
|||||||
@@ -17,77 +17,125 @@
|
|||||||
<NetList>
|
<NetList>
|
||||||
<IC name=" IC 1 " type="DSPSigma100">
|
<IC name=" IC 1 " type="DSPSigma100">
|
||||||
<Schematic>
|
<Schematic>
|
||||||
<Algorithm name="ICSigma100In1" friendlyname="170x\140x input " cell="Input1 " location="{X=-15, Y=104} " Growth="10 " GrowthB="0 " FS="48000">
|
<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="Link0" />
|
<Link pin="O_C33_A0_P3_out" dir="out" link="Link4" />
|
||||||
<Link pin="O_C33_A0_P4_out" dir="out" link="Link1" />
|
<Link pin="O_C33_A0_P4_out" dir="out" link="Link5" />
|
||||||
<Link pin="O_C33_A0_P5_out" dir="out" link="Link2" />
|
<Link pin="O_C33_A0_P5_out" dir="out" link="Link6" />
|
||||||
<Link pin="O_C33_A0_P6_out" dir="out" link="Link3" />
|
<Link pin="O_C33_A0_P6_out" dir="out" link="Link7" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="BeepAlg1" friendlyname="Beep - variable gain " cell="Beep1 " location="{X=30, Y=459} " Growth="0 " GrowthB="0 " FS="48000">
|
<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="Link15" />
|
<Link pin="O_C0_A0_P1_out" dir="out" link="Link16" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="Gain1940AlgNS1" friendlyname="Gain (no slew) " cell="Si4674 " location="{X=168, Y=5} " Growth="0 " GrowthB="0">
|
<Algorithm name="DCInpAlg1" friendlyname="dc Input " cell="DC1 " location="{X=609, Y=89.22221} " Growth="0 " GrowthB="0 " FS="48000">
|
||||||
<Link pin="I_C63_A0_P1_in" dir="in" link="Link0" />
|
<Link pin="O_C216_A0_P1_out" dir="out" link="Link19" />
|
||||||
<Link pin="O_C63_A0_P2_out" dir="out" link="Link4" />
|
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="Gain1940AlgNS2" friendlyname="Gain (no slew) " cell="Si4674 " location="{X=168, Y=5} " Growth="0 " GrowthB="0">
|
<Algorithm name="DCBlockAlgDoublePrec1" friendlyname="DC Blocking " cell="DCB1 " location="{X=101, Y=61.38417} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C63_A1_P1_in" dir="in" link="Link1" />
|
<Link pin="I_C67_A0_P1_in" dir="in" link="Link4" />
|
||||||
<Link pin="O_C63_A1_P2_out" dir="out" link="Link5" />
|
<Link pin="O_C67_A0_P2_out" dir="out" link="Link2" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="Gain1940AlgNS3" friendlyname="Gain (no slew) " cell="ESP32 " location="{X=166, Y=196} " Growth="0 " GrowthB="0">
|
<Algorithm name="DCBlockAlgDoublePrec2" friendlyname="DC Blocking " cell="DCB2 " location="{X=104, Y=138.3348} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C75_A0_P1_in" dir="in" link="Link2" />
|
<Link pin="I_C72_A0_P1_in" dir="in" link="Link5" />
|
||||||
<Link pin="O_C75_A0_P2_out" dir="out" link="Link6" />
|
<Link pin="O_C72_A0_P2_out" dir="out" link="Link3" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="Gain1940AlgNS4" friendlyname="Gain (no slew) " cell="ESP32 " location="{X=166, Y=196} " Growth="0 " GrowthB="0">
|
<Algorithm name="DCBlockAlgDoublePrec4" friendlyname="DC Blocking " cell="DCB4 " location="{X=103, Y=323.756} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C75_A1_P1_in" dir="in" link="Link3" />
|
<Link pin="I_C91_A0_P1_in" dir="in" link="Link6" />
|
||||||
<Link pin="O_C75_A1_P2_out" dir="out" link="Link7" />
|
<Link pin="O_C91_A0_P2_out" dir="out" link="Link10" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="Gain1940AlgNS7" friendlyname="Gain (no slew) " cell="Single 1 " location="{X=188, Y=404} " Growth="0 " GrowthB="0">
|
<Algorithm name="DCBlockAlgDoublePrec3" friendlyname="DC Blocking " cell="DCB3 " location="{X=92, Y=505.472} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C4_A0_P1_in" dir="in" link="Link15" />
|
<Link pin="I_C81_A0_P1_in" dir="in" link="Link7" />
|
||||||
<Link pin="O_C4_A0_P2_out" dir="out" link="Link16" />
|
<Link pin="O_C81_A0_P2_out" dir="out" link="Link11" />
|
||||||
</Algorithm>
|
</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="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_P2_out" dir="out" link="Link17" />
|
||||||
<Link pin="O_C9_A0_P3_out" dir="out" link="Link18" />
|
<Link pin="O_C9_A0_P3_out" dir="out" link="Link18" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="StereoMixerAlg1" friendlyname="Stereo Mixer " cell="St Mixer1 " location="{X=464, Y=112} " Growth="3 " GrowthB="0">
|
<Algorithm name="TwoChannelSingleDetectAlgFix1" friendlyname="Stereo RMS (Post Gain) " cell="Compressor1 " location="{X=187, Y=-4.364594} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C84_A0_P3_in" dir="in" link="Link4" />
|
<Link pin="I_C106_A0_P1_in" dir="in" link="Link2" />
|
||||||
<Link pin="I_C84_A0_P4_in" dir="in" link="Link5" />
|
<Link pin="I_C106_A0_P2_in" dir="in" link="Link3" />
|
||||||
<Link pin="I_C84_A0_P5_in" dir="in" link="Link6" />
|
<Link pin="O_C106_A0_P3_out" dir="out" link="Link8" />
|
||||||
<Link pin="I_C84_A0_P6_in" dir="in" link="Link7" />
|
<Link pin="O_C106_A0_P4_out" dir="out" link="Link9" />
|
||||||
<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>
|
</Algorithm>
|
||||||
<Algorithm name="PEQ1Chan1" friendlyname="PEQ1Chan - Double Precision " cell="Param EQ1 " location="{X=585, Y=153} " Growth="2 " GrowthB="0">
|
<Algorithm name="SingleBandLevelDet3" friendlyname="Single Band " cell="1 X RTA3 " location="{X=352, Y=296} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C125_A0_P1_in" dir="in" link="Link8" />
|
<Link pin="I_C155_A0_P1_in" dir="in" link="Link10" />
|
||||||
<Link pin="I_C125_A0_P3_in" dir="in" link="Link9" />
|
<Link pin="O_C155_A0_P2_out" dir="out" link="Link14" />
|
||||||
<Link pin="O_C125_A0_P2_out" dir="out" link="Link10" />
|
|
||||||
<Link pin="O_C125_A0_P4_out" dir="out" link="Link11" />
|
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="Gain1940AlgNS5" friendlyname="Gain (no slew) " cell="Multiple 1 " location="{X=711, Y=85} " Growth="0 " GrowthB="0">
|
<Algorithm name="SingleBandLevelDet4" friendlyname="Single Band " cell="1 X RTA4 " location="{X=355, Y=469} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C138_A0_P1_in" dir="in" link="Link10" />
|
<Link pin="I_C158_A0_P1_in" dir="in" link="Link11" />
|
||||||
<Link pin="O_C138_A0_P2_out" dir="out" link="Link12" />
|
<Link pin="O_C158_A0_P2_out" dir="out" link="Link15" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="Gain1940AlgNS6" friendlyname="Gain (no slew) " cell="Multiple 1 " location="{X=711, Y=85} " Growth="0 " GrowthB="0">
|
<Algorithm name="SingleBandLevelDet1" friendlyname="Single Band " cell="1 X RTA1 " location="{X=350, Y=-73} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C138_A1_P1_in" dir="in" link="Link11" />
|
<Link pin="I_C149_A0_P1_in" dir="in" link="Link8" />
|
||||||
<Link pin="O_C138_A1_P2_out" dir="out" link="Link13" />
|
<Link pin="O_C149_A0_P2_out" dir="out" link="Link12" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="limiterAlg1" friendlyname="Limiter with Indicator " cell="Limiter 1 " location="{X=844, Y=37} " Growth="0 " GrowthB="0">
|
<Algorithm name="SingleBandLevelDet2" friendlyname="Single Band " cell="1 X RTA2 " location="{X=344, Y=112} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C169_A0_P1_in" dir="in" link="Link12" />
|
<Link pin="I_C152_A0_P1_in" dir="in" link="Link9" />
|
||||||
<Link pin="O_C169_A0_P2_out" dir="out" link="Link19" />
|
<Link pin="O_C152_A0_P2_out" dir="out" link="Link13" />
|
||||||
</Algorithm>
|
</Algorithm>
|
||||||
<Algorithm name="limiterAlg2" friendlyname="Limiter with Indicator " cell="Limiter 2 " location="{X=848, Y=186} " Growth="0 " GrowthB="0">
|
<Algorithm name="DCinputmux_stereo_Alg1" friendlyname="Stereo " cell="MX1 " location="{X=730, Y=222.1111} " Growth="3 " GrowthB="0">
|
||||||
<Link pin="I_C174_A0_P1_in" dir="in" link="Link13" />
|
<Link pin="I_C174_A0_P3_in" dir="in" link="Link19" />
|
||||||
<Link pin="O_C174_A0_P2_out" dir="out" link="Link14" />
|
<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>
|
||||||
<Algorithm name="ICSigma100Out2" friendlyname="170x\140x output " cell="Output2 " location="{X=1003, Y=202} " Growth="0 " GrowthB="0">
|
<Algorithm name="PEQ1Chan1" friendlyname="PEQ1Chan - Double Precision " cell="Param EQ1 " location="{X=820, Y=211.9035} " Growth="2 " GrowthB="0">
|
||||||
<Link pin="I_C185_A0_P1_in" dir="in" link="Link14" />
|
<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>
|
||||||
<Algorithm name="ICSigma100Out1" friendlyname="170x\140x output " cell="Output1 " location="{X=1009.037, Y=52} " Growth="0 " GrowthB="0">
|
<Algorithm name="SuperPhatAlg1" friendlyname="Super Bass " cell="SPhat1 " location="{X=921, Y=196} " Growth="0 " GrowthB="0">
|
||||||
<Link pin="I_C183_A0_P1_in" dir="in" link="Link19" />
|
<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>
|
</Algorithm>
|
||||||
</Schematic>
|
</Schematic>
|
||||||
</IC>
|
</IC>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* File: defines.h
|
* File: defines.h
|
||||||
*
|
*
|
||||||
* Created: Friday, August 7, 2026 3:19:11 AM
|
* Created: Tuesday, August 25, 2026 8:11:05 PM
|
||||||
* Description: DigiRadio IC default download data definitions.
|
* Description: DigiRadioFinale IC default download data definitions.
|
||||||
*
|
*
|
||||||
* This software is distributed in the hope that it will be useful,
|
* This software is distributed in the hope that it will be useful,
|
||||||
* but is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
* but is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
|||||||
@@ -19,11 +19,9 @@ idf_component_register(
|
|||||||
"src/EqBandIndex.cpp"
|
"src/EqBandIndex.cpp"
|
||||||
"src/BiquadCoefficients.cpp"
|
"src/BiquadCoefficients.cpp"
|
||||||
"src/BiquadDesign.cpp"
|
"src/BiquadDesign.cpp"
|
||||||
"src/MixerState.cpp"
|
|
||||||
"src/EqProfile.cpp"
|
"src/EqProfile.cpp"
|
||||||
"src/EnhanceLevel.cpp"
|
"src/EnhanceLevel.cpp"
|
||||||
"src/AudioEnhancements.cpp"
|
"src/AudioEnhancements.cpp"
|
||||||
"src/EnhancementsDesign.cpp"
|
|
||||||
"src/AudioProfile.cpp"
|
"src/AudioProfile.cpp"
|
||||||
"src/AudioProfileJson.cpp"
|
"src/AudioProfileJson.cpp"
|
||||||
"src/Bt1035At.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 {
|
namespace core {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief AudioEnhancements — psychoacoustic EQ overlays (0–100 each).
|
* @brief AudioEnhancements — dedicated-block enhancement levels (0–100).
|
||||||
*
|
*
|
||||||
* @dname AudioEnhancements
|
* @dname AudioEnhancements
|
||||||
* @return n/a (type)
|
* @return n/a (type)
|
||||||
* @pubstate Mapped to PEQ bands at runtime (manual chapter sigmastudio).
|
* @pubstate Applied via IDsp::setStereoSpreadLevel/setBassBoostLevel, which
|
||||||
* No dedicated SigmaStudio blocks; see \c applyEnhancementsToEq.
|
* scale the SPhat1/Bass Boost1 SigmaStudio blocks toward their
|
||||||
|
* compiled response; does not touch EqProfile.
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @author Michele Bigi
|
||||||
* @date 2026-07-06
|
* @date 2026-07-06
|
||||||
*/
|
*/
|
||||||
struct AudioEnhancements {
|
struct AudioEnhancements {
|
||||||
EnhanceLevel stereo; ///< Stereo depth / presence (PEQ bands 3–5).
|
EnhanceLevel stereo; ///< Stereo spread (SPhat1 spatializer).
|
||||||
EnhanceLevel bass; ///< Bass emphasis (PEQ bands 1–2).
|
EnhanceLevel bass; ///< Bass boost intensity (Bass Boost1).
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief factoryDefault — both enhancements off.
|
* @brief factoryDefault — both enhancements off.
|
||||||
|
|||||||
@@ -12,10 +12,10 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/ActiveSource.hpp"
|
||||||
#include "core/AudioEnhancements.hpp"
|
#include "core/AudioEnhancements.hpp"
|
||||||
#include "core/EqProfile.hpp"
|
#include "core/EqProfile.hpp"
|
||||||
#include "core/GainDb.hpp"
|
#include "core/GainDb.hpp"
|
||||||
#include "core/MixerState.hpp"
|
|
||||||
|
|
||||||
namespace core {
|
namespace core {
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ namespace core {
|
|||||||
* @date 2026-07-06
|
* @date 2026-07-06
|
||||||
*/
|
*/
|
||||||
struct AudioProfile {
|
struct AudioProfile {
|
||||||
MixerState mixer; ///< Input and stereo-mixer gains.
|
ActiveSource activeSource; ///< Which MX1 pair reaches Param EQ1.
|
||||||
EqProfile eq; ///< Six-band parametric EQ.
|
EqProfile eq; ///< Six-band parametric EQ.
|
||||||
GainDb masterLeft; ///< Multiple 1 master volume, left.
|
GainDb masterLeft; ///< Multiple 1 master volume, left.
|
||||||
GainDb masterRight; ///< Multiple 1 master volume, right.
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/ActiveSource.hpp"
|
||||||
#include "core/AudioProfile.hpp"
|
#include "core/AudioProfile.hpp"
|
||||||
#include "core/DspError.hpp"
|
#include "core/DspError.hpp"
|
||||||
|
#include "core/EnhanceLevel.hpp"
|
||||||
#include "core/EqBandIndex.hpp"
|
#include "core/EqBandIndex.hpp"
|
||||||
#include "core/FrequencyHz.hpp"
|
#include "core/FrequencyHz.hpp"
|
||||||
#include "core/GainDb.hpp"
|
#include "core/GainDb.hpp"
|
||||||
#include "core/MixSource.hpp"
|
|
||||||
#include "core/MixerState.hpp"
|
|
||||||
#include "core/EqProfile.hpp"
|
#include "core/EqProfile.hpp"
|
||||||
|
|
||||||
#include <expected>
|
#include <expected>
|
||||||
@@ -56,18 +56,18 @@ public:
|
|||||||
const AudioProfile& profile) = 0;
|
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
|
* @dname selectSource
|
||||||
* @param mixer Per-source and St Mixer1 levels.
|
* @param source Which stereo pair MX1 passes through to Param EQ1.
|
||||||
* @return Ok on success, or DspError.
|
* @return Ok on success, or DspError.
|
||||||
* @pubstate writes ADAU1701 parameter RAM via safeload.
|
* @pubstate writes ADAU1701 parameter RAM via safeload.
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @author Michele Bigi
|
||||||
* @date 2026-07-06
|
* @date 2026-08-25
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] virtual std::expected<void, DspError> applyMixer(
|
[[nodiscard]] virtual std::expected<void, DspError> selectSource(
|
||||||
const MixerState& mixer) = 0;
|
ActiveSource source) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief applyEq — safeload all six PEQ bands.
|
* @brief applyEq — safeload all six PEQ bands.
|
||||||
@@ -83,22 +83,6 @@ public:
|
|||||||
[[nodiscard]] virtual std::expected<void, DspError> applyEq(
|
[[nodiscard]] virtual std::expected<void, DspError> applyEq(
|
||||||
const EqProfile& eq) = 0;
|
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.
|
* @brief setMasterVolume — safeload Multiple 1 master output gain.
|
||||||
*
|
*
|
||||||
@@ -146,6 +130,42 @@ public:
|
|||||||
[[nodiscard]] virtual std::expected<void, DspError> setBeepEnabled(
|
[[nodiscard]] virtual std::expected<void, DspError> setBeepEnabled(
|
||||||
bool enabled) = 0;
|
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.
|
* @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();
|
const GainDb unity = GainDb::zero();
|
||||||
return AudioProfile{
|
return AudioProfile{
|
||||||
.mixer = MixerState::factoryDefault(),
|
.activeSource = ActiveSource::Radio,
|
||||||
.eq = EqProfile::factoryDefault(),
|
.eq = EqProfile::factoryDefault(),
|
||||||
.masterLeft = unity,
|
.masterLeft = unity,
|
||||||
.masterRight = unity,
|
.masterRight = unity,
|
||||||
|
|||||||
@@ -92,35 +92,48 @@ namespace {
|
|||||||
return GainDb::tryFromDb(db);
|
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)
|
std::string_view json)
|
||||||
{
|
{
|
||||||
const std::size_t mixerStart = json.find("\"mixer\"");
|
constexpr std::string_view kKey = "\"active_source\"";
|
||||||
if (mixerStart == std::string_view::npos) {
|
const std::size_t needlePos = json.find(kKey);
|
||||||
|
if (needlePos == std::string_view::npos) {
|
||||||
return std::unexpected(ParseError::MissingField);
|
return std::unexpected(ParseError::MissingField);
|
||||||
}
|
}
|
||||||
const std::string_view mixer = json.substr(mixerStart);
|
const std::size_t quoteStart = json.find('"', needlePos + kKey.size());
|
||||||
|
if (quoteStart == std::string_view::npos) {
|
||||||
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) {
|
|
||||||
return std::unexpected(ParseError::MissingField);
|
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{
|
if (value == "radio") {
|
||||||
.si4684Left = *si4684Left,
|
return ActiveSource::Radio;
|
||||||
.si4684Right = *si4684Right,
|
}
|
||||||
.esp32Left = *esp32Left,
|
if (value == "bluetooth") {
|
||||||
.esp32Right = *esp32Right,
|
return ActiveSource::Bluetooth;
|
||||||
.mixLeft = *mixLeft,
|
}
|
||||||
.mixRight = *mixRight,
|
if (value == "beep") {
|
||||||
};
|
return ActiveSource::Beep;
|
||||||
|
}
|
||||||
|
return std::unexpected(ParseError::MissingField);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::expected<EqProfile, ParseError> parseEqJson(
|
[[nodiscard]] std::expected<EqProfile, ParseError> parseEqJson(
|
||||||
@@ -207,14 +220,8 @@ namespace {
|
|||||||
std::string serializeAudioProfileJson(const AudioProfile& profile)
|
std::string serializeAudioProfileJson(const AudioProfile& profile)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
const auto& m = profile.mixer;
|
out << "{\"active_source\":\"" << activeSourceName(profile.activeSource)
|
||||||
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() << "},"
|
|
||||||
<< "\"master\":{"
|
<< "\"master\":{"
|
||||||
<< "\"left_db\":" << profile.masterLeft.value() << ','
|
<< "\"left_db\":" << profile.masterLeft.value() << ','
|
||||||
<< "\"right_db\":" << profile.masterRight.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
|
// Per-band "locked" flag, added 2026-08-24: band 0 is a fixed high-pass
|
||||||
// Adau1701Driver::applyEq() never safeloads (SigmaStudio band 1, ST0 in
|
// Adau1701Driver::applyEq() never safeloads (SigmaStudio band 1, ST0 in
|
||||||
// the compiled program -- whatever gain_db/center_hz/q is stored/sent
|
// 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
|
// for it has zero audible effect, always). Since the 2026-08-25
|
||||||
// core::applyEnhancementsToEq() with formula-derived values whenever
|
// DigiRadioFinale revision, bass/stereo enhancement drive the dedicated
|
||||||
// bass_level > 0; bands 3-5 likewise whenever stereo_level > 0 -- a
|
// Bass Boost1/SPhat1 blocks directly instead of overwriting EQ bands,
|
||||||
// manual edit to those bands is silently inaudible while the
|
// so bands 1-5 are no longer locked by enhancement levels -- only
|
||||||
// corresponding enhancement is active. This was previously
|
// band 0 remains permanently inert.
|
||||||
// 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;
|
|
||||||
const bool locked[EqBandIndex::kBandCount] = {
|
const bool locked[EqBandIndex::kBandCount] = {
|
||||||
true, bassLocks, bassLocks, stereoLocks, stereoLocks, stereoLocks,
|
true, false, false, false, false, false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto& bands = profile.eq.bands();
|
const auto& bands = profile.eq.bands();
|
||||||
@@ -263,9 +264,9 @@ std::expected<AudioProfile, ParseError> parseAudioProfileJson(
|
|||||||
return std::unexpected(ParseError::InvalidJson);
|
return std::unexpected(ParseError::InvalidJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto mixer = parseMixerJson(json);
|
const auto activeSource = parseActiveSourceJson(json);
|
||||||
if (!mixer) {
|
if (!activeSource) {
|
||||||
return std::unexpected(mixer.error());
|
return std::unexpected(activeSource.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto eq = parseEqJson(json);
|
const auto eq = parseEqJson(json);
|
||||||
@@ -290,7 +291,7 @@ std::expected<AudioProfile, ParseError> parseAudioProfileJson(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return AudioProfile{
|
return AudioProfile{
|
||||||
.mixer = *mixer,
|
.activeSource = *activeSource,
|
||||||
.eq = *eq,
|
.eq = *eq,
|
||||||
.masterLeft = *masterLeft,
|
.masterLeft = *masterLeft,
|
||||||
.masterRight = *masterRight,
|
.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}/EqBandIndex.cpp"
|
||||||
"${CORE_SRC_DIR}/BiquadCoefficients.cpp"
|
"${CORE_SRC_DIR}/BiquadCoefficients.cpp"
|
||||||
"${CORE_SRC_DIR}/BiquadDesign.cpp"
|
"${CORE_SRC_DIR}/BiquadDesign.cpp"
|
||||||
"${CORE_SRC_DIR}/MixerState.cpp"
|
|
||||||
"${CORE_SRC_DIR}/EqProfile.cpp"
|
"${CORE_SRC_DIR}/EqProfile.cpp"
|
||||||
"${CORE_SRC_DIR}/EnhanceLevel.cpp"
|
"${CORE_SRC_DIR}/EnhanceLevel.cpp"
|
||||||
"${CORE_SRC_DIR}/AudioEnhancements.cpp"
|
"${CORE_SRC_DIR}/AudioEnhancements.cpp"
|
||||||
"${CORE_SRC_DIR}/EnhancementsDesign.cpp"
|
|
||||||
"${CORE_SRC_DIR}/AudioProfile.cpp"
|
"${CORE_SRC_DIR}/AudioProfile.cpp"
|
||||||
"${CORE_SRC_DIR}/AudioProfileJson.cpp"
|
"${CORE_SRC_DIR}/AudioProfileJson.cpp"
|
||||||
"${CORE_SRC_DIR}/Bt1035At.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)
|
target_link_libraries(audio_profile_json_test PRIVATE digiradio_core)
|
||||||
add_test(NAME audio_profile_json_test COMMAND audio_profile_json_test)
|
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)
|
add_executable(station_service_test station_service_test.cpp)
|
||||||
target_include_directories(station_service_test PRIVATE
|
target_include_directories(station_service_test PRIVATE
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/host_stubs"
|
"${CMAKE_CURRENT_SOURCE_DIR}/host_stubs"
|
||||||
|
|||||||
@@ -69,6 +69,23 @@ namespace {
|
|||||||
std::cerr << "enhancements round-trip mismatch\n";
|
std::cerr << "enhancements round-trip mismatch\n";
|
||||||
return EXIT_FAILURE;
|
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;
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::expected<void, core::DspError> applyMixer(
|
[[nodiscard]] std::expected<void, core::DspError> selectSource(
|
||||||
const core::MixerState&) override
|
core::ActiveSource) override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -52,12 +52,6 @@ public:
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::expected<void, core::DspError> setInputVolume(
|
|
||||||
core::MixSource, core::GainDb, core::GainDb) override
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::expected<void, core::DspError> setMasterVolume(
|
[[nodiscard]] std::expected<void, core::DspError> setMasterVolume(
|
||||||
core::GainDb, core::GainDb) override
|
core::GainDb, core::GainDb) override
|
||||||
{
|
{
|
||||||
@@ -76,6 +70,18 @@ public:
|
|||||||
return {};
|
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(
|
[[nodiscard]] std::expected<void, core::DspError> writeRawParam(
|
||||||
unsigned, float) override
|
unsigned, float) override
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
#include "adau1701/Adau1701Error.hpp"
|
#include "adau1701/Adau1701Error.hpp"
|
||||||
|
|
||||||
#include "core/AudioProfile.hpp"
|
#include "core/AudioProfile.hpp"
|
||||||
|
#include "core/EnhanceLevel.hpp"
|
||||||
#include "core/EqBandIndex.hpp"
|
#include "core/EqBandIndex.hpp"
|
||||||
#include "core/EqProfile.hpp"
|
#include "core/EqProfile.hpp"
|
||||||
#include "core/FrequencyHz.hpp"
|
#include "core/FrequencyHz.hpp"
|
||||||
#include "core/GainDb.hpp"
|
#include "core/GainDb.hpp"
|
||||||
#include "core/IDspProgramSource.hpp"
|
#include "core/IDspProgramSource.hpp"
|
||||||
#include "core/MixSource.hpp"
|
#include "core/ActiveSource.hpp"
|
||||||
#include "core/MixerState.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <expected>
|
#include <expected>
|
||||||
@@ -144,18 +144,18 @@ public:
|
|||||||
const core::AudioProfile& profile);
|
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
|
* @dname selectSource
|
||||||
* @param mixer Per-source and St Mixer1 levels.
|
* @param source Which stereo pair MX1 passes through.
|
||||||
* @return Ok on success, or Adau1701Error.
|
* @return Ok on success, or Adau1701Error.
|
||||||
* @pubstate writes parameter RAM via safeload.
|
* @pubstate writes parameter RAM via safeload.
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @author Michele Bigi
|
||||||
* @date 2026-07-06
|
* @date 2026-08-25
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::expected<void, Adau1701Error> applyMixer(
|
[[nodiscard]] std::expected<void, Adau1701Error> selectSource(
|
||||||
const core::MixerState& mixer);
|
core::ActiveSource source);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief applyEq — safeload all six PEQ bands.
|
* @brief applyEq — safeload all six PEQ bands.
|
||||||
@@ -171,22 +171,6 @@ public:
|
|||||||
[[nodiscard]] std::expected<void, Adau1701Error> applyEq(
|
[[nodiscard]] std::expected<void, Adau1701Error> applyEq(
|
||||||
const core::EqProfile& eq);
|
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.
|
* @brief setMasterVolume — safeload Multiple 1 master output gain.
|
||||||
*
|
*
|
||||||
@@ -234,6 +218,35 @@ public:
|
|||||||
[[nodiscard]] std::expected<void, Adau1701Error> setBeepEnabled(
|
[[nodiscard]] std::expected<void, Adau1701Error> setBeepEnabled(
|
||||||
bool enabled);
|
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.
|
* @brief writeRawParam — safeload any named Parameter RAM cell.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -45,15 +45,12 @@ public:
|
|||||||
[[nodiscard]] std::expected<void, core::DspError> applyProfile(
|
[[nodiscard]] std::expected<void, core::DspError> applyProfile(
|
||||||
const core::AudioProfile& profile) override;
|
const core::AudioProfile& profile) override;
|
||||||
|
|
||||||
[[nodiscard]] std::expected<void, core::DspError> applyMixer(
|
[[nodiscard]] std::expected<void, core::DspError> selectSource(
|
||||||
const core::MixerState& mixer) override;
|
core::ActiveSource source) override;
|
||||||
|
|
||||||
[[nodiscard]] std::expected<void, core::DspError> applyEq(
|
[[nodiscard]] std::expected<void, core::DspError> applyEq(
|
||||||
const core::EqProfile& eq) override;
|
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(
|
[[nodiscard]] std::expected<void, core::DspError> setMasterVolume(
|
||||||
core::GainDb left, core::GainDb right) override;
|
core::GainDb left, core::GainDb right) override;
|
||||||
|
|
||||||
@@ -64,6 +61,12 @@ public:
|
|||||||
[[nodiscard]] std::expected<void, core::DspError> setBeepEnabled(
|
[[nodiscard]] std::expected<void, core::DspError> setBeepEnabled(
|
||||||
bool enabled) override;
|
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(
|
[[nodiscard]] std::expected<void, core::DspError> writeRawParam(
|
||||||
unsigned address, float value) override;
|
unsigned address, float value) override;
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
#include "DigiRadio_IC_1_PARAM.h"
|
#include "DigiRadio_IC_1_PARAM.h"
|
||||||
|
|
||||||
|
#include "core/ActiveSource.hpp"
|
||||||
#include "core/EqBandIndex.hpp"
|
#include "core/EqBandIndex.hpp"
|
||||||
#include "core/MixSource.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
#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
|
* @dname paramSourceIndex
|
||||||
* @param source Si4684 or ESP32 path.
|
* @param source Which stereo pair MX1 should pass through.
|
||||||
* @return Parameter RAM address for the left channel gain cell.
|
* @return 0 (Radio), 1 (Bluetooth), or 2 (Beep) -- confirmed live
|
||||||
|
* 2026-08-25 against real hardware (see
|
||||||
|
* docs/adau1701-sigmastudio-analysis.md).
|
||||||
* @pubstate none
|
* @pubstate none
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @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
|
switch (source) {
|
||||||
? static_cast<unsigned>(ADDR_SI4674)
|
case core::ActiveSource::Radio:
|
||||||
: static_cast<unsigned>(ADDR_ESP32);
|
return 0U;
|
||||||
}
|
case core::ActiveSource::Bluetooth:
|
||||||
|
return 1U;
|
||||||
/**
|
case core::ActiveSource::Beep:
|
||||||
* @brief paramAddrInputRight — right volume address for an input source.
|
return 2U;
|
||||||
*
|
}
|
||||||
* @dname paramAddrInputRight
|
return 0U;
|
||||||
* @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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace adau1701
|
} // namespace adau1701
|
||||||
|
|||||||
@@ -8,13 +8,14 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Generated from Firmware/ADAU1701-Firmware/DigiRadio_IC_1_PARAM.h (the
|
* Generated from Firmware/ADAU1701-Firmware/DigiRadio_IC_1_PARAM.h (the
|
||||||
* SigmaStudio export). Regenerate by re-running the extraction over that
|
* SigmaStudio export, "DigiRadioFinale" revision, captured 2026-08-25).
|
||||||
* file if the SigmaStudio project's cell list changes; entries here must
|
* Regenerate by re-running the extraction over that file if the SigmaStudio
|
||||||
* stay in sync with the ADDR_* constants used by
|
* 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().
|
* components/drivers/adau1701/src/Adau1701Driver.cpp's replayProgram().
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @author Michele Bigi
|
||||||
* @date 2026-08-18
|
* @date 2026-08-25
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@@ -39,83 +40,239 @@ struct Adau1701ParamEntry {
|
|||||||
* @pubstate Read-only; see file header for regeneration instructions.
|
* @pubstate Read-only; see file header for regeneration instructions.
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @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_ENABLE", 0},
|
||||||
{"BEEP1_KICK", 1},
|
{"BEEP1_KICK", 1},
|
||||||
{"BEEP1_BEEP_FREQ", 2},
|
{"BEEP1_BEEP_FREQ", 2},
|
||||||
{"SI4674", 3},
|
{"DC1", 3},
|
||||||
{"SI4674_1", 4},
|
{"DCB1_POLE", 4},
|
||||||
{"ESP32", 5},
|
{"DCB2_POLE", 5},
|
||||||
{"ESP32_1", 6},
|
{"DCB4_POLE", 6},
|
||||||
{"SINGLE1", 7},
|
{"DCB3_POLE", 7},
|
||||||
{"SSPLITTER1", 8},
|
{"SSPLITTER1", 8},
|
||||||
{"STMIXER1_ST0_VOLUME", 9},
|
{"COMPRESSOR1_0", 9},
|
||||||
{"STMIXER1_ST1_VOLUME", 10},
|
{"COMPRESSOR1_1", 10},
|
||||||
{"STMIXER1_ST2_VOLUME", 11},
|
{"COMPRESSOR1_2", 11},
|
||||||
{"PARAMEQ1_ST0_B0", 12},
|
{"COMPRESSOR1_3", 12},
|
||||||
{"PARAMEQ1_ST0_B1", 13},
|
{"COMPRESSOR1_4", 13},
|
||||||
{"PARAMEQ1_ST0_B2", 14},
|
{"COMPRESSOR1_5", 14},
|
||||||
{"PARAMEQ1_ST0_A0", 15},
|
{"COMPRESSOR1_6", 15},
|
||||||
{"PARAMEQ1_ST0_A1", 16},
|
{"COMPRESSOR1_7", 16},
|
||||||
{"PARAMEQ1_ST1_B0", 17},
|
{"COMPRESSOR1_8", 17},
|
||||||
{"PARAMEQ1_ST1_B1", 18},
|
{"COMPRESSOR1_9", 18},
|
||||||
{"PARAMEQ1_ST1_B2", 19},
|
{"COMPRESSOR1_10", 19},
|
||||||
{"PARAMEQ1_ST1_A0", 20},
|
{"COMPRESSOR1_11", 20},
|
||||||
{"PARAMEQ1_ST1_A1", 21},
|
{"COMPRESSOR1_12", 21},
|
||||||
{"PARAMEQ1_ST2_B0", 22},
|
{"COMPRESSOR1_13", 22},
|
||||||
{"PARAMEQ1_ST2_B1", 23},
|
{"COMPRESSOR1_14", 23},
|
||||||
{"PARAMEQ1_ST2_B2", 24},
|
{"COMPRESSOR1_15", 24},
|
||||||
{"PARAMEQ1_ST2_A0", 25},
|
{"COMPRESSOR1_16", 25},
|
||||||
{"PARAMEQ1_ST2_A1", 26},
|
{"COMPRESSOR1_17", 26},
|
||||||
{"PARAMEQ1_ST3_B0", 27},
|
{"COMPRESSOR1_18", 27},
|
||||||
{"PARAMEQ1_ST3_B1", 28},
|
{"COMPRESSOR1_19", 28},
|
||||||
{"PARAMEQ1_ST3_B2", 29},
|
{"COMPRESSOR1_20", 29},
|
||||||
{"PARAMEQ1_ST3_A0", 30},
|
{"COMPRESSOR1_21", 30},
|
||||||
{"PARAMEQ1_ST3_A1", 31},
|
{"COMPRESSOR1_22", 31},
|
||||||
{"PARAMEQ1_ST4_B0", 32},
|
{"COMPRESSOR1_23", 32},
|
||||||
{"PARAMEQ1_ST4_B1", 33},
|
{"COMPRESSOR1_24", 33},
|
||||||
{"PARAMEQ1_ST4_B2", 34},
|
{"COMPRESSOR1_25", 34},
|
||||||
{"PARAMEQ1_ST4_A0", 35},
|
{"COMPRESSOR1_26", 35},
|
||||||
{"PARAMEQ1_ST4_A1", 36},
|
{"COMPRESSOR1_27", 36},
|
||||||
{"PARAMEQ1_ST5_B0", 37},
|
{"COMPRESSOR1_28", 37},
|
||||||
{"PARAMEQ1_ST5_B1", 38},
|
{"COMPRESSOR1_29", 38},
|
||||||
{"PARAMEQ1_ST5_B2", 39},
|
{"COMPRESSOR1_30", 39},
|
||||||
{"PARAMEQ1_ST5_A0", 40},
|
{"COMPRESSOR1_31", 40},
|
||||||
{"PARAMEQ1_ST5_A1", 41},
|
{"COMPRESSOR1_32", 41},
|
||||||
{"MULTIPLE1", 42},
|
{"COMPRESSOR1_33", 42},
|
||||||
{"MULTIPLE1_1", 43},
|
{"COMPRESSOR1_RMS", 43},
|
||||||
{"LIMITER1_S1", 44},
|
{"COMPRESSOR1_POST_GAIN", 44},
|
||||||
{"LIMITER1_INT1", 45},
|
{"COMPRESSOR1_HOLD", 45},
|
||||||
{"LIMITER1_S2", 46},
|
{"COMPRESSOR1_DECAY", 46},
|
||||||
{"LIMITER1_INT2", 47},
|
{"1XRTA3_TCONST", 47},
|
||||||
{"LIMITER1_S3", 48},
|
{"1XRTA3_HOLD", 48},
|
||||||
{"LIMITER1_INT3", 49},
|
{"1XRTA3_DECAY", 49},
|
||||||
{"LIMITER1_S4", 50},
|
{"1XRTA3", 2074},
|
||||||
{"LIMITER1_INT4", 51},
|
{"1XRTA4_TCONST", 50},
|
||||||
{"LIMITER1_C1", 52},
|
{"1XRTA4_HOLD", 51},
|
||||||
{"LIMITER1_C2", 53},
|
{"1XRTA4_DECAY", 52},
|
||||||
{"LIMITER1_C3", 54},
|
{"1XRTA4", 2074},
|
||||||
{"LIMITER1_THRESHOLD", 55},
|
{"1XRTA1_TCONST", 53},
|
||||||
{"LIMITER1_RMS", 56},
|
{"1XRTA1_HOLD", 54},
|
||||||
{"LIMITER1_DECAY", 57},
|
{"1XRTA1_DECAY", 55},
|
||||||
{"LIMITER1_DECAYCOMPLEMENT", 58},
|
{"1XRTA1", 2074},
|
||||||
{"LIMITER2_S1", 59},
|
{"1XRTA2_TCONST", 56},
|
||||||
{"LIMITER2_INT1", 60},
|
{"1XRTA2_HOLD", 57},
|
||||||
{"LIMITER2_S2", 61},
|
{"1XRTA2_DECAY", 58},
|
||||||
{"LIMITER2_INT2", 62},
|
{"1XRTA2", 2074},
|
||||||
{"LIMITER2_S3", 63},
|
{"PARAMEQ1_ST0_B0", 59},
|
||||||
{"LIMITER2_INT3", 64},
|
{"PARAMEQ1_ST0_B1", 60},
|
||||||
{"LIMITER2_S4", 65},
|
{"PARAMEQ1_ST0_B2", 61},
|
||||||
{"LIMITER2_INT4", 66},
|
{"PARAMEQ1_ST0_A0", 62},
|
||||||
{"LIMITER2_C1", 67},
|
{"PARAMEQ1_ST0_A1", 63},
|
||||||
{"LIMITER2_C2", 68},
|
{"PARAMEQ1_ST1_B0", 64},
|
||||||
{"LIMITER2_C3", 69},
|
{"PARAMEQ1_ST1_B1", 65},
|
||||||
{"LIMITER2_THRESHOLD", 70},
|
{"PARAMEQ1_ST1_B2", 66},
|
||||||
{"LIMITER2_RMS", 71},
|
{"PARAMEQ1_ST1_A0", 67},
|
||||||
{"LIMITER2_DECAY", 72},
|
{"PARAMEQ1_ST1_A1", 68},
|
||||||
{"LIMITER2_DECAYCOMPLEMENT", 73},
|
{"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
|
* @pubstate none
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @author Michele Bigi
|
||||||
* @date 2026-08-18
|
* @date 2026-08-25
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline std::optional<unsigned> findAdau1701ParamAddress(
|
[[nodiscard]] inline std::optional<unsigned> findAdau1701ParamAddress(
|
||||||
std::string_view name) noexcept
|
std::string_view name) noexcept
|
||||||
|
|||||||
@@ -358,18 +358,22 @@ namespace adau1701
|
|||||||
return safeloadFixpoint(paramAddr, core::gainDbToLinearFixpoint(gain));
|
return safeloadFixpoint(paramAddr, core::gainDbToLinearFixpoint(gain));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::expected<void, Adau1701Error> Adau1701Driver::setInputVolume(
|
std::expected<void, Adau1701Error> Adau1701Driver::selectSource(
|
||||||
core::MixSource source, core::GainDb left, core::GainDb right)
|
core::ActiveSource source)
|
||||||
{
|
{
|
||||||
if (auto ready = ensureBooted(); !ready)
|
if (auto ready = ensureBooted(); !ready)
|
||||||
{
|
{
|
||||||
return ready;
|
return ready;
|
||||||
}
|
}
|
||||||
if (auto result = safeloadGain(paramAddrInputLeft(source), left); !result)
|
// MX1 (DCinputmux_stereo) reads DC1 as a raw 32-bit integer pair
|
||||||
{
|
// index (0/1/2), NOT the 5.23 fixpoint conversion its compiled
|
||||||
return result;
|
// TYPE_DC1/VALUE_DC1 macros would suggest -- confirmed live
|
||||||
}
|
// 2026-08-25 (a 5.23-encoded write left the source unchanged; the
|
||||||
return safeloadGain(paramAddrInputRight(source), right);
|
// 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(
|
std::expected<void, Adau1701Error> Adau1701Driver::setMasterVolume(
|
||||||
@@ -387,45 +391,6 @@ namespace adau1701
|
|||||||
return safeloadGain(static_cast<unsigned>(ADDR_MULTIPLE1_1), right);
|
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(
|
std::expected<void, Adau1701Error> Adau1701Driver::setEqBand(
|
||||||
core::EqBandIndex band, core::GainDb gain, core::FrequencyHz center, float q)
|
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);
|
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(
|
std::expected<void, Adau1701Error> Adau1701Driver::writeRawParam(
|
||||||
unsigned address, float value)
|
unsigned address, float value)
|
||||||
{
|
{
|
||||||
@@ -535,7 +597,7 @@ namespace adau1701
|
|||||||
{
|
{
|
||||||
return ready;
|
return ready;
|
||||||
}
|
}
|
||||||
if (auto result = applyMixer(profile.mixer); !result)
|
if (auto result = selectSource(profile.activeSource); !result)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -543,7 +605,17 @@ namespace adau1701
|
|||||||
{
|
{
|
||||||
return result;
|
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
|
} // namespace adau1701
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ std::expected<void, core::DspError> Adau1701Dsp::applyProfile(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::expected<void, core::DspError> Adau1701Dsp::applyMixer(
|
std::expected<void, core::DspError> Adau1701Dsp::selectSource(
|
||||||
const core::MixerState& mixer)
|
core::ActiveSource source)
|
||||||
{
|
{
|
||||||
if (auto result = driver_.applyMixer(mixer); !result) {
|
if (auto result = driver_.selectSource(source); !result) {
|
||||||
return std::unexpected(mapError(result.error()));
|
return std::unexpected(mapError(result.error()));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@@ -61,15 +61,6 @@ std::expected<void, core::DspError> Adau1701Dsp::applyEq(
|
|||||||
return {};
|
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(
|
std::expected<void, core::DspError> Adau1701Dsp::setMasterVolume(
|
||||||
core::GainDb left, core::GainDb right)
|
core::GainDb left, core::GainDb right)
|
||||||
{
|
{
|
||||||
@@ -97,6 +88,24 @@ std::expected<void, core::DspError> Adau1701Dsp::setBeepEnabled(bool enabled)
|
|||||||
return {};
|
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(
|
std::expected<void, core::DspError> Adau1701Dsp::writeRawParam(
|
||||||
unsigned address, float value)
|
unsigned address, float value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,16 +12,15 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/ActiveSource.hpp"
|
||||||
#include "core/AudioProfile.hpp"
|
#include "core/AudioProfile.hpp"
|
||||||
#include "core/DspError.hpp"
|
#include "core/DspError.hpp"
|
||||||
#include "core/EnhanceLevel.hpp"
|
#include "core/EnhanceLevel.hpp"
|
||||||
#include "core/EnhancementsDesign.hpp"
|
|
||||||
#include "core/EqBandIndex.hpp"
|
#include "core/EqBandIndex.hpp"
|
||||||
#include "core/FrequencyHz.hpp"
|
#include "core/FrequencyHz.hpp"
|
||||||
#include "core/GainDb.hpp"
|
#include "core/GainDb.hpp"
|
||||||
#include "core/IAudioProfileStore.hpp"
|
#include "core/IAudioProfileStore.hpp"
|
||||||
#include "core/IDsp.hpp"
|
#include "core/IDsp.hpp"
|
||||||
#include "core/MixSource.hpp"
|
|
||||||
#include "core/StoreError.hpp"
|
#include "core/StoreError.hpp"
|
||||||
|
|
||||||
#include <expected>
|
#include <expected>
|
||||||
@@ -106,22 +105,19 @@ public:
|
|||||||
const core::AudioProfile& profile, bool persist);
|
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
|
* @dname selectSource
|
||||||
* @param source Si4684 or ESP32 path.
|
* @param source Which stereo pair MX1 should pass through.
|
||||||
* @param left Left gain.
|
|
||||||
* @param right Right gain.
|
|
||||||
* @param persist When true and store is set, write NVS.
|
* @param persist When true and store is set, write NVS.
|
||||||
* @return Ok on success, or StoreError wrapping DspError/IoFailed.
|
* @return Ok on success, or StoreError wrapping DspError/IoFailed.
|
||||||
* @pubstate updates profile_.mixer and safeloads.
|
* @pubstate updates profile_.activeSource and safeloads.
|
||||||
*
|
*
|
||||||
* @author Michele Bigi
|
* @author Michele Bigi
|
||||||
* @date 2026-07-06
|
* @date 2026-08-25
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::expected<void, core::StoreError> setInputVolume(
|
[[nodiscard]] std::expected<void, core::StoreError> selectSource(
|
||||||
core::MixSource source, core::GainDb left, core::GainDb right,
|
core::ActiveSource source, bool persist);
|
||||||
bool persist);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief setMasterVolume — update master output and apply live.
|
* @brief setMasterVolume — update master output and apply live.
|
||||||
@@ -239,9 +235,6 @@ private:
|
|||||||
[[nodiscard]] std::expected<void, core::StoreError> applyProfileToDsp(
|
[[nodiscard]] std::expected<void, core::StoreError> applyProfileToDsp(
|
||||||
const core::AudioProfile& profile);
|
const core::AudioProfile& profile);
|
||||||
|
|
||||||
[[nodiscard]] std::expected<void, core::StoreError> applyEffectiveEq(
|
|
||||||
bool persist);
|
|
||||||
|
|
||||||
core::IDsp& dsp_;
|
core::IDsp& dsp_;
|
||||||
core::IAudioProfileStore* store_;
|
core::IAudioProfileStore* store_;
|
||||||
core::AudioProfile profile_;
|
core::AudioProfile profile_;
|
||||||
|
|||||||
@@ -21,15 +21,6 @@ namespace {
|
|||||||
|
|
||||||
constexpr char kTag[] = "AudioService";
|
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
|
} // namespace
|
||||||
|
|
||||||
AudioService::AudioService(core::IDsp& dsp, core::IAudioProfileStore* store)
|
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(
|
std::expected<void, core::StoreError> AudioService::applyProfileToDsp(
|
||||||
const core::AudioProfile& profile)
|
const core::AudioProfile& profile)
|
||||||
{
|
{
|
||||||
const core::AudioProfile hardware = profileForHardware(profile);
|
if (auto applied = dsp_.applyProfile(profile); !applied) {
|
||||||
if (auto applied = dsp_.applyProfile(hardware); !applied) {
|
|
||||||
ESP_LOGW(kTag, "applyProfileToDsp: DSP safeload failed");
|
ESP_LOGW(kTag, "applyProfileToDsp: DSP safeload failed");
|
||||||
return std::unexpected(core::StoreError::IoFailed);
|
return std::unexpected(core::StoreError::IoFailed);
|
||||||
}
|
}
|
||||||
return {};
|
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(
|
std::expected<void, core::StoreError> AudioService::applyProfile(
|
||||||
const core::AudioProfile& profile, bool persist)
|
const core::AudioProfile& profile, bool persist)
|
||||||
{
|
{
|
||||||
@@ -116,21 +92,13 @@ std::expected<void, core::StoreError> AudioService::applyProfile(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::expected<void, core::StoreError> AudioService::setInputVolume(
|
std::expected<void, core::StoreError> AudioService::selectSource(
|
||||||
core::MixSource source, core::GainDb left, core::GainDb right, bool persist)
|
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);
|
return std::unexpected(core::StoreError::IoFailed);
|
||||||
}
|
}
|
||||||
|
profile_.activeSource = source;
|
||||||
if (source == core::MixSource::Si4684) {
|
|
||||||
profile_.mixer.si4684Left = left;
|
|
||||||
profile_.mixer.si4684Right = right;
|
|
||||||
} else {
|
|
||||||
profile_.mixer.esp32Left = left;
|
|
||||||
profile_.mixer.esp32Right = right;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (persist) {
|
if (persist) {
|
||||||
return persistProfile();
|
return persistProfile();
|
||||||
}
|
}
|
||||||
@@ -155,10 +123,10 @@ std::expected<void, core::StoreError> AudioService::applyRadioFirstMix(
|
|||||||
bool persist)
|
bool persist)
|
||||||
{
|
{
|
||||||
const core::GainDb unity = core::GainDb::zero();
|
const core::GainDb unity = core::GainDb::zero();
|
||||||
profile_.mixer = core::MixerState::radioFirst();
|
profile_.activeSource = core::ActiveSource::Radio;
|
||||||
profile_.masterLeft = unity;
|
profile_.masterLeft = unity;
|
||||||
profile_.masterRight = 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);
|
return std::unexpected(core::StoreError::IoFailed);
|
||||||
}
|
}
|
||||||
if (auto master = dsp_.setMasterVolume(unity, unity); !master) {
|
if (auto master = dsp_.setMasterVolume(unity, unity); !master) {
|
||||||
@@ -179,21 +147,39 @@ std::expected<void, core::StoreError> AudioService::setEqBand(
|
|||||||
.center = center,
|
.center = center,
|
||||||
.q = q,
|
.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(
|
std::expected<void, core::StoreError> AudioService::setStereoEnhance(
|
||||||
core::EnhanceLevel level, bool persist)
|
core::EnhanceLevel level, bool persist)
|
||||||
{
|
{
|
||||||
|
if (auto applied = dsp_.setStereoSpreadLevel(level); !applied) {
|
||||||
|
return std::unexpected(core::StoreError::IoFailed);
|
||||||
|
}
|
||||||
profile_.enhancements.stereo = level;
|
profile_.enhancements.stereo = level;
|
||||||
return applyEffectiveEq(persist);
|
if (persist) {
|
||||||
|
return persistProfile();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::expected<void, core::StoreError> AudioService::setBassEnhance(
|
std::expected<void, core::StoreError> AudioService::setBassEnhance(
|
||||||
core::EnhanceLevel level, bool persist)
|
core::EnhanceLevel level, bool persist)
|
||||||
{
|
{
|
||||||
|
if (auto applied = dsp_.setBassBoostLevel(level); !applied) {
|
||||||
|
return std::unexpected(core::StoreError::IoFailed);
|
||||||
|
}
|
||||||
profile_.enhancements.bass = level;
|
profile_.enhancements.bass = level;
|
||||||
return applyEffectiveEq(persist);
|
if (persist) {
|
||||||
|
return persistProfile();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::expected<void, core::DspError> AudioService::setBeepEnabled(bool enabled)
|
std::expected<void, core::DspError> AudioService::setBeepEnabled(bool enabled)
|
||||||
|
|||||||
Reference in New Issue
Block a user