static int build_afilter_chain(struct MPContext *mpctx) { struct sh_audio *sh_audio = mpctx->sh_audio; struct ao *ao = mpctx->ao; struct MPOpts *opts = mpctx->opts; int new_srate; if (af_control_any_rev(sh_audio->afilter, AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET, &opts->playback_speed)) new_srate = sh_audio->samplerate; else { new_srate = sh_audio->samplerate * opts->playback_speed; if (new_srate != ao->samplerate) { // limits are taken from libaf/af_resample.c if (new_srate < 8000) new_srate = 8000; if (new_srate > 192000) new_srate = 192000; opts->playback_speed = (double)new_srate / sh_audio->samplerate; } } return init_audio_filters(sh_audio, new_srate, &ao->samplerate, &ao->channels, &ao->format); }
void reinit_audio_chain(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; init_demux_stream(mpctx, STREAM_AUDIO); if (!mpctx->sh_audio) { uninit_player(mpctx, INITIALIZED_AO); goto no_audio; } if (!(mpctx->initialized_flags & INITIALIZED_ACODEC)) { if (!init_best_audio_codec(mpctx->sh_audio, opts->audio_decoders)) goto init_error; mpctx->initialized_flags |= INITIALIZED_ACODEC; } int ao_srate = opts->force_srate; int ao_format = opts->audio_output_format; struct mp_chmap ao_channels = {0}; if (mpctx->initialized_flags & INITIALIZED_AO) { ao_srate = mpctx->ao->samplerate; ao_format = mpctx->ao->format; ao_channels = mpctx->ao->channels; } else { // Automatic downmix if (mp_chmap_is_stereo(&opts->audio_output_channels) && !mp_chmap_is_stereo(&mpctx->sh_audio->channels)) { mp_chmap_from_channels(&ao_channels, 2); } } // Determine what the filter chain outputs. build_afilter_chain() also // needs this for testing whether playback speed is changed by resampling // or using a special filter. if (!init_audio_filters(mpctx->sh_audio, // preliminary init // input: mpctx->sh_audio->samplerate, // output: &ao_srate, &ao_channels, &ao_format)) { MP_ERR(mpctx, "Error at audio filter chain pre-init!\n"); goto init_error; } if (!(mpctx->initialized_flags & INITIALIZED_AO)) { mpctx->initialized_flags |= INITIALIZED_AO; mp_chmap_remove_useless_channels(&ao_channels, &opts->audio_output_channels); mpctx->ao = ao_init_best(mpctx->global, mpctx->input, mpctx->encode_lavc_ctx, ao_srate, ao_format, ao_channels); struct ao *ao = mpctx->ao; if (!ao) { MP_ERR(mpctx, "Could not open/initialize audio device -> no sound.\n"); goto init_error; } ao->buffer.start = talloc_new(ao); char *s = mp_audio_fmt_to_str(ao->samplerate, &ao->channels, ao->format); MP_INFO(mpctx, "AO: [%s] %s\n", ao->driver->name, s); talloc_free(s); MP_VERBOSE(mpctx, "AO: Description: %s\n", ao->driver->description); update_window_title(mpctx, true); } if (recreate_audio_filters(mpctx) < 0) goto init_error; mpctx->syncing_audio = true; return; init_error: uninit_player(mpctx, INITIALIZED_ACODEC | INITIALIZED_AO); cleanup_demux_stream(mpctx, STREAM_AUDIO); no_audio: mpctx->current_track[STREAM_AUDIO] = NULL; MP_INFO(mpctx, "Audio: no audio\n"); }
/* Init audio filters */ int preinit_audio_filters(sh_audio_t *sh_audio, int in_samplerate, int in_channels, int in_format, int* out_samplerate, int* out_channels, int* out_format){ return init_audio_filters(sh_audio, in_samplerate, in_channels, in_format, out_samplerate, out_channels, out_format, 0, 0); }