]> git.sesse.net Git - casparcg/blobdiff - modules/oal/consumer/oal_consumer.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / modules / oal / consumer / oal_consumer.cpp
index d32673dfa99594ec4da380a3dec413565d504f09..cf2ab9be7aa126071070a9b8d83a5e59ce78e65f 100644 (file)
 #include "oal_consumer.h"\r
 \r
 #include <common/diagnostics/graph.h>\r
-#include <common/utility/timer.h>\r
 #include <common/log/log.h>\r
+#include <common/utility/timer.h>\r
+#include <common/utility/string.h>\r
 \r
+#include <core/consumer/frame_consumer.h>\r
 #include <core/video_format.h>\r
 \r
-#include <core/consumer/frame/read_frame.h>\r
+#include <core/mixer/read_frame.h>\r
 \r
 #include <SFML/Audio.hpp>\r
 \r
 #include <boost/circular_buffer.hpp>\r
+#include <boost/timer.hpp>\r
 \r
 #include <tbb/concurrent_queue.h>\r
 \r
 namespace caspar {\r
 \r
-struct oal_consumer::implementation : public sf::SoundStream, boost::noncopyable\r
+struct oal_consumer : public core::frame_consumer,  public sf::SoundStream\r
 {\r
-       printer parent_printer_;\r
-       safe_ptr<diagnostics::graph> graph_;\r
-       timer perf_timer_;\r
+       safe_ptr<diagnostics::graph>                                            graph_;\r
+       boost::timer                                                                            perf_timer_;\r
 \r
-       tbb::concurrent_bounded_queue<std::vector<short>> input_;\r
-       boost::circular_buffer<std::vector<short>> container_;\r
-       tbb::atomic<bool> is_running_;\r
+       tbb::concurrent_bounded_queue<std::vector<short>>       input_;\r
+       boost::circular_buffer<std::vector<short>>                      container_;\r
+       tbb::atomic<bool>                                                                       is_running_;\r
 \r
-       core::video_format_desc format_desc_;\r
+       core::video_format_desc                                                         format_desc_;\r
+       int                                                                                                     preroll_count_;\r
 public:\r
-       implementation() \r
+       oal_consumer() \r
                : graph_(diagnostics::create_graph(narrow(print())))\r
-               , container_(5)\r
+               , container_(16)\r
+               , preroll_count_(0)\r
        {\r
                graph_->add_guide("tick-time", 0.5);\r
                graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f));\r
                is_running_ = true;\r
+               input_.set_capacity(core::consumer_buffer_depth()-2);\r
        }\r
 \r
-       ~implementation()\r
+       ~oal_consumer()\r
        {\r
                is_running_ = false;\r
                input_.try_push(std::vector<short>());\r
@@ -66,27 +71,27 @@ public:
                CASPAR_LOG(info) << print() << L" Shutting down.";      \r
        }\r
 \r
-       void initialize(const core::video_format_desc& format_desc, const printer& parent_printer)\r
+       virtual void initialize(const core::video_format_desc& format_desc)\r
        {\r
-               format_desc_ = format_desc;\r
-               parent_printer_ = parent_printer;\r
-               for(size_t n = 0; n < buffer_depth(); ++n)\r
-                       input_.push(std::vector<short>(static_cast<size_t>(48000.0f/format_desc_.fps)*2, 0)); \r
+               format_desc_ = format_desc;             \r
                sf::SoundStream::Initialize(2, 48000);\r
                Play();         \r
                CASPAR_LOG(info) << print() << " Sucessfully initialized.";\r
        }\r
-\r
-       void send(const safe_ptr<const core::read_frame>& frame)\r
-       {                               \r
-               if(!frame->audio_data().empty())\r
-                       input_.push(std::vector<short>(frame->audio_data().begin(), frame->audio_data().end()));        \r
-               else\r
-                       input_.push(std::vector<short>(static_cast<size_t>(48000.0f/format_desc_.fps)*2, 0)); \r
+       \r
+       virtual bool send(const safe_ptr<core::read_frame>& frame)\r
+       {                       \r
+               if(preroll_count_ < input_.capacity())\r
+               {\r
+                       while(input_.try_push(std::vector<int16_t>(format_desc_.audio_samples_per_frame, 0)))\r
+                               ++preroll_count_;\r
+               }\r
+\r
+               input_.push(std::vector<int16_t>(frame->audio_data().begin(), frame->audio_data().end()));      \r
+\r
+               return true;\r
        }\r
-\r
-       size_t buffer_depth() const{return 3;}\r
-\r
+       \r
        virtual bool OnGetData(sf::SoundStream::Chunk& data)\r
        {               \r
                std::vector<short> audio_data;          \r
@@ -96,24 +101,22 @@ public:
                data.Samples = container_.back().data();\r
                data.NbSamples = container_.back().size();      \r
                \r
-               graph_->update_value("tick-time", static_cast<float>(perf_timer_.elapsed()/format_desc_.interval*0.5));         \r
-               perf_timer_.reset();\r
+               graph_->update_value("tick-time", perf_timer_.elapsed()*format_desc_.fps*0.5);          \r
+               perf_timer_.restart();\r
 \r
                return is_running_;\r
        }\r
 \r
-       std::wstring print() const\r
+       virtual std::wstring print() const\r
        {\r
-               return (parent_printer_ ? parent_printer_() + L"/" : L"") + L"oal[default]";\r
+               return L"oal[" + format_desc_.name + L"]";\r
        }\r
-};\r
 \r
-oal_consumer::oal_consumer(oal_consumer&& other) : impl_(std::move(other.impl_)){}\r
-oal_consumer::oal_consumer() : impl_(new implementation()){}\r
-void oal_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
-size_t oal_consumer::buffer_depth() const{return impl_->buffer_depth();}\r
-void oal_consumer::initialize(const core::video_format_desc& format_desc, const printer& parent_printer){impl_->initialize(format_desc, parent_printer);}\r
-std::wstring oal_consumer::print() const { return impl_->print(); }\r
+       virtual const core::video_format_desc& get_video_format_desc() const\r
+       {\r
+               return format_desc_;\r
+       }\r
+};\r
 \r
 safe_ptr<core::frame_consumer> create_oal_consumer(const std::vector<std::wstring>& params)\r
 {\r
@@ -122,4 +125,10 @@ safe_ptr<core::frame_consumer> create_oal_consumer(const std::vector<std::wstrin
 \r
        return make_safe<oal_consumer>();\r
 }\r
+\r
+safe_ptr<core::frame_consumer> create_oal_consumer()\r
+{\r
+       return make_safe<oal_consumer>();\r
+}\r
+\r
 }\r