diff options
Diffstat (limited to 'audio')
28 files changed, 332 insertions, 177 deletions
diff --git a/audio/audio.c b/audio/audio.c index 9d41928436..ace455f123 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -17,42 +17,58 @@ #include <assert.h> +#include "mpvcore/mp_common.h" #include "mpvcore/mp_talloc.h" #include "audio.h" +static void update_redundant_info(struct mp_audio *mpa) +{ + assert(mp_chmap_is_empty(&mpa->channels) || + mp_chmap_is_valid(&mpa->channels)); + mpa->nch = mpa->channels.num; + mpa->bps = af_fmt2bits(mpa->format) / 8; + if (af_fmt_is_planar(mpa->format)) { + mpa->spf = 1; + mpa->num_planes = mpa->nch; + mpa->sstride = mpa->bps; + } else { + mpa->spf = mpa->nch; + mpa->num_planes = 1; + mpa->sstride = mpa->bps * mpa->nch; + } +} + void mp_audio_set_format(struct mp_audio *mpa, int format) { mpa->format = format; - mpa->bps = af_fmt2bits(format) / 8; + update_redundant_info(mpa); } void mp_audio_set_num_channels(struct mp_audio *mpa, int num_channels) { - struct mp_chmap map; - mp_chmap_from_channels(&map, num_channels); - mp_audio_set_channels(mpa, &map); + mp_chmap_from_channels(&mpa->channels, num_channels); + update_redundant_info(mpa); } // Use old MPlayer/ALSA channel layout. void mp_audio_set_channels_old(struct mp_audio *mpa, int num_channels) { - struct mp_chmap map; - mp_chmap_from_channels_alsa(&map, num_channels); - mp_audio_set_channels(mpa, &map); + mp_chmap_from_channels_alsa(&mpa->channels, num_channels); + update_redundant_info(mpa); } void mp_audio_set_channels(struct mp_audio *mpa, const struct mp_chmap *chmap) { - assert(mp_chmap_is_empty(chmap) || mp_chmap_is_valid(chmap)); mpa->channels = *chmap; - mpa->nch = mpa->channels.num; + update_redundant_info(mpa); } void mp_audio_copy_config(struct mp_audio *dst, const struct mp_audio *src) { - mp_audio_set_format(dst, src->format); - mp_audio_set_channels(dst, &src->channels); + dst->format = src->format; + dst->channels = src->channels; dst->rate = src->rate; + update_redundant_info(dst); } bool mp_audio_config_equals(const struct mp_audio *a, const struct mp_audio *b) @@ -74,3 +90,113 @@ char *mp_audio_config_to_str(struct mp_audio *mpa) { return mp_audio_fmt_to_str(mpa->rate, &mpa->channels, mpa->format); } + +void mp_audio_force_interleaved_format(struct mp_audio *mpa) +{ + if (af_fmt_is_planar(mpa->format)) + mp_audio_set_format(mpa, af_fmt_from_planar(mpa->format)); +} + +// Return used size of a plane. (The size is the same for all planes.) +int mp_audio_psize(struct mp_audio *mpa) +{ + return mpa->samples * mpa->sstride; +} + +void mp_audio_set_null_data(struct mp_audio *mpa) +{ + for (int n = 0; n < MP_NUM_CHANNELS; n++) + mpa->planes[n] = NULL; + mpa->samples = 0; +} + +/* Reallocate the data stored in mpa->planes[n] so that enough samples are + * available on every plane. The previous data is kept (for the smallest + * common number of samples before/after resize). + * + * mpa->samples is not set or used. + * + * This function is flexible enough to handle format and channel layout + * changes. In these cases, all planes are reallocated as needed. Unused + * planes are freed. + * + * mp_audio_realloc(mpa, 0) will still yield non-NULL for mpa->data[n]. + * + * Allocated data is implicitly freed on talloc_free(mpa). + */ +void mp_audio_realloc(struct mp_audio *mpa, int samples) +{ + assert(samples >= 0); + int size = MPMAX(samples * mpa->sstride, 1); + for (int n = 0; n < mpa->num_planes; n++) { + mpa->planes[n] = talloc_realloc_size(mpa, mpa->planes[n], size); + } + for (int n = mpa->num_planes; n < MP_NUM_CHANNELS; n++) { + talloc_free(mpa->planes[n]); + mpa->planes[n] = NULL; + } +} + +// Like mp_audio_realloc(), but only reallocate if the audio grows in size. +void mp_audio_realloc_min(struct mp_audio *mpa, int samples) +{ + if (samples > mp_audio_get_allocated_size(mpa)) + mp_audio_realloc(mpa, samples); +} + +/* Get the size allocated for the data, in number of samples. If the allocated + * size isn't on sample boundaries (e.g. after format changes), the returned + * sample number is a rounded down value. + * + * Note that this only works in situations where mp_audio_realloc() also works! + */ +int mp_audio_get_allocated_size(struct mp_audio *mpa) +{ + int size = 0; + for (int n = 0; n < mpa->num_planes; n++) { + int s = talloc_get_size(mpa->planes[n]) / mpa->sstride; + size = n == 0 ? s : MPMIN(size, s); + } + return size; +} + +// Clear the samples [start, start + length) with silence. +void mp_audio_fill_silence(struct mp_audio *mpa, int start, int length) +{ + assert(start >= 0 && length >= 0 && start + length <= mpa->samples); + int offset = start * mpa->sstride; + int size = length * mpa->sstride; + for (int n = 0; n < mpa->num_planes; n++) { + if (n > 0 && mpa->planes[n] == mpa->planes[0]) + continue; // silly optimization for special cases + af_fill_silence((char *)mpa->planes[n] + offset, size, mpa->format); + } +} + +// All integer parameters are in samples. +// dst and src can overlap. +void mp_audio_copy(struct mp_audio *dst, int dst_offset, + struct mp_audio *src, int src_offset, int length) +{ + assert(mp_audio_config_equals(dst, src)); + assert(length >= 0); + assert(dst_offset >= 0 && dst_offset + length <= dst->samples); + assert(src_offset >= 0 && src_offset + length <= src->samples); + + for (int n = 0; n < dst->num_planes; n++) { + memmove((char *)dst->planes[n] + dst_offset * dst->sstride, + (char *)src->planes[n] + src_offset * src->sstride, + length * dst->sstride); + } +} + +// Set data to the audio after the given number of samples (i.e. slice it). +void mp_audio_skip_samples(struct mp_audio *data, int samples) +{ + assert(samples >= 0 && samples <= data->samples); + + for (int n = 0; n < data->num_planes; n++) + data->planes[n] = (uint8_t *)data->planes[n] + samples * data->sstride; + + data->samples -= samples; +} diff --git a/audio/audio.h b/audio/audio.h index de35e697c8..b5cae0c83c 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -23,14 +23,19 @@ // Audio data chunk struct mp_audio { - void *audio; // data buffer - int len; // buffer length (in bytes) - int rate; // sample rate + int samples; // number of samples in data (per channel) + void *planes[MP_NUM_CHANNELS]; // data buffer (one per plane) + int rate; // sample rate struct mp_chmap channels; // channel layout, use mp_audio_set_*() to set int format; // format (AF_FORMAT_...), use mp_audio_set_format() to set // Redundant fields, for convenience - int nch; // number of channels (redundant with chmap) - int bps; // bytes per sample (redundant with format) + int sstride; // distance between 2 samples in bytes on a plane + // interleaved: bps * nch + // planar: bps + int nch; // number of channels (redundant with chmap) + int spf; // sub-samples per sample on each plane + int num_planes; // number of planes + int bps; // size of sub-samples (af_fmt2bits(format) / 8) }; void mp_audio_set_format(struct mp_audio *mpa, int format); @@ -43,4 +48,20 @@ bool mp_audio_config_equals(const struct mp_audio *a, const struct mp_audio *b); char *mp_audio_fmt_to_str(int srate, const struct mp_chmap *chmap, int format); char *mp_audio_config_to_str(struct mp_audio *mpa); +void mp_audio_force_interleaved_format(struct mp_audio *mpa); + +int mp_audio_psize(struct mp_audio *mpa); + +void mp_audio_set_null_data(struct mp_audio *mpa); + +void mp_audio_realloc(struct mp_audio *mpa, int samples); +void mp_audio_realloc_min(struct mp_audio *mpa, int samples); +int mp_audio_get_allocated_size(struct mp_audio *mpa); + +void mp_audio_fill_silence(struct mp_audio *mpa, int start, int length); + +void mp_audio_copy(struct mp_audio *dst, int dst_offset, + struct mp_audio *src, int src_offset, int length); +void mp_audio_skip_samples(struct mp_audio *data, int samples); + #endif diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index e381a12a3c..ef7993c83a 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -270,20 +270,20 @@ static int filter_n_bytes(sh_audio_t *sh, struct bstr *outbuf, int len) // Filter struct mp_audio filter_input = { - .audio = sh->a_buffer, - .len = len, + .planes = {sh->a_buffer}, .rate = sh->samplerate, }; mp_audio_set_format(&filter_input, sh->sample_format); mp_audio_set_channels(&filter_input, &sh->channels); + filter_input.samples = len / filter_input.sstride; struct mp_audio *filter_output = af_play(sh->afilter, &filter_input); if (!filter_output) return -1; - set_min_out_buffer_size(outbuf, outbuf->len + filter_output->len); - memcpy(outbuf->start + outbuf->len, filter_output->audio, - filter_output->len); - outbuf->len += filter_output->len; + int outlen = filter_output->samples * filter_output->sstride; + set_min_out_buffer_size(outbuf, outbuf->len + outlen); + memcpy(outbuf->start + outbuf->len, filter_output->planes[0], outlen); + outbuf->len += outlen; // remove processed data from decoder buffer: sh->a_buffer_len -= len; diff --git a/audio/filter/af.c b/audio/filter/af.c index edee4bef65..95d0e43673 100644 --- a/audio/filter/af.c +++ b/audio/filter/af.c @@ -523,8 +523,7 @@ static int af_reinit(struct af_stream *s) // Check if this is the first filter struct mp_audio in = *af->prev->data; // Reset just in case... - in.audio = NULL; - in.len = 0; + mp_audio_set_null_data(&in); int rv = af->control(af, AF_CONTROL_REINIT, &in); if (rv == AF_OK && !mp_audio_config_equals(&in, af->prev->data)) @@ -640,8 +639,8 @@ int af_init(struct af_stream *s) return -1; // Precaution in case caller is misbehaving - s->input.audio = s->output.audio = NULL; - s->input.len = s->output.len = 0; + mp_audio_set_null_data(&s->input); + mp_audio_set_null_data(&s->output); // Check if this is the first call if (s->first->next == s->last) { @@ -731,36 +730,39 @@ double af_calc_delay(struct af_stream *s) return delay; } -/* Calculate the minimum output buffer size for given input data d - * when using the af_resize_local_buffer function. The +t+1 part ensures the - * value is >= len*mul rounded upwards to whole samples even if the - * double 'mul' is inexact. */ -static int af_lencalc(double mul, struct mp_audio *d) -{ - int t = d->bps * d->nch; - return d->len * mul + t + 1; -} - /* I a local buffer is used (i.e. if the filter doesn't operate on the incoming * buffer), this macro must be called to ensure the buffer is big enough. */ int af_resize_local_buffer(struct af_instance *af, struct mp_audio *data) { - if (af->data->len >= af_lencalc(af->mul, data)) + assert(data->format); + + if (!af->data->format && !af->data->planes[0]) { + // Dummy initialization + mp_audio_set_format(af->data, AF_FORMAT_U8); + } + + int oldlen = af->data->samples * af->data->sstride; + + /* Calculate the minimum output buffer size for given input data d + * when using the af_resize_local_buffer function. The +x part ensures + * the value is >= len*mul rounded upwards to whole samples even if the + * double 'mul' is inexact. */ + int newlen = data->samples * data->sstride * af->mul + data->sstride + 1; + + if (oldlen >= newlen) return AF_OK; - // Calculate new length - register int len = af_lencalc(af->mul, data); mp_msg(MSGT_AFILTER, MSGL_V, "[libaf] Reallocating memory in module %s, " - "old len = %i, new len = %i\n", af->info->name, af->data->len, len); + "old len = %i, new len = %i\n", af->info->name, oldlen, newlen); // If there is a buffer free it - free(af->data->audio); + free(af->data->planes[0]); // Create new buffer and check that it is OK - af->data->audio = malloc(len); - if (!af->data->audio) { + af->data->planes[0] = malloc(newlen); + if (!af->data->planes[0]) { mp_msg(MSGT_AFILTER, MSGL_FATAL, "[libaf] Could not allocate memory \n"); return AF_ERROR; } - af->data->len = len; + af->data->samples = newlen / af->data->sstride; return AF_OK; } diff --git a/audio/filter/af_bs2b.c b/audio/filter/af_bs2b.c index 0e77b3e4eb..5e0caf28af 100644 --- a/audio/filter/af_bs2b.c +++ b/audio/filter/af_bs2b.c @@ -42,7 +42,7 @@ static struct mp_audio *play_##name(struct af_instance *af, struct mp_audio *dat { \ /* filter is called for all pairs of samples available in the buffer */ \ bs2b_cross_feed_##name(((struct af_bs2b*)(af->priv))->filter, \ - (type*)(data->audio), data->len/data->bps/2); \ + (type*)(data->planes[0]), data->samples); \ \ return data; \ } diff --git a/audio/filter/af_center.c b/audio/filter/af_center.c index 0cfdbc3b0e..c64c551f1c 100644 --- a/audio/filter/af_center.c +++ b/audio/filter/af_center.c @@ -87,9 +87,9 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) { struct mp_audio* c = data; // Current working data af_center_t* s = af->setup; // Setup for this instance - float* a = c->audio; // Audio data - int len = c->len/4; // Number of samples in current audio block + float* a = c->planes[0]; // Audio data int nch = c->nch; // Number of channels + int len = c->samples*c->nch; // Number of samples in current audio block int ch = s->ch; // Channel in which to insert the center audio register int i; diff --git a/audio/filter/af_channels.c b/audio/filter/af_channels.c index 27445aafe2..fd3b8262f5 100644 --- a/audio/filter/af_channels.c +++ b/audio/filter/af_channels.c @@ -169,6 +169,10 @@ static int control(struct af_instance* af, int cmd, void* arg) af->data->rate = ((struct mp_audio*)arg)->rate; mp_audio_set_format(af->data, ((struct mp_audio*)arg)->format); af->mul = (double)af->data->nch / ((struct mp_audio*)arg)->nch; + mp_audio_force_interleaved_format(af->data); + int r = af_test_output(af,(struct mp_audio*)arg); + if (r != AF_OK) + return r; return check_routes(s,((struct mp_audio*)arg)->nch,af->data->nch); case AF_CONTROL_COMMAND_LINE:{ int nch = 0; @@ -219,7 +223,7 @@ static void uninit(struct af_instance* af) { free(af->setup); if (af->data) - free(af->data->audio); + free(af->data->planes[0]); free(af->data); } @@ -235,16 +239,16 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) return NULL; // Reset unused channels - memset(l->audio,0,c->len / c->nch * l->nch); + memset(l->planes[0],0,mp_audio_psize(c) / c->nch * l->nch); if(AF_OK == check_routes(s,c->nch,l->nch)) for(i=0;i<s->nr;i++) - copy(c->audio,l->audio,c->nch,s->route[i][FR], - l->nch,s->route[i][TO],c->len,c->bps); + copy(c->planes[0],l->planes[0],c->nch,s->route[i][FR], + l->nch,s->route[i][TO],mp_audio_psize(c),c->bps); // Set output data - c->audio = l->audio; - c->len = c->len / c->nch * l->nch; + c->planes[0] = l->planes[0]; + c->samples = c->samples / c->nch * l->nch; mp_audio_set_channels(c, &l->channels); return c; diff --git a/audio/filter/af_convert24.c b/audio/filter/af_convert24.c index 18ce156467..96924de344 100644 --- a/audio/filter/af_convert24.c +++ b/audio/filter/af_convert24.c @@ -78,12 +78,12 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data) return NULL; struct mp_audio *out = af->data; - size_t len = data->len / data->bps; + size_t len = mp_audio_psize(data) / data->bps; if (data->bps == 4) { for (int s = 0; s < len; s++) { - uint32_t val = *((uint32_t *)data->audio + s); - uint8_t *ptr = (uint8_t *)out->audio + s * 3; + uint32_t val = *((uint32_t *)data->planes[0] + s); + uint8_t *ptr = (uint8_t *)out->planes[0] + s * 3; ptr[0] = val >> SHIFT(0); ptr[1] = val >> SHIFT(1); ptr[2] = val >> SHIFT(2); @@ -91,24 +91,23 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data) mp_audio_set_format(data, af_fmt_change_bits(data->format, 24)); } else { for (int s = 0; s < len; s++) { - uint8_t *ptr = (uint8_t *)data->audio + s * 3; + uint8_t *ptr = (uint8_t *)data->planes[0] + s * 3; uint32_t val = ptr[0] << SHIFT(0) | ptr[1] << SHIFT(1) | ptr[2] << SHIFT(2); - *((uint32_t *)out->audio + s) = val; + *((uint32_t *)out->planes[0] + s) = val; } mp_audio_set_format(data, af_fmt_change_bits(data->format, 32)); } - data->audio = out->audio; - data->len = len * data->bps; + data->planes[0] = out->planes[0]; return data; } static void uninit(struct af_instance* af) { if (af->data) - free(af->data->audio); + free(af->data->planes[0]); } static int af_open(struct af_instance *af) diff --git a/audio/filter/af_convertsignendian.c b/audio/filter/af_convertsignendian.c index bfea004bb2..5565438aad 100644 --- a/audio/filter/af_convertsignendian.c +++ b/audio/filter/af_convertsignendian.c @@ -24,6 +24,9 @@ static bool test_conversion(int src_format, int dst_format) { + if ((src_format & AF_FORMAT_PLANAR) || + (dst_format & AF_FORMAT_PLANAR)) + return false; int src_noend = src_format & ~AF_FORMAT_END_MASK; int dst_noend = dst_format & ~AF_FORMAT_END_MASK; // We can swap endian for all formats, but sign only for integer formats. @@ -100,13 +103,13 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data) { int infmt = data->format; int outfmt = af->data->format; - size_t len = data->len / data->bps; + size_t len = data->samples * data->nch; if ((infmt & AF_FORMAT_END_MASK) != (outfmt & AF_FORMAT_END_MASK)) - endian(data->audio, len, data->bps); + endian(data->planes[0], len, data->bps); if ((infmt & AF_FORMAT_SIGN_MASK) != (outfmt & AF_FORMAT_SIGN_MASK)) - si2us(data->audio, len, data->bps, + si2us(data->planes[0], len, data->bps, (outfmt & AF_FORMAT_END_MASK) == AF_FORMAT_LE); mp_audio_set_format(data, outfmt); diff --git a/audio/filter/af_delay.c b/audio/filter/af_delay.c index a6515f84cf..c979060fe3 100644 --- a/audio/filter/af_delay.c +++ b/audio/filter/af_delay.c @@ -56,6 +56,7 @@ static int control(struct af_instance* af, int cmd, void* arg) free(s->q[i]); mp_audio_copy_config(af->data, (struct mp_audio*)arg); + mp_audio_force_interleaved_format(af->data); // Allocate new delay queues for(i=0;i<af->data->nch;i++){ @@ -123,13 +124,13 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) struct mp_audio* c = data; // Current working data af_delay_t* s = af->setup; // Setup for this instance int nch = c->nch; // Number of channels - int len = c->len/c->bps; // Number of sample in data chunk + int len = mp_audio_psize(c)/c->bps; // Number of sample in data chunk int ri = 0; int ch,i; for(ch=0;ch<nch;ch++){ switch(c->bps){ case 1:{ - int8_t* a = c->audio; + int8_t* a = c->planes[0]; int8_t* q = s->q[ch]; int wi = s->wi[ch]; ri = s->ri; @@ -143,7 +144,7 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) break; } case 2:{ - int16_t* a = c->audio; + int16_t* a = c->planes[0]; int16_t* q = s->q[ch]; int wi = s->wi[ch]; ri = s->ri; @@ -157,7 +158,7 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) break; } case 4:{ - int32_t* a = c->audio; + int32_t* a = c->planes[0]; int32_t* q = s->q[ch]; int wi = s->wi[ch]; ri = s->ri; diff --git a/audio/filter/af_drc.c b/audio/filter/af_drc.c index 9bbbde4831..589844d89b 100644 --- a/audio/filter/af_drc.c +++ b/audio/filter/af_drc.c @@ -88,6 +88,7 @@ static int control(struct af_instance* af, int cmd, void* arg) // Sanity check if(!arg) return AF_ERROR; + mp_audio_force_interleaved_format((struct mp_audio*)arg); mp_audio_copy_config(af->data, (struct mp_audio*)arg); if(((struct mp_audio*)arg)->format != (AF_FORMAT_S16_NE)){ @@ -119,8 +120,8 @@ static void uninit(struct af_instance* af) static void method1_int16(af_drc_t *s, struct mp_audio *c) { register int i = 0; - int16_t *data = (int16_t*)c->audio; // Audio data - int len = c->len/2; // Number of samples + int16_t *data = (int16_t*)c->planes[0]; // Audio data + int len = c->samples*c->nch; // Number of samples float curavg = 0.0, newavg, neededmul; int tmp; @@ -161,8 +162,8 @@ static void method1_int16(af_drc_t *s, struct mp_audio *c) static void method1_float(af_drc_t *s, struct mp_audio *c) { register int i = 0; - float *data = (float*)c->audio; // Audio data - int len = c->len/4; // Number of samples + float *data = (float*)c->planes[0]; // Audio data + int len = c->samples*c->nch; // Number of samples float curavg = 0.0, newavg, neededmul, tmp; for (i = 0; i < len; i++) @@ -198,8 +199,8 @@ static void method1_float(af_drc_t *s, struct mp_audio *c) static void method2_int16(af_drc_t *s, struct mp_audio *c) { register int i = 0; - int16_t *data = (int16_t*)c->audio; // Audio data - int len = c->len/2; // Number of samples + int16_t *data = (int16_t*)c->planes[0]; // Audio data + int len = c->samples*c->nch; // Number of samples float curavg = 0.0, newavg, avg = 0.0; int tmp, totallen = 0; @@ -248,8 +249,8 @@ static void method2_int16(af_drc_t *s, struct mp_audio *c) static void method2_float(af_drc_t *s, struct mp_audio *c) { register int i = 0; - float *data = (float*)c->audio; // Audio data - int len = c->len/4; // Number of samples + float *data = (float*)c->planes[0]; // Audio data + int len = c->samples*c->nch; // Number of samples float curavg = 0.0, newavg, avg = 0.0, tmp; int totallen = 0; diff --git a/audio/filter/af_equalizer.c b/audio/filter/af_equalizer.c index cbdcd3f84a..718445c001 100644 --- a/audio/filter/af_equalizer.c +++ b/audio/filter/af_equalizer.c @@ -170,9 +170,9 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data) while(ci--){ float* g = s->g[ci]; // Gain factor - float* in = ((float*)c->audio)+ci; - float* out = ((float*)c->audio)+ci; - float* end = in + c->len/4; // Block loop end + float* in = ((float*)c->planes[0])+ci; + float* out = ((float*)c->planes[0])+ci; + float* end = in + c->samples*c->nch; // Block loop end while(in < end){ register int k = 0; // Frequency band index diff --git a/audio/filter/af_export.c b/audio/filter/af_export.c index 45143075a1..a6ebdc322e 100644 --- a/audio/filter/af_export.c +++ b/audio/filter/af_export.c @@ -213,9 +213,9 @@ static struct mp_audio* play( struct af_instance* af, struct mp_audio* data ) { struct mp_audio* c = data; // Current working data af_export_t* s = af->setup; // Setup for this instance - int16_t* a = c->audio; // Incomming sound + int16_t* a = c->planes[0]; // Incomming sound int nch = c->nch; // Number of channels - int len = c->len/c->bps; // Number of sample in data chunk + int len = c->samples*c->nch; // Number of sample in data chunk int sz = s->sz; // buffer size (in samples) int flag = 0; // Set to 1 if buffer is filled diff --git a/audio/filter/af_extrastereo.c b/audio/filter/af_extrastereo.c index 4cf27f2724..5b3792763b 100644 --- a/audio/filter/af_extrastereo.c +++ b/audio/filter/af_extrastereo.c @@ -49,6 +49,7 @@ static int control(struct af_instance* af, int cmd, void* arg) if(!arg) return AF_ERROR; mp_audio_copy_config(af->data, (struct mp_audio*)arg); + mp_audio_force_interleaved_format(af->data); mp_audio_set_num_channels(af->data, 2); if (af->data->format == AF_FORMAT_FLOAT_NE) { @@ -83,8 +84,8 @@ static struct mp_audio* play_s16(struct af_instance* af, struct mp_audio* data) { af_extrastereo_t *s = af->setup; register int i = 0; - int16_t *a = (int16_t*)data->audio; // Audio data - int len = data->len/2; // Number of samples + int16_t *a = (int16_t*)data->planes[0]; // Audio data + int len = data->samples*data->nch; // Number of samples int avg, l, r; for (i = 0; i < len; i+=2) @@ -105,8 +106,8 @@ static struct mp_audio* play_float(struct af_instance* af, struct mp_audio* data { af_extrastereo_t *s = af->setup; register int i = 0; - float *a = (float*)data->audio; // Audio data - int len = data->len/4; // Number of samples + float *a = (float*)data->planes[0]; // Audio data + int len = data->samples * data->nch; // Number of samples float avg, l, r; for (i = 0; i < len; i+=2) diff --git a/audio/filter/af_format.c b/audio/filter/af_format.c index 642ef927bb..b551ddba42 100644 --- a/audio/filter/af_format.c +++ b/audio/filter/af_format.c @@ -105,8 +105,9 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data) struct mp_audio *r = &priv->temp; *r = *af->data; - r->audio = data->audio; - r->len = data->len; + for (int n = 0; n < r->nch; n++) + r->planes[n] = data->planes[n]; + r->samples = data->samples; return r; } diff --git a/audio/filter/af_hrtf.c b/audio/filter/af_hrtf.c index 5b80bf0eec..01148dc6a6 100644 --- a/audio/filter/af_hrtf.c +++ b/audio/filter/af_hrtf.c @@ -3 |