]> git.sesse.net Git - nageru/commitdiff
Make audio input source selectable.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 25 Jan 2016 23:15:51 +0000 (00:15 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 25 Jan 2016 23:15:51 +0000 (00:15 +0100)
README
glwidget.cpp
glwidget.h
mixer.cpp
mixer.h

diff --git a/README b/README
index e140ce72643868fbaa5e995ef5dc956d742c3d09..747588a3d1118ad5dc2cec0b7655fe4e083471c8 100644 (file)
--- 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
index e71ac405721bf53d94fb3caffd05711ee8c17f06..e09060f4949c12ab1258de5ac9616b3155dfa8d8 100644 (file)
@@ -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);
        }
index ed5e48696ebf6f7bf606e86b9fb89f21db4b716b..b0dc79ed09e5e4ef49101e9f8f97761989548560 100644 (file)
@@ -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;
index 4b92041396bb896f67fa806c171d5edc7340c88b..133fc28108a9b50e68e1e7ffa46848313a5e3d65 100644 (file)
--- 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<float> samples_card;
        vector<float> 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 32e8168f64cc96a62c3cdc58a51d4773417c7e48..ef112b8c73c07648bba43fd262d3f54c87fc5094 100644 (file)
--- 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<movit::ResourcePool> resource_pool;
        std::unique_ptr<Theme> theme;
+       std::atomic<unsigned> audio_source_channel{0};
        std::unique_ptr<movit::EffectChain> display_chain;
        GLuint cbcr_program_num;  // Owned by <resource_pool>.
        std::unique_ptr<H264Encoder> h264_encoder;