]> 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 <tbb/cache_aligned_allocator.h>\r
8 \r
9 namespace caspar { namespace core {\r
10 \r
11 // NOTE: Input data pointer should be larger than input.size() to allow sse to read beyond\r
12 template<typename T>\r
13 static std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>> audio_32_to_16_sse(const T& audio_data)\r
14 {       \r
15         auto size                = std::distance(std::begin(audio_data), std::end(audio_data));\r
16         auto input32     = &(*std::begin(audio_data));\r
17         auto output16    = std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>>(size);\r
18 \r
19         auto input128    = reinterpret_cast<const __m128i*>(input32);\r
20         auto output128   = reinterpret_cast<__m128i*>(output16.data());\r
21 \r
22         for(int n = 0; n < size/8; ++n)         \r
23         {\r
24                 auto xmm0 = _mm_srai_epi32(_mm_load_si128(input128++), 16);\r
25                 auto xmm1 = _mm_srai_epi32(_mm_load_si128(input128++), 16);\r
26                 auto xmm3 = _mm_packs_epi32(xmm0, xmm1);\r
27                 _mm_store_si128(output128++, xmm3);\r
28         }\r
29 \r
30         for(int n = size/8; n < size; ++n)\r
31                 output16[n] = input32[n] >> 16;\r
32 \r
33         return output16;\r
34 }\r
35 \r
36 template<typename T>\r
37 static std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> audio_32_to_24(const T& audio_data)\r
38 {       \r
39         auto size                = std::distance(std::begin(audio_data), std::end(audio_data));\r
40         auto input8              = reinterpret_cast<const int8_t*>(&(*std::begin(audio_data)));\r
41         auto output8     = std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>();\r
42                         \r
43         output8.reserve(size*3);\r
44         for(int n = 0; n < size; ++n)\r
45         {\r
46                 output8.push_back(input8[n*4+1]);\r
47                 output8.push_back(input8[n*4+2]);\r
48                 output8.push_back(input8[n*4+3]);\r
49         }\r
50 \r
51         return output8;\r
52 }\r
53 \r
54 template<typename T>\r
55 static std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>> audio_32_to_16(const T& audio_data)\r
56 {       \r
57         auto size                = std::distance(std::begin(audio_data), std::end(audio_data));\r
58         auto input8              = reinterpret_cast<const int8_t*>(&(*std::begin(audio_data)));\r
59         auto output8     = std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>();\r
60                         \r
61         output8.reserve(size*2);\r
62         for(int n = 0; n < size; ++n)\r
63         {\r
64                 output8.push_back(input8[n*4+2]);\r
65                 output8.push_back(input8[n*4+3]);\r
66         }\r
67 \r
68         return output8;\r
69 }\r
70 \r
71 }}