]> 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 a899d949c0275db7077ae3d95adb1033fd30e8a0..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,7 +37,7 @@ 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
@@ -73,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
@@ -88,9 +90,9 @@ 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
@@ -108,10 +110,10 @@ public:
                        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
@@ -128,9 +130,9 @@ 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
@@ -147,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