-
-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WiP -Audio fastpath #40
Changes from all commits
fb03a37
40c96c1
f69142d
ac5aed8
0c58c12
e1cadbc
56b6290
91d36fa
7d0e627
4341d36
ca5a54b
f57c39c
63ffc6e
d4fb542
9a4c020
50b3c9d
04b55a5
d8bd451
237286f
4810a85
f050e60
c4664e5
f147d79
d5c33df
6317dcb
9f6278a
6d23eb6
2e6d58f
72f7f9c
175375e
40d1201
ef12aaa
894fdce
fc19340
63e63ad
d872629
e6fb6c4
4197f98
5edd5e6
71153ee
df26430
e2eb3e8
9cb6189
6d78e46
49f2e26
5081cfb
859adb3
d8bc5e2
1daeecc
c13a5d7
36c34b5
52fe8e2
1b8ebfd
63b03a4
c052da9
f877837
dc77c17
0f45b4f
55b0463
53c8f9f
be2da7b
62990cd
cfc1116
35f3f28
4d64efa
aded74d
143f842
b6f1a59
e6334d8
f0dd66e
4dc6a38
06344ae
7e1d15c
309e66b
af6091b
d8a6889
7465be7
82f9be5
337b117
5c79375
b473a40
d1b2759
7dcc8f1
d4a37ec
a9cdd21
6883996
47de28e
2410c22
3127c60
d51a41f
a7d627b
553f234
8aef434
708cd8e
310daa6
582b96f
1c53f14
3cc1d30
a84c361
ecf3317
29644cc
601499b
5fe12ee
a2e2ead
a45306b
c64f74a
9a832ed
9ed5dc7
c22c92e
0fb5edc
3295579
9a3a97e
99def64
9243b90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -254,7 +254,11 @@ constexpr SRate_t SAMPLE_RATE = 22050; // Base sample rate in Hz - 22Khz | |
//constexpr SRate_t SAMPLE_RATE = 16000; // 16kHz - use if FFTtask takes more than 20ms. Physical sample time -> 32ms | ||
//constexpr SRate_t SAMPLE_RATE = 20480; // Base sample rate in Hz - 20Khz is experimental. Physical sample time -> 25ms | ||
//constexpr SRate_t SAMPLE_RATE = 10240; // Base sample rate in Hz - previous default. Physical sample time -> 50ms | ||
#ifndef WLEDMM_FASTPATH | ||
#define FFT_MIN_CYCLE 21 // minimum time before FFT task is repeated. Use with 22Khz sampling | ||
#else | ||
#define FFT_MIN_CYCLE 15 // reduce min time, to allow faster catch-up when I2S is lagging | ||
#endif | ||
//#define FFT_MIN_CYCLE 30 // Use with 16Khz sampling | ||
//#define FFT_MIN_CYCLE 23 // minimum time before FFT task is repeated. Use with 20Khz sampling | ||
//#define FFT_MIN_CYCLE 46 // minimum time before FFT task is repeated. Use with 10Khz sampling | ||
|
@@ -794,7 +798,7 @@ static void detectSamplePeak(void) { | |
|
||
#if 0 | ||
// alternate detection, based on FFT_MajorPeak and FFT_Magnitude. Not much better... | ||
if ((binNum > 0) && (maxVol > 8) && (binNum < 10) && (sampleAgc > 127) && | ||
if ((binNum > 1) && (maxVol > 8) && (binNum < 10) && (sampleAgc > 127) && | ||
(FFT_MajorPeak > 50) && (FFT_MajorPeak < 250) && (FFT_Magnitude > (16.0f * (maxVol+42.0)) /*my_magnitude > 136.0f*16.0f*/) && | ||
(millis() - timeOfPeak > 80)) { | ||
havePeak = true; | ||
|
@@ -904,7 +908,6 @@ class AudioReactive : public Usermod { | |
|
||
// variables for UDP sound sync | ||
WiFiUDP fftUdp; // UDP object for sound sync (from WiFi UDP, not Async UDP!) | ||
uint8_t fftUdpBuffer[UDPSOUND_MAX_PACKET+1] = { 0 }; // static buffer for receiving | ||
unsigned long lastTime = 0; // last time of running UDP Microphone Sync | ||
const uint16_t delayMs = 10; // I don't want to sample too often and overload WLED | ||
uint16_t audioSyncPort= 11988;// default port for UDP sound sync | ||
|
@@ -1134,8 +1137,13 @@ class AudioReactive : public Usermod { | |
{ | ||
float sampleAdj; // Gain adjusted sample value | ||
float tmpSample; // An interim sample variable used for calculatioins. | ||
#ifdef WLEDMM_FASTPATH | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any downside to this change? "Compromise" for speed or just masking changes behind flag until we have done enough testing to know if this should just be right value for all uses? |
||
constexpr float weighting = 0.35f; // slightly reduced filter strength, to reduce audio latency | ||
constexpr float weighting2 = 0.25f; | ||
#else | ||
const float weighting = 0.2f; // Exponential filter weighting. Will be adjustable in a future release. | ||
const float weighting2 = 0.073f; // Exponential filter weighting, for rising signal (a bit more robust against spikes) | ||
#endif | ||
const int AGC_preset = (soundAgc > 0)? (soundAgc-1): 0; // make sure the _compiler_ knows this value will not change while we are inside the function | ||
static bool isFrozen = false; | ||
static bool haveSilence = true; | ||
|
@@ -1218,7 +1226,7 @@ class AudioReactive : public Usermod { | |
sampleMax = sampleMax + 0.5f * (sampleReal - sampleMax); // new peak - with some filtering | ||
#if 1 | ||
// another simple way to detect samplePeak - cannot detect beats, but reacts on peak volume | ||
if (((binNum < 11) || (maxVol < 1)) && (millis() - timeOfPeak > 80) && (sampleAvg > 1)) { | ||
if (((binNum < 12) || ((maxVol < 1))) && (millis() - timeOfPeak > 80) && (sampleAvg > 1)) { | ||
samplePeak = true; | ||
timeOfPeak = millis(); | ||
udpSamplePeak = true; | ||
|
@@ -1371,9 +1379,10 @@ class AudioReactive : public Usermod { | |
transmitData.FFT_Magnitude = my_magnitude; | ||
transmitData.FFT_MajorPeak = FFT_MajorPeak; | ||
|
||
fftUdp.beginMulticastPacket(); | ||
fftUdp.write(reinterpret_cast<uint8_t *>(&transmitData), sizeof(transmitData)); | ||
fftUdp.endPacket(); | ||
if (fftUdp.beginMulticastPacket() != 0) { // beginMulticastPacket returns 0 in case of error | ||
fftUdp.write(reinterpret_cast<uint8_t *>(&transmitData), sizeof(transmitData)); | ||
fftUdp.endPacket(); | ||
} | ||
return; | ||
} // transmitAudioData() | ||
|
||
|
@@ -1441,9 +1450,24 @@ class AudioReactive : public Usermod { | |
if (!udpSyncConnected) return false; | ||
bool haveFreshData = false; | ||
|
||
size_t packetSize = fftUdp.parsePacket(); | ||
size_t packetSize = 0; | ||
// WLEDMM use exception handler to catch out-of-memory errors | ||
#if __cpp_exceptions | ||
try{ | ||
packetSize = fftUdp.parsePacket(); | ||
} catch(...) { | ||
packetSize = 0; // low heap memory -> discard packet. | ||
fftUdp.flush(); | ||
DEBUG_PRINTLN(F("receiveAudioData: parsePacket out of memory exception caught!")); | ||
USER_FLUSH(); | ||
} | ||
#else | ||
packetSize = fftUdp.parsePacket(); | ||
#endif | ||
|
||
if ((packetSize > 0) && ((packetSize < 5) || (packetSize > UDPSOUND_MAX_PACKET))) fftUdp.flush(); // discard invalid packets (too small or too big) | ||
if ((packetSize > 5) && (packetSize <= UDPSOUND_MAX_PACKET)) { | ||
static uint8_t fftUdpBuffer[UDPSOUND_MAX_PACKET+1] = { 0 }; // static buffer for receiving, to reuse the same memory and avoid heap fragmentation | ||
//DEBUGSR_PRINTLN("Received UDP Sync Packet"); | ||
fftUdp.read(fftUdpBuffer, packetSize); | ||
|
||
|
@@ -1738,7 +1762,11 @@ class AudioReactive : public Usermod { | |
|
||
// get AGC sensitivity and sound pressure | ||
static unsigned long lastEstimate = 0; | ||
#ifdef WLEDMM_FASTPATH | ||
if (millis() - lastEstimate > 7) { | ||
#else | ||
if (millis() - lastEstimate > 12) { | ||
#endif | ||
lastEstimate = millis(); | ||
agcSensitivity = getSensitivity(); | ||
if (limiterOn) | ||
|
@@ -1763,6 +1791,8 @@ class AudioReactive : public Usermod { | |
have_new_sample = receiveAudioData(); | ||
if (have_new_sample) last_UDPTime = millis(); | ||
lastTime = millis(); | ||
} else { | ||
fftUdp.flush(); // WLEDMM: Flush this if we haven't read it. | ||
} | ||
if (have_new_sample) syncVolumeSmth = volumeSmth; // remember received sample | ||
else volumeSmth = syncVolumeSmth; // restore originally received sample for next run of dynamics limiter | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any downside to this change? "Compromise" for speed or just masking changes behind flag until we have done enough testing to know if this should just be right value for all uses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the downside is that the FFT task will block the core for longer (2ms in "standard", vs 7ms in "fastpath").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are using the second core, is that an issue? What else (if anything) is using that core?