UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
delay.cpp
Go to the documentation of this file.
1
5/*
6 * Copyright (c) 2022 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#include <memory>
45#include <string_view>
46
47#include "debug.h"
48#include "module.h"
49#include "audio/audio_filter.h"
50#include "audio/types.h"
51#include "lib_common.h"
52#include "utils/ring_buffer.h"
53#include "utils/misc.h"
55
56namespace{
57 struct Ring_buf_deleter{
58 void operator()(ring_buffer_t *ring){ ring_buffer_destroy(ring); }
59 };
60}
61
64
66
67 bool frame_mode = false;
68 int req_delay = 0;
69
70 int bps = 0;
71 int ch_count = 0;
72 int sample_rate = 0;
73
74 int delay_size = 0;
75 std::unique_ptr<ring_buffer_t, Ring_buf_deleter> ring;
76};
77
78static void usage(){
79 printf("Delays audio:\n\n");
80 printf("delay usage:\n");
81 printf("\tdelay:<delay in milliseconds>\n\n");
82}
83
84static af_result_code parse_cfg(state_delay *s, std::string_view cfg){
85 auto tok = tokenize(cfg, ':');
86 if(tok.empty() || tok == "help"){
87 usage();
88 return AF_HELP_SHOWN;
89 }
90
91 if(!parse_num(tok, s->req_delay)){
92 log_msg(LOG_LEVEL_ERROR, "Failed to parse delay time\n");
93 usage();
94 return AF_FAILURE;
95 }
96
97 s->frame_mode = (tokenize(cfg, ':') == "frames");
98
99 return AF_OK;
100}
101
102static af_result_code init(struct module *parent, const char *cfg, void **state){
103 auto s = std::make_unique<state_delay>(parent);
104
105 auto ret = parse_cfg(s.get(), cfg);
106 if(ret == AF_OK)
107 *state = s.release();
108
109 return ret;
110};
111
112static void set_delay_size(state_delay *s, int size){
113 if(size == s->delay_size)
114 return;
115
116 if(size == 0){
117 s->ring.reset();
118 } else {
119 s->ring.reset(ring_buffer_init(size * 2));
120 ring_fill(s->ring.get(), 0, size);
121 }
122 s->delay_size = size;
123}
124
126 int in_bps, int in_ch_count, int in_sample_rate)
127{
128 auto s = static_cast<state_delay *>(state);
129
130 s->bps = in_bps;
131 s->ch_count = in_ch_count;
132 s->sample_rate = in_sample_rate;
133
134 if(!s->frame_mode){
135 int samples = (s->sample_rate / 1000) * s->req_delay;
136 set_delay_size(s, samples * s->ch_count * s->bps);
137 }
138
139 return AF_OK;
140}
141
142static void done(void *state){
143 auto s = static_cast<state_delay *>(state);
144
145 delete s;
146}
147
148static void get_configured(void *state,
149 int *bps, int *ch_count, int *sample_rate)
150{
151 auto s = static_cast<state_delay *>(state);
152
153 if(bps) *bps = s->bps;
154 if(ch_count) *ch_count = s->ch_count;
155 if(sample_rate) *sample_rate = s->sample_rate;
156}
157
159 auto s = static_cast<state_delay *>(state);
160
161 struct message *msg;
162 while ((msg = check_message(s->mod.get()))) {
163 const char *text = ((msg_universal *) msg)->text;
164 if(parse_cfg(s, text) != AF_OK){
166 continue;
167 }
168
169 if(!s->frame_mode){
170 int samples = (s->sample_rate / 1000) * s->req_delay;
171 set_delay_size(s, samples * s->ch_count * s->bps);
172 }
173
175 }
176
177 auto f = *frame;
178 if(s->frame_mode){
179 set_delay_size(s, f->data_len * s->req_delay);
180 }
181
182 if(f->bps != s->bps || f->ch_count != s->ch_count){
183 if(configure(state, f->bps, f->ch_count, f->sample_rate) != AF_OK){
184 return AF_MISCONFIGURED;
185 }
186 }
187
188 //If ring is null, delay is 0
189 if(!s->ring)
190 return AF_OK;
191
192 if(f->data_len <= s->delay_size){
193 ring_buffer_write(s->ring.get(), f->data, f->data_len);
194 ring_buffer_read(s->ring.get(), f->data, f->data_len);
195 } else {
196 int excess_size = f->data_len - s->delay_size;
197
198 //Write the last delay_size bytes to buffer
199 ring_buffer_write(s->ring.get(), f->data + excess_size, s->delay_size);
200
201 //Move the beggining of frame to the end and prepend delay_size bytes from buffer
202 memmove(f->data + s->delay_size, f->data, excess_size);
203 ring_buffer_read(s->ring.get(), f->data, s->delay_size);
204 }
205
206 return AF_OK;
207}
208
210 .name = "delay",
211 .init = init,
212 .done = done,
213 .configure = configure,
214 .get_configured_in = get_configured,
215 .get_configured_out = get_configured,
216 .filter = filter,
217};
218
void ** state
int int int sample_rate
struct video_frame * frame
This file contains definition of some common audio types.
#define AUDIO_FILTER_ABI_VERSION
af_result_code
@ AF_FAILURE
@ AF_MISCONFIGURED
@ AF_HELP_SHOWN
@ AF_OK
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
static const struct audio_filter_info audio_filter_delay
Definition delay.cpp:209
static void set_delay_size(state_delay *s, int size)
Definition delay.cpp:112
static af_result_code filter(void *state, struct audio_frame **frame)
Definition delay.cpp:158
static void usage()
Definition delay.cpp:78
static void get_configured(void *state, int *bps, int *ch_count, int *sample_rate)
Definition delay.cpp:148
static af_result_code parse_cfg(state_delay *s, std::string_view cfg)
Definition delay.cpp:84
static af_result_code init(struct module *parent, const char *cfg, void **state)
Definition delay.cpp:102
static af_result_code configure(void *state, int in_bps, int in_ch_count, int in_sample_rate)
Definition delay.cpp:125
static void done(void *state)
Definition delay.cpp:142
@ MODULE_CLASS_DATA
Definition module.h:86
@ LIBRARY_CLASS_AUDIO_FILTER
Definition lib_common.h:85
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
Definition lib_common.h:144
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct message * check_message(struct module *mod)
#define RESPONSE_OK
Definition messaging.h:57
#define RESPONSE_BAD_REQUEST
Definition messaging.h:60
void ring_buffer_destroy(struct ring_buffer *ring)
struct ring_buffer * ring_buffer_init(int size)
int ring_buffer_read(struct ring_buffer *ring, char *out, int max_len)
void ring_buffer_write(struct ring_buffer *ring, const char *in, int len)
void ring_fill(struct ring_buffer *ring, int c, int size)
struct msghdr msg
const char * parent
Definition settings.cpp:198
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
bool parse_num(std::string_view sv, T &res, int base=10)
struct used to comunicate with audio capture/playback device
Definition types.h:99
int req_delay
Definition delay.cpp:68
int ch_count
Definition delay.cpp:71
int sample_rate
Definition delay.cpp:72
module_raii mod
Definition delay.cpp:65
int delay_size
Definition delay.cpp:74
std::unique_ptr< ring_buffer_t, Ring_buf_deleter > ring
Definition delay.cpp:75
bool frame_mode
Definition delay.cpp:67
state_delay(struct module *mod)
Definition delay.cpp:63