summaryrefslogtreecommitdiffstats
path: root/audio/filter
diff options
context:
space:
mode:
Diffstat (limited to 'audio/filter')
-rw-r--r--audio/filter/af_scaletempo2.c33
-rw-r--r--audio/filter/af_scaletempo2_internals.c72
-rw-r--r--audio/filter/af_scaletempo2_internals.h1
3 files changed, 38 insertions, 68 deletions
diff --git a/audio/filter/af_scaletempo2.c b/audio/filter/af_scaletempo2.c
index e43c29ac01..749e219454 100644
--- a/audio/filter/af_scaletempo2.c
+++ b/audio/filter/af_scaletempo2.c
@@ -8,7 +8,7 @@
#include "options/m_option.h"
struct priv {
- struct mp_scaletempo2 data;
+ struct mp_scaletempo2 *data;
struct mp_pin *in_pin;
struct mp_aframe *cur_format;
struct mp_aframe_pool *out_pool;
@@ -29,7 +29,7 @@ static void af_scaletempo2_process(struct mp_filter *f)
return;
while (!p->initialized || !p->pending ||
- !mp_scaletempo2_frames_available(&p->data, p->speed))
+ !mp_scaletempo2_frames_available(p->data, p->speed))
{
bool eof = false;
if (!p->pending || !mp_aframe_get_size(p->pending)) {
@@ -64,16 +64,16 @@ static void af_scaletempo2_process(struct mp_filter *f)
if (p->pending && !format_change && !p->sent_final) {
int frame_size = mp_aframe_get_size(p->pending);
uint8_t **planes = mp_aframe_get_data_ro(p->pending);
- int read = mp_scaletempo2_fill_input_buffer(&p->data,
+ int read = mp_scaletempo2_fill_input_buffer(p->data,
planes, frame_size, p->speed);
mp_aframe_skip_samples(p->pending, read);
}
if (final && p->pending && !p->sent_final) {
- mp_scaletempo2_set_final(&p->data);
+ mp_scaletempo2_set_final(p->data);
p->sent_final = true;
}
- if (mp_scaletempo2_frames_available(&p->data, p->speed)) {
+ if (mp_scaletempo2_frames_available(p->data, p->speed)) {
if (eof) {
mp_pin_out_repeat_eof(p->in_pin); // drain more next time
}
@@ -89,9 +89,9 @@ static void af_scaletempo2_process(struct mp_filter *f)
}
assert(p->pending);
- if (mp_scaletempo2_frames_available(&p->data, p->speed)) {
+ if (mp_scaletempo2_frames_available(p->data, p->speed)) {
struct mp_aframe *out = mp_aframe_new_ref(p->cur_format);
- int out_samples = p->data.ola_hop_size;
+ int out_samples = p->data->ola_hop_size;
if (mp_aframe_pool_allocate(p->out_pool, out, out_samples) < 0) {
talloc_free(out);
goto error;
@@ -101,14 +101,14 @@ static void af_scaletempo2_process(struct mp_filter *f)
uint8_t **planes = mp_aframe_get_data_rw(out);
assert(planes);
- assert(mp_aframe_get_planes(out) == p->data.channels);
+ assert(mp_aframe_get_planes(out) == p->data->channels);
- out_samples = mp_scaletempo2_fill_buffer(&p->data,
+ out_samples = mp_scaletempo2_fill_buffer(p->data,
(float**)planes, out_samples, p->speed);
double pts = mp_aframe_get_pts(p->pending);
if (pts != MP_NOPTS_VALUE) {
- double frame_delay = mp_scaletempo2_get_latency(&p->data, p->speed)
+ double frame_delay = mp_scaletempo2_get_latency(p->data, p->speed)
+ out_samples * p->speed;
mp_aframe_set_pts(out, pts - frame_delay / mp_aframe_get_effective_rate(out));
@@ -122,7 +122,7 @@ static void af_scaletempo2_process(struct mp_filter *f)
// reset the filter to ensure it stops generating audio
// and mp_scaletempo2_frames_available returns false
- mp_scaletempo2_reset(&p->data);
+ mp_scaletempo2_reset(p->data);
}
}
}
@@ -150,7 +150,7 @@ static bool init_scaletempo2(struct mp_filter *f)
p->sent_final = false;
mp_aframe_config_copy(p->cur_format, p->pending);
- mp_scaletempo2_init(&p->data, mp_aframe_get_channels(p->pending),
+ mp_scaletempo2_init(p->data, mp_aframe_get_channels(p->pending),
mp_aframe_get_rate(p->pending));
return true;
@@ -172,7 +172,7 @@ static bool af_scaletempo2_command(struct mp_filter *f, struct mp_filter_command
static void af_scaletempo2_reset(struct mp_filter *f)
{
struct priv *p = f->priv;
- mp_scaletempo2_reset(&p->data);
+ mp_scaletempo2_reset(p->data);
p->initialized = false;
TA_FREEP(&p->pending);
}
@@ -180,8 +180,8 @@ static void af_scaletempo2_reset(struct mp_filter *f)
static void af_scaletempo2_destroy(struct mp_filter *f)
{
struct priv *p = f->priv;
- mp_scaletempo2_destroy(&p->data);
- talloc_free(p->pending);
+ TA_FREEP(&p->data);
+ TA_FREEP(&p->pending);
}
static const struct mp_filter_info af_scaletempo2_filter = {
@@ -206,7 +206,8 @@ static struct mp_filter *af_scaletempo2_create(
mp_filter_add_pin(f, MP_PIN_OUT, "out");
struct priv *p = f->priv;
- p->data.opts = talloc_steal(p, options);
+ p->data = talloc_zero(p, struct mp_scaletempo2);
+ p->data->opts = talloc_steal(p, options);
p->speed = 1.0;
p->cur_format = talloc_steal(p, mp_aframe_create());
p->out_pool = mp_aframe_pool_create(p);
diff --git a/audio/filter/af_scaletempo2_internals.c b/audio/filter/af_scaletempo2_internals.c
index 924c0914b3..7f3a99638f 100644
--- a/audio/filter/af_scaletempo2_internals.c
+++ b/audio/filter/af_scaletempo2_internals.c
@@ -41,19 +41,15 @@ static bool in_interval(int n, struct interval q)
return n >= q.lo && n <= q.hi;
}
-static float **realloc_2d(float **p, int x, int y)
+static void alloc_sample_buffer(struct mp_scaletempo2 *p, float ***ptr, size_t size)
{
- float **array = realloc(p, sizeof(float*) * x + sizeof(float) * x * y);
- float* data = (float*) (array + x);
- for (int i = 0; i < x; ++i) {
- array[i] = data + i * y;
- }
- return array;
-}
+ talloc_free(*ptr);
-static void zero_2d(float **a, int x, int y)
-{
- memset(a + x, 0, sizeof(float) * x * y);
+ float **buff = talloc_array(p, float*, p->channels);
+ for (int i = 0; i < p->channels; ++i) {
+ buff[i] = talloc_array(buff, float, size);
+ }
+ *ptr = buff;
}
static void zero_2d_partial(float **a, int x, int y)
@@ -480,12 +476,6 @@ static bool can_perform_wsola(struct mp_scaletempo2 *p, double playback_rate)
return frames_needed(p, playback_rate) <= 0;
}
-static void resize_input_buffer(struct mp_scaletempo2 *p, int size)
-{
- p->input_buffer_size = size;
- p->input_buffer = realloc_2d(p->input_buffer, p->channels, size);
-}
-
// pad end with silence until a wsola iteration can be performed
static void add_input_buffer_final_silence(struct mp_scaletempo2 *p, double playback_rate)
{
@@ -493,11 +483,9 @@ static void add_input_buffer_final_silence(struct mp_scaletempo2 *p, double play
if (needed <= 0)
return; // no silence needed for iteration
- int required_size = needed + p->input_buffer_frames;
- if (required_size > p->input_buffer_size)
- resize_input_buffer(p, required_size);
-
+ int last_index = needed + p->input_buffer_frames - 1;
for (int i = 0; i < p->channels; ++i) {
+ MP_TARRAY_GROW(p, p->input_buffer[i], last_index);
float *ch_input = p->input_buffer[i];
for (int j = 0; j < needed; ++j) {
ch_input[p->input_buffer_frames + j] = 0.0f;
@@ -523,11 +511,9 @@ int mp_scaletempo2_fill_input_buffer(struct mp_scaletempo2 *p,
if (read == 0)
return 0;
- int required_size = read + p->input_buffer_frames;
- if (required_size > p->input_buffer_size)
- resize_input_buffer(p, required_size);
-
+ int last_index = read + p->input_buffer_frames - 1;
for (int i = 0; i < p->channels; ++i) {
+ MP_TARRAY_GROW(p, p->input_buffer[i], last_index);
memcpy(p->input_buffer[i] + p->input_buffer_frames,
planes[i], read * sizeof(float));
}
@@ -771,18 +757,6 @@ bool mp_scaletempo2_frames_available(struct mp_scaletempo2 *p, double playback_r
|| p->num_complete_frames > 0;
}
-void mp_scaletempo2_destroy(struct mp_scaletempo2 *p)
-{
- free(p->ola_window);
- free(p->transition_window);
- free(p->wsola_output);
- free(p->optimal_block);
- free(p->search_block);
- free(p->target_block);
- free(p->input_buffer);
- free(p->energy_candidate_blocks);
-}
-
void mp_scaletempo2_reset(struct mp_scaletempo2 *p)
{
p->input_buffer_frames = 0;
@@ -791,8 +765,6 @@ void mp_scaletempo2_reset(struct mp_scaletempo2 *p)
p->output_time = 0.0;
p->search_block_index = 0;
p->target_block_index = 0;
- // Clear the queue of decoded packets.
- zero_2d(p->wsola_output, p->channels, p->wsola_output_size);
p->num_complete_frames = 0;
p->wsola_output_started = false;
}
@@ -847,28 +819,26 @@ void mp_scaletempo2_init(struct mp_scaletempo2 *p, int channels, int rate)
// 1, ... |num_candidate_blocks|
p->search_block_center_offset = p->num_candidate_blocks / 2
+ (p->ola_window_size / 2 - 1);
- p->ola_window = realloc(p->ola_window, sizeof(float) * p->ola_window_size);
+ MP_RESIZE_ARRAY(p, p->ola_window, p->ola_window_size);
get_symmetric_hanning_window(p->ola_window_size, p->ola_window);
- p->transition_window = realloc(p->transition_window,
- sizeof(float) * p->ola_window_size * 2);
+ MP_RESIZE_ARRAY(p, p->transition_window, p->ola_window_size * 2);
get_symmetric_hanning_window(2 * p->ola_window_size, p->transition_window);
p->wsola_output_size = p->ola_window_size + p->ola_hop_size;
- p->wsola_output = realloc_2d(p->wsola_output, p->channels, p->wsola_output_size);
- // Initialize for overlap-and-add of the first block.
- zero_2d(p->wsola_output, p->channels, p->wsola_output_size);
+ alloc_sample_buffer(p, &p->wsola_output, p->wsola_output_size);
// Auxiliary containers.
- p->optimal_block = realloc_2d(p->optimal_block, p->channels, p->ola_window_size);
+ alloc_sample_buffer(p, &p->optimal_block, p->ola_window_size);
p->search_block_size = p->num_candidate_blocks + (p->ola_window_size - 1);
- p->search_block = realloc_2d(p->search_block, p->channels, p->search_block_size);
- p->target_block = realloc_2d(p->target_block, p->channels, p->ola_window_size);
+ alloc_sample_buffer(p, &p->search_block, p->search_block_size);
+ alloc_sample_buffer(p, &p->target_block, p->ola_window_size);
- resize_input_buffer(p, 4 * MPMAX(p->ola_window_size, p->search_block_size));
p->input_buffer_frames = 0;
p->input_buffer_final_frames = 0;
p->input_buffer_added_silence = 0;
+ size_t initial_size = 4 * MPMAX(p->ola_window_size, p->search_block_size);
+ alloc_sample_buffer(p, &p->input_buffer, initial_size);
- p->energy_candidate_blocks = realloc(p->energy_candidate_blocks,
- sizeof(float) * p->channels * p->num_candidate_blocks);
+ MP_RESIZE_ARRAY(p, p->energy_candidate_blocks,
+ p->channels * p->num_candidate_blocks);
}
diff --git a/audio/filter/af_scaletempo2_internals.h b/audio/filter/af_scaletempo2_internals.h
index 6c3c94c0a9..254d0a7704 100644
--- a/audio/filter/af_scaletempo2_internals.h
+++ b/audio/filter/af_scaletempo2_internals.h
@@ -110,7 +110,6 @@ struct mp_scaletempo2 {
float **target_block;
// Buffered audio data.
float **input_buffer;
- int input_buffer_size;
int input_buffer_frames;
// How many frames in |input_buffer| need to be flushed by padding with
// silence to process the final packet. While this is nonzero, the filter