-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathwriteWav.c
132 lines (102 loc) · 3.25 KB
/
writeWav.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <stdio.h>
#include <unistd.h>
#include "support.h"
/*
* General wave generation parameters.
*
* parameter 1 - wave frequency in Hertz; should be clamped to a sane range
* (e. g. 20-20000 Hz) with CLAMP_u(freq, min, max)
* parameter 2 - wave duration in milliseconds
* parameter 3 - wave amplitude (0.0-1.0)
*/
/*
* Size-based wave generatrion for malloc() calls.
*
* size - allocated memory size in bytes
*/
#define MALLOC_WAVE_PARAMS(size) \
CLAMP_u(size, 20u, 10000u), 20, 0.7f
/*
* Size and runtime based wave generation for malloc() calls.
*
* size - see above
* ticks - number of consumed CPU clock ticks since program start
*/
#define MALLOC_WAVE_TICKS_PARAMS(size, ticks) \
CLAMP_u(ticks, 20u, 20000u), 10, 0.7f
/*
* Size based wave generation for read() calls.
*
* requested - requested amount of bytes to read
* returned - actual amounts of bytes read
*/
#define READ_WAVE_PARAMS(requested, returned) \
CLAMP_u(requested, 20u, 20000u), CLAMP_u(returned, 100, 1700), 0.7f
// foward declarations ================================================
void* malloc(size_t size);
ssize_t read(int fd, void * data, size_t count);
static void gen_square_wave(unsigned frequency, unsigned duration, float amplitude);
static void __gen_square_wave_impl(unsigned samples, unsigned half_period_length, sample_t sample);
// implementations ====================================================
void* malloc(size_t size)
{
static __thread bool inside_malloc = false;
void *const p = __malloc_data.real_malloc(size);
if (!__malloc_data.nomalloc && !inside_malloc)
{
inside_malloc = true;
flockfile(__wave_out);
gen_square_wave(MALLOC_WAVE_TICKS_PARAMS(size,
clock() - __malloc_data.ticks_start));
gen_square_wave(MALLOC_WAVE_PARAMS(size));
fflush_unlocked(__wave_out);
funlockfile(__wave_out);
inside_malloc = false;
}
return p;
}
ssize_t read(int fd, void * data, size_t count)
{
const ssize_t p = __read_data.real_read(fd, data, count);
if (!__read_data.noread)
{
flockfile(__wave_out);
gen_square_wave(READ_WAVE_PARAMS(count, p));
fflush_unlocked(__wave_out);
funlockfile(__wave_out);
}
return p;
}
static inline
void gen_square_wave(unsigned frequency, unsigned duration, float amplitude)
{
assert(amplitude >= 0.f && amplitude <= 1.f);
__gen_square_wave_impl(
DIV_ROUND(SAMPLING_RATE * duration, 1000),
MAX(DIV_ROUND(SAMPLING_RATE / 2, frequency), 1u),
#ifndef SAMPLING_FORMAT_FLOAT
(sample_t)((float) INTTYPE_MAX(sample_t) * amplitude)
#else
amplitude
#endif
);
}
static void __gen_square_wave_impl(unsigned samples, unsigned half_period_length, sample_t sample)
{
assert(__wave_out != NULL);
assert(samples == 0 || half_period_length != 0);
for (unsigned half_period_start = 0;
half_period_start < samples;
half_period_start += half_period_length)
{
const unsigned half_period_end =
MIN(half_period_start + half_period_length, samples);
for (unsigned i = half_period_start; i != half_period_end; i++)
fwrite_unlocked(&sample, sizeof(sample), 1, __wave_out);
#ifndef SAMPLING_FORMAT_FLOAT
sample = (sample_t)(IS_SIGNED(sample_t) ? -sample : ~sample);
#else
sample = -sample;
#endif
}
}