Skip to content

Instantly share code, notes, and snippets.

@sreimers
Created April 4, 2022 11:56
Show Gist options
  • Save sreimers/67440f237cae34537c9c1667900a7c57 to your computer and use it in GitHub Desktop.
Save sreimers/67440f237cae34537c9c1667900a7c57 to your computer and use it in GitHub Desktop.
#include <re.h>
#include <rem.h>
#include <stdint.h>
enum {
SILENCE_Q = 1024 * 1024, /* Quadratic sample value for silence */
};
static bool auframe_silence(struct auframe *af)
{
const int16_t *v;
int32_t sum = 0;
size_t i;
v = af->sampv;
for (i = 0; i < af->sampc; i++) {
sum += v[i] * v[i];
if (sum > (int32_t)(i + 1) * SILENCE_Q)
return false;
}
return true;
}
static bool auframe_silence2(struct auframe *af)
{
return auframe_level(af) < -30.;
}
int main(void)
{
uint64_t start, end;
int16_t testv[1920] = {0, 0};
struct auframe af;
bool ret;
int cnt = 0;
auframe_init(&af, AUFMT_S16LE, testv, ARRAY_SIZE(testv), 48000, 2);
for (int j = 0; j < 2; j++) {
cnt = 0;
start = tmr_jiffies_usec();
for (int i = 0; i < 2000; i++) {
ret = auframe_silence(&af);
if (ret)
cnt++;
af.level = AULEVEL_UNDEF;
}
end = tmr_jiffies_usec();
re_printf("auframe_silence %d usecs (%d)\n", end - start, cnt);
cnt = 0;
start = tmr_jiffies_usec();
for (int i = 0; i < 2000; i++) {
ret = auframe_silence2(&af);
if (ret)
cnt++;
af.level = AULEVEL_UNDEF;
}
end = tmr_jiffies_usec();
re_printf("auframe_silence2 %d usecs (%d)\n", end - start,
cnt);
}
return 0;
}
@cspiel1
Copy link

cspiel1 commented Apr 4, 2022

Didn't realized that yours is faster. Okay, then I replace the auframe_silence() in my PR.

The compare is so slow?

if (sum > (int32_t)(i + 1) * SILENCE_Q)

Or why?

@sreimers
Copy link
Author

sreimers commented Apr 4, 2022

Yes I think so. For silence its done 1920 times (20ms audio stereo). For non silence your code is much faster (if early max values) but I think we can assume ~50% of a normal conversation could be silence (since only one person is talking).

@cspiel1
Copy link

cspiel1 commented Apr 4, 2022

We found that the example code has to be compiled also with same optimization level like rem. But anyway your silence detection is slightly faster:

auframe_silence2 1713 usecs (2000)
auframe_silence 2318 usecs (2000)
auframe_silence2 683 usecs (2000)
auframe_silence 2341 usecs (2000)

Also I tried with this code:

bool auframe_silence(struct auframe *af)
{
	const int16_t *v;
	int32_t sum = 0;
	int64_t b = SILENCE_Q;
	size_t i;
	size_t len = af->sampc;

	v = af->sampv;
	for (i = 0; i < len; i++) {
		sum += v[i] * v[i];
		b += SILENCE_Q;

		if (sum > b)
			return false;
	}

	return true;
}

Here b += SILENCE_Q; and if (sum > b) leads to the performance loss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment