├── README.md ├── hack.html └── hack.js /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript DX7 Emulator 2 | 3 | This is my hack from Music Hack Day London 2011 - it's a Yamaha DX7 4 | Emulator written entirely in JavaScript using HTML5 audio. I wrote it 5 | mainly to learn how to generate audio in a browser, but FM synthesis 6 | is cool too. 7 | 8 | ## Functionality 9 | 10 | Right now it implements basic FM synthesis (in practice it's actually 11 | phase modulation), with 6 oscillators ('operators' in DX7 speak) and 12 | the 32 'algorithms' from the physical synth. It's also capable of 13 | reading .SYX patch dumps, so you can load existing sound 14 | libraries. This mainly makes it obvious how bad it currently sounds! 15 | 16 | ## Known Limitations 17 | 18 | There are quite a few limitations currently - if I have time I'll try 19 | to work through some of these soon: 20 | 21 | * Above all, it mostly sounds pretty bad. Some patches are merely 22 | lacking the dynamics of a real DX7, some sound generally rubbish, 23 | and a few are just noise. /If you download this, please experiment 24 | at low volume before turning it up./ 25 | 26 | * Low level audio generation is very basic - it's generating .WAV 27 | files, base64 encoding and whacking that in the src attribute of an 28 | audio tag, which means its not very real time. I'd like to switch it 29 | to use newer APIs. As a result of this, all notes are .75 seconds 30 | long - it doesn't make use of offset information. 31 | 32 | * Fixed frequency operators are suspect - the numerical data from the 33 | patches I've looked at doesn't map in an obvious way to the 34 | behaviour of the DX7 UI, and patches with fixed frequency operators 35 | tend to be the ones that sound bad. 36 | 37 | * Envelope generation involves a lot of guesswork in mapping the rate 38 | parameters (0-99) to physical rates of change. It's not that 39 | terrible at the moment, but it's not authentic either. 40 | 41 | * Feedback loops and LFO modulation need some work. The LFO currently 42 | only supports sine and triangle waveforms. 43 | 44 | * There's currently no support for velocity information, nor keyboard 45 | level or rate scaling. 46 | 47 | * Many other unsupported features: 48 | * Velocity sensitivity. 49 | * Keboard level or rate scaling. 50 | * Oscillator synchronisation (kind of irrelevant with the current approach to audio generation). 51 | * Oscilaltor detune. 52 | * Transposition. 53 | * Pitch bend or modulation wheel. 54 | * Portmanteau mode. 55 | 56 | * A better patch editing UI would be nice. Right now you can edit the 57 | JSON in the text area and the synthesis routines will pick it up, 58 | but that's not very user friendly. 59 | 60 | * I'd like to add a MIDI bridge at some point, although I had 61 | difficulty getting the one I played with during the hack day to 62 | work. 63 | 64 | Many of these are missing or broken because I don't know how they're 65 | supposed to work, so if anyone does, input would definitely be 66 | appreciated. 67 | 68 | Here's a more specific list of assumptions: 69 | 70 | * Envelope rates are linear, with 1 = full dynamic range in 1 second. 71 | 72 | * The same non-linearity is applied to LFO pitch modulation as is to 73 | regular operator modulation. 74 | 75 | * LFO amplitude modulation depth is linear between 0 and half the 76 | dynamic range. 77 | 78 | * Pitch envelope is applied linearly betwen +/- 4 octaves (this is a 79 | /very/ bad assumption - extremes are known to be correct, but that 80 | gives ridiculously low sensitivity around zero). 81 | 82 | * LFO speed is linear, with 1 = 4 Hz. 83 | 84 | * Operator feedback is implemented by taking the output value from the 85 | previous sample as the input, applying the same nonlinearity as with 86 | regular modulation. 87 | 88 | * Feedback level is linear between 0 and 7/50. 89 | 90 | * In fixed frequency mode, frequency = (10 ^ (coarse frequency)) 91 | Hz. (In practice this gives frequencies in the MHz range for some of 92 | the patches I've tried, so unlikely.) 93 | 94 | 95 | 96 | ## DX7 Resources 97 | 98 | * [DX7 manual](http://ems.music.utexas.edu/docs/dx7-man.pdf) 99 | * [General DX7 resources](http://www.abdn.ac.uk/~mth192/html/dx7.html) 100 | * [SysEx patch format](http://www.abdn.ac.uk/~mth192/dx7/sysex-format.txt) 101 | -------------------------------------------------------------------------------- /hack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 |

