]> git.sesse.net Git - casparcg/blobdiff - core/mixer/audio/audio_mixer.cpp
2.0.2: audio_mixer: Fixed incorrect mixing.
[casparcg] / core / mixer / audio / audio_mixer.cpp
index 5a695e61c4e79a456c93df2e71600fc1a67e1f76..2f4706d1f6eb823029d9bb7a0c7a6a04d349852b 100644 (file)
 #include <core/mixer/write_frame.h>\r
 #include <core/producer/frame/frame_transform.h>\r
 \r
-#include <tbb/parallel_for.h>\r
-\r
-#include <safeint.h>\r
-\r
 #include <stack>\r
-#include <deque>\r
+#include <vector>\r
+\r
+#include <tbb/parallel_for.h>\r
 \r
 namespace caspar { namespace core {\r
 \r
@@ -45,7 +43,7 @@ struct audio_mixer::implementation
        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
+       std::vector<audio_item>                                                 items_;\r
 \r
 public:\r
        implementation(const core::video_format_desc& format_desc)\r
@@ -77,7 +75,7 @@ public:
                item.transform  = transform_stack_.top();\r
                item.audio_data = std::move(frame.audio_data());\r
 \r
-               items.push_back(item);          \r
+               items_.push_back(item);         \r
        }\r
 \r
        void begin(const core::frame_transform& transform)\r
@@ -95,12 +93,11 @@ public:
                // NOTE: auto data should be larger than format_desc_.audio_samples_per_frame to allow sse to read/write beyond size.\r
 \r
                auto intermediate = std::vector<float, tbb::cache_aligned_allocator<float>>(format_desc_.audio_samples_per_frame+128, 0.0f);\r
+               auto result               = audio_buffer(format_desc_.audio_samples_per_frame+128);     \r
 \r
                std::map<const void*, core::frame_transform> next_frame_transforms;\r
                \r
-               tbb::affinity_partitioner ap;\r
-\r
-               BOOST_FOREACH(auto& item, items)\r
+               BOOST_FOREACH(auto& item, items_)\r
                {                       \r
                        const auto next = item.transform;\r
                        auto prev = next;\r
@@ -122,31 +119,23 @@ public:
                                                \r
                        const float prev_volume = static_cast<float>(prev.volume);\r
                        const float next_volume = static_cast<float>(next.volume);\r
-                       const float delta               = 1.0f/static_cast<float>(format_desc_.audio_samples_per_frame/format_desc_.audio_channels);\r
-                                               \r
-                       auto alpha_ps   = _mm_setr_ps(delta, delta, 0.0f, 0.0f);\r
-                       auto delta2_ps  = _mm_set_ps1(delta*2.0f);\r
-                       auto prev_ps    = _mm_set_ps1(prev_volume);\r
-                       auto next_ps    = _mm_set_ps1(next_volume);     \r
+                                                                       \r
+                       auto alpha              = (next_volume-prev_volume)/static_cast<float>(format_desc_.audio_samples_per_frame/format_desc_.audio_channels);\r
+                       auto alpha_ps   = _mm_set_ps1(alpha*2.0f);\r
+                       auto volume_ps  = _mm_setr_ps(prev_volume, prev_volume, prev_volume+alpha, prev_volume+alpha);\r
 \r
                        for(size_t n = 0; n < format_desc_.audio_samples_per_frame/4; ++n)\r
                        {               \r
-                               auto next2_ps           = _mm_mul_ps(next_ps, alpha_ps);\r
-                               auto prev2_ps           = _mm_sub_ps(prev_ps, _mm_mul_ps(prev_ps, alpha_ps));\r
-                               auto volume_ps          = _mm_add_ps(next2_ps, prev2_ps);\r
-\r
                                auto sample_ps          = _mm_cvtepi32_ps(_mm_load_si128(reinterpret_cast<__m128i*>(&item.audio_data[n*4])));\r
                                auto res_sample_ps      = _mm_load_ps(&intermediate[n*4]);                                                                                      \r
                                sample_ps                       = _mm_mul_ps(sample_ps, volume_ps);     \r
                                res_sample_ps           = _mm_add_ps(sample_ps, res_sample_ps); \r
 \r
-                               alpha_ps                        = _mm_add_ps(alpha_ps, delta2_ps);\r
+                               volume_ps                       = _mm_add_ps(volume_ps, alpha_ps);\r
 \r
                                _mm_store_ps(&intermediate[n*4], res_sample_ps);\r
                        }\r
-               }\r
-               \r
-               auto result = audio_buffer(format_desc_.audio_samples_per_frame+128);   \r
+               }               \r
                        \r
                auto intermediate_128 = reinterpret_cast<__m128i*>(intermediate.data());\r
                auto result_128           = reinterpret_cast<__m128i*>(result.data());\r
@@ -172,7 +161,7 @@ public:
                        _mm_stream_si128(result_128++, _mm_cvtps_epi32(xmm7));\r
                }\r
 \r
-               items.clear();\r
+               items_.clear();\r
                prev_frame_transforms_ = std::move(next_frame_transforms);      \r
 \r
                result.resize(format_desc_.audio_samples_per_frame);\r