]> git.sesse.net Git - casparcg/blobdiff - core/mixer/audio/audio_mixer.cpp
2.0. audio: Audio pipeline is now in 32 bit.
[casparcg] / core / mixer / audio / audio_mixer.cpp
index a241ad39773fde6378eeb8c7841319dda8e03839..1c3a77364a8fe2bb725fb063d49233ea993f1c63 100644 (file)
@@ -26,6 +26,8 @@
 \r
 #include <tbb/parallel_for.h>\r
 \r
+#include <safeint.h>\r
+\r
 #include <stack>\r
 #include <deque>\r
 \r
@@ -35,19 +37,15 @@ struct audio_item
 {\r
        const void*                             tag;\r
        frame_transform                 transform;\r
-       std::vector<int16_t>    audio_data;\r
+       std::vector<int32_t>    audio_data;\r
 };\r
        \r
 struct audio_mixer::implementation\r
 {\r
-       std::stack<core::frame_transform> transform_stack_;\r
-\r
-       std::map<const void*, core::frame_transform> prev_frame_transforms_;\r
-       std::map<const void*, core::frame_transform> next_frame_transforms_;\r
-\r
-       const core::video_format_desc format_desc_;\r
-\r
-       std::vector<audio_item> items;\r
+       std::stack<core::frame_transform>                               transform_stack_;\r
+       std::map<const void*, core::frame_transform>    prev_frame_transforms_;\r
+       const core::video_format_desc                                   format_desc_;\r
+       std::vector<audio_item>                                                 items;\r
 \r
 public:\r
        implementation(const core::video_format_desc& format_desc)\r
@@ -77,7 +75,7 @@ public:
                audio_item item;\r
                item.tag                = frame.tag();\r
                item.transform  = transform_stack_.top();\r
-               item.audio_data = std::vector<int16_t>(frame.audio_data().begin(), frame.audio_data().end());\r
+               item.audio_data = std::vector<int32_t>(frame.audio_data().begin(), frame.audio_data().end());\r
 \r
                items.push_back(item);          \r
        }\r
@@ -92,9 +90,11 @@ public:
                transform_stack_.pop();\r
        }\r
        \r
-       std::vector<int16_t> mix()\r
+       std::vector<int32_t> mix()\r
        {\r
-               auto result = std::vector<int16_t>(format_desc_.audio_samples_per_frame);\r
+               auto result = std::vector<int32_t>(format_desc_.audio_samples_per_frame);\r
+\r
+               std::map<const void*, core::frame_transform> next_frame_transforms;\r
 \r
                BOOST_FOREACH(auto& item, items)\r
                {                               \r
@@ -105,15 +105,15 @@ public:
                        if(it != prev_frame_transforms_.end())\r
                                prev = it->second;\r
                                \r
-                       next_frame_transforms_[item.tag] = next; // Store all active tags, inactive tags will be removed at the end.\r
+                       next_frame_transforms[item.tag] = next; // Store all active tags, inactive tags will be removed at the end.\r
                                \r
                        if(next.volume < 0.001 && prev.volume < 0.001)\r
                                continue;\r
                \r
-                       static const int BASE = 1<<15;\r
+                       static const int BASE = 1<<31;\r
 \r
-                       const auto next_volume = static_cast<int>(next.volume*BASE);\r
-                       const auto prev_volume = static_cast<int>(prev.volume*BASE);\r
+                       const auto next_volume = static_cast<int64_t>(next.volume*BASE);\r
+                       const auto prev_volume = static_cast<int64_t>(prev.volume*BASE);\r
                \r
                        const int n_samples = result.size();\r
                \r
@@ -130,16 +130,16 @@ public:
                                {\r
                                        for(size_t n = r.begin(); n < r.end(); ++n)\r
                                        {\r
-                                               const int sample_volume = (prev_volume - (prev_volume * n)/n_samples) + (next_volume * n)/n_samples;\r
-                                               const int sample = (static_cast<int>(item.audio_data[n])*sample_volume)/BASE;\r
-                                               result[n] = static_cast<int16_t>((static_cast<int>(result[n]) + sample) & 0xFFFF);\r
+                                               const auto sample_volume = (prev_volume - (prev_volume * n)/n_samples) + (next_volume * n)/n_samples;\r
+                                               const auto sample = static_cast<int32_t>((static_cast<int64_t>(item.audio_data[n])*sample_volume)/BASE);\r
+                                               result[n] = result[n] + sample;\r
                                        }\r
                                }\r
                        );\r
                }\r
 \r
                items.clear();\r
-               prev_frame_transforms_ = std::move(next_frame_transforms_);     \r
+               prev_frame_transforms_ = std::move(next_frame_transforms);      \r
 \r
                return std::move(result);\r
        }\r
@@ -149,7 +149,7 @@ audio_mixer::audio_mixer(const core::video_format_desc& format_desc) : impl_(new
 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
-std::vector<int16_t> audio_mixer::mix(){return impl_->mix();}\r
+std::vector<int32_t> audio_mixer::mix(){return impl_->mix();}\r
 audio_mixer& audio_mixer::operator=(audio_mixer&& other)\r
 {\r
        impl_ = std::move(other.impl_);\r