]> git.sesse.net Git - casparcg/blob - core/mixer/audio/audio_mixer.cpp
2.0.0.2: More missing files.
[casparcg] / core / mixer / audio / audio_mixer.cpp
1 #include "../../stdafx.h"\r
2 \r
3 #include "audio_mixer.h"\r
4 \r
5 namespace caspar { namespace core {\r
6         \r
7 audio_transform& audio_transform::operator*=(const audio_transform &other) \r
8 {\r
9         gain *= other.gain;\r
10         return *this;\r
11 }\r
12 \r
13 const audio_transform audio_transform::operator*(const audio_transform &other) const \r
14 {\r
15         return audio_transform(*this) *= other;\r
16 }\r
17 \r
18 struct audio_mixer::implementation\r
19 {\r
20         std::vector<short> audio_data_;\r
21         std::stack<audio_transform> transform_stack_;\r
22 \r
23 public:\r
24         implementation()\r
25         {\r
26                 transform_stack_.push(audio_transform());\r
27         }\r
28 \r
29         void begin(const audio_transform& transform)\r
30         {\r
31                 transform_stack_.push(transform_stack_.top()*transform);\r
32         }\r
33 \r
34         void process(const std::vector<short>& audio_data)\r
35         {               \r
36                 if(audio_data_.empty())\r
37                         audio_data_.resize(audio_data.size(), 0);\r
38 \r
39                 tbb::parallel_for\r
40                 (\r
41                         tbb::blocked_range<size_t>(0, audio_data.size()),\r
42                         [&](const tbb::blocked_range<size_t>& r)\r
43                         {\r
44                                 for(size_t n = r.begin(); n < r.end(); ++n)\r
45                                 {\r
46                                         int sample = static_cast<int>(audio_data[n]);\r
47                                         sample = (static_cast<int>(transform_stack_.top().gain*8192.0)*sample)/8192;\r
48                                         audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + sample) & 0xFFFF);\r
49                                 }\r
50                         }\r
51                 );\r
52         }\r
53 \r
54         void end()\r
55         {\r
56                 transform_stack_.pop();\r
57         }\r
58 \r
59         std::vector<short> begin_pass()\r
60         {\r
61                 return std::move(audio_data_);\r
62         }\r
63 };\r
64 \r
65 audio_mixer::audio_mixer() : impl_(new implementation()){}\r
66 void audio_mixer::begin(const audio_transform& transform){impl_->begin(transform);}\r
67 void audio_mixer::process(const std::vector<short>& audio_data){impl_->process(audio_data);}\r
68 void audio_mixer::end(){impl_->end();}\r
69 std::vector<short> audio_mixer::begin_pass(){return impl_->begin_pass();}       \r
70 void audio_mixer::end_pass(){}\r
71 \r
72 }}