-
Notifications
You must be signed in to change notification settings - Fork 1
/
makeSamples.js
158 lines (132 loc) · 4.19 KB
/
makeSamples.js
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Code in ~2 hours by Bemmu, idea and sound code snippet from Viznut.
var functionParams = {
eightBit: false,
unsigned:false,
forBitmap: {
sf:"127+127*(EXPR)",
uf:"255*(EXPR)",
s8:"127+(EXPR)",
u8:'EXPR',
sampler:function(str) {
return functionParams.getSampler(str, this);
}
},
forAudio:{
sf:'EXPR',
uf:'2*(EXPR)-1',
s8:'((EXPR)&255)/128',
u8:'((EXPR)&255)/128 - 1',
sampler:function(str) {
return functionParams.getSampler(str, this);
}
},
toCode:function() {return (this.unsigned? 'u' : 's' ) + (this.eightBit? '8' : 'f')},
getSampler: function(str, targetType) {
var code = this.toCode();
var fragment = targetType[code];
return makeBulkSampler(str, fragment);
}
};
var replacements = {
sin: "Math.sin",
cos: "Math.cos",
tan: "Math.tan",
floor: "Math.floor",
ciel: "Math.ceil",
pi:"Math.PI",
round:"Math.round"
};
function preprocessFunction(oneLiner) {
for (var key in replacements) {
oneLiner = oneLiner.replace(RegExp(key, 'g'), replacements[key]);
}
return oneLiner;
}
function makeBulkSampler(rawOneLiner, conversionTemplate) {
var oneLiner = preprocessFunction(rawOneLiner);
var ourExpression = conversionTemplate.replace("EXPR",oneLiner);
var wrapper = "var f = function (buf,count,t) {for(var i=0; i<count;i++,t++)buf[i]=(EXPR);}";
var toEval = wrapper.replace('EXPR',ourExpression);
return makeFunction(toEval) || nullFunction;
}
function makeBulkSampleFunction(rawOneLiner) {
return functionParams.forAudio.sampler(rawOneLiner);
// var oneLiner = preprocessFunction(rawOneLiner);
// // if(!makeFunction(oneLiner)) return null;
//
//
// var toEval = "var f = function (buf,count,t) {for(i=0; i<count;i++,t++) {buf[i]=(" + oneLiner + ");}}";
// return makeFunction(toEval) || nullFunction;
}
function makeBulkSample8BitFunction(rawOneLiner) {
var oneLiner = preprocessFunction(rawOneLiner);
// if(!makeFunction(oneLiner)) return null;
var toEval = "var f =function(buf,count,t){for(i=0; i<count;i++,t++)buf[i]=127+127*(" + oneLiner + ");};"
return makeFunction(toEval) || nullFunction;
}
function makeFunction(evalString) {
try {
eval(evalString);
} catch(e) {
return null;
}
return f;
}
function nullFunction() {
return 1;
}
function makeSampleFunction(rawOneLiner) {
try {
var oneLiner = preprocessFunction(rawOneLiner);
eval("var f = function (t) { return " + oneLiner + "}");
return f;
} catch(e) {
if(elt) elt.innerHTML = e.toString();
return null;
}
}
function generateSound(f, seconds, frequency, bitsPerSample, channels) {
var count = frequency * seconds * channels;
var sampleArray = bitsPerSample == 16 ? new Int16Array(count) : new Uint8Array(count);
for (var t = 0; t < count; t++) {
var sample = f(t) & 0xff;
sampleArray[t] = sample << 8 | sample;
}
return sampleArray;
}
var backBuffer;
function genSound16x1(f, count) {
backBuffer = new ArrayBuffer(count * 2);
var sampleArray = new Int16Array(backBuffer);
for (var t = 0; t < count; t++) {
sampleArray[t] = ((f(t) * 256) % 0xffff) - 32768;
}
return sampleArray;
}
var sampleHelper = {
samples8: null,
makeSampleData8: function(sampleFunction, wd, ht) {
var sampleCount = wd * ht;
this.samples8 = this.samples8 || new Uint8Array(sampleCount);
var s = this.samples8;
for (var t = 0; t < sampleCount; t++) {
s[t] = 127 + 127 * sampleFunction(t);
}
return this.samples8;
}
}
function makeSampleData(sampleFunction) {
var bitsPerSample = 16;
var frequency = 44100;
var channels = 1;
var duration = 10;
var sampleCount = duration * channels * frequency;
return genSound16x1(sampleFunction, sampleCount);
// return generateSound(sampleFunction,30,frequency,bitsPerSample,channels);
}
function makeRiff(samples) {
var bitsPerSample = 16;
var frequency = 44100;
var channels = 1;
return RIFFChunk(channels, bitsPerSample, frequency, samples);
}