コード例 #1
0
ファイル: ac3.c プロジェクト: ratopi/CinelerraCV
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;
}
コード例 #2
0
ファイル: liba52_dec.c プロジェクト: bigbensk/gpac
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;
}
コード例 #3
0
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);
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: a52.c プロジェクト: ifroz/rockbox
/* 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(&param);

        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;
}
コード例 #6
0
ファイル: gsta52dec.c プロジェクト: zsx/ossbuild
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;
}
コード例 #7
0
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;
}
コード例 #8
0
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;
    }
}
コード例 #9
0
ファイル: a52tofloat32.c プロジェクト: cobr123/qtVlc
/*****************************************************************************
 * 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;
}
コード例 #10
0
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;
}
コード例 #11
0
ファイル: a52.c プロジェクト: claymodel/rockbox
/* 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;
}
コード例 #12
0
ファイル: a52_rm.c プロジェクト: 4nykey/rockbox
/* 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(&param);

        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;
}