AudioFrameEncoder.hpp
1 #pragma once
2 
3 #include <Media/Libav.hpp>
4 #if SCORE_HAS_LIBAV
5 extern "C" {
6 #include <libavutil/frame.h>
7 }
8 
9 #include <ossia/dataflow/float_to_sample.hpp>
10 
11 namespace Gfx
12 {
13 
15 {
16  explicit AudioFrameEncoder(int target_buffer_size)
17  : target_buffer_size{target_buffer_size}
18  {
19  }
20 
21  // We assume that vec has correct channel count here
22  // Also that vec.size() > 0
23  virtual void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) = 0;
24  virtual ~AudioFrameEncoder() = default;
25  int target_buffer_size{};
26 };
27 
29 {
30  using AudioFrameEncoder::AudioFrameEncoder;
31 
32  boost::container::vector<int16_t> data;
33 
34  void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
35  {
36  const int channels = vec.size();
37  const int frames = vec[0].size();
38  data.clear();
39  data.resize(frames * channels, boost::container::default_init);
40  auto ptr = data.data();
41  for(int i = 0; i < frames; i++)
42  for(int c = 0; c < channels; c++)
43  *ptr++ = ossia::float_to_sample<int16_t, 16>(vec[c][i]);
44 
45  frame.data[0] = (uint8_t*)data.data();
46  frame.data[1] = nullptr;
47  }
48 };
49 
51 {
52  using AudioFrameEncoder::AudioFrameEncoder;
53 
54  boost::container::vector<int32_t> data;
55  void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
56  {
57  const int channels = vec.size();
58  const int frames = vec[0].size();
59  data.clear();
60  data.resize(frames * channels, boost::container::default_init);
61  auto ptr = data.data();
62  for(int i = 0; i < frames; i++)
63  for(int c = 0; c < channels; c++)
64  *ptr++ = ossia::float_to_sample<int32_t, 24>(vec[c][i]);
65 
66  frame.data[0] = (uint8_t*)data.data();
67  frame.data[1] = nullptr;
68  }
69 };
70 
72 {
73  using AudioFrameEncoder::AudioFrameEncoder;
74 
75  boost::container::vector<int32_t> data;
76  void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
77  {
78  const int channels = vec.size();
79  const int frames = vec[0].size();
80  data.clear();
81  data.resize(frames * channels, boost::container::default_init);
82  auto ptr = data.data();
83  for(int i = 0; i < frames; i++)
84  for(int c = 0; c < channels; c++)
85  *ptr++ = ossia::float_to_sample<int32_t, 32>(vec[c][i]);
86 
87  frame.data[0] = (uint8_t*)data.data();
88  frame.data[1] = nullptr;
89  }
90 };
91 
93 {
94  using AudioFrameEncoder::AudioFrameEncoder;
95 
96  boost::container::vector<float> data;
97 
98  void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
99  {
100  const int channels = vec.size();
101  const int frames = vec[0].size();
102  data.clear();
103  data.resize(frames * channels, boost::container::default_init);
104  auto ptr = data.data();
105  for(int i = 0; i < frames; i++)
106  for(int c = 0; c < channels; c++)
107  *ptr++ = vec[c][i];
108 
109  frame.data[0] = (uint8_t*)data.data();
110  frame.data[1] = nullptr;
111  }
112 };
113 
115 {
116  using AudioFrameEncoder::AudioFrameEncoder;
117 
118  boost::container::vector<double> data;
119 
120  void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
121  {
122  const int channels = vec.size();
123  const int frames = vec[0].size();
124  data.clear();
125  data.resize(frames * channels, boost::container::default_init);
126  auto ptr = data.data();
127  for(int i = 0; i < frames; i++)
128  for(int c = 0; c < channels; c++)
129  *ptr++ = vec[c][i];
130 
131  frame.data[0] = (uint8_t*)data.data();
132  frame.data[1] = nullptr;
133  }
134 };
135 
137 {
138  using AudioFrameEncoder::AudioFrameEncoder;
139 
140  void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
141  {
142  const int channels = vec.size();
143  if(channels <= AV_NUM_DATA_POINTERS)
144  {
145  for(int i = 0; i < channels; ++i)
146  {
147  frame.data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
148  }
149  }
150  else
151  {
152  // FIXME where does this get freed???
153  frame.extended_data
154  = static_cast<uint8_t**>(av_malloc(channels * sizeof(*frame.extended_data)));
155  int i = 0;
156  for(; i < AV_NUM_DATA_POINTERS; ++i)
157  {
158  frame.data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
159  frame.extended_data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
160  }
161  for(; i < channels; ++i)
162  frame.extended_data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
163  }
164  }
165 };
166 }
167 #endif
Binds the rendering pipeline to ossia processes.
Definition: CameraDevice.cpp:28
Definition: AudioFrameEncoder.hpp:15
Definition: AudioFrameEncoder.hpp:115
Definition: AudioFrameEncoder.hpp:93
Definition: AudioFrameEncoder.hpp:137
Definition: AudioFrameEncoder.hpp:29
Definition: AudioFrameEncoder.hpp:51
Definition: AudioFrameEncoder.hpp:72