UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
types.cpp
Go to the documentation of this file.
1
5/*
6 * Copyright (c) 2011-2021 CESNET, z. s. p. o.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, is permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * 3. Neither the name of CESNET nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
26 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
28 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#include "config_unix.h"
41#include "config_win32.h"
42#endif // HAVE_CONFIG_H
43
44
45#include "audio/resampler.hpp"
46#include "audio/types.h"
47#include "audio/utils.h"
48#include "debug.h"
49#include "host.h"
50#include "utils/macros.h"
51
52#include <chrono>
53#include <sstream>
54#include <stdexcept>
55
56using std::copy;
57using std::logic_error;
58using std::ostringstream;
59using std::string;
60using std::tuple;
61using std::unique_ptr;
62using std::vector;
63
65{
66 return codec == AC_NONE;
67}
68
69bool audio_desc::operator==(audio_desc const & other) const
70{
71 return bps == other.bps &&
72 sample_rate == other.sample_rate &&
73 ch_count == other.ch_count &&
74 codec == other.codec;
75}
76
77audio_desc::operator string() const
78{
79 ostringstream oss;
80 oss << *this;
81 return oss.str();
82}
83
88 channels(old ? old->ch_count : 0)
89{
90 if (old == nullptr) {
91 return;
92 }
93 desc.bps = old->bps;
96 for (int i = 0; i < old->ch_count; i++) {
97 resize(i, old->data_len / old->ch_count);
98 char *data = channels[i].data.get();
99 demux_channel(data, old->data, old->bps, old->data_len,
100 old->ch_count, i);
101 }
102 if ((old->flags & TIMESTAMP_VALID) != 0) {
103 timestamp = old->timestamp;
104 }
105}
106
107audio_frame2::operator bool() const
108{
109 return desc.codec != AC_NONE;
110}
111
115void audio_frame2::init(int nr_channels, audio_codec_t c, int b, int sr)
116{
117 channels.clear();
118 channels.resize(nr_channels);
119 desc.bps = b;
120 desc.codec = c;
121 desc.sample_rate = sr;
122 duration = 0.0;
123}
124
126{
127 if (desc.bps != src.desc.bps || desc.sample_rate != src.desc.sample_rate ||
128 channels.size() != src.channels.size()) {
129 throw std::logic_error(
130 "Trying to append frame with different parameters!");
131 }
132
133 for (size_t i = 0; i < channels.size(); i++) {
134 append(i, src.get_data(i), src.get_data_len(i));
135 }
136}
137
138void audio_frame2::append(int channel, const char *data, size_t length)
139{
140 // allocate twice as much as we need to avoid frequent reallocations
141 // when append is called repeatedly
142 reserve(channel, 2 * (channels[channel].len + length));
143 copy(data, data + length, channels[channel].data.get() + channels[channel].len);
144 channels[channel].len += length;
145}
146
147
152void audio_frame2::replace(int channel, size_t offset, const char *data, size_t length)
153{
154 resize(channel, offset + length);
155 copy(data, data + length, channels[channel].data.get() + offset);
156}
157
161void audio_frame2::reserve(size_t length)
162{
163 for (size_t channel = 0; channel < channels.size(); ++channel) {
164 reserve(channel, length);
165 }
166}
167
168void audio_frame2::reserve(int channel, size_t length)
169{
170 if (channels[channel].max_len < length) {
171 unique_ptr<char []> new_data(new char[length]);
172 copy(channels[channel].data.get(), channels[channel].data.get() +
173 channels[channel].len, new_data.get());
174
175 channels[channel].max_len = length;
176 channels[channel].data = std::move(new_data);
177 }
178}
179
183void audio_frame2::resize(int channel, size_t length)
184{
185 reserve(channel, length);
186 channels[channel].len = length;
187}
188
193{
194 for (size_t i = 0; i < channels.size(); i++) {
195 channels[i].len = 0;
196 }
197 duration = 0.0;
198}
199
201{
202 return desc.bps;
203}
204
205struct audio_desc audio_frame2::get_desc() const
206{
207 struct audio_desc ret = desc;
208 ret.ch_count =
209 get_channel_count(); // ch_count is not set in audio_frame2::desc
210 return ret;
211}
212
214{
215 return desc.codec;
216}
217
219{
220 return channels[channel].data.get();
221}
222
223const char *audio_frame2::get_data(int channel) const
224{
225 return channels[channel].data.get();
226}
227
229{
230 return channels[channel].len;
231}
232
237{
238 size_t len = 0;
239 for (int i = 0; i < get_channel_count(); ++i) {
240 len += get_data_len(i);
241 }
242
243 return len;
244}
245
247{
248 if (desc.codec == AC_PCM) {
249 int samples = get_sample_count();
250 return (double) samples / get_sample_rate();
251 }
252 return duration;
253}
254
256{
257 return channels[channel].fec_params;
258}
259
261{
262 return channels.size();
263}
264
266{
267 // for PCM, we can deduce samples count from length of the data
268 if (desc.codec == AC_PCM) {
269 return channels[0].len / get_bps();
270 } else {
271 throw logic_error("Unknown sample count for compressed audio!");
272 }
273}
274
276{
277 return desc.sample_rate;
278}
279
281{
282 return desc.bps == frame.desc.bps &&
283 desc.sample_rate == frame.desc.sample_rate &&
284 desc.codec == frame.desc.codec &&
285 channels.size() == frame.channels.size();
286}
287
288void audio_frame2::set_duration(double new_duration)
289{
290 duration = new_duration;
291}
292
294{
295 channels[channel].fec_params = fec_params;
296}
297
299{
300 audio_frame2 ret;
301 ret.init(frame.get_channel_count(), frame.get_codec(), new_bps, frame.get_sample_rate());
302
303 for (size_t i = 0; i < ret.channels.size(); i++) {
304 ret.channels[i].len = frame.get_data_len(i) / frame.get_bps() * new_bps;
305 ret.channels[i].data = unique_ptr<char []>(new char[ret.channels[i].len]);
306 ::change_bps(ret.channels[i].data.get(), new_bps, frame.get_data(i), frame.get_bps(),
307 frame.get_data_len(i));
308 }
309
310 return ret;
311}
312
314{
315 if (new_bps == desc.bps) {
316 return;
317 }
318
319 vector<channel> new_channels(channels.size());
320
321 for (size_t i = 0; i < channels.size(); i++) {
322 size_t new_size = channels[i].len / desc.bps * new_bps;
323 new_channels[i] = {unique_ptr<char []>(new char[new_size]), new_size, new_size, {}};
324 }
325
326 for (size_t i = 0; i < channels.size(); i++) {
327 ::change_bps(new_channels[i].data.get(), new_bps, get_data(i), get_bps(),
328 get_data_len(i));
329 }
330
331 desc.bps = new_bps;
332 channels = std::move(new_channels);
333}
334
336{
337 assert(ts >= -1);
338 timestamp = ts;
339}
340int64_t audio_frame2::get_timestamp() const { return timestamp; }
341
342tuple<bool, audio_frame2> audio_frame2::resample_fake(audio_frame2_resampler & resampler_state, int new_sample_rate_num, int new_sample_rate_den)
343{
344 vector<channel> new_channels(channels.size());
345 for (size_t i = 0; i < channels.size(); i++) {
346 // allocate new storage + 10 ms headroom
347 size_t new_size = (long long) channels[i].len * new_sample_rate_num / desc.sample_rate / new_sample_rate_den
348 + new_sample_rate_num * desc.bps / 100 / new_sample_rate_den;
349 new_channels[i] = {unique_ptr<char []>(new char[new_size]), new_size, new_size, {}};
350 }
351
352 auto [ret, remainder] = resampler_state.resample(*this, new_channels, new_sample_rate_num, new_sample_rate_den);
353 if (!ret) {
354 return {false, audio_frame2{}};
355 }
356
357 channels = std::move(new_channels);
358 return {ret, std::move(remainder)};
359}
360
361bool audio_frame2::resample(audio_frame2_resampler & resampler_state, int new_sample_rate)
362{
363 auto [ret, remainder] = resample_fake(resampler_state, new_sample_rate, 1);
364 if (!ret) {
365 return false;
366 }
367 if (remainder.get_data_len() > 0) {
368 LOG(LOG_LEVEL_WARNING) << "Audio frame resampler: not all samples resampled!\n";
369 }
370 desc.sample_rate = new_sample_rate;
371
372 return true;
373}
struct video_desc desc
int int channels
struct video_frame * frame
int void size_t * len
This file contains definition of some common audio types.
audio_codec_t
Definition types.h:51
@ AC_PCM
Definition types.h:53
@ AC_NONE
Definition types.h:52
std::tuple< bool, audio_frame2 > resample(audio_frame2 &a, std::vector< audio_frame2::channel > &out, int new_sample_rate_num, int new_sample_rate_den)
Definition resampler.cpp:76
int64_t timestamp
Definition types.h:210
void change_bps(int new_bps)
Definition types.cpp:313
void resize(int channel, size_t len)
Definition types.cpp:183
char * get_data(int channel)
Definition types.cpp:218
bool has_same_prop_as(audio_frame2 const &frame) const
Definition types.cpp:280
void set_fec_params(int channel, fec_desc const &)
Definition types.cpp:293
std::vector< channel > channels
Definition types.h:208
void init(int nr_channels, audio_codec_t codec, int bps, int sample_rate)
Initializes audio_frame2 for use. If already initialized, data are dropped.
Definition types.cpp:115
void set_duration(double duration)
Definition types.cpp:288
void reset()
Definition types.cpp:192
audio_codec_t get_codec() const
Definition types.cpp:213
audio_frame2()=default
void reserve(size_t len)
Definition types.cpp:161
int get_channel_count() const
Definition types.cpp:260
bool resample(audio_frame2_resampler &resampler_state, int new_sample_rate)
Definition types.cpp:361
int64_t get_timestamp() const
Definition types.cpp:340
void replace(int channel, size_t offset, const char *data, size_t length)
replaces portion of data of specified channel. If the size of the channel is not sufficient,...
Definition types.cpp:152
fec_desc const & get_fec_params(int channel) const
Definition types.cpp:255
struct audio_desc desc
desc.ch_count not set, use channels.size() instead
Definition types.h:207
std::tuple< bool, audio_frame2 > resample_fake(audio_frame2_resampler &resampler_state, int new_sample_rate_num, int new_sample_rate_den)
@ resamples to new sample rate while keeping nominal sample rate intact
Definition types.cpp:342
void set_timestamp(int64_t ts)
Definition types.cpp:335
size_t get_data_len(int channel) const
Definition types.cpp:228
double get_duration() const
Definition types.cpp:246
int get_sample_rate() const
Definition types.cpp:275
static audio_frame2 copy_with_bps_change(audio_frame2 const &frame, int new_bps)
Definition types.cpp:298
int get_bps() const
Definition types.cpp:200
size_t get_data_len() const
Definition types.cpp:236
double duration
for compressed formats where this cannot be directly determined from samples/sample_rate
Definition types.h:209
void append(audio_frame2 const &frame)
Definition types.cpp:125
int get_sample_count() const
Definition types.cpp:265
static __device__ const float offset
Definition cuda_dxt.cu:139
#define LOG(level)
Definition debug.h:313
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
steady_clock::duration duration
Definition echo.cpp:67
int sample_rate
Definition types.h:78
int ch_count
Definition types.h:79
bool operator==(audio_desc const &) const
Definition types.cpp:69
int bps
Definition types.h:77
audio_codec_t codec
Definition types.h:80
bool operator!() const
Definition types.cpp:64
struct used to comunicate with audio capture/playback device
Definition types.h:99
int sample_rate
Definition types.h:101
char * data
Definition types.h:102
int ch_count
Definition types.h:104
int data_len
Definition types.h:103
int flags
Definition types.h:111
int bps
Definition types.h:100
struct fec_desc fec_params
Definition types.h:328
uint32_t ts
Definition tfrc.c:101
@ TIMESTAMP_VALID
timestamp set by source (in 90 kHz clock)
Definition types.h:223
void demux_channel(char *out, char *in, int bps, int in_len, int in_stream_channels, int pos_in_stream)
Definition utils.cpp:334