mpeg3_ac3_t* mpeg3_new_ac3() { mpeg3_ac3_t *result = calloc(1, sizeof(mpeg3_ac3_t)); result->stream = mpeg3bits_new_stream(0, 0); #ifdef A52_INIT_NEEDS_ARG result->state = a52_init(0); #else result->state = a52_init(); #endif result->output = a52_samples(result->state); return result; }
static GF_Err AC3_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { A52CTX(); if (ctx->ES_ID && ctx->ES_ID!=esd->ESID) return GF_NOT_SUPPORTED; GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[A52] Attaching stream %d\n", esd->ESID)); if (ctx->codec) a52_free(ctx->codec); ctx->codec = a52_init(MM_ACCEL_DJBFFT); if (!ctx->codec) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[A52] Error initializing decoder\n")); return GF_IO_ERR; } ctx->samples = a52_samples(ctx->codec); if (!ctx->samples) { a52_free(ctx->codec); GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[A52] Error initializing decoder\n")); return GF_IO_ERR; } ctx->num_channels = 0; ctx->sample_rate = 0; ctx->out_size = 0; ctx->num_samples = 1536; ctx->ES_ID = esd->ESID; return GF_OK; }
ADM_AudiocodecAC3::ADM_AudiocodecAC3( uint32_t fourcc, WAVHeader *info,uint32_t extraLength,uint8_t *extraData) : ADM_Audiocodec(fourcc) { int flags=0; ADM_assert(fourcc==WAV_AC3); ac3_handle=NULL; ac3_sample=NULL; #ifdef ADM_CPU_X86 #define CHK(x,y) if(CpuCaps::has##x()) flags|=MM_ACCEL_X86_##y; CHK(MMX,MMX); CHK(3DNOW,3DNOW); CHK(MMXEXT,MMXEXT); #endif ac3_handle=(void *)a52_init(flags); if(!ac3_handle) { printf("Cannot init a52\n"); ADM_assert(0); } ac3_sample=(sample_t *)a52_samples(AC3_HANDLE); if(!ac3_sample) { printf("Cannot init a52 sample\n"); ADM_assert(0); } _downmix=0; _wavHeader = info; ADM_assert(_wavHeader); }
static int liba52_init(adec_feeder_t * feeder) { uint32_t a52_accel = 0; int flags = 0; c_feeder = feeder; if (feeder == NULL) return -1; memset(&a52_buffer, 0, sizeof(a52_buffer)); a52_buffer.a_in_buffer = frame_buffer; a52_state = a52_init(a52_accel); if (a52_state == NULL) { printf("A52 init failed !\n"); return -1; } if (a52_fillbuff(&a52_buffer) < 0) { printf("A52 sync failed !\n"); return -1; } a52_buffer.channels = audio_output_channels; switch (a52_buffer.channels) { case 1: a52_flags = A52_MONO; break; /*case 2: a52_flags=A52_STEREO; break; */ case 2: a52_flags = A52_DOLBY; break; /*case 3: a52_flags=A52_3F; break; */ case 3: a52_flags = A52_2F1R; break; case 4: a52_flags = A52_2F2R; break; /* 2+2 */ case 5: a52_flags = A52_3F2R; break; case 6: a52_flags = A52_3F2R | A52_LFE; break; /* 5.1 */ } flags |= a52_flags; if (a52_resample_init(a52_accel, flags, a52_buffer.channels) < 0) { printf("a52_resample_init failed!\n"); a52_free(a52_state); return -1; } feeder->channel_num = audio_output_channels; feeder->sample_rate = a52_buffer.samplerate; return 0; }
/* this is called for each file to process */ enum codec_status codec_run(void) { size_t n; unsigned char *filebuf; int sample_loc; intptr_t param; if (codec_init()) return CODEC_ERROR; ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); codec_set_replaygain(ci->id3); /* Intialise the A52 decoder and check for success */ state = a52_init(0); samplesdone = 0; /* The main decoding loop */ if (ci->id3->offset) { if (ci->seek_buffer(ci->id3->offset)) { samplesdone = (ci->id3->offset / ci->id3->bytesperframe) * A52_SAMPLESPERFRAME; ci->set_elapsed(samplesdone/(ci->id3->frequency / 1000)); } } else { ci->seek_buffer(ci->id3->first_frame_offset); ci->set_elapsed(0); } while (1) { enum codec_command_action action = ci->get_command(¶m); if (action == CODEC_ACTION_HALT) break; if (action == CODEC_ACTION_SEEK_TIME) { sample_loc = param/1000 * ci->id3->frequency; if (ci->seek_buffer((sample_loc/A52_SAMPLESPERFRAME)*ci->id3->bytesperframe)) { samplesdone = sample_loc; ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); } ci->seek_complete(); } filebuf = ci->request_buffer(&n, BUFFER_SIZE); if (n == 0) /* End of Stream */ break; a52_decode_data(filebuf, filebuf + n); ci->advance_buffer(n); } return CODEC_OK; }
static GstStateChangeReturn gst_a52dec_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstA52Dec *a52dec = GST_A52DEC (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY:{ GstA52DecClass *klass; klass = GST_A52DEC_CLASS (G_OBJECT_GET_CLASS (a52dec)); a52dec->state = a52_init (klass->a52_cpuflags); break; } case GST_STATE_CHANGE_READY_TO_PAUSED: a52dec->samples = a52_samples (a52dec->state); a52dec->bit_rate = -1; a52dec->sample_rate = -1; a52dec->stream_channels = A52_CHANNEL; a52dec->using_channels = A52_CHANNEL; a52dec->level = 1; a52dec->bias = 0; a52dec->time = 0; a52dec->sent_segment = FALSE; a52dec->flag_update = TRUE; gst_segment_init (&a52dec->segment, GST_FORMAT_UNDEFINED); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: a52dec->samples = NULL; if (a52dec->cache) { gst_buffer_unref (a52dec->cache); a52dec->cache = NULL; } clear_queued (a52dec); break; case GST_STATE_CHANGE_READY_TO_NULL: a52_free (a52dec->state); a52dec->state = NULL; break; default: break; } return ret; }
static gboolean gst_a52dec_start (GstAudioDecoder * dec) { GstA52Dec *a52dec = GST_A52DEC (dec); GstA52DecClass *klass; GST_DEBUG_OBJECT (dec, "start"); klass = GST_A52DEC_CLASS (G_OBJECT_GET_CLASS (a52dec)); #if defined(A52_ACCEL_DETECT) a52dec->state = a52_init (); /* This line is just to avoid being accused of not using klass */ a52_accel (klass->a52_cpuflags & A52_ACCEL_DETECT); #else a52dec->state = a52_init (klass->a52_cpuflags); #endif if (!a52dec->state) { GST_ELEMENT_ERROR (GST_ELEMENT (a52dec), LIBRARY, INIT, (NULL), ("failed to initialize a52 state")); return FALSE; } a52dec->samples = a52_samples (a52dec->state); a52dec->bit_rate = -1; a52dec->sample_rate = -1; a52dec->stream_channels = A52_CHANNEL; a52dec->using_channels = A52_CHANNEL; a52dec->level = 1; a52dec->bias = 0; a52dec->flag_update = TRUE; /* call upon legacy upstream byte support (e.g. seeking) */ gst_audio_decoder_set_estimate_rate (dec, TRUE); return TRUE; }
bool TaudioCodecLiba52::init(const CMediaType &mt) { dll=new Tdll(dllname,config); dll->loadFunction(a52_init,"a52_init"); dll->loadFunction(a52_samples,"a52_samples"); dll->loadFunction(a52_syncinfo,"a52_syncinfo"); dll->loadFunction(a52_dynrng,"a52_dynrng"); dll->loadFunction(a52_dynrngsetlevel,"a52_dynrngsetlevel"); dll->loadFunction(a52_frame,"a52_frame"); dll->loadFunction(a52_block,"a52_block"); dll->loadFunction(a52_free,"a52_free"); if (dll->ok) { state=a52_init(Tconfig::cpu_flags); fmt.sf=TsampleFormat::SF_FLOAT32; inited=true; return true; } else { return false; } }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this, filter_sys_t *p_sys, audio_format_t input, audio_format_t output ) { p_sys->b_dynrng = var_InheritBool( p_this, "a52-dynrng" ); p_sys->b_dontwarn = 0; /* No upmixing: it's not necessary and some other filters may want to do * it themselves. */ if ( aout_FormatNbChannels( &output ) > aout_FormatNbChannels( &input ) ) { if ( ! var_InheritBool( p_this, "a52-upmix" ) ) { return VLC_EGENERIC; } } /* We'll do our own downmixing, thanks. */ p_sys->i_nb_channels = aout_FormatNbChannels( &output ); switch ( (output.i_physical_channels & AOUT_CHAN_PHYSMASK) & ~AOUT_CHAN_LFE ) { case AOUT_CHAN_CENTER: if ( (output.i_original_channels & AOUT_CHAN_CENTER) || (output.i_original_channels & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) ) { p_sys->i_flags = A52_MONO; } else if ( output.i_original_channels & AOUT_CHAN_LEFT ) { p_sys->i_flags = A52_CHANNEL1; } else { p_sys->i_flags = A52_CHANNEL2; } break; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT: if ( output.i_original_channels & AOUT_CHAN_DOLBYSTEREO ) { p_sys->i_flags = A52_DOLBY; } else if ( input.i_original_channels == AOUT_CHAN_CENTER ) { p_sys->i_flags = A52_MONO; } else if ( input.i_original_channels & AOUT_CHAN_DUALMONO ) { p_sys->i_flags = A52_CHANNEL; } else if ( !(output.i_original_channels & AOUT_CHAN_RIGHT) ) { p_sys->i_flags = A52_CHANNEL1; } else if ( !(output.i_original_channels & AOUT_CHAN_LEFT) ) { p_sys->i_flags = A52_CHANNEL2; } else { p_sys->i_flags = A52_STEREO; } break; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER: p_sys->i_flags = A52_3F; break; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER: p_sys->i_flags = A52_2F1R; break; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER: p_sys->i_flags = A52_3F1R; break; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT: p_sys->i_flags = A52_2F2R; break; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT: p_sys->i_flags = A52_3F2R; break; default: msg_Warn( p_this, "unknown sample format!" ); free( p_sys ); return VLC_EGENERIC; } if ( output.i_physical_channels & AOUT_CHAN_LFE ) { p_sys->i_flags |= A52_LFE; } p_sys->i_flags |= A52_ADJUST_LEVEL; /* Initialize liba52 */ p_sys->p_liba52 = a52_init( 0 ); if( p_sys->p_liba52 == NULL ) { msg_Err( p_this, "unable to initialize liba52" ); free( p_sys ); return VLC_EGENERIC; } aout_CheckChannelReorder( pi_channels_in, NULL, output.i_physical_channels & AOUT_CHAN_PHYSMASK, p_sys->i_nb_channels, p_sys->pi_chan_table ); return VLC_SUCCESS; }
static int init(sh_audio_t *sh_audio) { uint32_t a52_accel=0; sample_t level=a52_level, bias=384; int flags=0; /* Dolby AC3 audio:*/ #ifdef MM_ACCEL_X86_SSE if(gCpuCaps.hasSSE) a52_accel|=MM_ACCEL_X86_SSE; #endif if(gCpuCaps.hasMMX) a52_accel|=MM_ACCEL_X86_MMX; if(gCpuCaps.hasMMX2) a52_accel|=MM_ACCEL_X86_MMXEXT; if(gCpuCaps.has3DNow) a52_accel|=MM_ACCEL_X86_3DNOW; #ifdef MM_ACCEL_X86_3DNOWEXT if(gCpuCaps.has3DNowExt) a52_accel|=MM_ACCEL_X86_3DNOWEXT; #endif #ifdef MM_ACCEL_PPC_ALTIVEC if(gCpuCaps.hasAltiVec) a52_accel|=MM_ACCEL_PPC_ALTIVEC; #endif a52_state=a52_init (a52_accel); if (a52_state == NULL) { mp_msg(MSGT_DECAUDIO,MSGL_ERR,"A52 init failed\n"); return 0; } sh_audio->sample_format = AF_FORMAT_FLOAT_NE; if(a52_fillbuff(sh_audio)<0){ mp_msg(MSGT_DECAUDIO,MSGL_ERR,"A52 sync failed\n"); return 0; } /* Init a52 dynrng */ if (drc_level < 0.001) { /* level == 0 --> no compression, init library without callback */ a52_drc_action = DRC_NO_COMPRESSION; } else if (drc_level > 0.999) { /* level == 1 --> full compression, do nothing at all (library default = full compression) */ a52_drc_action = DRC_NO_ACTION; } else { a52_drc_action = DRC_CALLBACK; } /* Library init for dynrng has to be done for each frame, see decode_audio() */ /* 'a52 cannot upmix' hotfix:*/ a52_printinfo(sh_audio); sh_audio->channels=audio_output_channels; while(sh_audio->channels>0){ switch(sh_audio->channels){ case 1: a52_flags=A52_MONO; break; /* case 2: a52_flags=A52_STEREO; break;*/ case 2: a52_flags=A52_DOLBY; break; /* case 3: a52_flags=A52_3F; break;*/ case 3: a52_flags=A52_2F1R; break; case 4: a52_flags=A52_2F2R; break; /* 2+2*/ case 5: a52_flags=A52_3F2R; break; case 6: a52_flags=A52_3F2R|A52_LFE; break; /* 5.1*/ } /* test:*/ flags=a52_flags|A52_ADJUST_LEVEL; mp_msg(MSGT_DECAUDIO,MSGL_V,"A52 flags before a52_frame: 0x%X\n",flags); if (a52_frame (a52_state, sh_audio->a_in_buffer, &flags, &level, bias)){ mp_msg(MSGT_DECAUDIO,MSGL_ERR,"a52: error decoding frame -> nosound\n"); return 0; } mp_msg(MSGT_DECAUDIO,MSGL_V,"A52 flags after a52_frame: 0x%X\n",flags); /* frame decoded, let's init resampler:*/ channel_map = 0; if (sh_audio->sample_format == AF_FORMAT_FLOAT_NE) { if (!(flags & A52_LFE)) { switch ((flags<<3) | sh_audio->channels) { case (A52_MONO << 3) | 1: channel_map = 0x1; break; case (A52_CHANNEL << 3) | 2: case (A52_STEREO << 3) | 2: case (A52_DOLBY << 3) | 2: channel_map = 0x21; break; case (A52_2F1R << 3) | 3: channel_map = 0x321; break; case (A52_2F2R << 3) | 4: channel_map = 0x4321; break; case (A52_3F << 3) | 5: channel_map = 0x2ff31; break; case (A52_3F2R << 3) | 5: channel_map = 0x25431; break; } } else if (sh_audio->channels == 6) { switch (flags & ~A52_LFE) { case A52_MONO : channel_map = 0x12ffff; break; case A52_CHANNEL: case A52_STEREO : case A52_DOLBY : channel_map = 0x1fff32; break; case A52_3F : channel_map = 0x13ff42; break; case A52_2F1R : channel_map = 0x1f4432; break; case A52_2F2R : channel_map = 0x1f5432; break; case A52_3F2R : channel_map = 0x136542; break; } } if (channel_map) { a52_resample = a52_resample_float; break; } } else break; } if(sh_audio->channels<=0){ mp_msg(MSGT_DECAUDIO,MSGL_ERR,"a52: no resampler. try different channel setup!\n"); return 0; } return 1; }
/* this is the codec entry point */ enum codec_status codec_main(void) { size_t n; unsigned char *filebuf; int sample_loc; int retval; /* Generic codec initialisation */ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); ci->configure(DSP_SET_SAMPLE_DEPTH, 28); next_track: retval = CODEC_OK; if (codec_init()) { retval = CODEC_ERROR; goto exit; } if (codec_wait_taginfo() != 0) goto request_next_track; ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); codec_set_replaygain(ci->id3); /* Intialise the A52 decoder and check for success */ state = a52_init(0); /* The main decoding loop */ if (ci->id3->offset) { if (ci->seek_buffer(ci->id3->offset)) { samplesdone = (ci->id3->offset / ci->id3->bytesperframe) * A52_SAMPLESPERFRAME; ci->set_elapsed(samplesdone/(ci->id3->frequency / 1000)); } } else { samplesdone = 0; } while (1) { if (ci->stop_codec || ci->new_track) break; if (ci->seek_time) { sample_loc = (ci->seek_time - 1)/1000 * ci->id3->frequency; if (ci->seek_buffer((sample_loc/A52_SAMPLESPERFRAME)*ci->id3->bytesperframe)) { samplesdone = sample_loc; ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); } ci->seek_complete(); } filebuf = ci->request_buffer(&n, BUFFER_SIZE); if (n == 0) /* End of Stream */ break; a52_decode_data(filebuf, filebuf + n); ci->advance_buffer(n); } request_next_track: if (ci->request_next_track()) goto next_track; exit: a52_free(state); return retval; }
/* this is called for each file to process */ enum codec_status codec_run(void) { size_t n; uint8_t *filebuf; int consumed, packet_offset; int playback_on = -1; size_t resume_offset; intptr_t param; enum codec_command_action action = CODEC_ACTION_NULL; if (codec_init()) { return CODEC_ERROR; } resume_offset = ci->id3->offset; ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); codec_set_replaygain(ci->id3); ci->seek_buffer(ci->id3->first_frame_offset); /* Intializations */ state = a52_init(0); ci->memset(&rmctx,0,sizeof(RMContext)); ci->memset(&pkt,0,sizeof(RMPacket)); init_rm(&rmctx); samplesdone = 0; /* check for a mid-track resume and force a seek time accordingly */ if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; /* put number of subpackets to skip in resume_offset */ resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); action = CODEC_ACTION_SEEK_TIME; } else { /* Seek to the first packet */ ci->set_elapsed(0); ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE ); } /* The main decoding loop */ while((unsigned)rmctx.audio_pkt_cnt < rmctx.nb_packets) { if (action == CODEC_ACTION_NULL) action = ci->get_command(¶m); if (action == CODEC_ACTION_HALT) break; if (action == CODEC_ACTION_SEEK_TIME) { packet_offset = param / ((rmctx.block_align*8*1000)/rmctx.bit_rate); ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + packet_offset*(rmctx.block_align + PACKET_HEADER_SIZE)); rmctx.audio_pkt_cnt = packet_offset; samplesdone = (rmctx.sample_rate/1000 * param); ci->set_elapsed(samplesdone/(frequency/1000)); ci->seek_complete(); } action = CODEC_ACTION_NULL; filebuf = ci->request_buffer(&n, rmctx.block_align + PACKET_HEADER_SIZE); consumed = rm_get_packet(&filebuf, &rmctx, &pkt); if(consumed < 0 && playback_on != 0) { if(playback_on == -1) { /* Error only if packet-parsing failed and playback hadn't started */ DEBUGF("rm_get_packet failed\n"); return CODEC_ERROR; } else { break; } } playback_on = 1; a52_decode_data(filebuf, filebuf + rmctx.block_align); ci->advance_buffer(pkt.length); } return CODEC_OK; }