JavaScript DX7 Emulator

11 |
12 |

13 | 21 |

22 | 23 |

24 | 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /hack.js: -------------------------------------------------------------------------------- 1 | var angeloRomData = ["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AAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOABjAgBjY2NjMjIyMgAIIwAAADEYICAgICAgICAgIGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AGMCAGNjY2MyMjIyAAgjAAAAMRggICAgICAgICAgY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAYwIAY2NjYzIyMjIACCMAAAAxGCAgICAgICAgICBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOABjAgBjY2NjMjIyMgAIIwAAADEYICAgICAgICAgIHH3", 2 | "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", 3 | "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", 4 | "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", 5 | "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", 6 | "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AAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOABjAgBjY2NjMjIyMgAIIwAAADEYICAgICAgICAgIGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AGMCAGNjY2MyMjIyAAgjAAAAMRggICAgICAgICAgY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAYwIAY2NjYzIyMjIACCMAAAAxGCAgICAgICAgICBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOABjAgBjY2NjMjIyMgAIIwAAADEYICAgICAgICAgIDn3"]; 7 | 8 | 9 | var pi = 3.14; 10 | var globalVoice = 0; 11 | var globalBank = 0; 12 | var freqCoarseDebug = []; 13 | 14 | var midiToFrequency = [ 15 | 8.176, 16 | 8.662, 17 | 9.177, 18 | 9.723, 19 | 10.301, 20 | 10.913, 21 | 11.562, 22 | 12.25, 23 | 12.978, 24 | 13.75, 25 | 14.568, 26 | 15.434, 27 | 16.352, 28 | 17.324, 29 | 18.354, 30 | 19.445, 31 | 20.602, 32 | 21.827, 33 | 23.125, 34 | 24.5, 35 | 25.957, 36 | 27.5, 37 | 29.135, 38 | 30.868, 39 | 32.703, 40 | 34.648, 41 | 36.708, 42 | 38.891, 43 | 41.203, 44 | 43.654, 45 | 46.249, 46 | 48.999, 47 | 51.913, 48 | 55, 49 | 58.27, 50 | 61.735, 51 | 65.406, 52 | 69.296, 53 | 73.416, 54 | 77.782, 55 | 82.407, 56 | 87.307, 57 | 92.499, 58 | 97.999, 59 | 103.826, 60 | 110, 61 | 116.541, 62 | 123.471, 63 | 130.813, 64 | 138.591, 65 | 146.832, 66 | 155.563, 67 | 164.814, 68 | 174.614, 69 | 184.997, 70 | 195.998, 71 | 207.652, 72 | 220, 73 | 233.082, 74 | 246.942, 75 | 261.626, 76 | 277.183, 77 | 293.665, 78 | 311.127, 79 | 329.628, 80 | 349.228, 81 | 369.994, 82 | 391.995, 83 | 415.305, 84 | 440, 85 | 466.164, 86 | 493.883, 87 | 523.251, 88 | 554.365, 89 | 587.33, 90 | 622.254, 91 | 659.255, 92 | 698.456, 93 | 739.989, 94 | 783.991, 95 | 830.609, 96 | 880, 97 | 932.328, 98 | 987.767, 99 | 1046.502, 100 | 1108.731, 101 | 1174.659, 102 | 1244.508, 103 | 1318.51, 104 | 1396.913, 105 | 1479.978, 106 | 1567.982, 107 | 1661.219, 108 | 1760, 109 | 1864.655, 110 | 1975.533, 111 | 2093.005, 112 | 2217.461, 113 | 2349.318, 114 | 2489.016, 115 | 2637.02, 116 | 2793.826, 117 | 2959.955, 118 | 3135.963, 119 | 3322.438, 120 | 3520, 121 | 3729.31, 122 | 3951.066, 123 | 4186.009, 124 | 4434.922, 125 | 4698.636, 126 | 4978.032, 127 | 5274.041, 128 | 5587.652, 129 | 5919.911, 130 | 6271.927, 131 | 6644.875, 132 | 7040, 133 | 7458.62, 134 | 7902.133, 135 | 8372.018, 136 | 8869.844, 137 | 9397.273, 138 | 9956.063, 139 | 10548.08, 140 | 11175.3, 141 | 11839.82, 142 | 12543.85 143 | ]; 144 | 145 | function extractPatchFromRom(romData, patchId) { 146 | var dataStart = 128 * patchId + 6; 147 | var dataEnd = dataStart + 128; 148 | var voiceData = romData.substring(dataStart, dataEnd); 149 | 150 | var parameters = [{},{},{},{},{},{}]; 151 | 152 | for(var i = 5; i >= 0; --i) { 153 | var oscStart = (5 - i) * 17; 154 | var oscEnd = oscStart + 17; 155 | var oscData = voiceData.substring(oscStart, oscEnd); 156 | 157 | 158 | parameters[i]["outputLevel"] = oscData.charCodeAt(14); 159 | 160 | var freqCoarse = Math.floor(oscData.charCodeAt(15) / 2); 161 | if(freqCoarse == 0) { 162 | freqCoarse = 0.5; 163 | } 164 | 165 | var freqFine = oscData.charCodeAt(16); 166 | 167 | parameters[i]["freqCoarseRaw"] = Math.floor(oscData.charCodeAt(15) / 2); 168 | 169 | if(oscData.charCodeAt(15) % 2 == 0) { 170 | parameters[i]["oscMode"] = 0; 171 | parameters[i]["frequencyRatio"] = freqCoarse * (1 + freqFine / 100); 172 | } 173 | else { 174 | parameters[i]["oscMode"] = 1; 175 | parameters[i]["fixedFrequency"] = Math.pow(10, Math.floor(oscData.charCodeAt(15) / 2)) * (1 + (freqFine / 99)*8.772); 176 | } 177 | 178 | parameters[i]["envelope"] = { 179 | "levels" : [oscData.charCodeAt(4), oscData.charCodeAt(5), oscData.charCodeAt(6), oscData.charCodeAt(7)], 180 | "rates" : [oscData.charCodeAt(0), oscData.charCodeAt(1), oscData.charCodeAt(2), oscData.charCodeAt(3)] 181 | } 182 | } 183 | 184 | return { 185 | "algorithm": voiceData.charCodeAt(110), 186 | "feedback": voiceData.charCodeAt(111) % 8, 187 | "parameters": parameters, 188 | "name": voiceData.substring(118, 128), 189 | "lfoSpeed": voiceData.charCodeAt(112), 190 | "lfoDelay": voiceData.charCodeAt(113), 191 | "lfoPitchModulationDepth": voiceData.charCodeAt(114), 192 | "lfoAmplitudeModulationDepth": voiceData.charCodeAt(115), 193 | "lfoWaveform": Math.floor(voiceData.charCodeAt(116) / 2) % 8, 194 | "pitchEnvelope": { 195 | "levels" : [voiceData.charCodeAt(106), voiceData.charCodeAt(107), voiceData.charCodeAt(108), voiceData.charCodeAt(109)], 196 | "rates" : [voiceData.charCodeAt(102), voiceData.charCodeAt(103), voiceData.charCodeAt(104), voiceData.charCodeAt(105)] 197 | } 198 | }; 199 | } 200 | 201 | var sampleRate = 44100; 202 | 203 | var programs = [ 204 | { "outputMix": [0,2], 205 | "modulationPatches": [[1], [], [3], [4], [5], [5]] }, //1 206 | { "outputMix": [0,2], 207 | "modulationPatches": [[1], [], [3], [4], [5], []] }, //2 208 | { "outputMix": [0,3], 209 | "modulationPatches": [[1], [2], [], [4], [5], [5]] }, //3 210 | { "outputMix": [0,3], 211 | "modulationPatches": [[1], [2], [], [4], [5], [3]] }, //4 212 | { "outputMix": [0,2,4], 213 | "modulationPatches": [[1], [], [3], [], [5], [5]] }, //5 214 | { "outputMix": [0,2,4], 215 | "modulationPatches": [[1], [], [3], [], [5], [4]] }, //6 216 | { "outputMix": [0,2], 217 | "modulationPatches": [[1], [], [3,4], [], [5], [5]] }, //7 218 | { "outputMix": [0,2], 219 | "modulationPatches": [[1], [], [3,4], [3], [5], []] }, //8 220 | { "outputMix": [0,2], 221 | "modulationPatches": [[1], [1], [3,4], [], [5], []] }, //9 222 | { "outputMix": [0,3], 223 | "modulationPatches": [[1], [2], [2], [4,5], [], []] }, //10 224 | { "outputMix": [0,3], 225 | "modulationPatches": [[1], [2], [], [4,5], [], [5]] }, //11 226 | { "outputMix": [0,2], 227 | "modulationPatches": [[1], [1], [3,4,5], [], [], []] }, //12 228 | { "outputMix": [0,2], 229 | "modulationPatches": [[1], [], [3,4,5], [], [], [5]] }, //13 230 | { "outputMix": [0,2], 231 | "modulationPatches": [[1], [], [3], [4,5], [], [5]] }, //14 232 | { "outputMix": [0,2], 233 | "modulationPatches": [[1], [1], [3], [4,5], [], []] }, //15 234 | { "outputMix": [0], 235 | "modulationPatches": [[1,2,4], [], [3], [], [5], [5]] }, //16 236 | { "outputMix": [0], 237 | "modulationPatches": [[1,2,4], [1], [3], [], [5], []] }, //17 238 | { "outputMix": [0], 239 | "modulationPatches": [[1,2,3], [], [2], [4], [5], []] }, //18 240 | { "outputMix": [0,3,4], 241 | "modulationPatches": [[1], [2], [], [5], [5], [5]] }, //19 242 | { "outputMix": [0,1,3], 243 | "modulationPatches": [[2], [2], [2], [4,5], [], []] }, //20 244 | { "outputMix": [0,1,3,4], 245 | "modulationPatches": [[2], [2], [2], [5], [5], []] }, //21 246 | { "outputMix": [0,2,3,4], 247 | "modulationPatches": [[1], [], [5], [5], [5], [5]] }, //22 248 | { "outputMix": [0,1,3,4], 249 | "modulationPatches": [[], [2], [], [5], [5], [5]] }, //23 250 | { "outputMix": [0,1,2,3,4], 251 | "modulationPatches": [[], [], [5], [5], [5], [5]] }, //24 252 | { "outputMix": [0,1,2,3,4], 253 | "modulationPatches": [[], [], [], [5], [5], [5]] }, //25 254 | { "outputMix": [0,1,3], 255 | "modulationPatches": [[], [2], [], [4,5], [], [5]] }, //26 256 | { "outputMix": [0,1,3], 257 | "modulationPatches": [[], [2], [2], [4,5], [], []] }, //27 258 | { "outputMix": [0,2,5], 259 | "modulationPatches": [[1], [], [3], [4], [4], []] }, //28 260 | { "outputMix": [0,1,2,4], 261 | "modulationPatches": [[], [], [3], [], [5], [5]] }, //29 262 | { "outputMix": [0,1,2,5], 263 | "modulationPatches": [[], [], [3], [4], [4], []] }, //30 264 | { "outputMix": [0,1,2,3,4], 265 | "modulationPatches": [[], [], [], [], [5], [5]] }, //31 266 | { "outputMix": [0,1,2,3,4,5], 267 | "modulationPatches": [[], [], [], [], [], [5]] } //32 268 | ]; 269 | 270 | var dxModulationLookup = [ 271 | 0, 272 | 0.000337, 273 | 0.000476, 274 | 0.000674, 275 | 0.000952, 276 | 0.001235, 277 | 0.001602, 278 | 0.001905, 279 | 0.002265, 280 | 0.002694, 281 | 0.003204, 282 | 0.003810, 283 | 0.004531, 284 | 0.005388, 285 | 0.006408, 286 | 0.007620, 287 | 0.008310, 288 | 0.009062, 289 | 0.010776, 290 | 0.011752, 291 | 0.013975, 292 | 0.015240, 293 | 0.016619, 294 | 0.018123, 295 | 0.019764, 296 | 0.021552, 297 | 0.023503, 298 | 0.025630, 299 | 0.027950, 300 | 0.030480, 301 | 0.033238, 302 | 0.036247, 303 | 0.039527, 304 | 0.043105, 305 | 0.047006, 306 | 0.051261, 307 | 0.055900, 308 | 0.060960, 309 | 0.066477, 310 | 0.072494, 311 | 0.079055, 312 | 0.086210, 313 | 0.094012, 314 | 0.102521, 315 | 0.111800, 316 | 0.121919, 317 | 0.132954, 318 | 0.144987, 319 | 0.158110, 320 | 0.172420, 321 | 0.188025, 322 | 0.205043, 323 | 0.223601, 324 | 0.243838, 325 | 0.265907, 326 | 0.289974, 327 | 0.316219, 328 | 0.344839, 329 | 0.376050, 330 | 0.410085, 331 | 0.447201, 332 | 0.487676, 333 | 0.531815, 334 | 0.579948, 335 | 0.632438, 336 | 0.689679, 337 | 0.752100, 338 | 0.820171, 339 | 0.894403, 340 | 0.975353, 341 | 1.063630, 342 | 1.159897, 343 | 1.264876, 344 | 1.379357, 345 | 1.504200, 346 | 1.640341, 347 | 1.788805, 348 | 1.950706, 349 | 2.127260, 350 | 2.319793, 351 | 2.529752, 352 | 2.758714, 353 | 3.008399, 354 | 3.280683, 355 | 3.577610, 356 | 3.901411, 357 | 4.254519, 358 | 4.639586, 359 | 5.059505, 360 | 5.517429, 361 | 6.016799, 362 | 6.561366, 363 | 7.155220, 364 | 7.802823, 365 | 8.509039, 366 | 9.279172, 367 | 10.119009, 368 | 11.034858, 369 | 12.033598, 370 | 13.122731 371 | ]; 372 | 373 | 374 | function getWaveform(type, phase) { 375 | switch(type) { 376 | case 0: 377 | var cycles = phase/(2 * pi); 378 | var fracCycles = cycles - Math.floor(cycles); 379 | if(fracCycles < 0.25) { 380 | return fracCycles * 4; 381 | } 382 | else if(fracCycles < 0.75) { 383 | return 1 - ((fracCycles - 0.25) * 4); 384 | } 385 | else { 386 | return (fracCycles - 1) * 4; 387 | } 388 | case 4: 389 | return Math.sin(phase); 390 | } 391 | 392 | 393 | return Math.sin(phase); 394 | // return 0; 395 | } 396 | 397 | var envDebug = []; 398 | 399 | 400 | 401 | function generateSampleData(frequencyInHertz, dataFromRom) { 402 | var data = []; 403 | var length = 1; 404 | var safety = 0.9; 405 | 406 | var program = programs[dataFromRom["algorithm"]]; 407 | var parameters = dataFromRom["parameters"]; 408 | 409 | 410 | var numSamples = sampleRate * length; 411 | 412 | var patch = program["modulationPatches"]; 413 | var output = program["outputMix"]; 414 | 415 | // envelopes[6] is the pitch envelope 416 | var envelopes = [0,0,0,0,0,0,50]; 417 | var envelopeSegments = [0,0,0,0,0,0,0]; 418 | 419 | var outputs = [0,0,0,0,0,0]; 420 | 421 | var phis = [0,0,0,0,0,0]; 422 | 423 | for(var i = 0; i < numSamples; ++i) { 424 | var t = i / sampleRate; 425 | 426 | for(var operator2 = 5; operator2 >= 0; --operator2) { 427 | outputs[operator2] *= dataFromRom["feedback"] / 50 428 | } 429 | 430 | var lfo = getWaveform(dataFromRom["lfoWaveform"], t * dataFromRom["lfoSpeed"] * 2 * pi / 4); 431 | 432 | var baseOmega = frequencyInHertz * 2 * pi; // + 0.2 * lfo * dataFromRom["lfoPitchModulationDepth"] / 99; 433 | baseOmega *= Math.pow(2,(envelopes[6] - 50) / 12.5); 434 | 435 | var operatorFrequencies = []; 436 | 437 | for(var operator = 0; operator < 6; ++operator) { 438 | if(parameters[operator]["oscMode"] == 0) { 439 | operatorFrequencies.push(baseOmega * parameters[operator]["frequencyRatio"]); 440 | } 441 | else { 442 | operatorFrequencies.push(parameters[operator]["fixedFrequency"] * 2 * pi); 443 | } 444 | } 445 | 446 | 447 | for(var operator = 5; operator >= 0; --operator) { 448 | var modulationInput = 0; 449 | 450 | phis[operator] += operatorFrequencies[operator] / sampleRate; 451 | var phi = phis[operator]; 452 | 453 | for(var inputOperator = 0; inputOperator < patch[operator].length; ++inputOperator) { 454 | phi += dxModulationLookup[parameters[patch[operator][inputOperator]]["outputLevel"]] * outputs[patch[operator][inputOperator]]; 455 | } 456 | 457 | phi += dxModulationLookup[dataFromRom["lfoPitchModulationDepth"]] * lfo; 458 | 459 | outputs[operator] = Math.sin(phi) * envelopes[operator]; 460 | 461 | var envelopeRates = parameters[operator]["envelope"]["rates"]; 462 | var envelopeLevels = parameters[operator]["envelope"]["levels"]; 463 | var envelopeSegment = envelopeSegments[operator]; 464 | 465 | var envelopeSign = (envelopeLevels[envelopeSegment]/99) - envelopes[operator]; 466 | if (envelopeSign != 0) { 467 | envelopeSign /= Math.abs(envelopeSign); 468 | } 469 | 470 | if((envelopeSegment < 3) || ((envelopeSegment == 3) && (i > (numSamples / 2)))) { 471 | envelopes[operator] += envelopeSign * envelopeRates[envelopeSegment] / (sampleRate * 10); 472 | 473 | if(envelopes[operator] * envelopeSign >= (envelopeLevels[envelopeSegment]/99) * envelopeSign) { 474 | envelopes[operator] = (envelopeLevels[envelopeSegment]/99); 475 | envelopeSegments[operator] += 1; 476 | } 477 | } 478 | } 479 | 480 | var envelopeRates = dataFromRom["pitchEnvelope"]["rates"]; 481 | var envelopeLevels = dataFromRom["pitchEnvelope"]["levels"]; 482 | var envelopeSegment = envelopeSegments[6]; 483 | 484 | var envelopeSign = (envelopeLevels[envelopeSegment]) - envelopes[6]; 485 | if (envelopeSign != 0) { 486 | envelopeSign /= Math.abs(envelopeSign); 487 | } 488 | 489 | if((envelopeSegment < 3) || ((envelopeSegment == 3) && (i > (numSamples / 2)))) { 490 | envelopes[6] += envelopeSign * envelopeRates[envelopeSegment] / (sampleRate * 10); 491 | 492 | if(envelopes[6] * envelopeSign >= (envelopeLevels[envelopeSegment]) * envelopeSign) { 493 | envelopes[6] = (envelopeLevels[envelopeSegment]); 494 | envelopeSegments[6] += 1; 495 | } 496 | } 497 | 498 | 499 | var mixedOutput = 0; 500 | var total = 0; 501 | for(var k = 0; k < output.length; ++k) { 502 | mixedOutput += outputs[output[k]] * parameters[output[k]]["outputLevel"]; 503 | total += parameters[output[k]]["outputLevel"]; 504 | } 505 | mixedOutput /= total; 506 | 507 | data.push(mixedOutput * safety * 32768 * (1 - (((lfo + 1)/4) * dataFromRom["lfoAmplitudeModulationDepth"] / 99))); 508 | } 509 | 510 | return data; 511 | } 512 | 513 | function encodeAudio16bit(data) { 514 | var n = data.length; 515 | var integer = 0, i; 516 | 517 | // 16-bit mono WAVE header template 518 | var header = "RIFF<##>WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00<##><##>\x02\x00\x10\x00data<##>"; 519 | 520 | // Helper to insert a 32-bit little endian int. 521 | function insertLong(value) { 522 | var bytes = ""; 523 | for (i = 0; i < 4; ++i) { 524 | bytes += String.fromCharCode(value % 256); 525 | value = Math.floor(value / 256); 526 | } 527 | header = header.replace('<##>', bytes); 528 | } 529 | 530 | // ChunkSize 531 | insertLong(36 + n * 2); 532 | 533 | // SampleRate 534 | insertLong(sampleRate); 535 | 536 | // ByteRate 537 | insertLong(sampleRate * 2); 538 | 539 | // Subchunk2Size 540 | insertLong(n * 2); 541 | 542 | // Output sound data 543 | for (var i = 0; i < n; ++i) { 544 | var sample = Math.round(data[i]); 545 | if (sample < 0) { 546 | sample += 65536; // 2's complement signed 547 | } 548 | header += String.fromCharCode(sample % 256); 549 | header += String.fromCharCode(Math.floor(sample / 256)); 550 | } 551 | 552 | return 'data:audio/wav;base64,' + btoa(header); 553 | } 554 | 555 | function generateAndPlaySample(noteNumber, voice) { 556 | 557 | var dataFromRom = JSON.parse($('#patchDetails').val()); 558 | 559 | var data = generateSampleData(midiToFrequency[noteNumber], dataFromRom); 560 | var sampleUrl = encodeAudio16bit(data); 561 | 562 | audioPlayer = $('