diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/aframe.c | 2 | ||||
-rw-r--r-- | audio/decode/ad_lavc.c | 1 | ||||
-rw-r--r-- | audio/decode/ad_spdif.c | 25 | ||||
-rw-r--r-- | audio/filter/af_scaletempo.c | 238 | ||||
-rw-r--r-- | audio/out/ao.c | 2 | ||||
-rw-r--r-- | audio/out/ao_audiotrack.c | 2 | ||||
-rw-r--r-- | audio/out/ao_audiounit.m | 2 | ||||
-rw-r--r-- | audio/out/ao_avfoundation.m | 11 | ||||
-rw-r--r-- | audio/out/ao_coreaudio.c | 4 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_exclusive.c | 2 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.c | 28 | ||||
-rw-r--r-- | audio/out/ao_jack.c | 3 | ||||
-rw-r--r-- | audio/out/ao_opensles.c | 2 | ||||
-rw-r--r-- | audio/out/ao_oss.c | 3 | ||||
-rw-r--r-- | audio/out/ao_pcm.c | 4 | ||||
-rw-r--r-- | audio/out/ao_pipewire.c | 4 | ||||
-rw-r--r-- | audio/out/ao_pulse.c | 38 | ||||
-rw-r--r-- | audio/out/ao_sdl.c | 2 | ||||
-rw-r--r-- | audio/out/ao_wasapi_changenotify.c | 5 | ||||
-rw-r--r-- | audio/out/ao_wasapi_utils.c | 44 | ||||
-rw-r--r-- | audio/out/buffer.c | 57 | ||||
-rw-r--r-- | audio/out/internal.h | 8 |
22 files changed, 300 insertions, 187 deletions
diff --git a/audio/aframe.c b/audio/aframe.c index cb6ea17be3..03e8ab8ae8 100644 --- a/audio/aframe.c +++ b/audio/aframe.c @@ -600,7 +600,7 @@ bool mp_aframe_set_silence(struct mp_aframe *f, int offset, int samples) bool mp_aframe_reverse(struct mp_aframe *f) { int format = mp_aframe_get_format(f); - size_t bps = af_fmt_to_bytes(format); + int bps = af_fmt_to_bytes(format); if (!af_fmt_is_pcm(format) || bps > 16) return false; diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 9b5f1fb467..39cd74cd2a 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -17,7 +17,6 @@ #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <stdbool.h> #include <assert.h> diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index 98a53f3ca0..3f83ab240e 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -45,6 +45,7 @@ struct spdifContext { struct mp_log *log; + struct mp_codec_params *codec; enum AVCodecID codec_id; AVFormatContext *lavf_ctx; AVPacket *avpkt; @@ -117,15 +118,17 @@ static void determine_codec_params(struct mp_filter *da, AVPacket *pkt, uint8_t *d = NULL; int s = 0; - av_parser_parse2(parser, ctx, &d, &s, pkt->data, pkt->size, 0, 0, 0); - *out_profile = profile = ctx->profile; - *out_rate = ctx->sample_rate; + if (av_parser_parse2(parser, ctx, &d, &s, pkt->data, pkt->size, 0, 0, 0) > 0) { + *out_profile = profile = ctx->profile; + *out_rate = ctx->sample_rate; + spdif_ctx->codec->codec_profile = avcodec_profile_name(spdif_ctx->codec_id, profile); + } avcodec_free_context(&ctx); av_parser_close(parser); } - if (profile != AV_PROFILE_UNKNOWN || spdif_ctx->codec_id != AV_CODEC_ID_DTS) + if (profile != AV_PROFILE_UNKNOWN || spdif_ctx->codec_id == AV_CODEC_ID_AC3) return; const AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id); @@ -151,6 +154,13 @@ static void determine_codec_params(struct mp_filter *da, AVPacket *pkt, *out_profile = profile = ctx->profile; *out_rate = ctx->sample_rate; + struct mp_codec_params *c = spdif_ctx->codec; + c->codec_profile = av_get_profile_name(ctx->codec, ctx->profile); + if (!c->codec_profile) + c->codec_profile = avcodec_profile_name(ctx->codec_id, ctx->profile); + c->codec = ctx->codec_descriptor->name; + c->codec_desc = ctx->codec_descriptor->long_name; + done: av_frame_free(&frame); avcodec_free_context(&ctx); @@ -181,7 +191,7 @@ static int init_filter(struct mp_filter *da) goto fail; void *buffer = av_mallocz(OUTBUF_SIZE); - MP_HANDLE_OOM(buffer); + MP_HANDLE_OOM(buffer); lavf_ctx->pb = avio_alloc_context(buffer, OUTBUF_SIZE, 1, spdif_ctx, NULL, write_packet, NULL); if (!lavf_ctx->pb) { @@ -432,6 +442,7 @@ static struct mp_decoder *create(struct mp_filter *parent, struct spdifContext *spdif_ctx = da->priv; spdif_ctx->log = da->log; + spdif_ctx->codec = codec; spdif_ctx->pool = mp_aframe_pool_create(spdif_ctx); spdif_ctx->public.f = da; @@ -446,6 +457,10 @@ static struct mp_decoder *create(struct mp_filter *parent, return NULL; } + const AVCodecDescriptor *desc = avcodec_descriptor_get(spdif_ctx->codec_id); + if (desc) + codec->codec_desc = desc->long_name; + return &spdif_ctx->public; } diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c index e7b101b260..482b91209e 100644 --- a/audio/filter/af_scaletempo.c +++ b/audio/filter/af_scaletempo.c @@ -2,7 +2,7 @@ * scaletempo audio filter * * scale tempo while maintaining pitch - * (WSOLA technique with cross correlation) + * (WSOLA technique with taxicab distance) * inspired by SoundTouch library by Olli Parviainen * * basic algorithm @@ -35,6 +35,7 @@ #include <string.h> #include <limits.h> #include <assert.h> +#include <math.h> #include "audio/aframe.h" #include "audio/format.h" @@ -87,8 +88,6 @@ struct priv { // best overlap int frames_search; int num_channels; - void *buf_pre_corr; - void *table_window; int (*best_overlap_offset)(struct priv *s); }; @@ -135,72 +134,144 @@ static bool fill_queue(struct priv *s) return bytes_needed == 0; } -#define UNROLL_PADDING (4 * 4) +// Fit the curve f(x) = a * x^2 + b * x + c such that +// f(-1) = y[0] +// f(0) = y[1] +// f(1) = y[2] +// and return the extremum position and value +// assuming y[0] <= y[1] >= y[2] || y[0] >= y[1] <= y[2] +static void quadratic_interpolation_float( + const float* y_values, float* x, float* value) +{ + const float b = (y_values[2] - y_values[0]) * 0.5f; + const float c = y_values[1]; + const float a = y_values[0] + b - c; + + if (a == 0.f) { + // it's a flat line + *x = 0; + *value = c; + } else { + const float pos = -b / (2.f * a); + *x = pos; + *value = a * pos * pos + b * pos + c; + } +} + +static void quadratic_interpolation_s16( + const int32_t* y_values, float* x, int32_t* value) +{ + const float b = (y_values[2] - y_values[0]) * 0.5f; + const float c = y_values[1]; + const float a = y_values[0] + b - c; + + if (a == 0.f) { + // it's a flat line + *x = 0; + *value = c; + } else { + const float pos = -b / (2.f * a); + *x = pos; + *value = a * pos * pos + b * pos + c; + } +} static int best_overlap_offset_float(struct priv *s) { - float best_corr = INT_MIN; - int best_off = 0; - - float *pw = s->table_window; - float *po = s->buf_overlap; - po += s->num_channels; - float *ppc = s->buf_pre_corr; - for (int i = s->num_channels; i < s->samples_overlap; i++) - *ppc++ = *pw++ **po++; - - float *search_start = (float *)s->buf_queue + s->num_channels; - for (int off = 0; off < s->frames_search; off++) { - float corr = 0; - float *ps = search_start; - ppc = s->buf_pre_corr; - for (int i = s->num_channels; i < s->samples_overlap; i++) - corr += *ppc++ **ps++; - if (corr > best_corr) { - best_corr = corr; - best_off = off; + int num_channels = s->num_channels, frames_search = s->frames_search; + float *source = (float *)s->buf_queue + num_channels; + float *target = (float *)s->buf_overlap + num_channels; + int num_samples = s->samples_overlap - num_channels; + int step_size = 3; + float history[3] = {}; + + float best_distance = FLT_MAX; + int best_offset_approx = 0; + for (int offset = 0; offset < frames_search; offset += step_size) { + float distance = 0; + for (int i = 0; i < num_samples; i++) + distance += fabsf(target[i] - source[offset * num_channels + i]); + + int offset_approx = offset; + history[0] = history[1]; + history[1] = history[2]; + history[2] = distance; + if(offset >= 2 && history[0] >= history[1] && history[1] <= history[2]) { + float extremum; + quadratic_interpolation_float(history, &extremum, &distance); + offset_approx = offset - step_size + (int)(extremum * step_size + 0.5f); + } + + if (distance < best_distance) { + best_distance = distance; + best_offset_approx = offset_approx; + } + } + + best_distance = FLT_MAX; + int best_offset = 0; + int min_offset = MPMAX(0, best_offset_approx - step_size + 1); + int max_offset = MPMIN(frames_search, best_offset_approx + step_size); + for (int offset = min_offset; offset < max_offset; offset++) { + float distance = 0; + for (int i = 0; i < num_samples; i++) + distance += fabsf(target[i] - source[offset * num_channels + i]); + if (distance < best_distance) { + best_distance = distance; + best_offset = offset; } - search_start += s->num_channels; } - return best_off * 4 * s->num_channels; + return best_offset * 4 * num_channels; } static int best_overlap_offset_s16(struct priv *s) { - int64_t best_corr = INT64_MIN; - int best_off = 0; - - int32_t *pw = s->table_window; - int16_t *po = s->buf_overlap; - po += s->num_channels; - int32_t *ppc = s->buf_pre_corr; - for (long i = s->num_channels; i < s->samples_overlap; i++) - *ppc++ = (*pw++ **po++) >> 15; - - int16_t *search_start = (int16_t *)s->buf_queue + s->num_channels; - for (int off = 0; off < s->frames_search; off++) { - int64_t corr = 0; - int16_t *ps = search_start; - ppc = s->buf_pre_corr; - ppc += s->samples_overlap - s->num_channels; - ps += s->samples_overlap - s->num_channels; - long i = -(s->samples_overlap - s->num_channels); - do { - corr += ppc[i + 0] * (int64_t)ps[i + 0]; - corr += ppc[i + 1] * (int64_t)ps[i + 1]; - corr += ppc[i + 2] * (int64_t)ps[i + 2]; - corr += ppc[i + 3] * (int64_t)ps[i + 3]; - i += 4; - } while (i < 0); - if (corr > best_corr) { - best_corr = corr; - best_off = off; + int num_channels = s->num_channels, frames_search = s->frames_search; + int16_t *source = (int16_t *)s->buf_queue + num_channels; + int16_t *target = (int16_t *)s->buf_overlap + num_channels; + int num_samples = s->samples_overlap - num_channels; + int step_size = 3; + int32_t history[3] = {}; + + int32_t best_distance = INT32_MAX; + int best_offset_approx = 0; + for (int offset = 0; offset < frames_search; offset += step_size) { + int32_t distance = 0; + for (int i = 0; i < num_samples; i++) + distance += abs((int32_t)target[i] - source[offset * num_channels + i]); + + int offset_approx = offset; + history[0] = history[1]; + history[1] = history[2]; + history[2] = distance; + if(offset >= 2 && history[0] >= history[1] && history[1] <= history[2]) { + float extremum; + quadratic_interpolation_s16(history, &extremum, &distance); + offset_approx = offset - step_size + (int)(extremum * step_size + 0.5f); + } + + if (distance < best_distance) { + best_distance = distance; + best_offset_approx = offset_approx; } - search_start += s->num_channels; } - return best_off * 2 * s->num_channels; + best_distance = INT32_MAX; + int best_offset = 0; + int min_offset = MPMAX(0, best_offset_approx - step_size + 1); + int max_offset = MPMIN(frames_search, best_offset_approx + step_size); + for (int offset = min_offset; offset < max_offset; offset++) { + int32_t distance = 0; + for (int i = 0; i < num_samples; i++) + distance += abs((int32_t)target[i] - source[offset * num_channels + i]); + if (distance < best_distance) { + best_distance = distance; + best_offset = offset; + } + } + + return best_offset * 2 * s->num_channels; } static void output_overlap_float(struct priv *s, void *buf_out, @@ -211,8 +282,9 @@ static void output_overlap_float(struct priv *s, void *buf_out, float *po = s->buf_overlap; float *pin = (float *)(s->buf_queue + bytes_off); for (int i = 0; i < s->samples_overlap; i++) { - *pout++ = *po - *pb++ *(*po - *pin++); - po++; + // the math is equal to *po * (1 - *pb) + *pin * *pb + float o = *po++; + *pout++ = o - *pb++ * (o - *pin++); } } @@ -224,8 +296,9 @@ static void output_overlap_s16(struct priv *s, void *buf_out, int16_t *po = s->buf_overlap; int16_t *pin = (int16_t *)(s->buf_queue + bytes_off); for (int i = 0; i < s->samples_overlap; i++) { - *pout++ = *po - ((*pb++ *(*po - *pin++)) >> 16); - po++; + // the math is equal to *po * (1 - *pb) + *pin * *pb + int32_t o = *po++; + *pout++ = o - ((*pb++ *(o - *pin++)) >> 16); } } @@ -420,18 +493,20 @@ static bool reinit(struct mp_filter *f) memset(s->buf_overlap, 0, s->bytes_overlap); if (use_int) { int32_t *pb = s->table_blend; - int64_t blend = 0; + const float scale = M_PI / frames_overlap; for (int i = 0; i < frames_overlap; i++) { - int32_t v = blend / frames_overlap; + // Hann function + const int32_t v = 0.5f * (1.0f - cosf(i * scale)) * 65536 + 0.5; for (int j = 0; j < nch; j++) *pb++ = v; - blend += 65536; // 2^16 } s->output_overlap = output_overlap_s16; } else { float *pb = s->table_blend; + const float scale = M_PI / frames_overlap; for (int i = 0; i < frames_overlap; i++) { - float v = i / (float)frames_overlap; + // Hann function + const float v = 0.5f * (1.0f - cosf(i * scale)); for (int j = 0; j < nch; j++) *pb++ = v; } @@ -444,39 +519,8 @@ static bool reinit(struct mp_filter *f) s->best_overlap_offset = NULL; else { if (use_int) { - int64_t t = frames_overlap; - int32_t n = 8589934588LL / (t * t); // 4 * (2^31 - 1) / t^2 - s->buf_pre_corr = realloc(s->buf_pre_corr, - s->bytes_overlap * 2 + UNROLL_PADDING); - s->table_window = realloc(s->table_window, - s->bytes_overlap * 2 - nch * bps * 2); - if (!s->buf_pre_corr || !s->table_window) { - MP_FATAL(f, "Out of memory\n"); - return false; - } - memset((char *)s->buf_pre_corr + s->bytes_overlap * 2, 0, - UNROLL_PADDING); - int32_t *pw = s->table_window; - for (int i = 1; i < frames_overlap; i++) { - int32_t v = (i * (t - i) * n) >> 15; - for (int j = 0; j < nch; j++) - *pw++ = v; - } s->best_overlap_offset = best_overlap_offset_s16; } else { - s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap); - s->table_window = realloc(s->table_window, - s->bytes_overlap - nch * bps); - if (!s->buf_pre_corr || !s->table_window) { - MP_FATAL(f, "Out of memory\n"); - return false; - } - float *pw = s->table_window; - for (int i = 1; i < frames_overlap; i++) { - float v = i * (frames_overlap - i); - for (int j = 0; j < nch; j++) - *pw++ = v; - } s->best_overlap_offset = best_overlap_offset_float; } } @@ -486,7 +530,7 @@ static bool reinit(struct mp_filter *f) s->bytes_queue = (s->frames_search + s->frames_stride + frames_overlap) * bps * nch; - s->buf_queue = realloc(s->buf_queue, s->bytes_queue + UNROLL_PADDING); + s->buf_queue = realloc(s->buf_queue, s->bytes_queue); if (!s->buf_queue) { MP_FATAL(f, "Out of memory\n"); return false; @@ -548,9 +592,7 @@ static void af_scaletempo_destroy(struct mp_filter *f) struct priv *s = f->priv; free(s->buf_queue); free(s->buf_overlap); - free(s->buf_pre_corr); free(s->table_blend); - free(s->table_window); TA_FREEP(&s->in); mp_filter_free_children(f); } diff --git a/audio/out/ao.c b/audio/out/ao.c index 75fcbac6fa..ee20b736a3 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -241,7 +241,7 @@ static struct ao *ao_init(bool probing, struct mpv_global *global, } else { ao->sstride *= ao->channels.num; } - ao->bps = ao->samplerate * ao->sstride; + ao->bps = (int64_t)ao->samplerate * ao->sstride; if (ao->device_buffer <= 0 && ao->driver->write) { MP_ERR(ao, "Device buffer size not set.\n"); diff --git a/audio/out/ao_audiotrack.c b/audio/out/ao_audiotrack.c index db1da9c407..940bffbec9 100644 --- a/audio/out/ao_audiotrack.c +++ b/audio/out/ao_audiotrack.c @@ -564,7 +564,7 @@ static MP_THREAD_VOID ao_thread(void *arg) int64_t ts = mp_time_ns(); ts += MP_TIME_S_TO_NS(read_samples / (double)(ao->samplerate)); ts += MP_TIME_S_TO_NS(AudioTrack_getLatency(ao)); - int samples = ao_read_data_nonblocking(ao, &p->chunk, read_samples, ts); + int samples = ao_read_data(ao, &p->chunk, read_samples, ts, NULL, false, false); int ret = AudioTrack_write(ao, samples * ao->sstride); if (ret >= 0) { p->written_frames += ret / ao->sstride; diff --git a/audio/out/ao_audiounit.m b/audio/out/ao_audiounit.m index 85b1226dc9..d35912ceb8 100644 --- a/audio/out/ao_audiounit.m +++ b/audio/out/ao_audiounit.m @@ -97,7 +97,7 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags, int64_t end = mp_time_ns(); end += MP_TIME_S_TO_NS(p->device_latency); end += ca_get_latency(ts) + ca_frames_to_ns(ao, frames); - ao_read_data(ao, planes, frames, end); + ao_read_data(ao, planes, frames, end, NULL, true, true); return noErr; } diff --git a/audio/out/ao_avfoundation.m b/audio/out/ao_avfoundation.m index 7654916519..2e7d194b25 100644 --- a/audio/out/ao_avfoundation.m +++ b/audio/out/ao_avfoundation.m @@ -76,11 +76,14 @@ static void feed(struct ao *ao) int64_t cur_time_mp = mp_time_ns(); int64_t end_time_av = MPMAX(p->end_time_av, cur_time_av); int64_t time_delta = CMTimeGetNanoseconds(CMTimeMake(request_sample_count, samplerate)); - int real_sample_count = ao_read_data_nonblocking(ao, data, request_sample_count, end_time_av - cur_time_av + cur_time_mp + time_delta); + bool eof; + int real_sample_count = ao_read_data(ao, data, request_sample_count, end_time_av - cur_time_av + cur_time_mp + time_delta, &eof, false, true); + if (eof) { + [p->renderer stopRequestingMediaData]; + ao_stop_streaming(ao); + } if (real_sample_count == 0) { - // avoid spinning by blocking the thread - mp_sleep_ns(10000000); - goto finish; + return; } if ((err = CMBlockBufferCreateWithMemoryBlock( diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index 4abfac38ee..1b0f99a9d1 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -16,6 +16,7 @@ */ #include <CoreAudio/HostTime.h> +#include <libavutil/mathematics.h> #include "ao.h" #include "internal.h" @@ -90,7 +91,7 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags, int64_t end = mp_time_ns(); end += p->hw_latency_ns + ca_get_latency(ts) + ca_frames_to_ns(ao, frames); // don't use the returned sample count since CoreAudio always expects full frames - ao_read_data(ao, planes, frames, end); + ao_read_data(ao, planes, frames, end, NULL, true, true); return noErr; } @@ -178,6 +179,7 @@ static int init(struct ao *ao) goto coreaudio_error; reinit_latency(ao); + ao->device_buffer = av_rescale(p->hw_latency_ns, ao->samplerate, 1000000000) * 2; p->queue = dispatch_queue_create("io.mpv.coreaudio_stop_during_idle", DISPATCH_QUEUE_SERIAL); diff --git a/audio/out/ao_coreaudio_exclusive.c b/audio/out/ao_coreaudio_exclusive.c index 5e0ec3b19f..dbe7b94ed7 100644 --- a/audio/out/ao_coreaudio_exclusive.c +++ b/audio/out/ao_coreaudio_exclusive.c @@ -181,7 +181,7 @@ static OSStatus render_cb_compressed( end += p->hw_latency_ns + ca_get_latency(ts) + ca_frames_to_ns(ao, pseudo_frames); - ao_read_data(ao, &buf.mData, pseudo_frames, end); + ao_read_data(ao, &buf.mData, pseudo_frames, end, NULL, true, true); if (p->spdif_hack) bad_hack_mygodwhy(buf.mData, pseudo_frames * ao->channels.num); diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index 44604e6df2..78cdcad393 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -236,20 +236,20 @@ void ca_print_asbd(struct ao *ao, const char *description, int mpfmt = ca_asbd_to_mp_format(asbd); MP_VERBOSE(ao, - "%s %7.1fHz %" PRIu32 "bit %s " - "[%" PRIu32 "][%" PRIu32 "bpp][%" PRIu32 "fbp]" - "[%" PRIu32 "bpf][%" PRIu32 "ch] " - "%s %s %s%s%s%s (%s)\n", - description, asbd->mSampleRate, asbd->mBitsPerChannel, format, - asbd->mFormatFlags, asbd->mBytesPerPacket, asbd->mFramesPerPacket, - asbd->mBytesPerFrame, asbd->mChannelsPerFrame, - (flags & kAudioFormatFlagIsFloat) ? "float" : "int", - (flags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE", - (flags & kAudioFormatFlagIsSignedInteger) ? "S" : "U", - (flags & kAudioFormatFlagIsPacked) ? " packed" : "", - (flags & kAudioFormatFlagIsAlignedHigh) ? " aligned" : "", - (flags & kAudioFormatFlagIsNonInterleaved) ? " P" : "", - mpfmt ? af_fmt_to_str(mpfmt) : "-"); + "%s %7.1fHz %" PRIu32 "bit %s " + "[%" PRIu32 "][%" PRIu32 "bpp][%" PRIu32 "fbp]" + "[%" PRIu32 "bpf][%" PRIu32 "ch] " + "%s %s %s%s%s%s (%s)\n", + description, asbd->mSampleRate, asbd->mBitsPerChannel, format, + asbd->mFormatFlags, asbd->mBytesPerPacket, asbd->mFramesPerPacket, + asbd->mBytesPerFrame, asbd->mChannelsPerFrame, + (flags & kAudioFormatFlagIsFloat) ? "float" : "int", + (flags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE", + (flags & kAudioFormatFlagIsSignedInteger) ? "S" : "U", + (flags & kAudioFormatFlagIsPacked) ? " packed" : "", + (flags & kAudioFormatFlagIsAlignedHigh) ? " aligned" : "", + (flags & kAudioFormatFlagIsNonInterleaved) ? " P" : "", + mpfmt ? af_fmt_to_str(mpfmt) : "-"); } // Return whether new is an improvement over old. Assume a higher value means diff --git a/audio/out/ao_jack.c b/audio/out/ao_jack.c index 412e91d626..bd1a19e67a 100644 --- a/audio/out/ao_jack.c +++ b/audio/out/ao_jack.c @@ -26,7 +26,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include "config.h" #include "common/msg.h" @@ -125,7 +124,7 @@ static int process(jack_nframes_t nframes, void *arg) int64_t end_time = mp_time_ns(); end_time += MP_TIME_S_TO_NS((jack_latency + nframes) / (double)ao->samplerate); - ao_read_data(ao, buffers, nframes, end_time); + ao_read_data(ao, buffers, nframes, end_time, NULL, true, true); return 0; } diff --git a/audio/out/ao_opensles.c b/audio/out/ao_opensles.c index ddcff1904a..6d4b6a78db 100644 --- a/audio/out/ao_opensles.c +++ b/audio/out/ao_opensles.c @@ -81,7 +81,7 @@ static void buffer_callback(SLBufferQueueItf buffer_queue, void *context) delay = p->frames_per_enqueue / (double)ao->samplerate; delay += p->audio_latency; ao_read_data(ao, &p->buf, p->frames_per_enqueue, - mp_time_ns() + MP_TIME_S_TO_NS(delay)); + mp_time_ns() + MP_TIME_S_TO_NS(delay), NULL, true, true); res = (*buffer_queue)->Enqueue(buffer_queue, p->buf, p->bytes_per_enqueue); if (res != SL_RESULT_SUCCESS) diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c index afe5839dd5..31e4700b40 100644 --- a/audio/out/ao_oss.c +++ b/audio/out/ao_oss.c @@ -25,7 +25,6 @@ #include <errno.h> #include <fcntl.h> #include <stdio.h> -#include <unistd.h> #include <sys/ioctl.h> #include <sys/soundcard.h> @@ -328,7 +327,7 @@ static bool audio_write(struct ao *ao, void **data, int samples) while ((rc = write(p->dsp_fd, data[0], size)) == -1) { if (errno == EINTR) - continue; + continue; MP_WARN(ao, "audio_write: write() fail, err = %i: %s.\n", errno, mp_strerror(errno)); return false; diff --git a/audio/out/ao_pcm.c b/audio/out/ao_pcm.c index 4097aa3bd6..71650c39e3 100644 --- a/audio/out/ao_pcm.c +++ b/audio/out/ao_pcm.c @@ -86,7 +86,7 @@ static void write_wave_header(struct ao *ao, FILE *fp, uint64_t data_length) fput16le(WAV_ID_FORMAT_EXTENSIBLE, fp); fput16le(ao->channels.num, fp); fput32le(ao->samplerate, fp); - fput32le(ao->bps, fp); + fput32le(MPCLAMP(ao->bps, 0, UINT32_MAX), fp); fput16le(ao->channels.num * (bits / 8), fp); fput16le(bits, fp); @@ -145,7 +145,7 @@ static int init(struct ao *ao) if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels)) return -1; - ao->bps = ao->channels.num * ao->samplerate * af_fmt_to_bytes(ao->format); + ao->bps = ao->channels.num * (int64_t)ao->samplerate * af_fmt_to_bytes(ao->format); MP_INFO(ao, "File: %s (%s)\nPCM: Samplerate: %d Hz Channels: %d Format: %s\n", outputfilename, diff --git a/audio/out/ao_pipewire.c b/audio/out/ao_pipewire.c index 94d393a26d..a04ae9d3d0 100644 --- a/audio/out/ao_pipewire.c +++ b/audio/out/ao_pipewire.c @@ -38,7 +38,7 @@ #if !PW_CHECK_VERSION(0, 3, 50) static inline int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size) { - return pw_stream_get_time(stream, time); + return pw_stream_get_time(stream, time); } #endif @@ -206,7 +206,7 @@ static void on_process(void *userdata) #endif end_time -= pw_stream_get_nsec(p->stream) - time.now; - int samples = ao_read_data_nonblocking(ao, data, nframes, end_time); + int samples = ao_read_data(ao, data, nframes, end_time, NULL, false, false); b->size = samples; for (int i = 0; i < buf->n_datas; i++) { diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c index 5c86855d71..95a7fb0ea8 100644 --- a/audio/out/ao_pulse.c +++ b/audio/out/ao_pulse.c @@ -209,25 +209,25 @@ static pa_encoding_t map_digital_format(int format) } static const int speaker_map[][2] = { - {PA_CHANNEL_POSITION_FRONT_LEFT, MP_SPEAKER_ID_FL}, - {PA_CHANNEL_POSITION_FRONT_RIGHT, MP_SPEAKER_ID_FR}, - {PA_CHANNEL_POSITION_FRONT_CENTER, MP_SPEAKER_ID_FC}, - {PA_CHANNEL_POSITION_REAR_CENTER, MP_SPEAKER_ID_BC}, - {PA_CHANNEL_POSITION_REAR_LEFT, MP_SPEAKER_ID_BL}, - {PA_CHANNEL_POSITION_REAR_RIGHT, MP_SPEAKER_ID_BR}, - {PA_CHANNEL_POSITION_LFE, MP_SPEAKER_ID_LFE}, - {PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, MP_SPEAKER_ID_FLC}, - {PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, MP_SPEAKER_ID_FRC}, - {PA_CHANNEL_POSITION_SIDE_LEFT, MP_SPEAKER_ID_SL}, - {PA_CHANNEL_POSITION_SIDE_RIGHT, MP_SPEAKER_ID_SR}, - {PA_CHANNEL_POSITION_TOP_CENTER, MP_SPEAKER_ID_TC}, - {PA_CHANNEL_POSITION_TOP_FRONT_LEFT, MP_SPEAKER_ID_TFL}, - {PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, MP_SPEAKER_ID_TFR}, - {PA_CHANNEL_POSITION_TOP_FRONT_CENTER, MP_SPEAKER_ID_TFC}, - {PA_CHANNEL_POSITION_TOP_REAR_LEFT, MP_SPEAKER_ID_TBL}, - {PA_CHANNEL_POSITION_TOP_REAR_RIGHT, MP_SPEAKER_ID_TBR}, - {PA_CHANNEL_POSITION_TOP_REAR_CENTER, MP_SPEAKER_ID_TBC}, - {PA_CHANNEL_POSITION_INVALID, -1} + {PA_CHANNEL_POSITION_FRONT_LEFT, MP_SPEAKER_ID_FL}, + {PA_CHANNEL_POSITION_FRONT_RIGHT, MP_SPEAKER_ID_FR}, + {PA_CHANNEL_POSITION_FRONT_CENTER, MP_SPEAKER_ID_FC}, + {PA_CHANNEL_POSITION_REAR_CENTER, MP_SPEAKER_ID_BC}, + {PA_CHANNEL_POSITION_REAR_LEFT, MP_SPEAKER_ID_BL}, + {PA_CHANNEL_POSITION_REAR_RIGHT, MP_SPEAKER_ID_BR}, + {PA_CHANNEL_POSITION_LFE, MP_SPEAKER_ID_LFE}, + {PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, MP_SPEAKER_ID_FLC}, + {PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, MP_SPEAKER_ID_FRC}, + {PA_CHANNEL_POSITION_SIDE_LEFT, MP_SPEAKER_ID_SL}, + {PA_CHANNEL_POSITION_SIDE_RIGHT, MP_SPEAKER_ID_SR}, + {PA_CHANNEL_POSITION_TOP_CENTER, MP_SPEAKER_ID_TC}, + {PA_CHANNEL_POSITION_TOP_FRONT_LEFT, MP_SPEAKER_ID_TFL}, + {PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, MP_SPEAKER_ID_TFR}, + {PA_CHANNEL_POSITION_TOP_FRONT_CENTER, MP_SPEAKER_ID_TFC}, + {PA_CHANNEL_POSITION_TOP_REAR_LEFT, MP_SPEAKER_ID_TBL}, + {PA_CHANNEL_POSITION_TOP_REAR_RIGHT, MP_SPEAKER_ID_TBR}, + {PA_CHANNEL_POSITION_TOP_REAR_CENTER, MP_SPEAKER_ID_TBC}, + {PA_CHANNEL_POSITION_INVALID, -1} }; static bool chmap_pa_from_mp(pa_channel_map *dst, struct mp_chmap *src) diff --git a/audio/out/ao_sdl.c b/audio/out/ao_sdl.c index 5a6a58b124..5fa8ebbd56 100644 --- a/audio/out/ao_sdl.c +++ b/audio/out/ao_sdl.c @@ -61,7 +61,7 @@ static void audio_callback(void *userdata, Uint8 *stream, int len) // fixed latency. double delay = 2 * len / (double)ao->bps; - ao_read_data(ao, data, len / ao->sstride, mp_time_ns() + MP_TIME_S_TO_NS(delay)); + ao_read_data(ao, data, len / ao->sstride, mp_time_ns() + MP_TIME_S_TO_NS(delay), NULL, true, true); } static void uninit(struct ao *ao) diff --git a/audio/out/ao_wasapi_changenotify.c b/audio/out/ao_wasapi_changenotify.c index f0e1895305..7f1c16794f 100644 --- a/audio/out/ao_wasapi_changenotify.c +++ b/audio/out/ao_wasapi_changenotify.c @@ -155,6 +155,11 @@ static HRESULT STDMETHODCALLTYPE sIMMNotificationClient_OnDefaultDeviceChanged( return S_OK; } +// IsEqualIID in Windows SDK passes GUID as REFGUID (reference) in C++, but in +// C is has to get pointers... +#undef IsEqualPropertyKey +#define IsEqualPropertyKey(a, b) (((a).pid == (b).pid) && IsEqualIID(&(a).fmtid, &(b).fmtid)) + static HRESULT STDMETHODCALLTYPE sIMMNotificationClient_OnPropertyValueChanged( IMMNotificationClient *This, LPCWSTR pwstrDeviceId, |