Пример #1
0
cubeb_resampler_speex::cubeb_resampler_speex(SpeexResamplerState * r,
        cubeb_stream * s,
        cubeb_stream_params params,
        uint32_t out_rate,
        cubeb_data_callback cb,
        long max_count,
        void * ptr)
    : speex_resampler(r)
    , stream(s)
    , stream_params(params)
    , data_callback(cb)
    , user_ptr(ptr)
    , buffer_frame_count(max_count)
    , resampling_ratio(static_cast<float>(params.rate) / out_rate)
    , leftover_frame_size(static_cast<uint32_t>(ceilf(1 / resampling_ratio * 2) + 1))
    , leftover_frame_count(0)
{
    leftover_frames_buffer = new uint8_t[frames_to_bytes(params, leftover_frame_size)];
    size_t frames_needed = frame_count_at_rate(buffer_frame_count, resampling_ratio);
    resampling_src_buffer = new uint8_t[frames_to_bytes(params, frames_needed)];

    assert(r);
    assert(leftover_frames_buffer);
    assert(resampling_src_buffer);
}
Пример #2
0
long
cubeb_resampler_speex::fill(void * input_buffer, void * output_buffer, long frames_needed)
{
  // Use more input frames than strictly necessary, so in the worst case,
  // we have leftover unresampled frames at the end, that we can use
  // during the next iteration.
  assert(frames_needed <= buffer_frame_count);
  long before_resampling = frame_count_at_rate(frames_needed, resampling_ratio);
  long frames_requested = before_resampling - leftover_frame_count;

  // Copy the previous leftover frames to the front of the buffer.
  size_t leftover_bytes = frames_to_bytes(stream_params, leftover_frame_count);
  memcpy(resampling_src_buffer.get(), leftover_frames_buffer.get(), leftover_bytes);
  uint8_t * buffer_start = resampling_src_buffer.get() + leftover_bytes;

  long got = data_callback(stream, user_ptr, NULL, buffer_start, frames_requested);
  assert(got <= frames_requested);

  if (got < 0) {
    return CUBEB_ERROR;
  }

  uint32_t in_frames = leftover_frame_count + got;
  uint32_t out_frames = frames_needed;
  uint32_t old_in_frames = in_frames;

  if (stream_params.format == CUBEB_SAMPLE_FLOAT32NE) {
    float * in_buffer = reinterpret_cast<float *>(resampling_src_buffer.get());
    float * out_buffer = reinterpret_cast<float *>(output_buffer);
    speex_resampler_process_interleaved_float(speex_resampler, in_buffer, &in_frames,
                                              out_buffer, &out_frames);
  } else {
    short * in_buffer = reinterpret_cast<short *>(resampling_src_buffer.get());
    short * out_buffer = reinterpret_cast<short *>(output_buffer);
    speex_resampler_process_interleaved_int(speex_resampler, in_buffer, &in_frames,
                                            out_buffer, &out_frames);
  }

  // Copy the leftover frames to buffer for the next time.
  leftover_frame_count = old_in_frames - in_frames;
  assert(leftover_frame_count <= leftover_frame_size);

  size_t unresampled_bytes = frames_to_bytes(stream_params, leftover_frame_count);
  uint8_t * leftover_frames_start = resampling_src_buffer.get();
  leftover_frames_start += frames_to_bytes(stream_params, in_frames);
  memcpy(leftover_frames_buffer.get(), leftover_frames_start, unresampled_bytes);

  return out_frames;
}