int CFfAudioResample::Resample( sqbind::CSqBinary *pSrc, sqbind::CSqBinary *pDst ) {_STT(); // Validate resampler if ( !m_ctx || 0 >= m_nInRate || 0 >= m_nOutRate ) return 0; // Validate params if ( !pDst || !pSrc ) return 0; // Do we have data? if ( 0 >= pSrc->getUsed() ) return 0; // Calculate required output buffer size oex::oexINT64 nOutSize = pSrc->getUsed() * m_nOutRate / m_nInRate + FF_INPUT_BUFFER_PADDING_SIZE + 1024; // Allocate space for output data if needed if ( ( pDst->Size() - pDst->getUsed() ) < nOutSize ) if ( !pDst->Resize( pDst->getUsed() + nOutSize ) ) return 0; // Build resampling context int consumed = 0; int out = av_resample( m_ctx, (short*)pDst->Ptr( pDst->getUsed() ), (short*)pSrc->Ptr(), &consumed, pSrc->getUsed() / 2, pDst->Size() / 2, 0 ); if ( 0 > out ) { pDst->setUsed( 0 ); return 0; } // end if // Number of bytes used pDst->setUsed( out ); return out; }
void AudioProcessor::Resample() { if (!m_resample_ctx) { m_consumer->Consume(m_buffer.data(), m_buffer_offset); m_buffer_offset = 0; return; } int consumed = 0; int length = av_resample(m_resample_ctx, m_resample_buffer.data(), m_buffer.data(), &consumed, m_buffer_offset, kMaxBufferSize, 1); if (length > kMaxBufferSize) { DEBUG("chromaprint::AudioProcessor::Resample() -- Resampling overwrote output buffer."); length = kMaxBufferSize; } m_consumer->Consume(m_resample_buffer.data(), length); int remaining = m_buffer_offset - consumed; if (remaining > 0) { std::copy(m_buffer.begin() + consumed, m_buffer.begin() + m_buffer_offset, m_buffer.begin()); } else if (remaining < 0) { DEBUG("chromaprint::AudioProcessor::Resample() -- Resampling overread input buffer."); remaining = 0; } m_buffer_offset = remaining; }
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref) { AResampleContext *aresample = inlink->dst->priv; AVFilterLink * const outlink = inlink->dst->outputs[0]; int i, in_nb_samples = insamplesref->audio->nb_samples, cached_nb_samples = in_nb_samples + aresample->unconsumed_nb_samples, requested_out_nb_samples = aresample->ratio * cached_nb_samples, nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout); if (cached_nb_samples > aresample->max_cached_nb_samples) { for (i = 0; i < nb_channels; i++) { aresample->cached_data[i] = av_realloc(aresample->cached_data[i], cached_nb_samples * sizeof(int16_t)); aresample->resampled_data[i] = av_realloc(aresample->resampled_data[i], FFALIGN(sizeof(int16_t) * requested_out_nb_samples, 16)); if (aresample->cached_data[i] == NULL || aresample->resampled_data[i] == NULL) return; } aresample->max_cached_nb_samples = cached_nb_samples; if (aresample->outsamplesref) avfilter_unref_buffer(aresample->outsamplesref); aresample->outsamplesref = avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, requested_out_nb_samples); outlink->out_buf = aresample->outsamplesref; } avfilter_copy_buffer_ref_props(aresample->outsamplesref, insamplesref); aresample->outsamplesref->audio->sample_rate = outlink->sample_rate; aresample->outsamplesref->pts = av_rescale(outlink->sample_rate, insamplesref->pts, inlink->sample_rate); /* av_resample() works with planar audio buffers */ if (!inlink->planar && nb_channels > 1) { int16_t *out[8]; for (i = 0; i < nb_channels; i++) out[i] = aresample->cached_data[i] + aresample->unconsumed_nb_samples; deinterleave(out, (int16_t *)insamplesref->data[0], nb_channels, in_nb_samples); } else { for (i = 0; i < nb_channels; i++) memcpy(aresample->cached_data[i] + aresample->unconsumed_nb_samples, insamplesref->data[i], in_nb_samples * sizeof(int16_t)); } for (i = 0; i < nb_channels; i++) { int consumed_nb_samples; const int is_last = i+1 == nb_channels; aresample->outsamplesref->audio->nb_samples = av_resample(aresample->resample, aresample->resampled_data[i], aresample->cached_data[i], &consumed_nb_samples, cached_nb_samples, requested_out_nb_samples, is_last); /* move unconsumed data back to the beginning of the cache */ aresample->unconsumed_nb_samples = cached_nb_samples - consumed_nb_samples; memmove(aresample->cached_data[i], aresample->cached_data[i] + consumed_nb_samples, aresample->unconsumed_nb_samples * sizeof(int16_t)); } /* copy resampled data to the output samplesref */ if (!inlink->planar && nb_channels > 1) { interleave((int16_t *)aresample->outsamplesref->data[0], aresample->resampled_data, nb_channels, aresample->outsamplesref->audio->nb_samples); } else { for (i = 0; i < nb_channels; i++) memcpy(aresample->outsamplesref->data[i], aresample->resampled_data[i], aresample->outsamplesref->audio->nb_samples * sizeof(int16_t)); } avfilter_filter_samples(outlink, avfilter_ref_buffer(aresample->outsamplesref, ~0)); avfilter_unref_buffer(insamplesref); }
// Filter data through filter static af_data_t* play(struct af_instance_s* af, af_data_t* data) { af_resample_t *s = af->setup; int i, j, consumed, ret; int16_t *in = (int16_t*)data->audio; int16_t *out; int chans = data->nch; int in_len = data->len/(2*chans); int out_len = in_len * af->mul + 10; int16_t tmp[AF_NCH][out_len]; if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) return NULL; out= (int16_t*)af->data->audio; out_len= min(out_len, af->data->len/(2*chans)); if(s->in_alloc < in_len + s->index){ s->in_alloc= in_len + s->index; for(i=0; i<chans; i++){ s->in[i]= realloc(s->in[i], s->in_alloc*sizeof(int16_t)); } } if(chans==1){ memcpy(&s->in[0][s->index], in, in_len * sizeof(int16_t)); }else if(chans==2){ for(j=0; j<in_len; j++){ s->in[0][j + s->index]= *(in++); s->in[1][j + s->index]= *(in++); } }else{ for(j=0; j<in_len; j++){ for(i=0; i<chans; i++){ s->in[i][j + s->index]= *(in++); } } } in_len += s->index; for(i=0; i<chans; i++){ ret= av_resample(s->avrctx, tmp[i], s->in[i], &consumed, in_len, out_len, i+1 == chans); } out_len= ret; s->index= in_len - consumed; for(i=0; i<chans; i++){ memmove(s->in[i], s->in[i] + consumed, s->index*sizeof(int16_t)); } if(chans==1){ memcpy(out, tmp[0], out_len*sizeof(int16_t)); }else if(chans==2){ for(j=0; j<out_len; j++){ *(out++)= tmp[0][j]; *(out++)= tmp[1][j]; } }else{ for(j=0; j<out_len; j++){ for(i=0; i<chans; i++){ *(out++)= tmp[i][j]; } } } data->audio = af->data->audio; data->len = out_len*chans*2; data->rate = af->data->rate; return data; }