summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
authorMichael Giacomelli <giac2000@hotmail.com>2007-07-06 01:50:24 +0000
committerMichael Giacomelli <giac2000@hotmail.com>2007-07-06 01:50:24 +0000
commite0473717e5831fbf4adb7369ea6d6fdc122001dc (patch)
tree63d33e97dd8fc9a8f0ac63b79427e0abaadc8153 /apps/codecs
parent16b67e5812e8b6d5425864655c2825512709b538 (diff)
downloadrockbox-e0473717e5831fbf4adb7369ea6d6fdc122001dc.tar.gz
rockbox-e0473717e5831fbf4adb7369ea6d6fdc122001dc.zip
Merged in ffmpeg combined MDCT reconstruction. Saves us a 16KB buffer, and gives a nice speed increase. Brings code much closer to ffmpeg's.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13803 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/libwma/wmadeci.c177
1 files changed, 83 insertions, 94 deletions
diff --git a/apps/codecs/libwma/wmadeci.c b/apps/codecs/libwma/wmadeci.c
index e48720c043..0ad1a7b2a7 100644
--- a/apps/codecs/libwma/wmadeci.c
+++ b/apps/codecs/libwma/wmadeci.c
@@ -33,7 +33,7 @@ static inline
33void CMUL(fixed32 *x, fixed32 *y, 33void CMUL(fixed32 *x, fixed32 *y,
34 fixed32 a, fixed32 b, 34 fixed32 a, fixed32 b,
35 fixed32 t, fixed32 v) 35 fixed32 t, fixed32 v)
36{ 36{
37 /* This version loses one bit of precision. Could be solved at the cost 37 /* This version loses one bit of precision. Could be solved at the cost
38 * of 2 extra cycles if it becomes an issue. */ 38 * of 2 extra cycles if it becomes an issue. */
39 int x1, y1, l; 39 int x1, y1, l;
@@ -684,6 +684,78 @@ void ff_mdct_end(MDCTContext *s)
684 // fft_end(&s->fft); 684 // fft_end(&s->fft);
685} 685}
686 686
687/*
688 * Helper functions for wma_window.
689 * TODO: Optimize these to work with 1.31 format trig functions
690 * as was done for the MDCT rotation code
691 */
692
693static void vector_fmul_add_add(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, const fixed32 *src2, int src3, int len, int step){
694 int i;
695 for(i=0; i<len; i++)
696 dst[i*step] = fixmul32(src0[i], src1[i]) + src2[i] + src3;
697}
698
699static void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, int len){
700 int i;
701 src1 += len-1;
702 for(i=0; i<len; i++)
703 dst[i] = fixmul32(src0[i], src1[-i]);
704}
705
706/**
707 * Apply MDCT window and add into output.
708 *
709 * We ensure that when the windows overlap their squared sum
710 * is always 1 (MDCT reconstruction rule).
711 */
712 static void wma_window(WMADecodeContext *s, fixed32 *in, fixed32 *out)
713 {
714 //float *in = s->output;
715 int block_len, bsize, n;
716
717 /* left part */
718 if (s->block_len_bits <= s->prev_block_len_bits) {
719 block_len = s->block_len;
720 bsize = s->frame_len_bits - s->block_len_bits;
721
722 vector_fmul_add_add(out, in, s->windows[bsize],
723 out, 0, block_len, 1);
724
725 } else {
726 block_len = 1 << s->prev_block_len_bits;
727 n = (s->block_len - block_len) / 2;
728 bsize = s->frame_len_bits - s->prev_block_len_bits;
729
730 vector_fmul_add_add(out+n, in+n, s->windows[bsize],
731 out+n, 0, block_len, 1);
732
733 memcpy(out+n+block_len, in+n+block_len, n*sizeof(fixed32));
734 }
735
736 out += s->block_len;
737 in += s->block_len;
738
739 /* right part */
740 if (s->block_len_bits <= s->next_block_len_bits) {
741 block_len = s->block_len;
742 bsize = s->frame_len_bits - s->block_len_bits;
743
744 vector_fmul_reverse(out, in, s->windows[bsize], block_len);
745
746 } else {
747 block_len = 1 << s->next_block_len_bits;
748 n = (s->block_len - block_len) / 2;
749 bsize = s->frame_len_bits - s->next_block_len_bits;
750
751 memcpy(out, in, n*sizeof(fixed32));
752
753 vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len);
754
755 memset(out+n+block_len, 0, n*sizeof(fixed32));
756 }
757 }
758
687 759
688 760
689 761
@@ -1041,7 +1113,7 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx)
1041 for(j=0;j<n;++j) 1113 for(j=0;j<n;++j)
1042 { 1114 {
1043 fixed32 j2 = itofix32(j) + 0x8000; 1115 fixed32 j2 = itofix32(j) + 0x8000;
1044 window[n - j - 1] = fixsin32(fixmul32(j2,alpha)); //alpha between 0 and pi/2 1116 window[j] = fixsin32(fixmul32(j2,alpha)); //alpha between 0 and pi/2
1045 1117
1046 } 1118 }
1047 //printf("created window\n"); 1119 //printf("created window\n");
@@ -1326,11 +1398,9 @@ static int wma_decode_block(WMADecodeContext *s)
1326{ 1398{
1327 int n, v, a, ch, code, bsize; 1399 int n, v, a, ch, code, bsize;
1328 int coef_nb_bits, total_gain, parse_exponents; 1400 int coef_nb_bits, total_gain, parse_exponents;
1329 static fixed32 window[BLOCK_MAX_SIZE * 2]; //crap can't do this locally on the device! its big as the whole stack 1401 //static fixed32 window[BLOCK_MAX_SIZE * 2]; //crap can't do this locally on the device! its big as the whole stack
1330 int nb_coefs[MAX_CHANNELS]; 1402 int nb_coefs[MAX_CHANNELS];
1331 fixed32 mdct_norm; 1403 fixed32 mdct_norm;
1332//int filehandle = rb->open("/mul.txt", O_WRONLY|O_CREAT|O_APPEND);
1333// rb->fdprintf(filehandle,"\nIn wma_decode_block:\n use_variable_block_len %d\n nb_block_sizes %d\n reset_block_lengths %d\n", s->use_variable_block_len, s->nb_block_sizes, s->reset_block_lengths );
1334 1404
1335// printf("***decode_block: %d:%d (%d)\n", s->frame_count - 1, s->block_num, s->block_len); 1405// printf("***decode_block: %d:%d (%d)\n", s->frame_count - 1, s->block_num, s->block_len);
1336 /* compute current block length */ 1406 /* compute current block length */
@@ -1774,7 +1844,7 @@ static int wma_decode_block(WMADecodeContext *s)
1774 } 1844 }
1775 1845
1776 1846
1777//rb->splash(HZ, "in wma_decode_block 3b"); 1847
1778 if (s->ms_stereo && s->channel_coded[1]) 1848 if (s->ms_stereo && s->channel_coded[1])
1779 { 1849 {
1780 fixed32 a, b; 1850 fixed32 a, b;
@@ -1797,115 +1867,36 @@ static int wma_decode_block(WMADecodeContext *s)
1797 s->coefs[1][i] = a - b; 1867 s->coefs[1][i] = a - b;
1798 } 1868 }
1799 } 1869 }
1800//rb->splash(HZ, "in wma_decode_block 3c");
1801 /* build the window : we ensure that when the windows overlap
1802 their squared sum is always 1 (MDCT reconstruction rule) */
1803 /* XXX: merge with output */
1804 {
1805 int i, next_block_len, block_len, prev_block_len, n;
1806 fixed32 *wptr;
1807
1808 block_len = s->block_len;
1809 prev_block_len = 1 << s->prev_block_len_bits;
1810 next_block_len = 1 << s->next_block_len_bits;
1811 //rb->splash(HZ, "in wma_decode_block 3d"); //got here
1812 /* right part */
1813 wptr = window + block_len;
1814 if (block_len <= next_block_len)
1815 {
1816 for(i=0;i<block_len;++i)
1817 *wptr++ = s->windows[bsize][i];
1818 }
1819 else
1820 {
1821 /* overlap */
1822 n = (block_len / 2) - (next_block_len / 2);
1823 for(i=0;i<n;++i)
1824 *wptr++ = itofix32(1);
1825 for(i=0;i<next_block_len;++i)
1826 *wptr++ = s->windows[s->frame_len_bits - s->next_block_len_bits][i];
1827 for(i=0;i<n;++i)
1828 *wptr++ = 0;
1829 }
1830//rb->splash(HZ, "in wma_decode_block 3e");
1831 /* left part */
1832 wptr = window + block_len;
1833 if (block_len <= prev_block_len)
1834 {
1835 for(i=0;i<block_len;++i)
1836 *--wptr = s->windows[bsize][i];
1837 }
1838 else
1839 {
1840 /* overlap */
1841 n = (block_len / 2) - (prev_block_len / 2);
1842 for(i=0;i<n;++i)
1843 *--wptr = itofix32(1);
1844 for(i=0;i<prev_block_len;++i)
1845 *--wptr = s->windows[s->frame_len_bits - s->prev_block_len_bits][i];
1846 for(i=0;i<n;++i)
1847 *--wptr = 0;
1848 }
1849 }
1850
1851 1870
1852 for(ch = 0; ch < s->nb_channels; ++ch) 1871 for(ch = 0; ch < s->nb_channels; ++ch)
1853 { 1872 {
1854 if (s->channel_coded[ch]) 1873 if (s->channel_coded[ch])
1855 { 1874 {
1856 static fixed32 output[BLOCK_MAX_SIZE * 2]; 1875 static fixed32 output[BLOCK_MAX_SIZE * 2];
1857 fixed32 *ptr; 1876
1858 int i, n4, index, n; 1877 int n4, index, n;
1859 1878
1860 n = s->block_len; 1879 n = s->block_len;
1861 n4 = s->block_len >>1; 1880 n4 = s->block_len >>1;
1862 //rb->splash(HZ, "in wma_decode_block 4"); 1881
1863 ff_imdct_calc(&s->mdct_ctx[bsize], 1882 ff_imdct_calc(&s->mdct_ctx[bsize],
1864 output, 1883 output,
1865 s->coefs[ch], 1884 s->coefs[ch],
1866 s->mdct_tmp); 1885 s->mdct_tmp);
1867 1886
1868 /* XXX: optimize all that by build the window and
1869 multipying/adding at the same time */
1870 /* multiply by the window */
1871//already broken here!
1872
1873
1874
1875
1876
1877 for(i=0;i<n * 2;++i)
1878 {
1879
1880 output[i] = fixmul32(output[i], window[i]);
1881 //output[i] *= window[i];
1882
1883 }
1884
1885 1887
1886 /* add in the frame */ 1888 /* add in the frame */
1887 index = (s->frame_len / 2) + s->block_pos - n4; 1889 index = (s->frame_len / 2) + s->block_pos - n4;
1888 ptr = &s->frame_out[ch][index];
1889
1890 for(i=0;i<n * 2;++i)
1891 {
1892 *ptr += output[i];
1893 ++ptr;
1894 1890
1891 wma_window(s, output, &s->frame_out[ch][index]);
1895 1892
1896 }
1897 1893
1898 1894
1899 /* specific fast case for ms-stereo : add to second 1895 /* specific fast case for ms-stereo : add to second
1900 channel if it is not coded */ 1896 channel if it is not coded */
1901 if (s->ms_stereo && !s->channel_coded[1]) 1897 if (s->ms_stereo && !s->channel_coded[1])
1902 { 1898 {
1903 ptr = &s->frame_out[1][index]; 1899 wma_window(s, output, &s->frame_out[1][index]);
1904 for(i=0;i<n * 2;++i)
1905 {
1906 *ptr += output[i];
1907 ++ptr;
1908 }
1909 } 1900 }
1910 } 1901 }
1911 } 1902 }
@@ -1981,9 +1972,7 @@ static int wma_decode_frame(WMADecodeContext *s, int16_t *samples)
1981 /* prepare for next block */ 1972 /* prepare for next block */
1982 memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len], 1973 memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len],
1983 s->frame_len * sizeof(fixed32)); 1974 s->frame_len * sizeof(fixed32));
1984 /* XXX: suppress this */ 1975
1985 memset(&s->frame_out[ch][s->frame_len], 0,
1986 s->frame_len * sizeof(fixed32));
1987 } 1976 }
1988 1977
1989 return 0; 1978 return 0;