Skip to content

Commit b634053

Browse files
committed
added silence audio filter
1 parent b329b18 commit b634053

File tree

3 files changed

+166
-6
lines changed

3 files changed

+166
-6
lines changed

Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ COMMON_OBJS = \
123123
src/audio/filter/delay.o \
124124
src/audio/filter/discard.o \
125125
src/audio/filter/controlport_stats.o \
126+
src/audio/filter/silence.o \
126127
src/capture_filter.o \
127128
src/capture_filter/change_pixfmt.o \
128129
src/capture_filter/color.o \

src/audio/audio_filter.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct audio_filter_info{
6464
/// @retval 0 if initialized successfully
6565
/// @retval <0 if error
6666
/// @retval >0 no error but state was not returned, eg. showing help
67-
af_result_code (*init)(struct module *mod, const char *cfg, void **state);
67+
enum af_result_code (*init)(struct module *mod, const char *cfg, void **state);
6868

6969
/// @brief Frees filter
7070
void (*done)(void *state);
@@ -76,7 +76,7 @@ struct audio_filter_info{
7676
/// @param sample_rate sample rate
7777
/// @retval 0 if initialized successfully
7878
/// @retval <0 if error
79-
af_result_code (*configure)(void *state,
79+
enum af_result_code (*configure)(void *state,
8080
int bps, int ch_count, int sample_rate);
8181

8282
/// @brief Get configured input audio format
@@ -91,20 +91,20 @@ struct audio_filter_info{
9191
/// @param state filter state
9292
/// @param f frame to filter, can take ownership of passed
9393
// frame and return a different one
94-
af_result_code (*filter)(void *state, struct audio_frame **f);
94+
enum af_result_code (*filter)(void *state, struct audio_frame **f);
9595
};
9696

9797
struct audio_filter{
9898
const struct audio_filter_info *info;
9999
void *state;
100100
};
101101

102-
af_result_code audio_filter_init(struct module *parent, const char *name, const char *cfg,
102+
enum af_result_code audio_filter_init(struct module *parent, const char *name, const char *cfg,
103103
struct audio_filter *filter);
104104

105105
void audio_filter_destroy(struct audio_filter *state);
106106

107-
af_result_code audio_filter_configure(struct audio_filter *state,
107+
enum af_result_code audio_filter_configure(struct audio_filter *state,
108108
int bps, int ch_count, int sample_rate);
109109

110110
void audio_filter_get_configured_out(struct audio_filter *state,
@@ -113,7 +113,7 @@ void audio_filter_get_configured_out(struct audio_filter *state,
113113
void audio_filter_get_configured_in(struct audio_filter *state,
114114
int *bps, int *ch_count, int *sample_rate);
115115

116-
af_result_code audio_filter(struct audio_filter *state, struct audio_frame **frame);
116+
enum af_result_code audio_filter(struct audio_filter *state, struct audio_frame **frame);
117117

118118
//void register_audio_filter(struct audio_filter_info *filter);
119119

src/audio/filter/silence.c

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/**
2+
* @file audio/filter/silence.c
3+
* @author Martin Pulec <pulec@cesnet.cz>
4+
*/
5+
/*
6+
* Copyright (c) 2023 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+
#include <assert.h>
39+
#include <stddef.h>
40+
#include <stdlib.h>
41+
#include <string.h>
42+
43+
#include "audio/audio_filter.h"
44+
#include "audio/types.h"
45+
#include "lib_common.h"
46+
#include "utils/color_out.h"
47+
48+
enum {
49+
MAX_CHANNELS = 16,
50+
};
51+
52+
struct state_silence {
53+
struct audio_desc desc;
54+
size_t silence_channels[MAX_CHANNELS];
55+
int silence_channels_count;
56+
};
57+
58+
static void
59+
usage()
60+
{
61+
color_printf("Audio capture " TBOLD(
62+
"silence") " allows muting individual channels.\n\n");
63+
color_printf("Usage:\n");
64+
color_printf("\t" TBOLD("--audio-filter silence[:<idx1>,<idx2>]\n\n"));
65+
color_printf("(indexed from zero)\n");
66+
color_printf("If no index is given, all channels will be muted.\n");
67+
}
68+
69+
static enum af_result_code
70+
init(struct module *parent, const char *cfg, void **state)
71+
{
72+
(void) parent;
73+
if (strlen(cfg) > 0) {
74+
cfg++;
75+
}
76+
if (strcmp(cfg, "help") == 0) {
77+
usage();
78+
return AF_HELP_SHOWN;
79+
}
80+
struct state_silence *s = calloc(1, sizeof *s);
81+
82+
char *fmt = strdupa(cfg);
83+
char *item = NULL;
84+
char *end_ptr = NULL;
85+
while ((item = strtok_r(fmt, ",", &end_ptr)) != NULL) {
86+
assert(s->silence_channels_count < MAX_CHANNELS - 1);
87+
s->silence_channels[s->silence_channels_count++] =
88+
strtol(item, NULL, 10);
89+
fmt = NULL;
90+
}
91+
*state = s;
92+
return AF_OK;
93+
}
94+
95+
static enum af_result_code
96+
configure(void *state, int in_bps, int in_ch_count, int in_sample_rate)
97+
{
98+
struct state_silence *s = state;
99+
100+
s->desc.bps = in_bps;
101+
s->desc.ch_count = in_ch_count;
102+
s->desc.sample_rate = in_sample_rate;
103+
return AF_OK;
104+
}
105+
106+
static void
107+
done(void *state)
108+
{
109+
free(state);
110+
}
111+
112+
static void
113+
get_configured_desc(void *state, int *bps, int *ch_count, int *sample_rate)
114+
{
115+
struct state_silence *s = state;
116+
117+
*bps = s->desc.bps;
118+
*ch_count = s->desc.ch_count;
119+
*sample_rate = s->desc.sample_rate;
120+
}
121+
122+
static enum af_result_code
123+
filter(void *state, struct audio_frame **frame)
124+
{
125+
struct state_silence *s = state;
126+
127+
if (s->silence_channels_count == 0) {
128+
memset((*frame)->data, 0, (*frame)->data_len);
129+
return AF_OK;
130+
}
131+
132+
const int frame_size = s->desc.bps * s->desc.ch_count;
133+
for (int i = 0; i < s->silence_channels_count; ++i) {
134+
if (s->silence_channels[i] >= (size_t) (*frame)->ch_count) {
135+
continue;
136+
}
137+
char *ptr =
138+
(*frame)->data + s->silence_channels[i] * (*frame)->bps;
139+
for (int j = 0; j < (*frame)->data_len; j += frame_size) {
140+
memset(ptr, 0, (*frame)->bps);
141+
ptr += frame_size;
142+
}
143+
}
144+
145+
return AF_OK;
146+
}
147+
148+
static const struct audio_filter_info audio_filter_silence = {
149+
.name = "silence",
150+
.init = init,
151+
.done = done,
152+
.configure = configure,
153+
.get_configured_in = get_configured_desc,
154+
.get_configured_out = get_configured_desc,
155+
.filter = filter,
156+
};
157+
158+
REGISTER_MODULE(silence, &audio_filter_silence, LIBRARY_CLASS_AUDIO_FILTER,
159+
AUDIO_FILTER_ABI_VERSION);

0 commit comments

Comments
 (0)