Revision 63cae55d libavcodec/qdm2.c

View differences:

libavcodec/qdm2.c
98 98
} QDM2SubPNode;
99 99

  
100 100
typedef struct {
101
    float re;
102
    float im;
103
} QDM2Complex;
104

  
105
typedef struct {
101 106
    float level;
102
    float *samples_im;
103
    float *samples_re;
107
    QDM2Complex *complex;
104 108
    const float *table;
105 109
    int   phase;
106 110
    int   phase_shift;
......
118 122
} FFTCoefficient;
119 123

  
120 124
typedef struct {
121
    float re;
122
    float im;
123
} QDM2Complex;
124

  
125
typedef struct {
126
    DECLARE_ALIGNED_16(QDM2Complex, complex[256 + 1]);
127
    float       samples_im[MPA_MAX_CHANNELS][256];
128
    float       samples_re[MPA_MAX_CHANNELS][256];
125
    DECLARE_ALIGNED_16(QDM2Complex, complex[MPA_MAX_CHANNELS][256]);
129 126
} QDM2FFT;
130 127

  
131 128
/**
......
166 163
    int fft_coefs_min_index[5];
167 164
    int fft_coefs_max_index[5];
168 165
    int fft_level_exp[6];
169
    FFTContext fft_ctx;
170
    FFTComplex exptab[128];
166
    RDFTContext rdft_ctx;
171 167
    QDM2FFT fft;
172 168

  
173 169
    /// I/O data
......
1507 1503

  
1508 1504
    /* generate FFT coefficients for tone */
1509 1505
    if (tone->duration >= 3 || tone->cutoff >= 3) {
1510
        tone->samples_im[0] += c.im;
1511
        tone->samples_re[0] += c.re;
1512
        tone->samples_im[1] -= c.im;
1513
        tone->samples_re[1] -= c.re;
1506
        tone->complex[0].im += c.im;
1507
        tone->complex[0].re += c.re;
1508
        tone->complex[1].im -= c.im;
1509
        tone->complex[1].re -= c.re;
1514 1510
    } else {
1515 1511
        f[1] = -tone->table[4];
1516 1512
        f[0] =  tone->table[3] - tone->table[0];
......
1519 1515
        f[4] =  tone->table[0] - tone->table[1];
1520 1516
        f[5] =  tone->table[2];
1521 1517
        for (i = 0; i < 2; i++) {
1522
            tone->samples_re[fft_cutoff_index_table[tone->cutoff][i]] += c.re * f[i];
1523
            tone->samples_im[fft_cutoff_index_table[tone->cutoff][i]] += c.im *((tone->cutoff <= i) ? -f[i] : f[i]);
1518
            tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re += c.re * f[i];
1519
            tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im += c.im *((tone->cutoff <= i) ? -f[i] : f[i]);
1524 1520
        }
1525 1521
        for (i = 0; i < 4; i++) {
1526
            tone->samples_re[i] += c.re * f[i+2];
1527
            tone->samples_im[i] += c.im * f[i+2];
1522
            tone->complex[i].re += c.re * f[i+2];
1523
            tone->complex[i].im += c.im * f[i+2];
1528 1524
        }
1529 1525
    }
1530 1526

  
......
1542 1538
    const double iscale = 0.25 * M_PI;
1543 1539

  
1544 1540
    for (ch = 0; ch < q->channels; ch++) {
1545
        memset(q->fft.samples_im[ch], 0, q->fft_size * sizeof(float));
1546
        memset(q->fft.samples_re[ch], 0, q->fft_size * sizeof(float));
1541
        memset(q->fft.complex[ch], 0, q->fft_size * sizeof(QDM2Complex));
1547 1542
    }
1548 1543

  
1549 1544

  
......
1561 1556

  
1562 1557
            c.re = level * cos(q->fft_coefs[i].phase * iscale);
1563 1558
            c.im = level * sin(q->fft_coefs[i].phase * iscale);
1564
            q->fft.samples_re[ch][q->fft_coefs[i].offset + 0] += c.re;
1565
            q->fft.samples_im[ch][q->fft_coefs[i].offset + 0] += c.im;
1566
            q->fft.samples_re[ch][q->fft_coefs[i].offset + 1] -= c.re;
1567
            q->fft.samples_im[ch][q->fft_coefs[i].offset + 1] -= c.im;
1559
            q->fft.complex[ch][q->fft_coefs[i].offset + 0].re += c.re;
1560
            q->fft.complex[ch][q->fft_coefs[i].offset + 0].im += c.im;
1561
            q->fft.complex[ch][q->fft_coefs[i].offset + 1].re -= c.re;
1562
            q->fft.complex[ch][q->fft_coefs[i].offset + 1].im -= c.im;
1568 1563
        }
1569 1564

  
1570 1565
    /* generate existing FFT tones */
......
1594 1589
                        tone.cutoff = (offset >= 60) ? 3 : 2;
1595 1590

  
1596 1591
                    tone.level = (q->fft_coefs[j].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[j].exp & 63];
