Beispiel #1
0
static int init(struct ao *ao)
{
    struct priv *priv = ao->priv;

    ao->untimed = priv->untimed;

    struct mp_chmap_sel sel = {.tmp = ao};
    if (priv->channel_layouts) {
        for (int n = 0; priv->channel_layouts[n]; n++) {
            struct mp_chmap map = {0};
            if (!mp_chmap_from_str(&map, bstr0(priv->channel_layouts[n]))) {
                MP_FATAL(ao, "Invalid channel map in option.\n");
                return -1;
            }
            mp_chmap_sel_add_map(&sel, &map);
        }
    } else {
        mp_chmap_sel_add_any(&sel);
    }
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        mp_chmap_from_channels(&ao->channels, 2);

    priv->latency = priv->latency_sec * ao->samplerate;

    // A "buffer" for this many seconds of audio
    int bursts = (int)(ao->samplerate * priv->bufferlen + 1) / priv->outburst;
    priv->buffersize = priv->outburst * bursts + priv->latency;

    priv->last_time = mp_time_sec();

    return 0;
}
Beispiel #2
0
static bool chmap_from_waveformat(struct mp_chmap *channels,
                                  const WAVEFORMATEX *wf)
{
    if (wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
        WAVEFORMATEXTENSIBLE *wformat = (WAVEFORMATEXTENSIBLE *)wf;
        mp_chmap_from_waveext(channels, wformat->dwChannelMask);
    } else {
        mp_chmap_from_channels(channels, wf->nChannels);
    }

    if (channels->num != wf->nChannels) {
        mp_chmap_from_str(channels, bstr0("empty"));
        return false;
    }

    return true;
}
Beispiel #3
0
int AudioController::reinitialize(mp_audio *in) {
	if (!in)
		return AF_ERROR;
	auto makeFormat = [] (const mp_audio *audio) {
		AudioFormat format;
		format.m_samplerate = audio->rate/1000.0; // kHz
		format.m_bitrate = audio->rate*audio->nch*audio->bps*8;
		format.m_bits = audio->bps*8;
		format.m_channels = ChannelLayoutInfo::description(ChannelLayoutMap::toLayout(audio->channels));
		format.m_type = af_fmt_to_str(audio->format);
		return format;
	};
	d->input = makeFormat(in);
	auto out = d->af->data;
	out->rate = in->rate;
	bool ret = true;
	if (!isSupported(in->format)) {
		ret = false;
		mp_audio_set_format(in, af_fmt_is_planar(in->format) ? AF_FORMAT_FLOATP : AF_FORMAT_FLOAT);
	}
	if (d->fmt_conv) {
		mp_audio_set_format(out, d->fmt_conv);
		d->fmt_conv = AF_FORMAT_UNKNOWN;
	} else
		mp_audio_set_format(out, in->format);
	d->chmap = in->channels;
	if (!mp_chmap_from_str(&d->chmap, bstr0(ChannelLayoutInfo::data(d->layout).constData())))
		_Error("Cannot find matched channel layout for '%%'", ChannelLayoutInfo::description(d->layout));
	mp_audio_set_channels(out, &d->chmap);
	if (d->outrate != 0)
		out->rate = d->outrate;
	if (!ret)
		return false;
	d->af->mul = (double)out->channels.num/in->channels.num;
	if (d->tempoScalerActivated)
		d->af->mul /= d->scale;
	if ((d->resample = out->rate != in->rate)) {
		d->af->mul *= (double)out->rate/in->rate;
		const auto nch = in->channels.num;/*mp_chmap_to_lavc_unchecked(&in->channels);*/
		const auto fmt = af_to_avformat(in->format);
		if (!d->swr)
			d->swr = swr_alloc();
		av_opt_set_int(d->swr,  "in_channel_count", nch, 0);
		av_opt_set_int(d->swr, "out_channel_count", nch, 0);
		av_opt_set_int(d->swr,  "in_sample_rate", in->rate, 0);
		av_opt_set_int(d->swr, "out_sample_rate", out->rate, 0);
		av_opt_set_sample_fmt(d->swr,  "in_sample_fmt", fmt, 0);
		av_opt_set_sample_fmt(d->swr, "out_sample_fmt", fmt, 0);
		swr_init(d->swr);
		if (!d->resampled)
			d->resampled = talloc_zero(nullptr, mp_audio);
		*d->resampled = *in;
		d->resampled->rate = out->rate;
		in = d->resampled;
	}
	d->output = makeFormat(out);
	const AudioDataFormat fmt_in(*in), fmt_out(*out);
	check(d->mixer, d->clip, fmt_in, fmt_out);
	d->mixer->setOutput(out);
	d->mixer->setChannelLayoutMap(d->map);
	d->dirty = 0xffffffff;
	return true;
}