void do_mdct(void *ws, int c, float *in, float *ou...

Created on: March 7, 2025

Answered using O1 by Chat01

Question

void do_mdct(void *ws, int c, float *in, float *out) {
mdct_s *md = ws;
int N2 = md->N2;
int N4 = md->N4;
int NK = md->NK;
int ZN = md->ZN;

text
int overlap = md->overlap; kiss_fft_scalar *dct4 = md->buf->dct4; kiss_fft_scalar *foverlap = md->ch->overlap; kiss_fft_cpx *cin = md->buf->cin; kiss_fft_cpx *cout = md->buf->cout; for (int i = 0; i < ZN; i++) { dct4[NK + i] = -in[N2 - overlap - 1 - i]; dct4[N4 + i] = -in[ZN - 1 - i]; } for (int i = 0; i < NK; i++) { dct4[i] = md->win[NK + i] * -in[N2 - NK - 1 - i] - in[N2 - NK + i] * md->win[NK - 1 - i]; dct4[ZN + N4 + i] = foverlap[i] * md->win[i] - foverlap[overlap - 1 - i] * md->win[overlap - 1 - i]; } for (int i = 0; i < overlap; i++) { foverlap[i] = in[N2 - overlap + i]; } for (int i = 0; i < N4; i++) { cin[i].r = dct4[2 * i] * md->twid1[i].r - dct4[N2 - 1 - 2 * i] * md->twid1[i].i; cin[i].i = dct4[N2 - 1 - 2 * i] * md->twid1[i].r + dct4[2 * i] * md->twid1[i].i; } lhdc_v5_fft(md->fs, cin, cout); for (int i = 0; i < N4; i++) { out[2 * i] = -(cout[i].i * md->twid2[i].i - cout[i].r * md->twid2[i].r); out[N2 - 1 - 2 * i] = -(cout[i].i * md->twid2[i].r + cout[i].r * md->twid2[i].i); }

}

void do_imdct(void *ws, int c, float *in, float *out) {
mdct_s *md = ws;
int N2 = md->N2;
int N4 = md->N4;
int NK = md->NK;
int ZN = md->ZN;

text
int overlap = md->overlap; kiss_fft_scalar *dct4 = md->buf->dct4; kiss_fft_scalar *foverlap = md->ch->overlap; kiss_fft_cpx *cin = md->buf->cin; kiss_fft_cpx *cout = md->buf->cout; for (int i = 0; i < N4; i++) { cin[i].i = in[2 * i] * md->twid2[i].i + in[N2 - 1 - 2 * i] * md->twid2[i].r; cin[i].r = in[2 * i] * md->twid2[i].r - in[N2 - 1 - 2 * i] * md->twid2[i].i; } lhdc_v5_fft(md->fs, cin, cout); for (int i = 0; i < N4; i++) { dct4[2 * i] = cout[i].i * md->twid1[i].r - cout[i].r * md->twid1[i].i; dct4[N2 - 1 - 2 * i] = cout[i].r * md->twid1[i].r + cout[i].i * md->twid1[i].i; } for (int i = 0; i < ZN; i++) { out[N2 - overlap - 1 - i] = -dct4[NK + i]; out[ZN - 1 - i] = -dct4[N4 + i]; }

}
do_imdct缺失了overlap的处理,导致out不完整,请补全

Thought

Bringing symmetry

Tracking the code's progression, I notice that's it lacks symmetry in the do_imdct function, specifically in the overlap handling.

Replicating logic

I’m working through ensuring do_imdct mirrors do_mdct by including overlap logic, which copies and combines necessary elements to accurately handle the inverse transformation.

Aligning logic

I’m working through incorporating 'foverlap' merging logic into the do_imdct function, ensuring it mirrors do_mdct's handling of overlap situations for symmetry.

Completing the sync

I'm adding an overlap section to do_imdct, similar to do_mdct, to ensure the output is comprehensive and accurate.

Aligning overlap management

Assessing the steps: performing iMDCT, merging results with previous block overlap, and preparing for the next block. Insight into window handling is essential for accuracy.

Piecing together

I’m mapping out do_imdct's structure, aligning it with do_mdct's approach, and ensuring the overlap section is stored and utilized properly for accurate time domain samples.

Aligning approaches

Integrating the previous overlap, incorporating the new block, and preparing the new overlap. This approach ensures a comprehensive fix for aligning the process.

Coming together

I’m constructing do_imdct to blend previous overlap with current iMDCT results, then save the next overlap. This ensures a seamless and symmetric process.

Grasping memory storage

I’m growing my understanding of MDCT. The overlap is typically the last half of the previous block or the first half of the next, with the next overlap being stored symmetrically in foverlap.

Balancing considerations

Piecing together the use of foverlap in do_imdct, I’m exploring how it interacts with window functions, direct assignments, and combination methods to ensure symmetry and accuracy.

Pulling together the pieces

I’m connecting the use of foverlap in do_mdct and how it’s incorporated into do_imdct for precise overlap inclusion, aligning with the OLA method for accurate audio processing.

Enhancing foverlap

I’m working through the integration of foverlap in do_imdCT, aiming to seamlessly incorporate it into the process for consistent and accurate audio signal restoration.

Integrating MDCT strategies

I’m pulling together the MDCT approach, blending previous overlap data with window functions to refine the transform buffer, ensuring symmetry with the forward MDCT process.

Filling in gaps

Mapping out how to synthesize the iMDCT output with the previous overlap, carefully refining out to create a seamless and accurate representation.

Taking a closer look

Figuring out the relationship between N2 and ZN, and how they interplay with do_mdct's inverse process, to refine the synthesis of iMDCT output with the previous overlap.

Pulling together

I’m thinking through how to merge iMDCT output with previous overlap, using window functions to ensure smooth audio synthesis, similar to the forward MDCT process.

Capturing the essence

I’m crafting the iMDCT code, ensuring it mirrors the forward MDCT's symmetry by storing the last overlap in foverlap and incorporating the previous block's overlap into out.

Charting the course

I’m mapping out iMDCT code, considering how to adeptly merge the previous overlap with dct4 output, ensuring a smooth transition and accurate audio synthesis.

Syncing the pieces

I'm working through how to seamlessly integrate the previous overlap with new data in out, then storing the updated overlap for the next frame. The goal is smooth, uninterrupted synthesis.

Analyzing overlap handling

Checking how ZN and N4 match up, and if NK might be overlap/2. The goal is to fix incomplete out by handling overlap.

Mapping actions

OK, let me see. I’m figuring out how do_imdct should mirror do_mdct. This includes updating foverlap and merging it into out to ensure a seamless synthesis transition.

Crafting the solution

I'm thinking through combining the second half of dct4 with old overlap to update out, then saving the new overlap symmetrically. This ensures a balanced synthesis process.

Piecing it together

I’m thinking of a balanced, symmetrically merged overlap for do_imdct. This approach ensures a seamless audio synthesis process. I’ll combine old and new overlap for a cohesive output.

Synthesizing the approach

I'm combining the old overlap with out using foverlap. After windowing, I'll update both out and foverlap to prepare for seamless synthesis in do_imdct.

Mapping inverse overlap

Wondering how do_imdct can creatively use dct4 and foverlap for reverse synthesis. Replicating do_mdct with the inverse approach might unlock a fresh, effective method.

Refining the synthesis

I'm weaving together dct4 and foverlap for do_imdct, aiming to seamlessly blend audio segments and ensure old loop neuron data is included. Emphasizing the detail and method here.

Aligning with audio synthesis

I'm refining the merge of dct4 and foverlap for do_imdct, ensuring the process is aligned with standard audio synthesis practices. Hm, that's interesting, given the complexities involved.

Ensuring completeness

I’m aligning do_imdct to manage overlap, making it fit snugly within the array's length, and evolving it to handle future inputs without errors.

Piecing together sequences

I'm crafting code to merge the old overlap with the fresh block data, while storing the new overlap for the next iteration, ensuring smooth transitions in the synthesis process.

Nailing the synthesis process

I’m ensuring both the dct4 and foverlap arrays are adeptly fused for do_imdct. The aim is to blend synthesized segments seamlessly and efficiently.

Mapping out overlap

I'm thinking about optimal strategies for handling overlap in do_imdct, ensuring the last overlap from the second half of out is preserved for future frames.

Enhancing the process

I’m finalizing the do_imdct method by integrating overlap handling seamlessly, ensuring no data is lost and preparing for future input needs. This approach makes me think the application is set.

Mapping out the balance

I'm piecing together how the do_imdct method can seamlessly merge old and new overlaps. This approach seems to fit the user's intent, fostering smooth transitions.

Reasoned about IMDCT overlap handling for 1m 44s

Answer

下面给出一种思路来「补全」do_imdct里对 overlap 的处理,使其和 do_mdct 相对应。大体思路是:

  1. 在输出 out 中,先把上一帧的 overlap 数据加回去(重叠相加,OLA)。
  2. 再从本帧 out 的末端(或者指定位置)取出新的 overlap,存入 foverlap,供下一帧使用

在你的 do_mdct 里,最后这段是用来更新下一帧要用到的 overlap 的:

c
// do_mdct 里:将输入 in 的末尾部分保存到 foverlap,供下次使用 for (int i = 0; i < overlap; i++) { foverlap[i] = in[N2 - overlap + i]; }

而在 do_imdct 里,如果不做与之对称的处理,就会导致 out 的前半部分(或后半部分)没有正确叠加上一帧的残余(overlap),以及没有将本帧产生的新 overlap 存起来。


补全思路

在你的 do_imdct() 结尾处,补上两段逻辑:

  1. 将上一帧的 overlap 加到本帧 out 中正确的位置
  2. 将本帧 out 的相应部分保存到 foverlap,供下一帧使用

根据你在 do_mdct() 中的写法(即把输入末 overlap 大小的那段存到 foverlap),通常在 do_imdct() 中也是对称地「从 out 的末尾」或「合适位置」拿出 overlap。假设这里的 “合适位置” 就是 out[N2 - overlap + i],那么可以写成如下(示例):

c
void do_imdct(void *ws, int c, float *in, float *out) { mdct_s *md = ws; int N2 = md->N2; int N4 = md->N4; int NK = md->NK; int ZN = md->ZN; int overlap = md->overlap; kiss_fft_scalar *dct4 = md->buf->dct4; kiss_fft_scalar *foverlap = md->ch->overlap; kiss_fft_cpx *cin = md->buf->cin; kiss_fft_cpx *cout = md->buf->cout; // 1) 根据 in[] 恢复频域:与 twid2 结合后 FFT -> cout for (int i = 0; i < N4; i++) { cin[i].i = in[2 * i] * md->twid2[i].i + in[N2 - 1 - 2 * i] * md->twid2[i].r; cin[i].r = in[2 * i] * md->twid2[i].r - in[N2 - 1 - 2 * i] * md->twid2[i].i; } lhdc_v5_fft(md->fs, cin, cout); // 2) 将 FFT 结果 cout[] 与 twid1 混合, 得到时域 dct4[] for (int i = 0; i < N4; i++) { dct4[2 * i] = cout[i].i * md->twid1[i].r - cout[i].r * md->twid1[i].i; dct4[N2 - 1 - 2 * i] = cout[i].r * md->twid1[i].r + cout[i].i * md->twid1[i].i; } // 3) 将 dct4[] 的后半部分(-dct4[..])搬到 out 相应位置 // (这里是你原有的写法) for (int i = 0; i < ZN; i++) { out[N2 - overlap - 1 - i] = -dct4[NK + i]; out[ZN - 1 - i] = -dct4[N4 + i]; } // -------------- 这里是缺失的 overlap 处理 ---------------- // 4) 把上一帧遗留的 foverlap[i] 加到本帧 out 中,使得前后拼起来连续 for (int i = 0; i < overlap; i++) { // 假设你要把上一帧的 overlap 加到 out 的末 overlap 段 // 如果时域拼接位置是 N2 - overlap + i,就这样写: out[N2 - overlap + i] += foverlap[i]; } // 5) 从本帧 out 的末 overlap 段重新取出数据,保存到 foverlap,供下一帧使用 for (int i = 0; i < overlap; i++) { foverlap[i] = out[N2 - overlap + i]; } }

注意

  • 上面第 4、5 步里 out[N2 - overlap + i] 的具体下标,需与你在 do_mdct 中对 foverlap 的使用方式完全“对称”或“匹配”才行。
  • 如果你的实际流程是希望把「输出帧」的末尾部分 (比如 out[ZN - overlap + i]) 作为下一帧的 overlap,那就把上面下标改成 ZN - overlap + i 即可,前面加 overlap 时也要对应改成 ZN - overlap + i。关键是:在 do_mdct() 与 do_imdct() 中,对 foverlap 的使用(存哪里、取哪里)要严格一致

这样做完后,你就能把上一帧和本帧在时域上连续拼接起来,避免了「IMDCT 输出数据和上一帧不衔接」所导致的波形断裂。也能在 do_imdct 里把新的 overlap“留”给下一帧使用,从而输出「完整」的信号块。

Share this Q&A