1597
                    tone.samples_im = &q->fft.samples_im[ch][offset];
1598
                    tone.samples_re = &q->fft.samples_re[ch][offset];
1592
                    tone.complex = &q->fft.complex[ch][offset];
1599 1593
                    tone.table = fft_tone_sample_table[i][q->fft_coefs[j].offset - (offset << four_i)];
1600 1594
                    tone.phase = 64 * q->fft_coefs[j].phase - (offset << 8) - 128;
1601 1595
                    tone.phase_shift = (2 * q->fft_coefs[j].offset + 1) << (7 - four_i);
......
1612 1606

  
1613 1607
static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet)
1614 1608
{
1615
    const int n = 1 << (q->fft_order - 1);
1616
    const int n2 = n >> 1;
1617
    const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.25f : 0.50f;
1618
    float c, s, f0, f1, f2, f3;
1619
    int i, j;
1620

  
1621
    /* prerotation (or something like that) */
1622
    for (i=1; i < n2; i++) {
1623
        j  = (n - i);
1624
        c = q->exptab[i].re;
1625
        s = -q->exptab[i].im;
1626
        f0 = (q->fft.samples_re[channel][i] - q->fft.samples_re[channel][j]) * gain;
1627
        f1 = (q->fft.samples_im[channel][i] + q->fft.samples_im[channel][j]) * gain;
1628
        f2 = (q->fft.samples_re[channel][i] + q->fft.samples_re[channel][j]) * gain;
1629
        f3 = (q->fft.samples_im[channel][i] - q->fft.samples_im[channel][j]) * gain;
1630
        q->fft.complex[i].re =  s * f0 - c * f1 + f2;
1631
        q->fft.complex[i].im =  c * f0 + s * f1 + f3;
1632
        q->fft.complex[j].re = -s * f0 + c * f1 + f2;
1633
        q->fft.complex[j].im =  c * f0 + s * f1 - f3;
1634
    }
1635

  
1636
    q->fft.complex[ 0].re =  q->fft.samples_re[channel][ 0] * gain * 2.0;
1637
    q->fft.complex[ 0].im =  q->fft.samples_re[channel][ 0] * gain * 2.0;
1638
    q->fft.complex[n2].re =  q->fft.samples_re[channel][n2] * gain * 2.0;
1639
    q->fft.complex[n2].im = -q->fft.samples_im[channel][n2] * gain * 2.0;
1640

  
1641
    ff_fft_permute(&q->fft_ctx, (FFTComplex *) q->fft.complex);
1642
    ff_fft_calc (&q->fft_ctx, (FFTComplex *) q->fft.complex);
1609
    const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.5f : 1.0f;
1610
    int i;
1611
    q->fft.complex[channel][0].re *= 2.0f;
1612
    q->fft.complex[channel][0].im = 0.0f;
1613
    ff_rdft_calc(&q->rdft_ctx, (FFTSample *)q->fft.complex[channel]);
1643 1614
    /* add samples to output buffer */
1644 1615
    for (i = 0; i < ((q->fft_frame_size + 15) & ~15); i++)
1645
        q->output_buffer[q->channels * i + channel] += ((float *) q->fft.complex)[i];
1616
        q->output_buffer[q->channels * i + channel] += ((float *) q->fft.complex[channel])[i] * gain;
1646 1617
}
1647 1618

  
1648 1619

  
......
1761 1732
    uint8_t *extradata;
1762 1733
    int extradata_size;
1763 1734
    int tmp_val, tmp, size;
1764
    int i;
1765
    float alpha;
1766 1735

  
1767 1736
    /* extradata parsing
1768 1737

  
......
1910 1879
    else
1911 1880
        s->coeff_per_sb_select = 2;
1912 1881

  
1913
    // Fail on unknown fft order, if it's > 9 it can overflow s->exptab[]
1882
    // Fail on unknown fft order
1914 1883
    if ((s->fft_order < 7) || (s->fft_order > 9)) {
1915 1884
        av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order);
1916 1885
        return -1;
1917 1886
    }
1918 1887

  
1919
    ff_fft_init(&s->fft_ctx, s->fft_order - 1, 1);
1920

  
1921
    for (i = 1; i < (1 << (s->fft_order - 2)); i++) {
1922
        alpha = 2 * M_PI * (float)i / (float)(1 << (s->fft_order - 1));
1923
        s->exptab[i].re = cos(alpha);
1924
        s->exptab[i].im = sin(alpha);
1925
    }
1888
    ff_rdft_init(&s->rdft_ctx, s->fft_order, IRDFT);
1926 1889

  
1927 1890
    qdm2_init(s);
1928 1891

  
......
1937 1900
{
1938 1901
    QDM2Context *s = avctx->priv_data;
1939 1902

  
1940
    ff_fft_end(&s->fft_ctx);
1903
    ff_rdft_end(&s->rdft_ctx);
1941 1904

  
1942 1905
    return 0;
1943 1906
}

Also available in: Unified diff