]> git.sesse.net Git - casparcg/commitdiff
Merged OSC audio levels sending
authorHelge Norberg <helge.norberg@svt.se>
Fri, 21 Aug 2015 12:42:04 +0000 (14:42 +0200)
committerHelge Norberg <helge.norberg@svt.se>
Fri, 21 Aug 2015 12:42:04 +0000 (14:42 +0200)
core/mixer/audio/audio_mixer.cpp
core/mixer/audio/audio_mixer.h
core/mixer/mixer.cpp
core/mixer/mixer.h
core/video_channel.cpp

index eb2f12052840eb2f8c71c6b85fe29d8182d6152f..a030526e9598a3494cb33f8422fd754f7952101c 100644 (file)
 
 #include <core/frame/frame.h>
 #include <core/frame/frame_transform.h>
+#include <core/monitor/monitor.h>
+
 #include <common/diagnostics/graph.h>
 #include <common/linq.h>
 
 #include <boost/range/adaptors.hpp>
 #include <boost/range/distance.hpp>
+#include <boost/lexical_cast.hpp>
 
 #include <map>
 #include <stack>
@@ -66,6 +69,7 @@ struct audio_stream
 
 struct audio_mixer::impl : boost::noncopyable
 {
+       monitor::subject                                        monitor_subject_                { "/audio" };
        std::stack<core::audio_transform>       transform_stack_;
        std::map<const void*, audio_stream>     audio_streams_;
        std::vector<audio_item>                         items_;
@@ -73,9 +77,12 @@ struct audio_mixer::impl : boost::noncopyable
        video_format_desc                                       format_desc_;
        float                                                           master_volume_                  = 1.0f;
        float                                                           previous_master_volume_ = master_volume_;
+       spl::shared_ptr<diagnostics::graph>     graph_;
 public:
-       impl()
+       impl(spl::shared_ptr<diagnostics::graph> graph)
+               : graph_(std::move(graph))
        {
+               graph_->set_color("volume", diagnostics::color(1.0f, 0.8f, 0.1f));
                transform_stack_.push(core::audio_transform());
        }
        
@@ -209,6 +216,32 @@ public:
                result.reserve(result_ps.size());
                boost::range::transform(result_ps, std::back_inserter(result), [](float sample){return static_cast<int32_t>(sample);});         
                
+               const int num_channels = format_desc_.audio_channels;
+               monitor_subject_ << monitor::message("/nb_channels") % num_channels;
+
+               auto max = std::vector<int32_t>(num_channels, std::numeric_limits<int32_t>::min());
+
+               for (size_t n = 0; n < result.size(); n += num_channels)
+                       for (int ch = 0; ch < num_channels; ++ch)
+                               max[ch] = std::max(max[ch], std::abs(result[n + ch]));
+
+               // Makes the dBFS of silence => -dynamic range of 32bit LPCM => about -192 dBFS
+               // Otherwise it would be -infinity
+               static const auto MIN_PFS = 0.5f / static_cast<float>(std::numeric_limits<int32_t>::max());
+
+               for (int i = 0; i < num_channels; ++i)
+               {
+                       const auto pFS = max[i] / static_cast<float>(std::numeric_limits<int32_t>::max());
+                       const auto dBFS = 20.0f * std::log10(std::max(MIN_PFS, pFS));
+
+                       auto chan_str = boost::lexical_cast<std::string>(i + 1);
+
+                       monitor_subject_ << monitor::message("/" + chan_str + "/pFS") % pFS;
+                       monitor_subject_ << monitor::message("/" + chan_str + "/dBFS") % dBFS;
+               }
+
+               graph_->set_value("volume", static_cast<double>(*boost::max_element(max)) / std::numeric_limits<int32_t>::max());
+
                return result;
        }
 
@@ -218,12 +251,13 @@ public:
        }
 };
 
-audio_mixer::audio_mixer() : impl_(new impl()){}
+audio_mixer::audio_mixer(spl::shared_ptr<diagnostics::graph> graph) : impl_(new impl(std::move(graph))){}
 void audio_mixer::push(const frame_transform& transform){impl_->push(transform);}
 void audio_mixer::visit(const const_frame& frame){impl_->visit(frame);}
 void audio_mixer::pop(){impl_->pop();}
 void audio_mixer::set_master_volume(float volume) { impl_->set_master_volume(volume); }
 float audio_mixer::get_master_volume() { return impl_->get_master_volume(); }
 audio_buffer audio_mixer::operator()(const video_format_desc& format_desc){ return impl_->mix(format_desc); }
