Merge branch 'pr/125' into pr/124
This commit is contained in:
@@ -141,7 +141,7 @@ static uint8_t fftResult[NUM_GEQ_CHANNELS]= {0}; // Our calculated freq. chann
|
|||||||
static float fftCalc[NUM_GEQ_CHANNELS] = {0.0f}; // Try and normalize fftBin values to a max of 4096, so that 4096/16 = 256. (also used by dynamics limiter)
|
static float fftCalc[NUM_GEQ_CHANNELS] = {0.0f}; // Try and normalize fftBin values to a max of 4096, so that 4096/16 = 256. (also used by dynamics limiter)
|
||||||
static float fftAvg[NUM_GEQ_CHANNELS] = {0.0f}; // Calculated frequency channel results, with smoothing (used if dynamics limiter is ON)
|
static float fftAvg[NUM_GEQ_CHANNELS] = {0.0f}; // Calculated frequency channel results, with smoothing (used if dynamics limiter is ON)
|
||||||
|
|
||||||
uint_fast16_t zeroCrossingCount = 0;
|
static uint16_t zeroCrossingCount = 0; // number of zero crossings in the current batch of 512 samples
|
||||||
|
|
||||||
// TODO: probably best not used by receive nodes
|
// TODO: probably best not used by receive nodes
|
||||||
static float agcSensitivity = 128; // AGC sensitivity estimation, based on agc gain (multAgc). calculated by getSensitivity(). range 0..255
|
static float agcSensitivity = 128; // AGC sensitivity estimation, based on agc gain (multAgc). calculated by getSensitivity(). range 0..255
|
||||||
@@ -497,17 +497,6 @@ void FFTcode(void * parameter)
|
|||||||
// get a fresh batch of samples from I2S
|
// get a fresh batch of samples from I2S
|
||||||
if (audioSource) audioSource->getSamples(vReal, samplesFFT);
|
if (audioSource) audioSource->getSamples(vReal, samplesFFT);
|
||||||
|
|
||||||
// WLED-MM/TroyHacks: Calculate zero crossings
|
|
||||||
//
|
|
||||||
zeroCrossingCount = 0;
|
|
||||||
for (int i=0; i < samplesFFT; i++) {
|
|
||||||
if (i < (samplesFFT)-2) {
|
|
||||||
if((vReal[i] >= 0 && vReal[i+1] < 0) || (vReal[i+1] < 0 && vReal[i+1] >= 0)) {
|
|
||||||
zeroCrossingCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
|
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
|
||||||
// debug info in case that stack usage changes
|
// debug info in case that stack usage changes
|
||||||
static unsigned int minStackFree = UINT32_MAX;
|
static unsigned int minStackFree = UINT32_MAX;
|
||||||
@@ -556,15 +545,25 @@ void FFTcode(void * parameter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find highest sample in the batch
|
// find highest sample in the batch, and count zero crossings
|
||||||
float maxSample = 0.0f; // max sample from FFT batch
|
float maxSample = 0.0f; // max sample from FFT batch
|
||||||
|
uint_fast16_t newZeroCrossingCount = 0;
|
||||||
for (int i=0; i < samplesFFT; i++) {
|
for (int i=0; i < samplesFFT; i++) {
|
||||||
// set imaginary parts to 0
|
// set imaginary parts to 0
|
||||||
vImag[i] = 0;
|
vImag[i] = 0;
|
||||||
// pick our our current mic sample - we take the max value from all samples that go into FFT
|
// pick our our current mic sample - we take the max value from all samples that go into FFT
|
||||||
if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) //skip extreme values - normally these are artefacts
|
if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) //skip extreme values - normally these are artefacts
|
||||||
if (fabsf((float)vReal[i]) > maxSample) maxSample = fabsf((float)vReal[i]);
|
if (fabsf((float)vReal[i]) > maxSample) maxSample = fabsf((float)vReal[i]);
|
||||||
|
|
||||||
|
// WLED-MM/TroyHacks: Calculate zero crossings
|
||||||
|
//
|
||||||
|
if (i < (samplesFFT-1)) {
|
||||||
|
if((vReal[i] >= 0 && vReal[i+1] < 0) || (vReal[i] < 0 && vReal[i+1] >= 0)) {
|
||||||
|
newZeroCrossingCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
zeroCrossingCount = newZeroCrossingCount; // update only once, to avoid that effects pick up an intermediate value
|
||||||
|
|
||||||
// release highest sample to volume reactive effects early - not strictly necessary here - could also be done at the end of the function
|
// release highest sample to volume reactive effects early - not strictly necessary here - could also be done at the end of the function
|
||||||
// early release allows the filters (getSample() and agcAvg()) to work with fresh values - we will have matching gain and noise gate values when we want to process the FFT results.
|
// early release allows the filters (getSample() and agcAvg()) to work with fresh values - we will have matching gain and noise gate values when we want to process the FFT results.
|
||||||
@@ -1020,7 +1019,7 @@ class AudioReactive : public Usermod {
|
|||||||
uint8_t samplePeak; // 01 Bytes offset 16 - 0 no peak; >=1 peak detected. In future, this will also provide peak Magnitude
|
uint8_t samplePeak; // 01 Bytes offset 16 - 0 no peak; >=1 peak detected. In future, this will also provide peak Magnitude
|
||||||
uint8_t frameCounter; // 01 Bytes offset 17 - track duplicate/out of order packets
|
uint8_t frameCounter; // 01 Bytes offset 17 - track duplicate/out of order packets
|
||||||
uint8_t fftResult[16]; // 16 Bytes offset 18
|
uint8_t fftResult[16]; // 16 Bytes offset 18
|
||||||
uint8_t gap2[2]; // gap added by compiler: 02 Bytes, offset 34
|
uint16_t zeroCrossingCount; // 02 Bytes, offset 34
|
||||||
float FFT_Magnitude; // 04 Bytes offset 36
|
float FFT_Magnitude; // 04 Bytes offset 36
|
||||||
float FFT_MajorPeak; // 04 Bytes offset 40
|
float FFT_MajorPeak; // 04 Bytes offset 40
|
||||||
};
|
};
|
||||||
@@ -1560,6 +1559,7 @@ class AudioReactive : public Usermod {
|
|||||||
transmitData.samplePeak = udpSamplePeak ? 1:0;
|
transmitData.samplePeak = udpSamplePeak ? 1:0;
|
||||||
udpSamplePeak = false; // Reset udpSamplePeak after we've transmitted it
|
udpSamplePeak = false; // Reset udpSamplePeak after we've transmitted it
|
||||||
transmitData.frameCounter = frameCounter;
|
transmitData.frameCounter = frameCounter;
|
||||||
|
transmitData.zeroCrossingCount = zeroCrossingCount;
|
||||||
|
|
||||||
for (int i = 0; i < NUM_GEQ_CHANNELS; i++) {
|
for (int i = 0; i < NUM_GEQ_CHANNELS; i++) {
|
||||||
transmitData.fftResult[i] = (uint8_t)constrain(fftResult[i], 0, 254);
|
transmitData.fftResult[i] = (uint8_t)constrain(fftResult[i], 0, 254);
|
||||||
@@ -1632,6 +1632,7 @@ class AudioReactive : public Usermod {
|
|||||||
FFT_MajorPeak = constrain(receivedPacket->FFT_MajorPeak, 1.0f, 11025.0f); // restrict value to range expected by effects
|
FFT_MajorPeak = constrain(receivedPacket->FFT_MajorPeak, 1.0f, 11025.0f); // restrict value to range expected by effects
|
||||||
soundPressure = volumeSmth; // substitute - V2 format does not (yet) include this value
|
soundPressure = volumeSmth; // substitute - V2 format does not (yet) include this value
|
||||||
agcSensitivity = 128.0f; // substitute - V2 format does not (yet) include this value
|
agcSensitivity = 128.0f; // substitute - V2 format does not (yet) include this value
|
||||||
|
zeroCrossingCount = receivedPacket->zeroCrossingCount;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1733,7 +1734,7 @@ class AudioReactive : public Usermod {
|
|||||||
// usermod exchangeable data
|
// usermod exchangeable data
|
||||||
// we will assign all usermod exportable data here as pointers to original variables or arrays and allocate memory for pointers
|
// we will assign all usermod exportable data here as pointers to original variables or arrays and allocate memory for pointers
|
||||||
um_data = new um_data_t;
|
um_data = new um_data_t;
|
||||||
um_data->u_size = 11;
|
um_data->u_size = 12;
|
||||||
um_data->u_type = new um_types_t[um_data->u_size];
|
um_data->u_type = new um_types_t[um_data->u_size];
|
||||||
um_data->u_data = new void*[um_data->u_size];
|
um_data->u_data = new void*[um_data->u_size];
|
||||||
um_data->u_data[0] = &volumeSmth; //*used (New)
|
um_data->u_data[0] = &volumeSmth; //*used (New)
|
||||||
@@ -1775,6 +1776,8 @@ class AudioReactive : public Usermod {
|
|||||||
um_data->u_type[9] = UMT_FLOAT;
|
um_data->u_type[9] = UMT_FLOAT;
|
||||||
um_data->u_data[10] = &agcSensitivity; // used (New) - dummy value (128 => 50%)
|
um_data->u_data[10] = &agcSensitivity; // used (New) - dummy value (128 => 50%)
|
||||||
um_data->u_type[10] = UMT_FLOAT;
|
um_data->u_type[10] = UMT_FLOAT;
|
||||||
|
um_data->u_data[11] = &zeroCrossingCount;
|
||||||
|
um_data->u_type[11] = UMT_UINT16;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1936,7 +1939,7 @@ class AudioReactive : public Usermod {
|
|||||||
USER_PRINTF("| uint8_t samplePeak offset = %2d size = %2d\n", offsetof(audioSyncPacket, samplePeak), sizeof(data.samplePeak)); // offset 16 size 1
|
USER_PRINTF("| uint8_t samplePeak offset = %2d size = %2d\n", offsetof(audioSyncPacket, samplePeak), sizeof(data.samplePeak)); // offset 16 size 1
|
||||||
USER_PRINTF("| uint8_t frameCounter offset = %2d size = %2d\n", offsetof(audioSyncPacket, frameCounter), sizeof(data.frameCounter)); // offset 17 size 1
|
USER_PRINTF("| uint8_t frameCounter offset = %2d size = %2d\n", offsetof(audioSyncPacket, frameCounter), sizeof(data.frameCounter)); // offset 17 size 1
|
||||||
USER_PRINTF("| uint8_t fftResult[16] offset = %2d size = %2d\n", offsetof(audioSyncPacket, fftResult[0]), sizeof(data.fftResult)); // offset 18 size 16
|
USER_PRINTF("| uint8_t fftResult[16] offset = %2d size = %2d\n", offsetof(audioSyncPacket, fftResult[0]), sizeof(data.fftResult)); // offset 18 size 16
|
||||||
USER_PRINTF("| uint8_t gap2[2] offset = %2d size = %2d\n", offsetof(audioSyncPacket, gap2[0]), sizeof(data.gap2)); // offset 34 size 2
|
USER_PRINTF("| uint16_t zeroCrossingCount offset = %2d size = %2d\n", offsetof(audioSyncPacket, zeroCrossingCount), sizeof(data.zeroCrossingCount)); // offset 34 size 2
|
||||||
USER_PRINTF("| float FFT_Magnitude offset = %2d size = %2d\n", offsetof(audioSyncPacket, FFT_Magnitude), sizeof(data.FFT_Magnitude));// offset 36 size 4
|
USER_PRINTF("| float FFT_Magnitude offset = %2d size = %2d\n", offsetof(audioSyncPacket, FFT_Magnitude), sizeof(data.FFT_Magnitude));// offset 36 size 4
|
||||||
USER_PRINTF("| float FFT_MajorPeak offset = %2d size = %2d\n", offsetof(audioSyncPacket, FFT_MajorPeak), sizeof(data.FFT_MajorPeak));// offset 40 size 4
|
USER_PRINTF("| float FFT_MajorPeak offset = %2d size = %2d\n", offsetof(audioSyncPacket, FFT_MajorPeak), sizeof(data.FFT_MajorPeak));// offset 40 size 4
|
||||||
USER_PRINTLN(); USER_FLUSH();
|
USER_PRINTLN(); USER_FLUSH();
|
||||||
|
|||||||
Reference in New Issue
Block a user