From: Steinar H. Gunderson Date: Mon, 25 Jan 2016 23:15:51 +0000 (+0100) Subject: Make audio input source selectable. X-Git-Tag: 1.0.0~1 X-Git-Url: https://git.sesse.net/?p=nageru;a=commitdiff_plain;h=adaeecd2ab8f1da45169861b7af22a0c7af066be Make audio input source selectable. --- diff --git a/README b/README index e140ce7..747588a 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ Nageru is a live video mixer, based around the standard M/E workflow. -Features (those marked with * are still in progress or not started yet): +Features: - High performance on modest hardware (720p60 with two input streams on my Thinkpad X240[1]); almost all pixel processing is done on the GPU. @@ -11,8 +11,9 @@ Features (those marked with * are still in progress or not started yet): for intermediate calculations, dithered output. - Proper sound support: Syncing of multiple unrelated sources through - high-quality resampling, mixing (*), cue out for headphones, - dynamic range compression, fixed EQ, level meters conforming to EBU R128. + high-quality resampling, freely selectable input, cue out for headphones, + dynamic range compression, simple EQ (lowpass), level meters conforming + to EBU R128. - Theme engine encapsulating the design demands of each individual event; Lua code is responsible for setting up the pixel processing diff --git a/glwidget.cpp b/glwidget.cpp index e71ac40..e09060f 100644 --- a/glwidget.cpp +++ b/glwidget.cpp @@ -112,11 +112,13 @@ void GLWidget::mousePressEvent(QMouseEvent *event) emit clicked(); } -void GLWidget::show_context_menu(int signal_num, const QPoint &pos) +void GLWidget::show_context_menu(unsigned signal_num, const QPoint &pos) { QPoint global_pos = mapToGlobal(pos); QMenu menu; + + // Add an action for each card. QActionGroup group(&menu); unsigned num_cards = global_mixer->get_num_cards(); @@ -131,8 +133,22 @@ void GLWidget::show_context_menu(int signal_num, const QPoint &pos) action->setData(card_index); menu.addAction(action); } + + menu.addSeparator(); + + // Add an audio source selector. + QAction *audio_source_action = new QAction("Use as audio source", &menu); + audio_source_action->setCheckable(true); + if (global_mixer->get_audio_source() == signal_num) { + audio_source_action->setChecked(true); + audio_source_action->setEnabled(false); + } + menu.addAction(audio_source_action); + QAction *selected_item = menu.exec(global_pos); - if (selected_item) { + if (selected_item == audio_source_action) { + global_mixer->set_audio_source(signal_num); + } else if (selected_item != nullptr) { unsigned card_index = selected_item->data().toInt(nullptr); global_mixer->set_signal_mapping(signal_num, card_index); } diff --git a/glwidget.h b/glwidget.h index ed5e486..b0dc79e 100644 --- a/glwidget.h +++ b/glwidget.h @@ -49,7 +49,7 @@ signals: void resolution_updated(Mixer::Output output); private slots: - void show_context_menu(int signal_num, const QPoint &pos); + void show_context_menu(unsigned signal_num, const QPoint &pos); private: Mixer::Output output; diff --git a/mixer.cpp b/mixer.cpp index 4b92041..133fc28 100644 --- a/mixer.cpp +++ b/mixer.cpp @@ -692,6 +692,11 @@ void Mixer::process_audio_one_frame(int64_t frame_pts_int, int num_samples) { vector samples_card; vector samples_out; + + // TODO: Allow mixing audio from several sources. + unsigned selected_audio_card = theme->map_signal(audio_source_channel); + assert(selected_audio_card < num_cards); + for (unsigned card_index = 0; card_index < num_cards; ++card_index) { samples_card.resize(num_samples * 2); { @@ -700,8 +705,7 @@ void Mixer::process_audio_one_frame(int64_t frame_pts_int, int num_samples) printf("Card %d reported previous underrun.\n", card_index); } } - // TODO: Allow using audio from the other card(s) as well. - if (card_index == 0) { + if (card_index == selected_audio_card) { samples_out = move(samples_card); } } diff --git a/mixer.h b/mixer.h index 32e8168..ef112b8 100644 --- a/mixer.h +++ b/mixer.h @@ -136,6 +136,16 @@ public: return theme->map_signal(channel); } + unsigned get_audio_source() const + { + return audio_source_channel; + } + + void set_audio_source(unsigned channel) + { + audio_source_channel = channel; + } + void set_signal_mapping(int signal, int card) { return theme->set_signal_mapping(signal, card); @@ -249,6 +259,7 @@ private: QSurface *mixer_surface, *h264_encoder_surface; std::unique_ptr resource_pool; std::unique_ptr theme; + std::atomic audio_source_channel{0}; std::unique_ptr display_chain; GLuint cbcr_program_num; // Owned by . std::unique_ptr h264_encoder;