+monitor::subject& audio_mixer::monitor_output(){ return impl_->monitor_subject_; }
 
 }}
index 4764d89cf45e9f6fdb54a5e3492c76951d07383a..1a93008fec5349d8b743bbec7d81e1b7fa1fe412 100644 (file)
@@ -26,6 +26,7 @@
 #include <common/cache_aligned_vector.h>
 
 #include <core/frame/frame_visitor.h>
+#include <core/monitor/monitor.h>
 
 #include <vector>
 #include <cstdint>
@@ -46,13 +47,14 @@ public:
 
        // Constructors
 
-       audio_mixer();
+       audio_mixer(spl::shared_ptr<diagnostics::graph> graph);
 
        // Methods
        
        audio_buffer operator()(const struct video_format_desc& format_desc);
        void set_master_volume(float volume); 
        float get_master_volume();
+       monitor::subject& monitor_output();
 
        // frame_visitor
 
index 8562dbb8d1da122b2fe3678f5a6f7ca662721d95..021d2c5ab76d238655a3d86aab116ac3bbe173dc 100644 (file)
@@ -56,12 +56,13 @@ namespace caspar { namespace core {
 struct mixer::impl : boost::noncopyable
 {
        int                                                                     channel_index_;
-       spl::shared_ptr<diagnostics::graph> graph_;
+       spl::shared_ptr<diagnostics::graph>     graph_;
        tbb::atomic<int64_t>                            current_mix_time_;
-       audio_mixer                                                     audio_mixer_;
+       spl::shared_ptr<monitor::subject>       monitor_subject_        = spl::make_shared<monitor::subject>("/mixer");
+       audio_mixer                                                     audio_mixer_            { graph_ };
        spl::shared_ptr<image_mixer>            image_mixer_;
                        
-       executor                                                        executor_               { L"mixer " + boost::lexical_cast<std::wstring>(channel_index_) };
+       executor                                                        executor_                       { L"mixer " + boost::lexical_cast<std::wstring>(channel_index_) };
 
 public:
        impl(int channel_index, spl::shared_ptr<diagnostics::graph> graph, spl::shared_ptr<image_mixer> image_mixer) 
@@ -71,6 +72,7 @@ public:
        {                       
                graph_->set_color("mix-time", diagnostics::color(1.0f, 0.0f, 0.9f, 0.8f));
                current_mix_time_ = 0;
+               audio_mixer_.monitor_output().attach_parent(monitor_subject_);
        }
        
        const_frame operator()(std::map<int, draw_frame> frames, const video_format_desc& format_desc)
@@ -154,4 +156,5 @@ std::future<boost::property_tree::wptree> mixer::info() const{return impl_->info
 std::future<boost::property_tree::wptree> mixer::delay_info() const{ return impl_->delay_info(); }
 const_frame mixer::operator()(std::map<int, draw_frame> frames, const video_format_desc& format_desc){ return (*impl_)(std::move(frames), format_desc); }
 mutable_frame mixer::create_frame(const void* tag, const core::pixel_format_desc& desc) {return impl_->image_mixer_->create_frame(tag, desc);}
+monitor::subject& mixer::monitor_output() { return *impl_->monitor_subject_; }
 }}
index 6bd6197d53960273640e5b94a684ef415795716d..dbd23309239754f51393e6d086edabd8c88cb402 100644 (file)
@@ -29,6 +29,7 @@
 #include <common/reactive.h>
 
 #include <core/fwd.h>
+#include <core/monitor/monitor.h>
 
 #include <boost/property_tree/ptree_fwd.hpp>
 
@@ -64,6 +65,8 @@ public:
        std::future<boost::property_tree::wptree> info() const;
        std::future<boost::property_tree::wptree> delay_info() const;
 
+       monitor::subject& monitor_output();
+
 private:
        struct impl;
        spl::shared_ptr<impl> impl_;
index 777f8e35e1fea95cb251da28cdf09c72c47b32db..d91aee379bb185113eba3a7a24597d8dabf26aa9 100644 (file)
@@ -86,8 +86,9 @@ public:
                graph_->set_color("tick-time", caspar::diagnostics::color(0.0f, 0.6f, 0.9f));
                graph_->set_text(print());
                caspar::diagnostics::register_graph(graph_);
-               
+
                output_.monitor_output().attach_parent(monitor_subject_);
+               mixer_.monitor_output().attach_parent(monitor_subject_);
                stage_.monitor_output().attach_parent(monitor_subject_);
 
                executor_.begin_invoke([=]{tick();});