├── 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 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/hack.js:
--------------------------------------------------------------------------------
1 | var angeloRomData = ["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AAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOABjAgBjY2NjMjIyMgAIIwAAADEYICAgICAgICAgIGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AGMCAGNjY2MyMjIyAAgjAAAAMRggICAgICAgICAgY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAYwIAY2NjYzIyMjIACCMAAAAxGCAgICAgICAgICBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOAAAAgBjY2NjY2NjAAAAAAA4AAACAGNjY2NjY2MAAAAAADgAAAIAY2NjY2NjYwAAAAAAOABjAgBjY2NjMjIyMgAIIwAAADEYICAgICAgICAgIHH3",
2 | "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",
3 | "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",
4 | "8EMACSAARg08NWJQVQA2AAAAUQBcCABGDTw1YlBVADYAAABxADcEAEYNPDViUFUAEgEAD3EEVAQARkYUNmNcVAAAAAAAAgBjCQhGLjw1Yl9fADYAAAABBFUEAEZGFDZjYV8AAAAAAAIEYwEFXkNfPDIyMjIBDyYhCEcoAFBST1BIRVQgNS4sFiUmXmMAABoABQ5JAE8EAENGFCdjY2AAAAAAADoAYAElRQ08JmJQVQANEwAPcQRUBABFRhQnY1xUAAAAAAACAGMJCDoXLSZjXlYADRMAAwEEVwQAQ0YUJ2NjXwANAAADAgRjARBeQ188MjIyMgUNJiEIRygALVEtIFBST1BIVDU5JSpjXDgANxkAAwIANhIANUMmKlZcVAAAAAAAagBUBgBDJRQiSmFeAAAAfwBSAFEGACYkIx5VYF8AQGI8A3IEYwEEXTUfKFJcWgA2BgAAAQBYBgAoHhkdUWJaAAAAAAASBGMBCF5DXzwyMjIyDgchGggAKAVPUlRFR0EgU1RHSEwKIGNcAAAAAAAAYAhLEABMSQocY1wAAAAAAAAoCEcEADFKCiBiYmIAKTgAAkgISAQAMw8KL2NcXAA4WwADcARjBABNBwcdXTgcAEQAYwIAAFEEASA4Ci9jYiQAJ2MAD1gIYgQBYmJiYjUxMjIbDyEjDwAQDENIQU1CRVJPUkNjLCVGY1EAAC4AAAA9GEs+AFslHUhjWgAAKAAODDkATAgAY04cUWNiAAAnAEcAOQRjAgBjQxlVY1wAADQAKAA6DGMWAGNOKFJjUwAAJwAYADkYYwYAY0wcUWNcAAAoNQAAOghjAgBVY0sAMTIyMggPHh8ADykMRElHSS1DTEFWMV8dFDJjXwAAKQATAHMYTwIAXxQUMmNfAAAAAAAAAwBjAgBfHRQyY18AADYAGwA7GFUCAF8UFDJjXwAAAAAAADMIYwIAXzIjTmNLAAAkLgAAOxhOJgBgGRlDY0sAAAAAAABTCGMCAF5DXzwyMjIyBAYPIQcAKBhEWU5PUkhPREUyY003AE5OAAApAAAAOBBXDgBjQGMIUjAAACsAWgA4DGAOAFpLKFJSMAAAMAAAADkUWw4AYx0mLmNQAAAAAAAAPRxjAgBjIS4yY1AAADYALgA8GDwKAGMgLS5jUAAAAAAAAD0cYwIAXkNfPDIyMjIGDxUAAAAhDE1BUklNQkEgICBfHRQyY18AACkAEwBzGE8CAF8UFDJjXwAAAAAAAAMAYwIAXx0UMmNfAAA2ABsAOxhVAgBfFBQyY18AAAAAAAA7CGMCAF8yI05jSwAANwA0ADscOjQAYBkZQ2NLAAAAAAAAUwhjAgBeQ188MjIyMgQGDyEAACgYRFlOT1JIT0RFU18cGy9jWgAABQAABDoAOwIAUwAbMmNaAAAxAAAAUgxEAgBYHBsyY1oAADEAAAA8EGICAF8cGy9jWgAABQBjBEoMTwoAWFxHP2NDW1onAA0ASgRYAgBYHBsyY1oAADEAAAA7EGMCAAAAAAAyMjIyAw0jAAAAMQxQSUFOTyAgICAgYzgYN10cAAAAAAAAORwNEgBjAAAAYwAAADRLAAA/DFMAAGMqBzdaHgAAJyUADDwUXgwAYz4ROmNfIAAkOQ4DPxBNAABjFAAAYwAAACkAAAA/AE8AAGM+ETpjXyAAJDkOAj8AYwEXXkNfPDIyMjIQDiMAAABADEZMQU5HREJBU1NjYxYvY2MAAGMACAM7AEsOAGJjAD1jYwAAAAAMBCgQTgwAY2MDPWNjAAAAAAoEGABWAgBjEgk9Y04AAAAAAARAAGMCAC4uAENgY1UADwAGBDgASgoAOS4AY2BjVQAPAAAEOABjBABiYmJiMjIyMgAPKDoCMjgMTEVBRC1HVUlUUjgNAyFjYF4ANgAAAEgAQAgAOA0EIWNgXgA2AAAAOABNAgA4DQUjY2BeACIAFAAoAFICAEcpNj1jX2MAAAAAAHAAYwEIOy4FJmJfXwAPAAIAAABWAgBHKTY9Y19jAAAAAAAAAGMBAF5DXzwyMjIyAQ8mISAAGAxKVU1QIC4uLi4gRSIgR2NiWgAzAC4HGAhSBABWJyBHY2JRACcAAA9YAGMBFUUnIEdjYmIAJwAADzgAYwEARScgR2NiUQAnAAAPGABjAQhjJyBHY2NjADMABw9wAVwEAE4nIEdjYmMAMwAmD3AAYwEDVF9fPDIyMjIVDygACAAoAE1JTkkgTU9PR1lVPxgZY2BcADYAAAAzBFEQAGM8Jy1jYAAANgAAADkIYwgAJSAYJGNgXAA2AAAAKwhVBABjIhQjY1xZABQbAAACHF4IAGMuABxjXVcAIAAEDAkIWAQALyEUI2NcVAAAAAAAAgRjKR9eQ188MjIyMgsPJiERRygAIEpFUk9NRSAgIEUCIEd/Yl4AEQclBDAIVgQAVicgR2NiUQAnAAAPAABjARFFJyBHY2JiACcAAA84AGMBAkUnIEdjYlEAJwAADxgAYwEEYycgR2NjYwAzAAAHAAFjBABOJyBHY2JjABsAJg8AAGMBA1RfXzwyMjIyFQ8oLwYAOABNSU5JIE1PT0cgYzklAElcWAA3DGMBcghPMABjQyYAVlxcADQuYwMCCGMGAWMlGxpIYV4AJgoCABIISgYAYyQjMVBgXwBAYjwDSghjBgBjNR8AUl9bACcDBg4BBFYGAGMyGTFjXF8ANwAAAzoAYxkaFFhjYzIyMjIOByEACAA4BUFFUklFTEJPTkQ4TTIpY2FEAA8AAARHHEQEAkpXMilXGwAADwAABDcAYgIEWjoyKWAbAAAPAAAEVgBiAgJTIDIpYxcAAA8AAAQ7AGMAAGNNKiNjAAAAAAAAADgAYwAAWC8uLmMAAAAAAAAAOwBjAABIAGIAMmMyUA0PERwCUHIMVE9NIERSVU1TIF8xETZjXwBjKiMAB3AQQQIAXyESOGNfAFInJwAHWAxaAABfLxU1Y2EAAAAAAARkAGMAAF8RES1jXwBjJmNjBmAcRxAAYycVGmNVAGMpBQAHCBBXAABQIBIyY18AAAAAAAAMAGMAAGNjAAAxMzIzCQYsAAAAMBhNRURMIFhQUlNWYzBjMmMgAAAHAAAAOh0+JABQVRgpY1oAAAAAAABzDGMCACIAYzJjGQAAAAAAAAMEYAIAPlUrMmNKKgAkAAAAOxBIAgBjHGMyYxkAAAAAAAAjBGMCAGMcYzJjGQAAAAAAAF0EYwBjXkNfPDIyMjIZBxoAAAAhGFNOT09QWSBLT09NGQ84Y14AACcADgA5AEwEAEZMRzljXgAAJwAaAD8AYwUOYw8uNGNgAAAAAAAAOgBjAgA8KSA+Y18AAC0AQAA7AFoAC0EpJj5jYQAAAAAAADsAWwACRxwmNWNeAAAAAAAAOgBjAABjY1BjMjIAMgoPIwAAADEYU1lORFJVTSAxIGMpGgpjYgAADwAABEIMJRIAY00aB2NiAAAPAAAEEghXAgBjKSoHY2IAAA8AAAQiBFoOAGNNGhxjYgAADwAABDoIWwIAYykaB2NiAAAPAAAEOghhAgBjTRoqY2IAAA8AAAQ6BEkoAGNjY2MyMjIyBwgcAAAAIBhTSVRBUiAgICAgT1IUY1gAACB/AAAAcxhULgBgGRkyY0sAAAAAAA8DAGMCAF9UFGNjAABFAAAAADsQYwQAYBkZN2NLAAAAAAAAOwBjAgARKiNOY2NjAAAAAAA7DF0CAGAZGTZjSwAAAAAAD3MAYwIAXkN/PDIyMjIEByYhAABIGFNZTi1QSUFOTyBOMCYhY1UAACYAHgNTCD0aADUiGydjUQAADwAVB0gIRwoASUUKL2NhAAAZACkHKAxWAgBjDg0oY1sAABtjAAdIBGMBCkIAGCdaXgAAIgQnA3MMUgoAYw4NKGNbAAAbYwAHNwxjAQtSY2NjMjIyMg4NLAAAADAMICBNT05EUkUgIGMuABxjXVcANgAAADEARxAAYy4AHGNdVwA2AAAAOQBNCABjLgAcY11XADYAAAB/BFQIAC4hFCNjXFQAAAAAAAIAYwEBYy4AHGNdVwA2AAAACQRUCAAuIRQjY1xUAAAAAAACBGMBAF5DXzwyMjIyAQ8mIRFHKABBTkxHIFNUUk5HJSAYHGNgXAA2AAAAMwRIFgAlIBgcY2BcADYAAAA5CDsOACUgGBxjYFwANgAAACsIYwIAYyIUI2NcVAAAAAAAAgA9CABjLgAcY11XADYAAAAJCFoEAC8hFCNjXFQAAAAAAAIEYwEcXkNfPDIyMjICByYhEUcoDENBUkxPUyAgIDFjNR8AUl9bAAAAAABABAAEAGMlNzljAAAACg5jADAcTgIAYzQUJmNaRgAAAAAMAwBjAgBjNBE5Y2NGABYAYwA9AGMBHmM1HwBSX1sAGwAADDkAVQQAYzIZMWNfXQAeYwAAAgBjARpjVF88MzQyMgEPIgAIYyEARE9MQlkgU1BMVEYNPDViUFUANgAAAFEAXAgARg08NWJQVQA2AAAAcQQ5BABGDTw1YlBVAH8BAA9xCFYEAEZGFDZjXFQAAAAAAAIAYwkIYzUfAFJfWwA2AAAAAQBVBABjMhkxY19dAAAAAAACAGMBGl5DXzwyMjIyAQ8mIQhHKABQUk9QSEVUIFQ4Y0BiPWNDNAAuAAAMQARVAjVBJgA9YwAAADUAKwA4ADYEAD0ZGTxjY2EAPAoKADsALwI1NSZLPVgsGAAuAAADWARFAgBjYT42Y2NaAAAAAABMAU0CAEJISz1dWWIAKQAAADgEYwIAXkNfPDIyMjIPDSEXAg0wGFRPTyBDT09MICAOSDARNS8pAAAAAABACFQEAiQVJD9jWlUAAAAAADAEYwQBChMpDDA6FAkAAAAAUAxcAgIkFDUnY15hAAAAAABwDGMCABMaNRkuOEcuAAAAADgONgQAJBQ1OWNeYQAAAAAAAABjAgASPF88MDMyMgQPJDITAjAYVk9JQ0VTICAgICsjGTljY2MAMwAyAEAASgQCKyMZOWNjYwAzADIAMABRBAErIxk5Y2NjADMAMgBQAE8CAmNhKDlcXgAAMwAAAHAAYgIAKyMZOX9jYwAzADIAOABUBABjYSg5XF4AADMAAAAAAGMCABI8XzwwMzIyCA4kMhMCMBhHT09ETFVWSU5HRhsQH1pjXgAAABEACABjBABGGxAoWmNfAAAAAABwAEEAAEYbECdaY14AAAAAAAgAUgAAQCgXKmNhXgAAAAAAOABjAQIyGgkkXmNeABgABQBwBFYAAEFjYyljY2MAAAAAAGgAYwEeY2NjYzIyMjIIDhcACwAhGE1PT0ctNTIgTU84MzcyY14AAD0AGAA4CFsEAGNFFDJjXgAAMmMADDoEYwMUVzMtKWNjAAAAAAAAUQBSAABjRRQxY14AADJjAAA4AGMBCDlCKx5jXAAAPQASACkIXwIAUCgcLmNcWgAvYwAASARjAQBjY2NjMjIyMgQIIwAAADEkU1RFRUwgRFJVTX3r",
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 = $('').attr({ src: sampleUrl });
563 |
564 | $('body').append(audioPlayer);
565 |
566 | audioPlayer[0].play();
567 |
568 |
569 |
570 | return dataFromRom["name"];
571 | }
572 |
573 | function playScale(voice) {
574 | generateAndPlaySample(60, voice);
575 | generateAndPlaySample(62, voice);
576 | generateAndPlaySample(64, voice);
577 | generateAndPlaySample(65, voice);
578 | generateAndPlaySample(67, voice);
579 | generateAndPlaySample(69, voice);
580 | generateAndPlaySample(71, voice);
581 | generateAndPlaySample(72, voice);
582 | }
583 |
584 | function patchNames() {
585 | var options = '';
586 | for(var i = 0; i < 32; ++i) {
587 | options += "" + extractPatchFromRom(atob(angeloRomData[globalBank]), i)["name"] + " ";
588 | }
589 | $('#patchSelect').html(options);
590 | }
591 |
592 | window.addEventListener('load', function() {
593 |
594 |
595 | $('#patchSelect').change( function() {
596 | globalVoice = parseInt($('#patchSelect option:selected')[0].value);
597 | $('#patchDetails').html( JSON.stringify(extractPatchFromRom(atob(angeloRomData[globalBank]), globalVoice), undefined, 2) )
598 | } );
599 |
600 | $('#bankSelect').change( function() {
601 | globalBank = parseInt($('#bankSelect option:selected')[0].value);
602 | patchNames();
603 | $('#patchDetails').html( JSON.stringify(extractPatchFromRom(atob(angeloRomData[globalBank]), globalVoice), undefined, 2) )
604 | } );
605 |
606 |
607 |
608 | // midiBridge.connectAllInputs();
609 |
610 | var noteNumbers = {
611 | //white keys
612 | 65 : 60, //key a -> note c
613 | 83 : 62, //key s -> note d
614 | 68 : 64, //key d -> note e
615 | 70 : 65, //key f -> note f
616 | 71 : 67, //key g -> note g
617 | 72 : 69, //key h -> note a
618 | 74 : 71, //key j -> note b
619 | 75 : 72, //key k -> note c
620 | 76 : 74, //key l -> note d
621 | 186 : 76, //key ; -> note e
622 | 222 : 77, //key : -> note f
623 | //black keys
624 | 87 : 61, //key w -> note c#/d
625 | 69 : 63, //key e -> note d#/e
626 | 84 : 66, //key t -> note f#/g
627 | 89 : 68, //key y -> note g#/a
628 | 85 : 70, //key u -> note a#/b
629 | 79 : 73, //key o -> note c#/d
630 | 80 : 75 //key p -> note d#/e
631 | }
632 |
633 | var keysPressed = {};
634 |
635 | var connectKeyboard = function(){
636 |
637 | document.addEventListener("keydown", function(e) {
638 | if(noteNumbers[e.which] && !keysPressed[e.which]) {
639 | generateAndPlaySample(noteNumbers[e.which], globalVoice);
640 | }
641 | }, false);
642 | };
643 |
644 | patchNames();
645 | connectKeyboard();
646 |
647 |
648 | }, false);
--------------------------------------------------------------------------------