]> git.sesse.net Git - casparcg/blob - core/mixer/audio/audio_util.h
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / core / mixer / audio / audio_util.h
1 #pragma once\r
2 \r
3 #include <vector>\r
4 \r
5 #include <stdint.h>\r
6 \r
7 #include <boost/range/iterator_range.hpp>\r
8 \r
9 #include <tbb/cache_aligned_allocator.h>\r
10 \r
11 namespace caspar { namespace core {\r
12 \r
13 // NOTE: Input data pointer should be larger than input.size() to allow sse to read beyond\r
14 static std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>> audio_32_to_16_sse(const boost::iterator_range<int32_t*>& input)\r
15 {       \r
16         std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>> audio16(input.size());\r
17         auto audio32_ptr = reinterpret_cast<const __m128i*>(input.begin());\r
18         auto audio16_ptr = reinterpret_cast<__m128i*>(audio16.data());\r
19         auto size                = input.size();\r
20         for(int n = 0; n < size/8; ++n)         \r
21         {\r
22                 auto xmm0 = _mm_srai_epi32(_mm_load_si128(audio32_ptr++), 16);\r
23                 auto xmm1 = _mm_srai_epi32(_mm_load_si128(audio32_ptr++), 16);\r
24                 auto xmm3 = _mm_packs_epi32(xmm0, xmm1);\r
25                 _mm_store_si128(audio16_ptr++, xmm3);\r
26         }\r
27         return audio16;\r
28 }\r
29 \r
30 static std::vector<int8_t> audio_32_to_24(const boost::iterator_range<int32_t*>& input)\r
31 {       \r
32         std::vector<int8_t> audio24(input.size()*3+16);\r
33         auto audio32_ptr = reinterpret_cast<const uint32_t*>(input.begin());\r
34         auto audio24_ptr = reinterpret_cast<uint8_t*>(audio24.data());\r
35         auto size                = input.size();\r
36         for(int n = 0; n < size; ++n)           \r
37                 *reinterpret_cast<uint32_t*>(audio24_ptr + n*3) = *(audio32_ptr + n) >> 8;      \r
38         audio24.resize(input.size()*3);\r
39         return audio24;\r
40 }\r
41 \r
42 }}