\r
#include "oal_consumer.h"\r
\r
-#include "../../frame/gpu_frame.h"\r
-#include "../../frame/frame_format.h"\r
+#include "../../processor/frame.h"\r
+#include "../../format/video_format.h"\r
\r
#include <SFML/Audio.hpp>\r
\r
\r
struct consumer::implementation : public sf::SoundStream, boost::noncopyable\r
{\r
- implementation(const frame_format_desc& format_desc) : format_desc_(format_desc), container_(5)\r
+ implementation() : container_(5), underrun_count_(0)\r
{\r
- input_.set_capacity(2);\r
+ input_.set_capacity(3);\r
sf::SoundStream::Initialize(2, 48000);\r
}\r
\r
Stop();\r
}\r
\r
- void push(const gpu_frame_ptr& frame)\r
+ void push(const frame_ptr& frame)\r
{\r
// NOTE: tbb::concurrent_queue does not have rvalue support. \r
// Use shared_ptr to emulate move semantics\r
- input_.push(std::make_shared<std::vector<short>>(std::move(frame->audio_data()))); \r
+ input_.push(std::make_shared<std::vector<short>>(std::move(frame->get_audio_data()))); \r
\r
- if(GetStatus() != Playing)\r
+ if(GetStatus() != Playing && input_.size() > 2)\r
Play();\r
}\r
\r
}\r
\r
bool OnGetData(sf::SoundStream::Chunk& data)\r
- {\r
+ {\r
static std::vector<short> silence(1920*2, 0);\r
\r
std::shared_ptr<std::vector<short>> audio_data;\r
+ \r
if(!input_.try_pop(audio_data))\r
{\r
- CASPAR_LOG(trace) << "Sound Buffer Underrun";\r
+ if(underrun_count_ == 0)\r
+ CASPAR_LOG(trace) << "### Sound Input underflow has STARTED.";\r
+ ++underrun_count_;\r
input_.pop(audio_data);\r
}\r
-\r
+ else if(underrun_count_ > 0)\r
+ {\r
+ CASPAR_LOG(trace) << "### Sound Input Underrun has ENDED with " << underrun_count_ << " ticks.";\r
+ underrun_count_ = 0;\r
+ }\r
+ \r
if(audio_data->empty())\r
{ \r
data.Samples = silence.data();\r
data.Samples = container_.back().data();\r
data.NbSamples = container_.back().size();\r
}\r
- return true;\r
- }\r
+ return true;\r
+ }\r
\r
+ long underrun_count_;\r
boost::circular_buffer<std::vector<short>> container_;\r
tbb::concurrent_bounded_queue<std::shared_ptr<std::vector<short>>> input_;\r
- frame_format_desc format_desc_;\r
};\r
\r
-consumer::consumer(const frame_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-const frame_format_desc& consumer::get_frame_format_desc() const{return impl_->format_desc_;}\r
-void consumer::prepare(const gpu_frame_ptr& frame){impl_->push(frame);}\r
+consumer::consumer(const video_format_desc&) : impl_(new implementation()){}\r
+void consumer::prepare(const frame_ptr& frame){impl_->push(frame);}\r
}}}\r