示例#1
0
文件: block.c 项目: svn2github/sdljy
static void _preextrapolate_helper(vorbis_dsp_state *v) {
    int i;
    int order=32;
    float *lpc=(float *)alloca(order*sizeof(*lpc));
    float *work=(float *)alloca(v->pcm_current*sizeof(*work));
    long j;
    v->preextrapolate=1;

    if(v->pcm_current-v->centerW>order*2) { /* safety */
        for(i=0; i<v->vi->channels; i++) {
            /* need to run the extrapolation in reverse! */
            for(j=0; j<v->pcm_current; j++)
                work[j]=v->pcm[i][v->pcm_current-j-1];

            /* prime as above */
            vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);

            /* run the predictor filter */
            vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
                               order,
                               work+v->pcm_current-v->centerW,
                               v->centerW);

            for(j=0; j<v->pcm_current; j++)
                v->pcm[i][v->pcm_current-j-1]=work[j];

        }
    }
}
示例#2
0
void CoreAudioPaddedEncoder::extrapolate(float *input, size_t ilen,
                                         float *output, size_t olen)
{
    unsigned n = getInputDescription().mChannelsPerFrame;
    float lpc[LPC_ORDER];
    for (unsigned i = 0; i < n; ++i) {
        vorbis_lpc_from_data(input + i, lpc, ilen, LPC_ORDER, n);
        vorbis_lpc_predict(lpc, &input[i + n * (ilen - LPC_ORDER)],
                           LPC_ORDER, output + i, olen, n);
    }
}
示例#3
0
static int extrapolate(extrapolater_t *self, const buffer_t *bp,
                        void *dst, unsigned nframes)
{
    const pcm_sample_description_t *sfmt = pcm_get_format(self->src);
    unsigned i, n = sfmt->channels_per_frame;
    float lpc[LPC_ORDER];

    for (i = 0; i < n; ++i) {
        vorbis_lpc_from_data(bp->data + i, lpc, bp->count, LPC_ORDER, n);
        vorbis_lpc_predict(lpc, &bp->data[i + n * (bp->count - LPC_ORDER)],
                           LPC_ORDER, (sample_t*)dst + i, nframes, n);
    }
    return nframes;
}
示例#4
0
static void _preextrapolate_helper( vorbis_dsp_state *v )
{
    int i;
    int order = 16;
    float *lpc = alloca( order * sizeof( *lpc ) );
    float *work = alloca( v->pcm_current * sizeof( *work ) );
    long j;
    v->preextrapolate = 1;

    if ( v->pcm_current - v->centerW > order*2 )
    {
        /* safety */
        for ( i = 0;i < v->vi->channels;i++ )
        {
            /* need to run the extrapolation in reverse! */
            for ( j = 0;j < v->pcm_current;j++ )
                work[j] = v->pcm[i][v->pcm_current-j-1];

            /* prime as above */
            vorbis_lpc_from_data( work, lpc, v->pcm_current - v->centerW, order );

#if 0
            if ( v->vi->channels == 2 )
            {
                if ( i == 0 )
                    _analysis_output( "predataL", 0, work, v->pcm_current - v->centerW, 0, 0, 0 );
                else
                    _analysis_output( "predataR", 0, work, v->pcm_current - v->centerW, 0, 0, 0 );
            }
            else
            {
                _analysis_output( "predata", 0, work, v->pcm_current - v->centerW, 0, 0, 0 );
            }
#endif

            /* run the predictor filter */
            vorbis_lpc_predict( lpc, work + v->pcm_current - v->centerW - order,
                                order,
                                work + v->pcm_current - v->centerW,
                                v->centerW );

            for ( j = 0;j < v->pcm_current;j++ )
                v->pcm[i][v->pcm_current-j-1] = work[j];

        }
    }
}
示例#5
0
文件: block.c 项目: denjones/spengine
int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
  vorbis_info *vi=v->vi;
  codec_setup_info *ci=vi->codec_setup;

  if(vals<=0){
    int order=32;
    int i;
    float *lpc=alloca(order*sizeof(*lpc));

    /* if it wasn't done earlier (very short sample) */
    if(!v->preextrapolate)
      _preextrapolate_helper(v);

    /* We're encoding the end of the stream.  Just make sure we have
       [at least] a few full blocks of zeroes at the end. */
    /* actually, we don't want zeroes; that could drop a large
       amplitude off a cliff, creating spread spectrum noise that will
       suck to encode.  Extrapolate for the sake of cleanliness. */

    vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
    v->eofflag=v->pcm_current;
    v->pcm_current+=ci->blocksizes[1]*3;

    for(i=0;i<vi->channels;i++){
      if(v->eofflag>order*2){
        /* extrapolate with LPC to fill in */
        long n;

        /* make a predictor filter */
        n=v->eofflag;
        if(n>ci->blocksizes[1])n=ci->blocksizes[1];
        vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);

        /* run the predictor filter */
        vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
                           v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
      }else{
        /* not enough data to extrapolate (unlikely to happen due to
           guarding the overlap, but bulletproof in case that
           assumtion goes away). zeroes will do. */
        memset(v->pcm[i]+v->eofflag,0,
               (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));

      }
    }
  }else{

    if(v->pcm_current+vals>v->pcm_storage)
      return(OV_EINVAL);

    v->pcm_current+=vals;

    /* we may want to reverse extrapolate the beginning of a stream
       too... in case we're beginning on a cliff! */
    /* clumsy, but simple.  It only runs once, so simple is good. */
    if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
      _preextrapolate_helper(v);

  }
  return(0);
}
示例#6
0
void dumb_it_add_lpc(struct DUMB_IT_SIGDATA *sigdata){
    float lpc[lpc_order * 2];
    float lpc_input[lpc_max * 2];
    float lpc_output[lpc_extra * 2];

    signed char * s8;
    signed short * s16;

    int n, o, offset, lpc_samples;

    for ( n = 0; n < sigdata->n_samples; n++ ) {
        IT_SAMPLE * sample = sigdata->sample + n;
        if ( ( sample->flags & ( IT_SAMPLE_EXISTS | IT_SAMPLE_LOOP) ) == IT_SAMPLE_EXISTS ) {
            /* If we have enough sample data to train the filter, use the filter to generate the padding */
            if ( sample->length >= lpc_order ) {
                lpc_samples = sample->length;
                if (lpc_samples > lpc_max) lpc_samples = lpc_max;
                offset = sample->length - lpc_samples;

                if ( sample->flags & IT_SAMPLE_STEREO )
                {
                    if ( sample->flags & IT_SAMPLE_16BIT )
                    {
                        s16 = ( signed short * ) sample->data;
                        s16 += offset * 2;
                        for ( o = 0; o < lpc_samples; o++ )
                        {
                            lpc_input[ o ] = s16[ o * 2 + 0 ];
                            lpc_input[ o + lpc_max ] = s16[ o * 2 + 1 ];
                        }
                    }
                    else
                    {
                        s8 = ( signed char * ) sample->data;
                        s8 += offset * 2;
                        for ( o = 0; o < lpc_samples; o++ )
                        {
                            lpc_input[ o ] = s8[ o * 2 + 0 ];
                            lpc_input[ o + lpc_max ] = s8[ o * 2 + 1 ];
                        }
                    }

                    vorbis_lpc_from_data( lpc_input, lpc, lpc_samples, lpc_order );
                    vorbis_lpc_from_data( lpc_input + lpc_max, lpc + lpc_order, lpc_samples, lpc_order );

                    vorbis_lpc_predict( lpc, lpc_input + lpc_samples - lpc_order, lpc_order, lpc_output, lpc_extra );
                    vorbis_lpc_predict( lpc + lpc_order, lpc_input + lpc_max + lpc_samples - lpc_order, lpc_order, lpc_output + lpc_extra, lpc_extra );

                    if ( sample->flags & IT_SAMPLE_16BIT )
                    {
                        s16 = ( signed short * ) realloc( sample->data, ( sample->length + lpc_extra ) * 2 * sizeof(short) );
                        sample->data = s16;

                        s16 += sample->length * 2;
                        sample->length += lpc_extra;

                        for ( o = 0; o < lpc_extra; o++ )
                        {
                            s16[ o * 2 + 0 ] = (signed short)lpc_output[ o ];
                            s16[ o * 2 + 1 ] = (signed short)lpc_output[ o + lpc_extra ];
                        }
                    }
                    else
                    {
                        s8 = ( signed char * ) realloc( sample->data, ( sample->length + lpc_extra ) * 2 );
                        sample->data = s8;

                        s8 += sample->length * 2;
                        sample->length += lpc_extra;

                        for ( o = 0; o < lpc_extra; o++ )
                        {
                            s8[ o * 2 + 0 ] = (signed char)lpc_output[ o ];
                            s8[ o * 2 + 1 ] = (signed char)lpc_output[ o + lpc_extra ];
                        }
                    }
                }
                else
                {
                    if ( sample->flags & IT_SAMPLE_16BIT )
                    {
                        s16 = ( signed short * ) sample->data;
                        s16 += offset;
                        for ( o = 0; o < lpc_samples; o++ )
                        {
                            lpc_input[ o ] = s16[ o ];
                        }
                    }
                    else
                    {
                        s8 = ( signed char * ) sample->data;
                        s8 += offset;
                        for ( o = 0; o < lpc_samples; o++ )
                        {
                            lpc_input[ o ] = s8[ o ];
                        }
                    }

                    vorbis_lpc_from_data( lpc_input, lpc, lpc_samples, lpc_order );

                    vorbis_lpc_predict( lpc, lpc_input + lpc_samples - lpc_order, lpc_order, lpc_output, lpc_extra );

                    if ( sample->flags & IT_SAMPLE_16BIT )
                    {
                        s16 = ( signed short * ) realloc( sample->data, ( sample->length + lpc_extra ) * sizeof(short) );
                        sample->data = s16;

                        s16 += sample->length;
                        sample->length += lpc_extra;

                        for ( o = 0; o < lpc_extra; o++ )
                        {
                            s16[ o ] = (signed short)lpc_output[ o ];
                        }
                    }
                    else
                    {
                        s8 = ( signed char * ) realloc( sample->data, sample->length + lpc_extra );
                        sample->data = s8;

                        s8 += sample->length;
                        sample->length += lpc_extra;

                        for ( o = 0; o < lpc_extra; o++ )
                        {
                            s8[ o ] = (signed char)lpc_output[ o ];
                        }
                    }
                }
            }
            else
            /* Otherwise, pad with silence. */
            {
                offset = sample->length;
                lpc_samples = lpc_extra;

                sample->length += lpc_samples;

                n = 1;
                if ( sample->flags & IT_SAMPLE_STEREO ) n *= 2;
                if ( sample->flags & IT_SAMPLE_16BIT ) n *= 2;

                offset *= n;
                lpc_samples *= n;

                sample->data = realloc( sample->data, offset + lpc_samples );
                memset( (char*)sample->data + offset, 0, lpc_samples );
            }
        }
    }
}