static Bool audiobuffer_get_config(GF_AudioInterface *aifc, Bool for_reconf) { AudioBufferStack *st = (AudioBufferStack *) gf_node_get_private( ((GF_AudioInput *) aifc->callback)->owner); if (gf_mixer_must_reconfig(st->am)) { if (gf_mixer_reconfig(st->am)) { if (st->buffer) gf_free(st->buffer); st->buffer = NULL; st->buffer_size = 0; } gf_mixer_get_config(st->am, &aifc->samplerate, &aifc->chan, &aifc->bps, &aifc->ch_cfg); st->is_init = (aifc->samplerate && aifc->chan && aifc->bps) ? 1 : 0; assert(st->is_init); if (!st->is_init) aifc->samplerate = aifc->chan = aifc->bps = aifc->ch_cfg = 0; /*this will force invalidation*/ return (for_reconf && st->is_init) ? 1 : 0; } return st->is_init; }
GF_EXPORT GF_Err gf_sc_add_audio_listener(GF_Compositor *compositor, GF_AudioListener *al) { GF_AudioMixer *mixer; u32 sr, ch, bps, ch_cfg; if (!compositor || !al || !al->on_audio_frame || !al->on_audio_reconfig) return GF_BAD_PARAM; if (!compositor->audio_renderer) return GF_NOT_SUPPORTED; mixer = compositor->audio_renderer->mixer; gf_mixer_lock(mixer, GF_TRUE); if (!compositor->audio_renderer->audio_listeners) compositor->audio_renderer->audio_listeners = gf_list_new(); gf_list_add(compositor->audio_renderer->audio_listeners, al); gf_mixer_get_config(mixer, &sr, &ch, &bps, &ch_cfg); al->on_audio_reconfig(al->udta, sr, bps, ch, ch_cfg); gf_mixer_lock(mixer, GF_FALSE); return GF_OK; }
static GF_Err gf_ar_setup_output_format(GF_AudioRenderer *ar) { GF_Err e; u32 freq, nb_bits, nb_chan, ch_cfg; u32 in_ch, in_cfg, in_bps, in_freq; gf_mixer_get_config(ar->mixer, &freq, &nb_chan, &nb_bits, &ch_cfg); /*user disabled multichannel audio*/ if (ar->disable_multichannel && (nb_chan>2) ) nb_chan = 2; in_ch = nb_chan; in_cfg = ch_cfg; in_bps = nb_bits; in_freq = freq; if (ar->filter_chain.filters) { u32 osr, obps, och, ocfg; e = gf_afc_setup(&ar->filter_chain, nb_bits, freq, nb_chan, ch_cfg, &och, &ocfg); osr = freq; obps = nb_bits; nb_chan = och; /*try to reconfigure audio output*/ if (!e) e = ar->audio_out->ConfigureOutput(ar->audio_out, &osr, &och, &obps, ocfg); /*output module cannot support filter output, disable it ...*/ if (e || (osr != freq) || (och != nb_chan) || (obps != nb_bits)) { nb_bits = in_bps; freq = in_freq; nb_chan = in_ch; ar->filter_chain.enable_filters = GF_FALSE; e = ar->audio_out->ConfigureOutput(ar->audio_out, &freq, &nb_chan, &nb_bits, ch_cfg); } } else { e = ar->audio_out->ConfigureOutput(ar->audio_out, &freq, &nb_chan, &nb_bits, ch_cfg); } if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[AudioRender] reconfigure error %d\n", e)); if (nb_chan>2) { nb_chan=2; in_ch=2; ch_cfg=0; e = ar->audio_out->ConfigureOutput(ar->audio_out, &freq, &nb_chan, &nb_bits, ch_cfg); } if (e) return e; } gf_mixer_set_config(ar->mixer, freq, nb_chan, nb_bits, in_cfg); ar->audio_delay = ar->audio_out->GetAudioDelay(ar->audio_out); ar->audio_out->SetVolume(ar->audio_out, ar->volume); ar->audio_out->SetPan(ar->audio_out, ar->pan); ar->time_at_last_config = ar->current_time; ar->bytes_requested = 0; ar->bytes_per_second = freq * nb_chan * nb_bits / 8; if (ar->audio_listeners) { u32 k=0; GF_AudioListener *l; while ((l = (GF_AudioListener*)gf_list_enum(ar->audio_listeners, &k))) { l->on_audio_reconfig(l->udta, in_freq, in_bps, in_ch, in_cfg); } } return GF_OK; }