X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Foal%2Fconsumer%2Foal_consumer.cpp;h=cd0130a5fedac3dbdd001b8eb5d809f58ad8e90b;hb=7dd8bdd6999be5bf21f6963a7b4ed312806244e4;hp=99d0df4efee1a8f5341044fe42264d386f1e1e28;hpb=d100d17e81ed61c7638b681989cfdab5276430db;p=casparcg diff --git a/modules/oal/consumer/oal_consumer.cpp b/modules/oal/consumer/oal_consumer.cpp index 99d0df4ef..cd0130a5f 100644 --- a/modules/oal/consumer/oal_consumer.cpp +++ b/modules/oal/consumer/oal_consumer.cpp @@ -20,13 +20,17 @@ #include "oal_consumer.h" +#include #include #include #include +#include +#include +#include #include -#include +#include #include @@ -37,61 +41,68 @@ namespace caspar { -struct oal_consumer::implementation : public sf::SoundStream, boost::noncopyable +struct oal_consumer : public core::frame_consumer, public sf::SoundStream { - safe_ptr graph_; - boost::timer perf_timer_; + safe_ptr graph_; + boost::timer perf_timer_; - tbb::concurrent_bounded_queue> input_; - boost::circular_buffer> container_; - tbb::atomic is_running_; + tbb::concurrent_bounded_queue>>> input_; + boost::circular_buffer>> container_; + tbb::atomic is_running_; - core::video_format_desc format_desc_; + core::video_format_desc format_desc_; + int preroll_count_; public: - implementation(const core::video_format_desc& format_desc) + oal_consumer() : graph_(diagnostics::create_graph(narrow(print()))) - , container_(5) - , format_desc_(format_desc) + , container_(16) + , preroll_count_(0) { + if(core::consumer_buffer_depth() < 3) + BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("audio-consumer does not support buffer-depth lower than 3.")); + graph_->add_guide("tick-time", 0.5); - graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f)); + graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); is_running_ = true; - input_.set_capacity(4); - - // Fill input buffer with silence. - for(size_t n = 0; n < buffer_depth(); ++n) - input_.push(std::vector(static_cast(48000.0f/format_desc_.fps)*2, 0)); - - sf::SoundStream::Initialize(2, 48000); - Play(); - CASPAR_LOG(info) << print() << " Sucessfully initialized."; + input_.set_capacity(core::consumer_buffer_depth()-2); } - ~implementation() + ~oal_consumer() { is_running_ = false; - input_.try_push(std::vector()); - input_.try_push(std::vector()); + input_.try_push(std::make_shared>>()); + input_.try_push(std::make_shared>>()); Stop(); CASPAR_LOG(info) << print() << L" Shutting down."; } + + virtual void initialize(const core::video_format_desc& format_desc) + { + format_desc_ = format_desc; + sf::SoundStream::Initialize(2, 48000); + CASPAR_LOG(info) << print() << " Sucessfully initialized."; + } - void send(const safe_ptr& frame) - { - if(!frame->audio_data().empty()) - input_.push(std::vector(frame->audio_data().begin(), frame->audio_data().end())); - else - input_.push(std::vector(static_cast(48000.0f/format_desc_.fps)*2, 0)); + virtual bool send(const safe_ptr& frame) + { + if(preroll_count_ < input_.capacity()) + { + while(input_.try_push(std::make_shared>>(format_desc_.audio_samples_per_frame, 0))) + ++preroll_count_; + Play(); + } + + input_.push(std::make_shared>>(core::audio_32_to_16_sse(frame->audio_data()))); + + return true; } - - size_t buffer_depth() const{return 3;} - + virtual bool OnGetData(sf::SoundStream::Chunk& data) { - std::vector audio_data; + std::shared_ptr>> audio_data; input_.pop(audio_data); - container_.push_back(std::move(audio_data)); + container_.push_back(std::move(*audio_data)); data.Samples = container_.back().data(); data.NbSamples = container_.back().size(); @@ -101,24 +112,28 @@ public: return is_running_; } - std::wstring print() const + virtual std::wstring print() const { - return L"oal[default]"; + return L"oal[" + format_desc_.name + L"]"; } -}; -oal_consumer::oal_consumer(){} -oal_consumer::oal_consumer(oal_consumer&& other) : impl_(std::move(other.impl_)){} -void oal_consumer::send(const safe_ptr& frame){impl_->send(frame);} -size_t oal_consumer::buffer_depth() const{return impl_->buffer_depth();} -void oal_consumer::initialize(const core::video_format_desc& format_desc){impl_.reset(new implementation(format_desc));} -std::wstring oal_consumer::print() const { return impl_->print(); } + virtual const core::video_format_desc& get_video_format_desc() const + { + return format_desc_; + } +}; safe_ptr create_oal_consumer(const std::vector& params) { - if(params.size() < 1 || params[0] != L"OAL") + if(params.size() < 1 || params[0] != L"AUDIO") return core::frame_consumer::empty(); return make_safe(); } + +safe_ptr create_oal_consumer() +{ + return make_safe(); +} + }