-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfadef.c
121 lines (97 loc) · 2.48 KB
/
fadef.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
// fade for float samples
// invocation:
// fadef in|out lin|log|cos|logcos start end [quietvol]
// with lin, cos: quietvol is a multiplier (0 < quietvol < 1)
// with log, logcos: quietvol is a number of dB (quietvol < 0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <err.h>
#include <sys/types.h>
#include "synth.h"
#include "rate.inc"
enum { LIN, LOG, COS, LOGCOS };
#define M_20_OVER_LN10 8.68588963806503655302257838
#define M_LN10_OVER_20 0.115129254649702284200899573
#define RATTODB(x) (log(x) * M_20_OVER_LN10)
#define DBTORAT(x) exp((x) * M_LN10_OVER_20)
static void usage(void)
{
errx(1, "usage: fadef in|out lin|log|cos|logcos start end [quietvol]");
}
int main(int argc, char *argv[])
{
int fostart, foend;
int fonum = 0;
int fadetype = LIN;
int fadein = 0;
float loudvol, quietvol;
float smp[2];
float fofstart, fofend;
if (argc != 5 && argc != 6)
usage();
if (!strcasecmp(argv[1], "in"))
fadein = 1;
else if (!strcasecmp(argv[1], "out"))
fadein = 0;
else usage();
if (!strcasecmp(argv[2], "lin"))
fadetype = LIN;
else if (!strcasecmp(argv[2], "log"))
fadetype = LOG;
else if (!strcasecmp(argv[2], "cos"))
fadetype = COS;
else if (!strcasecmp(argv[2], "logcos"))
fadetype = LOGCOS;
else usage();
fofstart = atof(argv[3]);
fofend = atof(argv[4]);
if (fadetype == LIN || fadetype == COS)
{
loudvol = 1.0;
quietvol = 0.0;
}
else // LOG, LOGCOS
{
loudvol = 0.0; // dB
quietvol = -90.0; // dB
}
if (argc == 6) // custom quietvol supplied
quietvol = atof(argv[5]);
fostart = (int)(fofstart * RATE);
foend = (int)(fofend * RATE);
// before the fade
while (fostart > 0 && fread(smp, sizeof smp[0], 2, stdin) == 2)
{
fostart--, foend--;
if (fwrite(smp, sizeof smp[0], 2, stdout) < 2)
err(1, "write error");
}
// during the fade
while (fonum < foend && fread(smp, sizeof smp[0], 2, stdin) == 2)
{
double progress;
double amp;
progress = (double)fonum / foend;
if (fadein)
progress = 1.0 - progress;
if (fadetype == COS || fadetype == LOGCOS)
progress = 1.0 - cos(progress * M_PI/2);
amp = loudvol*(1.0 - progress) + quietvol*progress;
if (fadetype == LOG || fadetype == LOGCOS)
amp = DBTORAT(amp);
smp[0] *= amp;
smp[1] *= amp;
if (fwrite(smp, sizeof smp[0], 2, stdout) < 2)
err(1, "write error");
fonum++;
}
// after the fade
while (fread(smp, sizeof smp[0], 2, stdin) == 2)
{
if (fwrite(smp, sizeof smp[0], 2, stdout) < 2)
err(1, "write error");
}
return 0;
}