3535 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3636 */
3737
38+ #include < algorithm>
3839#include < cassert>
3940#include < memory>
4041
4445#include " lib_common.h"
4546#include " video_codec.h"
4647#include " video_frame.h"
48+ #include " audio/types.h"
49+ #include " audio/utils.h"
4750#include " utils/color_out.h"
4851#include " utils/string_view_utils.hpp"
4952
@@ -57,6 +60,9 @@ struct state_omt_cap{
5760
5861 video_frame_uniq ug_frame;
5962
63+ audio_frame audio_f{};
64+ std::vector<short > ug_audio_f_buf;
65+
6066 std::string sender_addr = " localhost" ;
6167 int port = 6400 ;
6268};
@@ -122,10 +128,63 @@ void capture_omt_done(void *state){
122128 delete s;
123129}
124130
125- video_frame *capture_omt_grab (void *state, audio_frame **/*audio*/){
131+ void float2S16 (short *out , const float *in, int samples) {
132+ for (int i = 0 ; i < samples; i++) {
133+ float sample = in[i];
134+ if (sample < -1 .f ) sample = -1 .f ;
135+ if (sample > 1 .f ) sample = 1 .f ;
136+ out[i] = INT16_MAX * sample;
137+ }
138+ }
139+
140+ audio_frame *omt_to_audio_frame (state_omt_cap *s, const OMTMediaFrame& omt_audio){
141+ constexpr int S16_BPS = 2 ;
142+ const auto ch_count = omt_audio.Channels ;
143+
144+ s->ug_audio_f_buf .resize (omt_audio.SamplesPerChannel * ch_count);
145+ s->audio_f .ch_count = ch_count;
146+ s->audio_f .data = reinterpret_cast <char *>(s->ug_audio_f_buf .data ());
147+ s->audio_f .bps = S16_BPS;
148+ s->audio_f .data_len = s->ug_audio_f_buf .size () * S16_BPS;
149+ s->audio_f .max_size = s->ug_audio_f_buf .size () * S16_BPS;
150+ s->audio_f .sample_rate = omt_audio.SampleRate ;
151+
152+ int16_t *dst = s->ug_audio_f_buf .data ();
153+ auto src = static_cast <const float *>(omt_audio.Data );
154+ auto samples_left = omt_audio.SamplesPerChannel ;
155+ while (samples_left > 0 ){
156+ constexpr auto chunk_samples = 128 ;
157+ const auto to_process = std::min (chunk_samples, samples_left);
158+
159+ for (int ch = 0 ; ch < ch_count; ch++){
160+ alignas (32 ) int16_t S16samples[chunk_samples];
161+ const float *ch_src = src + ch * omt_audio.SamplesPerChannel ;
162+
163+ float2S16 (S16samples, ch_src, to_process);
164+
165+ mux_channel (reinterpret_cast <char *>(dst),
166+ reinterpret_cast <const char *>(S16samples),
167+ S16_BPS, to_process * S16_BPS, ch_count, ch, 1.0 );
168+ }
169+
170+ dst += to_process * ch_count;
171+ src += to_process;
172+ samples_left -= to_process;
173+ }
174+
175+ return &s->audio_f ;
176+ }
177+
178+ video_frame *capture_omt_grab (void *state, audio_frame **audio){
126179 auto s = static_cast <state_omt_cap *>(state);
127180
128- const auto omt_frame = omt_receive(s->omt_h.get(), OMTFrameType_Video, 1000 );
181+ const auto omt_audio = omt_receive (s->omt_h .get (), OMTFrameType_Audio, 0 );
182+ if (omt_audio){
183+ *audio = omt_to_audio_frame (s, *omt_audio);
184+ log_msg (LOG_LEVEL_INFO, " got audio %d (%d)\n " , omt_audio->SamplesPerChannel , (*audio)->data_len );
185+ }
186+
187+ const auto omt_frame = omt_receive (s->omt_h .get (), OMTFrameType_Video, 100 );
129188 if (!omt_frame){
130189 return nullptr ;
131190 }
0 commit comments