ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
audio/test_pattern.c
Go to the documentation of this file.
2#include <math.h>
3
4static double tone(double frequency, double time) {
5 return sin(6.283185307179586 * frequency * time);
6}
7
8void audio_test_pattern(float *output, size_t count, uint64_t position, uint32_t sample_rate) {
9 if (!output || !sample_rate)
10 return;
11 const uint64_t period = (uint64_t)sample_rate * 20;
12 uint64_t current = position;
13 for (size_t i = 0; i < count; ++i) {
14 uint64_t phase = current % period;
15 current = current == UINT64_MAX ? 0 : current + 1;
16 double t = (double)phase / sample_rate;
17 int section = (int)(t / 4);
18 double u = t - section * 4;
19 double value = 0;
20 double fade = fmin(1.0, fmin(u, 4 - u) / 0.08);
21 fade = sin(1.5707963267948966 * fade);
22 fade *= fade;
23 if (section == 0) {
24 // A quiet major arpeggio tests pitch and transients without sharp clicks.
25 const double notes[] = {261.625565, 329.627557, 391.995436, 523.251131};
26 double beat = u - floor(u);
27 double envelope = sin(3.141592653589793 * beat);
28 value = 0.16 * envelope * envelope * tone(notes[(int)u], beat);
29 } else if (section == 1) {
30 // Soft harmonic chord: simultaneous low, middle, and upper frequencies.
31 value = 0.06 * tone(130.812783, u) + 0.05 * tone(329.627557, u) + 0.04 * tone(783.990872, u);
32 } else if (section == 2) {
33 // Smooth logarithmic sweep from 150 Hz to 3 kHz.
34 double k = log(20.0) / 4;
35 value = 0.12 * sin(6.283185307179586 * 150 * (exp(k * u) - 1) / k);
36 } else if (section == 3) {
37 // Deterministic broadband noise bursts, with a low level and soft edges.
38 // The hash uses the low 32 bits of each product and sum.
39 uint32_t hash = (uint32_t)((uint64_t)(uint32_t)phase * 747796405u + 2891336453u);
40 hash = (uint32_t)((uint64_t)((hash >> ((hash >> 28) + 4)) ^ hash) * 277803737u);
41 hash = (hash >> 22) ^ hash;
42 double noise = (double)hash / 2147483648.0 - 1;
43 double beat = fmod(u, 1.0);
44 double envelope = beat < 0.5 ? sin(6.283185307179586 * beat) : 0;
45 value = 0.045 * noise * envelope * envelope;
46 } else if (u < 2) {
47 // Speech-like amplitude modulation, then two seconds of silence.
48 double envelope = 0.5 + 0.5 * tone(4, u);
49 double end = fmin(1.0, (2 - u) / 0.08);
50 value = end * envelope * (0.08 * tone(180, u) + 0.04 * tone(540, u) + 0.02 * tone(1260, u));
51 }
52 output[i] = (float)(value * fade);
53 }
54}
void audio_test_pattern(float *output, size_t count, uint64_t position, uint32_t sample_rate)
unsigned int uint32_t
Definition common.h:62
unsigned long long uint64_t
Definition common.h:63
🔢 Mathematical Utility Functions