\r
#include <tbb/cache_aligned_allocator.h>\r
\r
-#include <boost/range.hpp>\r
-#include <boost/range/algorithm_ext/push_back.hpp>\r
+#include <boost/range/adaptors.hpp>\r
+#include <boost/range/distance.hpp>\r
\r
-#include <array>\r
#include <map>\r
#include <stack>\r
#include <vector>\r
-#include <valarray>\r
\r
namespace caspar { namespace core {\r
\r
const float prev_volume = static_cast<float>(prev_transform.volume);\r
const float next_volume = static_cast<float>(next_transform.volume);\r
\r
- auto alpha = (next_volume-prev_volume)/static_cast<float>(item.audio_data.size()/format_desc.audio_channels);\r
+ auto alpha = (next_volume-prev_volume)/static_cast<float>(item.audio_data.size()/format_desc.audio_channels);\r
\r
- audio_buffer_ps result;\r
- result.reserve(item.audio_data.size());\r
- for(size_t n = 0; n < item.audio_data.size()/2; ++n)\r
- {\r
- result.push_back(item.audio_data[n*2+0] * (prev_volume + n * alpha));\r
- result.push_back(item.audio_data[n*2+1] * (prev_volume + n * alpha));\r
- }\r
- \r
- boost::range::push_back(next_audio, std::move(result));\r
- \r
+ for(size_t n = 0; n < item.audio_data.size(); ++n)\r
+ next_audio.push_back(item.audio_data[n] * (prev_volume + static_cast<float>(n)/static_cast<float>(format_desc_.audio_channels) * alpha));\r
+ \r
next_audio_streams_[item.tag].transform = std::move(next_transform); // Store all active tags, inactive tags will be removed at the end.\r
next_audio_streams_[item.tag].audio_data = std::move(next_audio); \r
} \r
+\r
items_.clear();\r
\r
- audio_streams_ = std::move(next_audio_streams_);\r
- next_audio_streams_.clear();\r
+ audio_streams_ = std::move(next_audio_streams_);\r
\r
if(audio_streams_.empty()) \r
audio_streams_[nullptr].audio_data = audio_buffer_ps(audio_cadence_.front(), 0.0f);\r
\r
- std::vector<float> result_ps(audio_cadence_.front(), 0.0f);\r
- BOOST_FOREACH(auto& stream, audio_streams_)\r
- {\r
- auto& audio_data = stream.second.audio_data;\r
- \r
- if(audio_data.size() < audio_cadence_.front())\r
- {\r
- CASPAR_LOG(warning) << "[audio_mixer] Incorrect frame audio cadence, prepending silence: " << audio_cadence_.front()-audio_data.size();\r
- boost::range::push_back(audio_data, audio_buffer_ps(audio_cadence_.front()-audio_data.size(), 0.0f));\r
- }\r
+ { // sanity check\r
+\r
+ auto invalid_streams = boost::distance(audio_streams_ | \r
+ boost::adaptors::map_values | \r
+ boost::adaptors::filtered([&](const audio_stream& x)\r
+ {return x.audio_data.size() < audio_cadence_.front();}));\r
\r
- for(size_t n = 0; n < audio_cadence_.front(); ++n)\r
- result_ps[n] += audio_data[n];\r
+ if(invalid_streams > 0) \r
+ CASPAR_LOG(trace) << "[audio_mixer] Incorrect frame audio cadence detected."; \r
+ }\r
\r
- audio_data.erase(std::begin(audio_data), std::begin(audio_data) + audio_cadence_.front());\r
+ std::vector<float> result_ps(audio_cadence_.front(), 0.0f);\r
+ BOOST_FOREACH(auto& stream, audio_streams_ | boost::adaptors::map_values)\r
+ {\r
+ auto out = boost::range::transform(result_ps, stream.audio_data, std::begin(result_ps), std::plus<float>());\r
+ stream.audio_data.erase(std::begin(stream.audio_data), std::begin(stream.audio_data) + std::distance(std::begin(result_ps), out));\r
} \r
\r
boost::range::rotate(audio_cadence_, std::begin(audio_cadence_)+1);\r