CMSIS_DSP overlap-add signal reconstrucion - Page 1
Forum section: electronics / projects

author: analityk
author_rank: Regular Contributor
timestamp: June 22, 2025, 01:11:14 pm
content: Hi folks.I always dream about some DSP but it is a bit not my job (rather hardware stuffs etc but not exactly digital signal processing).But today it seems to be GPT can do a part of my task so i ask him/his/it (many many times in different way) to write some code together.He help me a lot with linker job, divide code to section etc...So now i have fast code, unfortunately it didn't work.So i will present you all (important in this task) code. It will be nice if someone will explain me it's behavior and point why it not work as intended.My setup is NAU88C22 audio codeck, it perform ADC and DAC, but full digital stream is flow by SMAE70Q21 uC (by I2S/PCM time slot and XDAMC direct memory access controller handles all in and out memory transfer)(Serial synchronous controller talk with codeck, i2s controller in uC is not work). Anyway while i copy data from receive buffer to transmit buffer sound is good (but it exhibit some delay ofc).Now GPT comes to code. He show me some code for perform FFT and IFFT on block of data with fully reconstruction signals after IFFT. GPT explain me we need overlap-add algorithm with windowing.But, as you can expect, this code do not work.So here is all code and effect how it is work. I'm sending to codeck audio signals form Audacity (100 Hz). And i expect 100 Hz not distorted signal on output.Pic rel ofc on socpe and because code is a bit long i place it in pastebin. All important comments is in code below.https://pastebin.com/LhdtTqmkThis picture with looking nice sin function is just copy data from receiver to transmiter.Sincerely

author: Marco
author_rank: Super Contributor
timestamp: June 22, 2025, 01:47:43 pm
content: Why not try to get it working with rectangular window first?

author: moffy
author_rank: Super Contributor
timestamp: June 22, 2025, 01:56:12 pm
content: ChatGPT is not he way to go, you need to write your own code so that you can understand it and then debug it if something goes wrong. This is especially true for real time tasks that have time dependency and memory constraints. The first place to start is to just read the ADC data in realtime and output it to the DAC in realtime without any processing just to see that things are working properly. Once that is established you can do some signal manipulation.

author: analityk
author_rank: Regular Contributor
timestamp: June 22, 2025, 03:43:57 pm
content: Rectangular windows means do not apply any window. During reconstruction that window signal phase is lost and signal between pack is not in phase, picture below.@moffy: i was placed oscilloscope screenshot with "pass trhu" data. Ofc chat gpt is not good in this topic on code level but is helpful some times.I start looking for information in literature but i think here is some specialist that can help.SincerelyAnalityk

author: gf
author_rank: Super Contributor
timestamp: June 22, 2025, 04:00:25 pm
content: Quote from: analityk on June 22, 2025, 03:43:57 pmhttps://www.dsprelated.com/freebooks/sasp/Overlap_Add_OLA_STFT_Processing.htmlBut I'm not sure what exactly you are after?Do you want to do STFT processing / reconstruction in order to modify a signal in the frequency domain?Or do you just want to convolve long data with a FIR filter kernel, using FFT+OLA as a tool to perform the convolution?

author: analityk
author_rank: Regular Contributor
timestamp: June 22, 2025, 04:14:48 pm
content: I will apply modification on signal in frequency domain an then analyse it effect on them. First of all I need fully recovered continuous signal after reverse fft.

author: Siwastaja
author_rank: Super Contributor
timestamp: June 22, 2025, 06:28:16 pm
content: Quote from: analityk on June 22, 2025, 01:11:14 pmDreaming about something sounds like there is some passion and true interest behind it. This plays poorly with ChatGPT coding (which kinda works if the tasks are easy enough, and you arenotinterested in learning, just getting done something you have no idea how you would even start).Just take it piece by piece. Very first step is hello world. The next step is making sure the output works: e.g. generate sawtooth wave by outputting (i++). Then verify that input works: assign input values into output in the loop. Then start adding FFT and inverse FFT.

author: SiliconWizard
author_rank: Super Contributor
timestamp: June 22, 2025, 06:45:24 pm
content: From your last scope capture, you seem to be having an issue when the buffer is looped (as it seems), so as moffy suggested, you should start with no processing other than just copying samples from in to out and ensure no lost sample especially when looping through the buffer. You should also implement a double-buffer scheme. Once that part is done and works 100% fine, you can move on to some simple processing (such as volume, just a multiply) and get to more complex stuff progressively. Just my 2 cents.

author: Marco
author_rank: Super Contributor
timestamp: June 22, 2025, 06:57:13 pm
content: Quote from: analityk on June 22, 2025, 03:43:57 pmQuite right.QuoteWhat is a pack? Using a rectangular window both for input and output before overlap add is the simplest case, and it should work ... no phase lost. It should just pass your sine, if not you're doing it wrong.

author: gf
author_rank: Super Contributor
timestamp: June 22, 2025, 08:51:14 pm
content: In order to obtain a perfect reconstruction from STFT OLA processing, the constant-overlap-add (COLA) condition must be met. For example: R = M for a rectangular window; R = M/2 for a (periodic) Hann window; or R = M/3 for a (periodic) Blackman window, etc. IOW, a rectangular window is COLA without overlap, a Hann window is COLA with 50% overlap, a Blackman window is COLA for 2/3 overlap, etc. Any window function is COLA for R = 1 (but you may not have enough CPU power for R = 1). Here, R is the hop size, M is the window size, and R and M are positive integers.

