/* * playerd_tables * copyright (c) 2009 AVM (and FFMPEG) * * This file is mainly extracted from FFmpeg. * * playerd_tables is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * playerd_tables is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define AVM_FFMPEG #define AVM_FFMPEG_SYNC_LOOKAHEAD #define AVM_FFMPEG_PURE_MEMORYMGNT #define AVM_FFMPEG_REMOVE_UNNEEDED #define AVM_FFMPEG_NO_LAYER25 #define AVM_FFMPEG_NO_FREEFORMAT //#define CONFIG_MPEGAUDIO_HP #define CONFIG_AUDIO_NONSHORT #define _ISOC9X_SOURCE 1 #include #include #include #include #include #include #include #include #include #include #include #include #include "avformat.h" // Okay - C-Files included man eigentlich nicht, aber ffmpeg legt die Tables die hier vorberechnet werden sollen leider nur dort ab. // Man könnte den Code zwar jetzt auch hierhin kopieren, aber wenn sich die Tabellen mal ändern, dann bekommen wir das zu spät mit, // was für mich Grund genug ist hier das C-File zu includen. #include "mpegaudiodec.c" void calc_tables (void) { int i, j, k; for(i=0;i<64;i++) { int shift, mod; /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */ shift = (i / 3); mod = i % 3; scale_factor_modshift[i] = mod | (shift << 2); } /* scale factor multiply for layer 1 */ for(i=0;i<15;i++) { int n, norm; n = i + 2; norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1); scale_factor_mult[i][0] = MULL(FIXR(1.0 * 2.0), norm); scale_factor_mult[i][1] = MULL(FIXR(0.7937005259 * 2.0), norm); scale_factor_mult[i][2] = MULL(FIXR(0.6299605249 * 2.0), norm); } ff_mpa_synth_init(window); /* huffman decode tables */ for(i=1;i<16;i++) { const HuffTable *h = &mpa_huff_tables[i]; int xsize, x, y; unsigned int __attribute__ ((unused)) n; uint8_t tmp_bits [512]; uint16_t tmp_codes[512]; memset(tmp_bits , 0, sizeof(tmp_bits )); memset(tmp_codes, 0, sizeof(tmp_codes)); xsize = h->xsize; n = xsize * xsize; /* <-- unused?!? */ j = 0; for(x=0;xbits [j ]; tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++]; } } /* XXX: fail test */ init_vlc(&huff_vlc[i], 7, 512, tmp_bits, 1, 1, tmp_codes, 2, 2, 1); } for(i=0;i<2;i++) { init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16, mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1, 1); } for(i=0;i<9;i++) { k = 0; for(j=0;j<22;j++) { band_index_long[i][j] = k; k += band_size_long[i][j]; } band_index_long[i][22] = k; } /* compute n ^ (4/3) and store it in mantissa/exp format */ int_pow_init(); for(i=1;i>4); double f= pow(i&15, 4.0 / 3.0) * pow(2, (exponent-400)*0.25 + FRAC_BITS + 5); expval_table[exponent][i&15]= llrint(f); if((i&15)==1) exp_table[exponent]= llrint(f); } for(i=0;i<7;i++) { float f; int v; if (i != 6) { f = tan((double)i * M_PI / 12.0); v = FIXR(f / (1.0 + f)); } else { v = FIXR(1.0); } is_table[0][i] = v; is_table[1][6 - i] = v; } /* invalid values */ for(i=7;i<16;i++) is_table[0][i] = is_table[1][i] = 0.0; for(i=0;i<16;i++) { double f; int e, k; for(j=0;j<2;j++) { e = -(j + 1) * ((i + 1) >> 1); f = pow(2.0, e / 4.0); k = i & 1; is_table_lsf[j][k ^ 1][i] = FIXR(f); is_table_lsf[j][k][i] = FIXR(1.0); //dprintf(avctx, "is_table_lsf %d %d: %x %x\n", // i, j, is_table_lsf[j][0][i], is_table_lsf[j][1][i]); } } for(i=0;i<8;i++) { float ci, cs, ca; ci = ci_table[i]; cs = 1.0 / sqrt(1.0 + ci * ci); ca = cs * ci; csa_table[i][0] = FIXHR(cs/4); csa_table[i][1] = FIXHR(ca/4); csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4); csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4); csa_table_float[i][0] = cs; csa_table_float[i][1] = ca; csa_table_float[i][2] = ca + cs; csa_table_float[i][3] = ca - cs; // printf("%d %d %d %d\n", FIX(cs), FIX(cs-1), FIX(ca), FIX(cs)-FIX(ca)); // av_log(NULL, AV_LOG_DEBUG,"%f %f %f %f\n", cs, ca, ca+cs, ca-cs); } /* compute mdct windows */ for(i=0;i<36;i++) { for(j=0; j<4; j++){ double d; if(j==2 && i%3 != 1) continue; d= sin(M_PI * (i + 0.5) / 36.0); if(j==1){ if (i>=30) d= 0; else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0); else if(i>=18) d= 1; }else if(j==3){ if (i< 6) d= 0; else if(i< 12) d= sin(M_PI * (i - 6 + 0.5) / 12.0); else if(i< 18) d= 1; } //merge last stage of imdct into the window coefficients d*= 0.5 / cos(M_PI*(2*i + 19)/72); if(j==2) mdct_win[j][i/3] = FIXHR((d / (1<<5))); else mdct_win[j][i ] = FIXHR((d / (1<<5))); // av_log(NULL, AV_LOG_DEBUG, "%2d %d %f\n", i,j,d / (1<<5)); } } /* NOTE: we do frequency inversion adter the MDCT by changing the sign of the right window coefs */ for(j=0;j<4;j++) { for(i=0;i<36;i+=2) { mdct_win[j + 4][i] = mdct_win[j][i]; mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1]; } } } #define WRITE(type) fret += (write (fd, type, sizeof (type)) == sizeof (type)) #define WRITE_CHECK fret += (write (fd, &check, sizeof (int)) == sizeof (int)) int main (int argc, char ** argv) { unsigned fret = 0; int check = 0xbeadface; int fd; signal (SIGHUP, SIG_IGN); signal (SIGRTMIN, SIG_IGN); signal (SIGTTOU, SIG_IGN); signal (SIGPIPE, SIG_IGN); signal (SIGINT, SIG_IGN); signal (SIGTERM, SIG_IGN); fprintf (stderr, "playerd_tables, init\n"); /* testing!!! */ /* exklusives Oeffnen, weil das Programm ggf parallel gestartet worden ist */ fd = open ("/var/tmp/ffmpeg_mp3.tables.part", O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { fprintf (stderr, "playerd_tables, failed to open /var/tmp/ffmpeg_mp3.tables.part, err: %u\n", errno); return -1; } avcodec_init(); av_register_all(); calc_tables(); WRITE (table_4_3_value); WRITE_CHECK; WRITE (table_4_3_exp); WRITE_CHECK; WRITE (expval_table); WRITE_CHECK; WRITE (exp_table); WRITE_CHECK; WRITE (is_table); WRITE_CHECK; WRITE (is_table_lsf); WRITE_CHECK; WRITE (csa_table); WRITE_CHECK; WRITE (csa_table_float); WRITE_CHECK; WRITE (mdct_win); close (fd); if (fret != 17) { fprintf (stderr, "playerd_tables, write failed, rm /var/tmp_ffmpeg_mp3.tables.part!\n"); unlink ("/var/tmp/ffmpeg_mp3.tables.part"); return -2; } if (rename ("/var/tmp/ffmpeg_mp3.tables.part", "/var/tmp/ffmpeg_mp3.tables") == -1) { fprintf (stderr, "playerd_tables, rename failed, errno %u, rm /var/tmp_ffmpeg_mp3.tables.part!\n", errno); unlink ("/var/tmp/ffmpeg_mp3.tables.part"); return -2; } fprintf (stderr, "playerd_tables, /var/tmp_ffmpeg_mp3.tables written\n"); /* testing!!! */ return 0; }