// liba52 sample by A'rpi/ESP-team // reads ac3 stream form stdin, decodes and downmix to s16 stereo pcm and // writes it to stdout. resulting stream playbackable with sox: // play -c 2 -r 48000 out.sw #include #include #include #include "a52.h" static sample_t * samples; static a52_state_t state; static uint8_t buf[3840]; static int buf_size=0; static int16_t out_buf[6*256*6]; static inline int16_t convert (int32_t i) { if (i > 0x43c07fff) return 32767; else if (i < 0x43bf8000) return -32768; else return i - 0x43c00000; } static inline void float_to_int (float * _f, int16_t * s16, int flags) { int i; int32_t * f = (int32_t *) _f; switch (flags) { case A52_MONO: for (i = 0; i < 256; i++) { s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; s16[5*i+4] = convert (f[i]); } break; case A52_CHANNEL: case A52_STEREO: case A52_DOLBY: for (i = 0; i < 256; i++) { s16[2*i] = convert (f[i]); s16[2*i+1] = convert (f[i+256]); } break; case A52_3F: for (i = 0; i < 256; i++) { s16[5*i] = convert (f[i]); s16[5*i+1] = convert (f[i+512]); s16[5*i+2] = s16[5*i+3] = 0; s16[5*i+4] = convert (f[i+256]); } break; case A52_2F2R: for (i = 0; i < 256; i++) { s16[4*i] = convert (f[i]); s16[4*i+1] = convert (f[i+256]); s16[4*i+2] = convert (f[i+512]); s16[4*i+3] = convert (f[i+768]); } break; case A52_3F2R: for (i = 0; i < 256; i++) { s16[5*i] = convert (f[i]); s16[5*i+1] = convert (f[i+512]); s16[5*i+2] = convert (f[i+768]); s16[5*i+3] = convert (f[i+1024]); s16[5*i+4] = convert (f[i+256]); } break; case A52_MONO | A52_LFE: for (i = 0; i < 256; i++) { s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; s16[6*i+4] = convert (f[i+256]); s16[6*i+5] = convert (f[i]); } break; case A52_CHANNEL | A52_LFE: case A52_STEREO | A52_LFE: case A52_DOLBY | A52_LFE: for (i = 0; i < 256; i++) { s16[6*i] = convert (f[i+256]); s16[6*i+1] = convert (f[i+512]); s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; s16[6*i+5] = convert (f[i]); } break; case A52_3F | A52_LFE: for (i = 0; i < 256; i++) { s16[6*i] = convert (f[i+256]); s16[6*i+1] = convert (f[i+768]); s16[6*i+2] = s16[6*i+3] = 0; s16[6*i+4] = convert (f[i+512]); s16[6*i+5] = convert (f[i]); } break; case A52_2F2R | A52_LFE: for (i = 0; i < 256; i++) { s16[6*i] = convert (f[i+256]); s16[6*i+1] = convert (f[i+512]); s16[6*i+2] = convert (f[i+768]); s16[6*i+3] = convert (f[i+1024]); s16[6*i+4] = 0; s16[6*i+5] = convert (f[i]); } break; case A52_3F2R | A52_LFE: for (i = 0; i < 256; i++) { s16[6*i] = convert (f[i+256]); s16[6*i+1] = convert (f[i+768]); s16[6*i+2] = convert (f[i+1024]); s16[6*i+3] = convert (f[i+1280]); s16[6*i+4] = convert (f[i+512]); s16[6*i+5] = convert (f[i]); } break; } } int main(){ int accel=0; int sample_rate=0; int bit_rate=0; samples = a52_init (accel); if (samples == NULL) { fprintf (stderr, "A52 init failed\n"); return 1; } while(1){ int length,i; int16_t *s16; sample_t level=1, bias=384; int flags=0; while(buf_size<7){ int c=getchar(); if(c<0) goto eof; buf[buf_size++]=c; } length = a52_syncinfo (buf, &flags, &sample_rate, &bit_rate); if(!length){ // bad file => resync memcpy(buf,buf+1,6); --buf_size; continue; } fprintf(stderr,"sync. %d bytes 0x%X %d Hz %d kbit\n",length,flags,sample_rate,bit_rate); while(buf_size