author: analityk
author_rank: Regular Contributor
timestamp: June 22, 2025, 09:26:24 pm
content: I do not expect answer form user who do not read post, but i hope someone looks code...ok.Data goes into and out of uC are duble buffered. All activity for this pipeline is handled by direct memory access controller, where i've build circular descriptors, so all transfers are automate.XDMAC gives me only interrupts where i set up (or clear) some flags. This is signals for loop in main for execute adjacent code.And it is work.My sample rate is 24 ksps for two channel, i store in single buffer 1024 samples (int16_t) and there is four tx and rx buffer for samples.As you can see in first post on oscilloscope screen xdmac rise interrupt by 22 ms while all calculation cost me about 2.5 ms. Data buffers (float32_t) is placed in fast sram memory (TCM in Cortex M7 core). This uC has core speed equal 300 MHz and it has floating point unit, this 2.5 ms is when code is not execute from sram, just it fly from flash. It is another room for be faster but first of all i need algorithm.So in each time where XDMAC tell me he receive new 1024 samples i copy it for temp. buffer (accu_in)(and convert int16_t to float32_t), then i call for process new data and when all dsp magic is finished i copy data (with cast them to int16_t) to Tx buffer. And this data is on scope.If i copy data form accu_in buffer just to tx buffer all sounds goes thru this system without any degradation (just sample rate is low but it is good enough at this moment). I can setup sample rate even in 48 ksps and it work but i do not need it.In describe each step in my cola algorithm but i see none of you looks into code. Maybe it will be just - do not execute this step or - in this step place correct window offset.Code:float32_t* sfft_process_block(sfft_instance_t *inst, const float32_t *input_block){// (1) SHIFT old half-frame//memmove(inst->input_buffer, inst->input_buffer + SFFT_HOP_SIZE, SFFT_HOP_SIZE * sizeof(float32_t));for(uint32_t i=0; i<1024; i++){inst->input_buffer = inst->input_buffer[i+1024];}// (2) LOAD + WINDOW new half// why only half window function is used here?for (uint32_t i = 0; i < SFFT_HOP_SIZE; i++) {inst->input_buffer[SFFT_HOP_SIZE + i] = input_block * sfft_window[SFFT_HOP_SIZE + i];}// (3) WINDOW old half// is this window function isn't symetric?// and this half chunk of data was multiply by window function earlier, in previoius call of this funcionfor (uint32_t i = 0; i < SFFT_HOP_SIZE; i++) {inst->input_buffer *= sfft_window;}// (4) FORWARD FFT (time->freq)arm_rfft_fast_f32(&fft_inst, inst->input_buffer, inst->frq_buffer, 0);// (5) MODIFY SPECTRUM (opcjonalnie)// e.g., zero bins 100..200:// for (uint32_t k = 100; k <= 200; k++) {// inst->frq_buffer[2*k] = 0.0f;// inst->frq_buffer[2*k+1] = 0.0f;// }// (6) INVERSE FFT (freq->time)arm_rfft_fast_f32(&fft_inst, inst->frq_buffer, inst->input_buffer, 1);// (7) NORMALIZE by FFT_SIZEfloat32_t invN = 1.0f / (float32_t)SFFT_FFT_SIZE;for(uint32_t j = 0; j < SFFT_FFT_SIZE; j++){inst->input_buffer *= invN;};// (8) OVERLAP-ADD + WINDOW CORRECTIONfor(uint32_t i = 0; i < SFFT_HOP_SIZE; i++){float32_t a = inst->input_buffer * sfft_window;float32_t b = inst->overlap_buffer;float32_t sumW = sfft_window + sfft_window[i + SFFT_HOP_SIZE];// combine and correct amplitudeinst->frq_buffer = (a + b) / sumW;// prepare next overlapinst->overlap_buffer = inst->input_buffer[i + SFFT_HOP_SIZE] * sfft_window[i + SFFT_HOP_SIZE];};// (9) RETURN pointer to first HOP_SIZE samples of frq_bufferreturn inst->frq_buffer;}

author: moffy
author_rank: Super Contributor
timestamp: June 22, 2025, 11:20:09 pm
content: Quote from: analityk on June 22, 2025, 03:43:57 pmAre you OK with the discontinuity shown in the trace? Continuous capture means at least two buffers which you ping pong capture the data to. One buffer is used for capture while the other is used for processing or transfer, when the current buffer is full you switch to using the other buffer which should be finished being used. You can also use a circular buffer but that is a little tricker.P.S. It appears to have been already mentioned by SiliconWizard perhaps by a different name.

author: analityk
author_rank: Regular Contributor
timestamp: June 23, 2025, 01:31:00 pm
content: This one picture...And here is my full algorithm, 1 h without any gpt, just this picture.QuoteThere is some artifacts but now is right time for optimize memory utility and speed.

author: moffy
author_rank: Super Contributor
timestamp: June 24, 2025, 11:24:19 am
content: Very nice, that is quick progress.