Changeset 29152
- Timestamp:
- 01/28/09 05:36:50 (4 years ago)
- Location:
- lang/javascript/SoundGenerator
- Files:
-
- 2 modified
Legend:
- Unmodified
- Added
- Removed
-
lang/javascript/SoundGenerator/sound.js
r29142 r29152 40 40 var n = document.createElement("iframe"); 41 41 document.body.appendChild(n); 42 n.s rc = d;42 n.setAttribute('src', d); 43 43 n.style.visibility = "hidden"; 44 44 } … … 56 56 }, 57 57 58 generate PulseWave: function(freq, duration, vol) {58 generateSquareWave: function(freq, duration, vol) { 59 59 var t = 0, d = this.data, res = this.resolution, 60 60 eg = this.envelopeGenerator; … … 63 63 v = 0; 64 64 for (var i = pi, e = pi * 40; i <= e; i += pi + pi) { 65 var m = t * freq / res, z = i / 40;65 var m = t * freq / res, z = i / 50; 66 66 v += sin(i * 2 * m) * sin(z) / z / i; 67 67 } … … 240 240 var MusicBuilder = function() { this.initialize.apply(this, arguments); }; 241 241 MusicBuilder.prototype = { 242 initialize: function(sg , tone) {242 initialize: function(sg) { 243 243 this.sg = sg; 244 this.tempo = 120;245 this.volume = 120;246 this.tone = 'square';244 this.tempo_ = 120; 245 this.volume_ = 120; 246 this.tone_ = 'square'; 247 247 this.initializeTone(); 248 248 }, 249 249 250 250 initializeTone: function() { 251 var volume = this.volume;252 switch (this.tone ) {251 var self = this; 252 switch (this.tone_) { 253 253 case 'saw': 254 254 this.sound = function(freq, duration) { 255 this.sg.generateSawWave(freq, duration, volume);255 this.sg.generateSawWave(freq, duration, self.volume_); 256 256 }; 257 257 break; 258 258 case 'square': 259 259 this.sound = function(freq, duration) { 260 this.sg.generate PulseWave(freq, duration, volume);260 this.sg.generateSquareWave(freq, duration, self.volume_); 261 261 }; 262 262 break; … … 265 265 266 266 calculateDuration: function(len) { 267 return (this.sg.resolution * 240 / this.tempo) / len; 267 return (this.sg.resolution * 240 / this.tempo_) / len; 268 }, 269 270 tone: function(v) { 271 this.tone_ = v; 272 this.initializeTone(); 273 }, 274 275 tempo: function(v) { 276 this.tempo_ = v; 268 277 }, 269 278 … … 276 285 rest: function(len) { 277 286 this.sg.generateSilence(this.calculateDuration(len)); 287 }, 288 289 envelope: function(eg) { 290 this.sg.envelopeGenerator = eg; 291 }, 292 293 parseMML: function(mml) { 294 var regex = /([><])|([LMOSTVS@])\s*(\d*)|([ABCDEFG]([#+-]?)|R)\s*(?:(\d+)\s*|(\.+)\s*){0,2}|\s+/gi; 295 var m; 296 var pitch_base = 36, default_len = 4; 297 var syntax_error = { message: "Syntax error" }; 298 var invalid_parameter = { message: "Invalid parameter" }; 299 var pitch_table = { 300 "a": 0, "A": 0, 301 "b": 2, "B": 2, 302 "c": -9, "C": -9, 303 "d": -7, "D": -7, 304 "e": -5, "E": -5, 305 "f": -4, "F": -4, 306 "g": -2, "G": -2 307 }; 308 var envelope_cycle = 1000; 309 var envelopes = [ 310 function(t) { return 1; }, 311 function(t) { return Math.max(0, 1 - t / envelope_cycle); }, 312 function(t) { return Math.min(1, t / envelope_cycle); }, 313 function(t) { return 1 - (t % envelope_cycle) / envelope_cycle; }, 314 function(t) { return (t % envelope_cycle) / envelope_cycle; }, 315 function(t) { return Math.abs((t % (envelope_cycle * 2)) - envelope_cycle) / envelope_cycle; }, 316 function(t) { return 1 - Math.abs((t % (envelope_cycle * 2)) - envelope_cycle) / envelope_cycle; }, 317 function(t) { return t < envelope_cycle ? 1 - t / envelope_cycle: 1; }, 318 function(t) { return t < envelope_cycle ? t / envelope_cycle: 0; } 319 ]; 320 321 var envelope_table = [ 322 envelopes[0], 323 envelopes[1], 324 envelopes[1], 325 envelopes[1], 326 envelopes[8], 327 envelopes[8], 328 envelopes[8], 329 envelopes[8], 330 envelopes[3], 331 envelopes[1], 332 envelopes[5], 333 envelopes[7], 334 envelopes[4], 335 envelopes[2], 336 envelopes[6], 337 envelopes[8] 338 ]; 339 340 tone_table = [ 'square', 'saw' ]; 341 while (m = regex.exec(mml)) { 342 switch (m[1]) { 343 case "<": 344 pitch_base += 12; 345 continue; 346 case ">": 347 pitch_base -= 12; 348 continue; 349 } 350 if (m[2]) { 351 var param = m[3] == '' ? -1: parseInt(m[3]); 352 switch (m[2]) { 353 case "l": case "L": 354 if (param < 0) 355 throw syntax_error; 356 default_len = param; 357 break; 358 case "o": case "O": 359 if (param < 0) 360 throw syntax_error; 361 pitch_base = (param - 1) * 12; 362 break; 363 case "t": case "T": 364 if (param < 0) 365 throw syntax_error; 366 this.tempo(param); 367 break; 368 case "v": case "V": 369 if (param < 0) 370 throw syntax_error; 371 this.volume(param); 372 break; 373 case 's': case 'S': 374 if (param < 0) 375 throw syntax_error; 376 if (param >= envelope_table.length) 377 throw invalid_parameter; 378 this.envelope(envelope_table[param]); 379 break; 380 case 'm': case 'M': 381 if (param < 0) 382 throw syntax_error; 383 if (param < 1) 384 throw invalid_parameter; 385 envelope_cycle = this.sg.resolution * param / 8000; 386 break; 387 case '@': 388 if (param < 0) 389 throw syntax_error; 390 if (param >= tone_table.length) 391 throw invalid_parameter; 392 this.tone(tone_table[param]); 393 } 394 continue; 395 } 396 var l = typeof(m[6]) == 'undefined' ? default_len: parseInt(m[6]), 397 a = typeof(m[7]) == 'undefined' ? 0: m[7].length, 398 d = l * (1 << a) / ((1 << (a + 1)) - 1); 399 if (m[4]) { 400 this.note(pitch_base + pitch_table[m[4].charAt(0)] 401 + (m[5] ? ("#+".indexOf(m[5]) < 0 ? -1: 1): 0), d); 402 } else { 403 this.rest(d); 404 } 405 } 278 406 } 279 407 }; -
lang/javascript/SoundGenerator/test.html
r29142 r29152 7 7 8 8 var m1 = new MusicBuilder(new SoundGenerator(16000)); 9 m1.note(43, 16); 10 m1.note(43, 16); 11 m1.rest(16); 12 m1.note(43, 16); 13 m1.rest(16); 14 m1.note(39, 16); 15 m1.note(43, 8); 16 m1.note(46, 8); 17 m1.rest(8); 18 m1.note(34, 8); 19 m1.rest(8); 20 9 m1.parseMML("O5@0T120L16E E RE RC E8 G8R8>G8R8"); 21 10 var m2 = new MusicBuilder(new SoundGenerator(16000)); 22 m2.note(33, 16); 23 m2.note(33, 16); 24 m2.rest(16); 25 m2.note(33, 16); 26 m2.rest(16); 27 m2.note(33, 16); 28 m2.note(33, 8); 29 m2.note(34, 8); 30 m2.rest(4); 31 m2.rest(8); 32 11 m2.parseMML("O4@0T120L16F+F+RF+RF+F+8G8R4."); 33 12 var m3 = new MusicBuilder(new SoundGenerator(16000)); 34 m3.note(17, 16); 35 m3.note(17, 16); 36 m3.rest(16); 37 m3.note(17, 16); 38 m3.rest(16); 39 m3.note(17, 16); 40 m3.note(17, 8); 41 m3.note(22, 8); 42 m3.rest(8); 43 m3.note(22, 8); 44 m3.rest(8); 45 13 m3.parseMML("O3@0T120L16D D RD RD D8 G8R8 G8R8"); 46 14 new SoundPlayer(16000).play(m1.sg.data, m2.sg.data, m3.sg.data); 47 //new SoundPlayer(16000).play(m1.sg.data);48 15 }; 49 16 </script>
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)