Skip to content

Commit f2285d3

Browse files
authored
filtbank: reuse shared work buffer for MDCT scratch (#119)
Carve the MDCT pre/post-twiddle buffers (xr, xi) out of the existing gpsyInfo.sharedWorkBuffLong instead of using dedicated mdctXr/mdctXi allocations. This removes two per-encoder heap allocations of BLOCK_LEN_LONG/2 (512) faac_real each, freeing 4-8 KiB per encoder depending on the build's precision.
1 parent b54d464 commit f2285d3

3 files changed

Lines changed: 11 additions & 13 deletions

File tree

libfaac/blockswitch.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ typedef struct {
4545
faac_real sampleRate;
4646

4747
/* shared work buffers */
48-
faac_real *sharedWorkBuffLong; /* Used for 2048-sample windows (filtbank, psy, tns) */
49-
faac_real *mdctXr; /* MDCT pre-twiddle work buffer (xr) */
50-
faac_real *mdctXi; /* MDCT pre-twiddle work buffer (xi) */
48+
faac_real *sharedWorkBuffLong; /* Used for 2048-sample windows (filtbank, psy, tns, mdct) */
5149
} GlobalPsyInfo;
5250

5351
typedef struct

libfaac/filtbank.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ void FilterBankInit(faacEncStruct* hEncoder)
7373
CalculateKBDWindow(hEncoder->kbd_window_short, 6, BLOCK_LEN_SHORT*2);
7474

7575
hEncoder->gpsyInfo.sharedWorkBuffLong = (faac_real*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(faac_real));
76-
hEncoder->gpsyInfo.mdctXr = (faac_real*)AllocMemory((BLOCK_LEN_LONG / 2)*sizeof(faac_real));
77-
hEncoder->gpsyInfo.mdctXi = (faac_real*)AllocMemory((BLOCK_LEN_LONG / 2)*sizeof(faac_real));
7876
}
7977

8078
void FilterBankEnd(faacEncStruct* hEncoder)
@@ -92,8 +90,6 @@ void FilterBankEnd(faacEncStruct* hEncoder)
9290
if (hEncoder->kbd_window_short) FreeMemory(hEncoder->kbd_window_short);
9391

9492
if (hEncoder->gpsyInfo.sharedWorkBuffLong) FreeMemory(hEncoder->gpsyInfo.sharedWorkBuffLong);
95-
if (hEncoder->gpsyInfo.mdctXr) FreeMemory(hEncoder->gpsyInfo.mdctXr);
96-
if (hEncoder->gpsyInfo.mdctXi) FreeMemory(hEncoder->gpsyInfo.mdctXi);
9793
}
9894

9995
void FilterBank(faacEncStruct* hEncoder,
@@ -158,7 +154,7 @@ void FilterBank(faacEncStruct* hEncoder,
158154
p_out_mdct[i] = p_o_buf[i] * first_window[i];
159155
p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
160156
}
161-
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi );
157+
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.sharedWorkBuffLong );
162158
break;
163159

164160
case LONG_SHORT_WINDOW :
@@ -168,7 +164,7 @@ void FilterBank(faacEncStruct* hEncoder,
168164
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
169165
p_out_mdct[i+BLOCK_LEN_LONG+NFLAT_LS] = p_o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
170166
SetMemory(p_out_mdct+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(faac_real));
171-
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi );
167+
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.sharedWorkBuffLong );
172168
break;
173169

174170
case SHORT_LONG_WINDOW :
@@ -178,7 +174,7 @@ void FilterBank(faacEncStruct* hEncoder,
178174
memcpy(p_out_mdct+NFLAT_LS+BLOCK_LEN_SHORT,p_o_buf+NFLAT_LS+BLOCK_LEN_SHORT,NFLAT_LS*sizeof(faac_real));
179175
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
180176
p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
181-
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi );
177+
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.sharedWorkBuffLong );
182178
break;
183179

184180
case ONLY_SHORT_WINDOW :
@@ -188,7 +184,7 @@ void FilterBank(faacEncStruct* hEncoder,
188184
p_out_mdct[i] = p_o_buf[i] * first_window[i];
189185
p_out_mdct[i+BLOCK_LEN_SHORT] = p_o_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1];
190186
}
191-
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_SHORT, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi );
187+
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_SHORT, hEncoder->gpsyInfo.sharedWorkBuffLong );
192188
p_out_mdct += BLOCK_LEN_SHORT;
193189
p_o_buf += BLOCK_LEN_SHORT;
194190
first_window = second_window;
@@ -244,7 +240,7 @@ static void CalculateKBDWindow(faac_real* win, faac_real alpha, int length)
244240
}
245241
}
246242

247-
void MDCT( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *xr, faac_real *xi )
243+
void MDCT( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *work )
248244
{
249245
faac_real tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
250246
faac_real freq = TWOPI / N;
@@ -255,6 +251,10 @@ void MDCT( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *xr, faac_r
255251
const int N4 = N >> 2;
256252
const int N8 = N >> 3;
257253

254+
/* Pre/post-twiddle FFT buffers carved from the shared work buffer */
255+
faac_real *xr = work;
256+
faac_real *xi = work + N4;
257+
258258
/* Base pointers for address simplification */
259259
faac_real *base0 = data + N4;
260260
faac_real *base1 = data + (N4 - 1);

libfaac/filtbank.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void FilterBankInit ( faacEncStruct* hEncoder );
3939

4040
void FilterBankEnd ( faacEncStruct* hEncoder );
4141

42-
void MDCT ( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *xr, faac_real *xi );
42+
void MDCT ( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *work );
4343

4444
void FilterBank( faacEncStruct* hEncoder,
4545
CoderInfo *coderInfo,

0 commit comments

Comments
 (0)