std::map<int, core::audio_transform> prev_audio_transforms_;\r
std::map<int, core::audio_transform> next_audio_transforms_;\r
\r
+ const core::video_format_desc format_desc_;\r
+\r
public:\r
- implementation()\r
+ implementation(const core::video_format_desc& format_desc)\r
+ : format_desc_(format_desc)\r
{\r
transform_stack_.push(core::audio_transform());\r
audio_data_.push_back(std::vector<int16_t>()); // One frame delay\r
\r
const auto& audio_data = frame.audio_data();\r
const auto tag = frame.tag(); // Get the identifier for the audio-stream.\r
-\r
- if(audio_data_.back().empty())\r
- audio_data_.back().resize(audio_data.size(), 0);\r
- \r
+ \r
const auto next = transform_stack_.top();\r
auto prev = next;\r
\r
prev_audio_transforms_ = std::move(next_audio_transforms_); \r
auto result = std::move(audio_data_.front());\r
audio_data_.pop_front();\r
- audio_data_.push_back(std::vector<int16_t>());\r
+ audio_data_.push_back(std::vector<int16_t>(format_desc_.audio_samples_per_frame));\r
return std::move(result);\r
}\r
};\r
\r
-audio_mixer::audio_mixer() : impl_(new implementation()){}\r
+audio_mixer::audio_mixer(const core::video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
void audio_mixer::begin(core::basic_frame& frame){impl_->begin(frame);}\r
void audio_mixer::visit(core::write_frame& frame){impl_->visit(frame);}\r
void audio_mixer::end(){impl_->end();}\r
#include <boost/noncopyable.hpp>\r
\r
namespace caspar { namespace core {\r
+\r
+struct video_format_desc;\r
\r
class audio_mixer : public core::frame_visitor, boost::noncopyable\r
{\r
public:\r
- audio_mixer();\r
+ audio_mixer(const core::video_format_desc& format_desc);\r
\r
virtual void begin(core::basic_frame& frame);\r
virtual void visit(core::write_frame& frame);\r
#include <common/concurrency/executor.h>\r
#include <common/utility/tweener.h>\r
\r
-\r
#include <core/mixer/read_frame.h>\r
#include <core/mixer/write_frame.h>\r
#include <core/producer/frame/basic_frame.h>\r
public:\r
implementation(video_channel_context& video_channel) \r
: channel_(video_channel)\r
+ , audio_mixer_(channel_.get_format_desc())\r
, image_mixer_(channel_)\r
{ \r
CASPAR_LOG(info) << print() << L" Successfully initialized."; \r
{\r
channel_.ogl().gc().wait();\r
image_mixer_ = image_mixer(channel_);\r
- audio_mixer_ = audio_mixer();\r
+ audio_mixer_ = audio_mixer(channel_.get_format_desc());\r
channel_.ogl().gc().wait();\r
\r
CASPAR_LOG_CURRENT_EXCEPTION();\r
size_t preroll_count_;\r
\r
std::list<std::shared_ptr<IDeckLinkVideoFrame>> frame_container_; // Must be std::list in order to guarantee that pointers are always valid.\r
- boost::circular_buffer<std::vector<short>> audio_container_;\r
+ boost::circular_buffer<std::vector<int16_t>> audio_container_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<core::read_frame>> video_frame_buffer_;\r
tbb::concurrent_bounded_queue<std::shared_ptr<core::read_frame>> audio_frame_buffer_;\r
\r
void schedule_next_audio(const safe_ptr<core::read_frame>& frame)\r
{\r
- static std::vector<short> silence(48000, 0);\r
- \r
- const int sample_count = format_desc_.audio_samples_per_frame;\r
- const int sample_frame_count = sample_count/2;\r
+ const int sample_frame_count = frame->audio_data().size()/format_desc_.audio_channels;\r
\r
- const int16_t* frame_audio_data = frame->audio_data().size() == sample_count ? frame->audio_data().begin() : silence.data();\r
- audio_container_.push_back(std::vector<int16_t>(frame_audio_data, frame_audio_data+sample_count));\r
+ audio_container_.push_back(std::vector<int16_t>(frame->audio_data().begin(), frame->audio_data().end()));\r
\r
if(FAILED(output_->ScheduleAudioSamples(audio_container_.back().data(), sample_frame_count, (audio_scheduled_++) * sample_frame_count, format_desc_.audio_sample_rate, nullptr)))\r
CASPAR_LOG(error) << print() << L" Failed to schedule audio.";\r
{ \r
if(preroll_count_ < input_.capacity())\r
{\r
- while(input_.try_push(std::vector<short>(format_desc_.audio_samples_per_frame, 0)))\r
+ while(input_.try_push(std::vector<int16_t>(format_desc_.audio_samples_per_frame, 0)))\r
++preroll_count_;\r
}\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>(format_desc_.audio_samples_per_frame, 0)); //static_cast<size_t>(48000.0f/format_desc_.fps)*2\r
+ input_.push(std::vector<int16_t>(frame->audio_data().begin(), frame->audio_data().end())); \r
}\r
\r
size_t buffer_depth() const{return 3;}\r