Mercurial > libavcodec.hg
comparison eac3dec.c @ 8136:3085502c4f33 libavcodec
add support for spectral extension
author | jbr |
---|---|
date | Thu, 13 Nov 2008 03:18:13 +0000 |
parents | 1c0e498ac7bd |
children | f17b1eb9ccd1 |
comparison
equal
deleted
inserted
replaced
8135:c82f8f5657ff | 8136:3085502c4f33 |
---|---|
34 EAC3_GAQ_124 | 34 EAC3_GAQ_124 |
35 } EAC3GaqMode; | 35 } EAC3GaqMode; |
36 | 36 |
37 #define EAC3_SR_CODE_REDUCED 3 | 37 #define EAC3_SR_CODE_REDUCED 3 |
38 | 38 |
39 | |
40 void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) | |
41 { | |
42 int bin, bnd, ch, i; | |
43 int wrapflag[SPX_MAX_BANDS]={0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS]; | |
44 int rms_energy[SPX_MAX_BANDS]; | |
45 | |
46 /* Set copy index mapping table. Set wrap flags to apply a notch filter at | |
47 wrap points later on. */ | |
48 bin = s->spx_copy_start_freq; | |
49 num_copy_sections = 0; | |
50 for (bnd = 0; bnd < s->num_spx_bands; bnd++) { | |
51 int bandsize = s->spx_band_sizes[bnd]; | |
52 if ((bin + bandsize) > s->spx_start_freq) { | |
53 copy_sizes[num_copy_sections++] = bin - s->spx_copy_start_freq; | |
54 bin = s->spx_copy_start_freq; | |
55 wrapflag[bnd] = 1; | |
56 } | |
57 for (i = 0; i < bandsize; i++) { | |
58 if (bin == s->spx_start_freq) { | |
59 copy_sizes[num_copy_sections++] = bin - s->spx_copy_start_freq; | |
60 bin = s->spx_copy_start_freq; | |
61 } | |
62 bin++; | |
63 } | |
64 } | |
65 copy_sizes[num_copy_sections++] = bin - s->spx_copy_start_freq; | |
66 | |
67 for (ch = 1; ch <= s->fbw_channels; ch++) { | |
68 if (!s->channel_in_spx[ch]) | |
69 continue; | |
70 | |
71 /* Copy coeffs from normal bands to extension bands */ | |
72 bin = s->spx_start_freq; | |
73 for (bnd = 0; bnd < num_copy_sections; bnd++) { | |
74 memcpy(&s->fixed_coeffs[ch][bin], | |
75 &s->fixed_coeffs[ch][s->spx_copy_start_freq], | |
76 copy_sizes[bnd]*sizeof(int)); | |
77 bin += copy_sizes[bnd]; | |
78 } | |
79 | |
80 /* Calculate RMS energy for each SPX band. */ | |
81 bin = s->spx_start_freq; | |
82 for (bnd = 0; bnd < s->num_spx_bands; bnd++) { | |
83 int bandsize = s->spx_band_sizes[bnd]; | |
84 int64_t accum = 0; | |
85 for (i = 0; i < bandsize; i++) { | |
86 int64_t coeff = s->fixed_coeffs[ch][bin++]; | |
87 accum += coeff * coeff; | |
88 } | |
89 rms_energy[bnd] = ff_sqrt((accum >> 15) / bandsize) * M_SQRT_POW2_15; | |
90 } | |
91 | |
92 /* Apply a notch filter at transitions between normal and extension | |
93 bands and at all wrap points. */ | |
94 if (s->spx_atten_code[ch] >= 0) { | |
95 const int32_t *atten_tab = ff_eac3_spx_atten_tab[s->spx_atten_code[ch]]; | |
96 /* apply notch filter at baseband / extension region border */ | |
97 bin = s->spx_start_freq - 2; | |
98 for (i = 0; i < 5; i++) { | |
99 s->fixed_coeffs[ch][bin] = ((int64_t)atten_tab[2-abs(i-2)] * | |
100 (int64_t)s->fixed_coeffs[ch][bin]) >> 23; | |
101 bin++; | |
102 } | |
103 /* apply notch at all other wrap points */ | |
104 bin += s->spx_band_sizes[0]; | |
105 for (bnd = 1; bnd < s->num_spx_bands; bnd++) { | |
106 if (wrapflag[bnd]) { | |
107 bin -= 5; | |
108 for (i = 0; i < 5; i++) { | |
109 s->fixed_coeffs[ch][bin] = (atten_tab[2-abs(i-2)] * | |
110 (int64_t)s->fixed_coeffs[ch][bin]) >> 23; | |
111 bin++; | |
112 } | |
113 } | |
114 bin += s->spx_band_sizes[bnd]; | |
115 } | |
116 } | |
117 | |
118 /* Apply noise-blended coefficient scaling based on previously | |
119 calculated RMS energy, blending factors, and SPX coordinates for | |
120 each band. */ | |
121 bin = s->spx_start_freq; | |
122 for (bnd = 0; bnd < s->num_spx_bands; bnd++) { | |
123 int64_t nscale, sscale, spxco; | |
124 nscale = (s->spx_noise_blend [ch][bnd] * rms_energy[bnd]) >> 23; | |
125 nscale = (nscale * 14529495) >> 23; | |
126 sscale = s->spx_signal_blend[ch][bnd]; | |
127 spxco = s->spx_coords[ch][bnd]; | |
128 for (i = 0; i < s->spx_band_sizes[bnd]; i++) { | |
129 int64_t noise = (nscale * (((int)av_lfg_get(&s->dith_state))>>8)) >> 23; | |
130 int64_t signal = (sscale * s->fixed_coeffs[ch][bin]) >> 23; | |
131 s->fixed_coeffs[ch][bin++] = ((noise + signal) * spxco) >> 23; | |
132 } | |
133 } | |
134 } | |
135 } | |
136 | |
39 /** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */ | 137 /** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */ |
40 #define COEFF_0 10273905LL | 138 #define COEFF_0 10273905LL |
41 | 139 |
42 /** lrint(M_SQRT2*cos(0*M_PI/12)*(1<<23)) = lrint(M_SQRT2*(1<<23)) */ | 140 /** lrint(M_SQRT2*cos(0*M_PI/12)*(1<<23)) = lrint(M_SQRT2*(1<<23)) */ |
43 #define COEFF_1 11863283LL | 141 #define COEFF_1 11863283LL |
457 } | 555 } |
458 } | 556 } |
459 } | 557 } |
460 | 558 |
461 /* spectral extension attenuation data */ | 559 /* spectral extension attenuation data */ |
462 if (parse_spx_atten_data) { | 560 for (ch = 1; ch <= s->fbw_channels; ch++) { |
463 av_log_missing_feature(s->avctx, "Spectral extension attenuation", 1); | 561 if (parse_spx_atten_data && get_bits1(gbc)) |
464 for (ch = 1; ch <= s->fbw_channels; ch++) { | 562 s->spx_atten_code[ch] = get_bits(gbc, 5); |
465 if (get_bits1(gbc)) { // channel has spx attenuation | 563 else |
466 skip_bits(gbc, 5); // skip spx attenuation code | 564 s->spx_atten_code[ch] = -1; |
467 } | 565 } |
468 } | |
469 } | |
470 | 566 |
471 /* block start information */ | 567 /* block start information */ |
472 if (s->num_blocks > 1 && get_bits1(gbc)) { | 568 if (s->num_blocks > 1 && get_bits1(gbc)) { |
473 /* reference: Section E2.3.2.27 | 569 /* reference: Section E2.3.2.27 |
474 nblkstrtbits = (numblks - 1) * (4 + ceiling(log2(words_per_frame))) | 570 nblkstrtbits = (numblks - 1) * (4 + ceiling(log2(words_per_frame))) |
478 skip_bits(gbc, block_start_bits); | 574 skip_bits(gbc, block_start_bits); |
479 } | 575 } |
480 | 576 |
481 /* syntax state initialization */ | 577 /* syntax state initialization */ |
482 for (ch = 1; ch <= s->fbw_channels; ch++) { | 578 for (ch = 1; ch <= s->fbw_channels; ch++) { |
579 s->first_spx_coords[ch] = 1; | |
483 s->first_cpl_coords[ch] = 1; | 580 s->first_cpl_coords[ch] = 1; |
484 } | 581 } |
485 s->first_cpl_leak = 1; | 582 s->first_cpl_leak = 1; |
486 | 583 |
487 return 0; | 584 return 0; |