2 * liba52 sample by A'rpi/ESP-team
3 * Reads an AC-3 stream from stdin, decodes and downmixes to s16 stereo PCM
4 * and writes it to stdout. The resulting stream is playable with sox:
5 * play -c2 -r48000 -sw -fs out.sw
7 * Copyright (C) 2001 Árpád Gereöffy
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 //#define TIMING //needs Pentium or newer
33 #include "../cpudetect.h"
35 static a52_state_t
*state
;
36 static uint8_t buf
[3840];
37 static int buf_size
=0;
39 static int16_t out_buf
[6*256*6];
41 void mp_msg( int x
, const char *format
, ... ) // stub for cpudetect.c
46 static inline long long rdtsc()
49 asm volatile( "rdtsc\n\t"
52 // printf("%d\n", int(l/1000));
56 #define STARTTIMING t=rdtsc();
57 #define ENDTIMING sum+=rdtsc()-t; t=rdtsc();
69 long long t
, sum
=0, min
=256*256*256*64;
73 stdout
= stderr
; //EVIL HACK FIXME
74 GetCpuCaps(&gCpuCaps
);
78 if(gCpuCaps
.hasMMX
) accel
|= MM_ACCEL_X86_MMX
;
79 if(gCpuCaps
.hasMMX2
) accel
|= MM_ACCEL_X86_MMXEXT
;
80 if(gCpuCaps
.hasSSE
) accel
|= MM_ACCEL_X86_SSE
;
81 if(gCpuCaps
.has3DNow
) accel
|= MM_ACCEL_X86_3DNOW
;
82 // if(gCpuCaps.has3DNowExt) accel |= MM_ACCEL_X86_3DNOWEXT;
84 state
= a52_init (accel
);
86 fprintf (stderr
, "A52 init failed\n");
93 sample_t level
=1, bias
=384;
103 length
= a52_syncinfo (buf
, &flags
, &sample_rate
, &bit_rate
);
106 // bad file => resync
111 fprintf(stderr
,"sync. %d bytes 0x%X %d Hz %d kbit\n",length
,flags
,sample_rate
,bit_rate
);
112 while(buf_size
<length
){
113 buf
[buf_size
++]=getchar();
119 flags
=A52_STEREO
; //A52_STEREO; //A52_DOLBY; //A52_STEREO; // A52_DOLBY // A52_2F2R // A52_3F2R | A52_LFE
122 flags
|= A52_ADJUST_LEVEL
;
124 if (a52_frame (state
, buf
, &flags
, &level
, bias
))
125 { fprintf(stderr
,"error at decoding\n"); continue; }
128 // a52_dynrng (state, NULL, NULL); // disable dynamic range compensation
131 a52_resample_init(accel
,flags
,channels
);
133 for (i
= 0; i
< 6; i
++) {
134 if (a52_block (state
))
135 { fprintf(stderr
,"error at sampling\n"); break; }
136 // float->int + channels interleaving:
137 s16
+=a52_resample(a52_samples(state
),s16
);
144 fwrite(out_buf
,6*256*2*channels
,1,stdout
);
150 fprintf(stderr
, "%4.4fk cycles\n",min
/1000.0);