-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtforkraw.c
executable file
·137 lines (115 loc) · 2.82 KB
/
tforkraw.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
133
134
135
136
137
/**
* tforkraw.c gen raw sfile with native endianness based on tfork2.c
* usage ./tforkraw outfile.raw 1.5 440 44100 0.95 0
* (0 = 16bit | 1 = 32bit)
* import into audacity as 16 bit/32 bit raw
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef M_PI
#define M_PI (3.141592654)
#endif
enum {
ARG_NAME,
ARG_OUTFILE,
ARG_DUR,
ARG_HZ,
ARG_SR,
ARG_AMP,
ARG_TYPE,
ARG_NARGS
};
enum samptype {
RAWSAMP_SHORT,
RAWSAMP_FLOAT
};
// thanks to the SNDAN programmers for this
// return 0 for big-endian machine, 1 for little-endian machine
// so we can tell user what order the data is
int byte_order()
{
int one = 1;
char* endptr = (char *) &one;
return (*endptr);
}
const char* endianness[2] = { "big_endian", "little_endian" };
int main(int argc, char** argv)
{
unsigned int i,nsamps;
unsigned int maxframe = 0;
unsigned int samptype, endian, bitreverse;
double samp, dur, freq, srate, amp, step;
double start, end, fac, maxsamp;
double twopi = 2.0 * M_PI;
double angleincr;
FILE* fp = NULL;
float fsamp;
short ssamp;
if (argc != ARG_NARGS) {
printf("Usage: tforkraw outsfile.raw dur freq srate amp isfloat\n");
return 1;
}
dur = atof(argv[ARG_DUR]);
freq = atof(argv[ARG_HZ]);
srate = atof(argv[ARG_SR]);
amp = atof(argv[ARG_AMP]);
samptype = (unsigned int) atoi(argv[ARG_TYPE]);
if (samptype > 1){
printf("error: sampletype can be only 0 or 1\n");
return 1;
}
// create binary file: not all systems require the 'b'
fp = fopen(argv[ARG_OUTFILE], "wb");
if (fp == NULL) {
fprintf(stderr, "Error creating output file %s\n", argv[ARG_OUTFILE]);
return 1;
}
nsamps = (int)(dur * srate);
angleincr = twopi * freq / nsamps;
step = dur / nsamps;
// normalized range always - just scale by amp
start = 1.0;
end = 1.0e-4;
maxsamp = 0.0;
fac = pow(end / start, 1.0 / nsamps);
endian = byte_order();
printf("Writing %d %s samples\n", nsamps, endianness[endian]);
// run the loop for this samptype
if (samptype == RAWSAMP_SHORT) {
for (i=0; i < nsamps; i++) {
samp = amp * sin(angleincr * i);
samp *= start;
start *= fac;
// use 32767 to avoid overflow problem
ssamp = (short) (samp * 32767.0);
if (fwrite(&ssamp, sizeof(short), 1, fp) != 1) {
printf("Error writing data to file\n");
return 1;
}
if (fabs(samp) > maxsamp) {
maxsamp = fabs(samp);
maxframe = i;
}
}
} else {
// RAWSAMP_FLOAT
for (i=0; i < nsamps; i++) {
samp = amp * sin(angleincr * i);
samp *= start;
start *= fac;
fsamp = (float) samp;
if (fwrite(&fsamp, sizeof(float), 1, fp) != 1) {
printf("Error writing data to file\n");
return 1;
}
if (fabs(samp) > maxsamp) {
maxsamp = fabs(samp);
maxframe = i;
}
}
}
fclose(fp);
printf("done. Maximum sample value = %.8lf at frame %d\n", maxsamp, maxframe);
return 0;
}