--- a/media/libcubeb/src/cubeb_resampler.cpp
+++ b/media/libcubeb/src/cubeb_resampler.cpp
@@ -8,16 +8,39 @@
#include <cassert>
#include <cstring>
#include <cstddef>
#include <cstdio>
#include "cubeb_resampler.h"
#include "cubeb-speex-resampler.h"
namespace {
+
+template<typename T>
+class auto_array
+{
+public:
+ auto_array(uint32_t size)
+ : data(new T[size])
+ {}
+
+ ~auto_array()
+ {
+ delete [] data;
+ }
+
+ T * get() const
+ {
+ return data;
+ }
+
+private:
+ T * data;
+};
+
long
frame_count_at_rate(long frame_count, float rate)
{
return static_cast<long>(ceilf(rate * frame_count) + 1);
}
size_t
frames_to_bytes(cubeb_stream_params params, size_t frames)
@@ -99,19 +122,19 @@ private:
// Maximum frames that can be stored in |leftover_frames_buffer|.
const uint32_t leftover_frame_size;
// Number of leftover frames stored in |leftover_frames_buffer|.
uint32_t leftover_frame_count;
// A little buffer to store the leftover frames,
// that is, the samples not consumed by the resampler that we will end up
// using next time fill() is called.
- uint8_t * leftover_frames_buffer;
+ auto_array<uint8_t> leftover_frames_buffer;
// A buffer to store frames that will be consumed by the resampler.
- uint8_t * resampling_src_buffer;
+ auto_array<uint8_t> resampling_src_buffer;
};
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,
@@ -120,79 +143,74 @@ cubeb_resampler_speex::cubeb_resampler_s
, 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(auto_array<uint8_t>(frames_to_bytes(params, leftover_frame_size)))
+ , resampling_src_buffer(auto_array<uint8_t>(frames_to_bytes(params,
+ frame_count_at_rate(buffer_frame_count, resampling_ratio))))
{
- 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);
}
cubeb_resampler_speex::~cubeb_resampler_speex()
{
speex_resampler_destroy(speex_resampler);
- delete[] leftover_frames_buffer;
- delete[] resampling_src_buffer;
}
long
cubeb_resampler_speex::fill(void * 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, leftover_frames_buffer, leftover_bytes);
- uint8_t * buffer_start = resampling_src_buffer + leftover_bytes;
+ 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, 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);
+ float * in_buffer = reinterpret_cast<float *>(resampling_src_buffer.get());
float * out_buffer = reinterpret_cast<float *>(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);
+ short * in_buffer = reinterpret_cast<short *>(resampling_src_buffer.get());
short * out_buffer = reinterpret_cast<short *>(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;
+ uint8_t * leftover_frames_start = resampling_src_buffer.get();
leftover_frames_start += frames_to_bytes(stream_params, in_frames);
- memcpy(leftover_frames_buffer, leftover_frames_start, unresampled_bytes);
+ memcpy(leftover_frames_buffer.get(), leftover_frames_start, unresampled_bytes);
return out_frames;
}
cubeb_resampler *
cubeb_resampler_create(cubeb_stream * stream,
cubeb_stream_params params,
unsigned int out_rate,