⌈⌋ ⎇ branch:  Bitrhythm


Hex Artifact Content

Artifact 3c5afc75cbce09761b2c0c1470691047fb6e295eeff80441d1e0d43a2f3a4881:


0000: 23 20 41 6c 74 65 72 6e 61 74 65 20 49 6d 70 6c  # Alternate Impl
0010: 65 6d 65 6e 74 61 74 69 6f 6e 73 0a 0a 48 65 72  ementations..Her
0020: 65 27 73 20 73 6f 6d 65 20 6d 6f 72 65 20 64 65  e's some more de
0030: 6d 6f 20 73 6f 6e 67 73 20 66 72 6f 6d 20 6f 74  mo songs from ot
0040: 68 65 72 20 73 79 73 74 65 6d 73 0a 0a 2d 20 3c  her systems..- <
0050: 61 20 68 72 65 66 3d 22 68 74 74 70 73 3a 2f 2f  a href="https://
0060: 77 77 77 2e 79 6f 75 74 75 62 65 2e 63 6f 6d 2f  www.youtube.com/
0070: 77 61 74 63 68 3f 76 3d 78 58 4e 42 31 42 62 4b  watch?v=xXNB1BbK
0080: 59 38 41 22 3e 46 6f 78 64 6f 74 20 61 6e 64 20  Y8A">Foxdot and 
0090: 50 79 74 68 6f 6e 3c 2f 61 3e 0a 2d 20 3c 61 20  Python</a>.- <a 
00a0: 68 72 65 66 3d 22 68 74 74 70 73 3a 2f 2f 77 77  href="https://ww
00b0: 77 2e 79 6f 75 74 75 62 65 2e 63 6f 6d 2f 77 61  w.youtube.com/wa
00c0: 74 63 68 3f 76 3d 41 4c 72 67 75 64 52 53 32 41  tch?v=ALrgudRS2A
00d0: 51 22 3e 43 73 6f 75 6e 64 3c 2f 61 3e 0a 0a 54  Q">Csound</a>..T
00e0: 68 65 20 63 6f 72 65 20 69 64 65 61 73 20 6f 66  he core ideas of
00f0: 20 62 69 74 72 68 79 74 68 6d 20 61 72 65 20 74   bitrhythm are t
0100: 72 61 6e 73 66 65 72 61 62 6c 65 20 74 6f 20 6f  ransferable to o
0110: 74 68 65 72 20 6c 61 6e 67 75 61 67 65 73 20 61  ther languages a
0120: 73 20 77 65 6c 6c 2e 20 41 74 20 6d 6f 73 74 20  s well. At most 
0130: 61 6c 6c 20 79 6f 75 20 6e 65 65 64 20 69 73 20  all you need is 
0140: 61 20 6d 75 73 69 63 20 6c 6f 6f 70 20 61 6e 64  a music loop and
0150: 20 73 61 6d 70 6c 65 73 20 74 6f 20 67 65 74 20   samples to get 
0160: 73 74 61 72 74 65 64 2e 0a 0a 41 20 62 61 73 69  started...A basi
0170: 63 20 70 6f 72 74 20 74 6f 20 4a 55 43 45 20 63  c port to JUCE c
0180: 61 6e 20 62 65 20 66 6f 75 6e 64 20 5b 68 65 72  an be found [her
0190: 65 5d 28 68 74 74 70 73 3a 2f 2f 78 79 7a 7a 79  e](https://xyzzy
01a0: 61 70 70 73 2e 6c 69 6e 6b 2f 62 69 74 72 68 79  apps.link/bitrhy
01b0: 74 68 6d 2d 61 6c 74 29 2e 0a 0a 48 65 72 65 27  thm-alt)...Here'
01c0: 73 20 61 20 64 65 6d 6f 20 62 79 20 53 75 6e 56  s a demo by SunV
01d0: 6f 78 27 73 20 61 75 74 68 6f 72 20 3f 0a 0a 3c  ox's author ?..<
01e0: 69 66 72 61 6d 65 20 77 69 64 74 68 3d 22 35 36  iframe width="56
01f0: 30 22 20 68 65 69 67 68 74 3d 22 33 31 35 22 20  0" height="315" 
0200: 73 72 63 3d 22 68 74 74 70 73 3a 2f 2f 77 77 77  src="https://www
0210: 2e 79 6f 75 74 75 62 65 2e 63 6f 6d 2f 65 6d 62  .youtube.com/emb
0220: 65 64 2f 38 72 38 77 73 76 48 55 62 43 6f 22 20  ed/8r8wsvHUbCo" 
0230: 74 69 74 6c 65 3d 22 59 6f 75 54 75 62 65 20 76  title="YouTube v
0240: 69 64 65 6f 20 70 6c 61 79 65 72 22 20 66 72 61  ideo player" fra
0250: 6d 65 62 6f 72 64 65 72 3d 22 30 22 20 61 6c 6c  meborder="0" all
0260: 6f 77 3d 22 61 63 63 65 6c 65 72 6f 6d 65 74 65  ow="acceleromete
0270: 72 3b 20 61 75 74 6f 70 6c 61 79 3b 20 63 6c 69  r; autoplay; cli
0280: 70 62 6f 61 72 64 2d 77 72 69 74 65 3b 20 65 6e  pboard-write; en
0290: 63 72 79 70 74 65 64 2d 6d 65 64 69 61 3b 20 67  crypted-media; g
02a0: 79 72 6f 73 63 6f 70 65 3b 20 70 69 63 74 75 72  yroscope; pictur
02b0: 65 2d 69 6e 2d 70 69 63 74 75 72 65 22 20 61 6c  e-in-picture" al
02c0: 6c 6f 77 66 75 6c 6c 73 63 72 65 65 6e 3e 3c 2f  lowfullscreen></
02d0: 69 66 72 61 6d 65 3e 0a 0a 41 6e 20 65 78 61 6d  iframe>..An exam
02e0: 70 6c 65 20 69 6e 20 43 20 77 69 74 68 20 72 61  ple in C with ra
02f0: 79 6c 69 62 0a 0a 60 60 60 0a 62 72 65 77 20 69  ylib..```.brew i
0300: 6e 73 74 61 6c 6c 20 72 61 79 6c 69 62 0a 63 63  nstall raylib.cc
0310: 20 72 61 79 2e 63 20 20 60 70 6b 67 2d 63 6f 6e   ray.c  `pkg-con
0320: 66 69 67 20 2d 2d 6c 69 62 73 20 2d 2d 63 66 6c  fig --libs --cfl
0330: 61 67 73 20 72 61 79 6c 69 62 60 20 2d 6f 20 72  ags raylib` -o r
0340: 61 79 0a 60 60 60 0a 0a 60 60 60 43 0a 23 69 6e  ay.```..```C.#in
0350: 63 6c 75 64 65 20 22 72 61 79 6c 69 62 2e 68 22  clude "raylib.h"
0360: 0a 23 69 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74  .#include <unist
0370: 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  d.h>.#include <s
0380: 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  tdio.h>.#include
0390: 20 3c 74 69 6d 65 2e 68 3e 0a 23 69 6e 63 6c 75   <time.h>.#inclu
03a0: 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 0a 76  de <stdlib.h>..v
03b0: 6f 69 64 20 73 65 74 54 69 6d 65 6f 75 74 28 69  oid setTimeout(i
03c0: 6e 74 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73 29  nt milliseconds)
03d0: 0a 7b 0a 20 20 20 20 2f 2f 20 49 66 20 6d 69 6c  .{.    // If mil
03e0: 6c 69 73 65 63 6f 6e 64 73 20 69 73 20 6c 65 73  liseconds is les
03f0: 73 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 30 0a  s or equal to 0.
0400: 20 20 20 20 2f 2f 20 77 69 6c 6c 20 62 65 20 73      // will be s
0410: 69 6d 70 6c 65 20 72 65 74 75 72 6e 20 66 72 6f  imple return fro
0420: 6d 20 66 75 6e 63 74 69 6f 6e 20 77 69 74 68 6f  m function witho
0430: 75 74 20 74 68 72 6f 77 20 65 72 72 6f 72 0a 20  ut throw error. 
0440: 20 20 20 69 66 20 28 6d 69 6c 6c 69 73 65 63 6f     if (milliseco
0450: 6e 64 73 20 3c 3d 20 30 29 20 7b 0a 20 20 20 20  nds <= 0) {.    
0460: 20 20 20 20 66 70 72 69 6e 74 66 28 73 74 64 65      fprintf(stde
0470: 72 72 2c 20 22 43 6f 75 6e 74 20 6d 69 6c 6c 69  rr, "Count milli
0480: 73 65 63 6f 6e 64 73 20 66 6f 72 20 74 69 6d 65  seconds for time
0490: 6f 75 74 20 69 73 20 6c 65 73 73 20 6f 72 20 65  out is less or e
04a0: 71 75 61 6c 20 74 6f 20 30 5c 6e 22 29 3b 0a 20  qual to 0\n");. 
04b0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20         return;. 
04c0: 20 20 20 7d 0a 0a 20 20 20 20 2f 2f 20 61 20 63     }..    // a c
04d0: 75 72 72 65 6e 74 20 74 69 6d 65 20 6f 66 20 6d  urrent time of m
04e0: 69 6c 6c 69 73 65 63 6f 6e 64 73 0a 20 20 20 20  illiseconds.    
04f0: 69 6e 74 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73  int milliseconds
0500: 5f 73 69 6e 63 65 20 3d 20 63 6c 6f 63 6b 28 29  _since = clock()
0510: 20 2a 20 31 30 30 30 20 2f 20 43 4c 4f 43 4b 53   * 1000 / CLOCKS
0520: 5f 50 45 52 5f 53 45 43 3b 0a 0a 20 20 20 20 2f  _PER_SEC;..    /
0530: 2f 20 6e 65 65 64 65 64 20 63 6f 75 6e 74 20 6d  / needed count m
0540: 69 6c 6c 69 73 65 63 6f 6e 64 73 20 6f 66 20 72  illiseconds of r
0550: 65 74 75 72 6e 20 66 72 6f 6d 20 74 68 69 73 20  eturn from this 
0560: 74 69 6d 65 6f 75 74 0a 20 20 20 20 69 6e 74 20  timeout.    int 
0570: 65 6e 64 20 3d 20 6d 69 6c 6c 69 73 65 63 6f 6e  end = millisecon
0580: 64 73 5f 73 69 6e 63 65 20 2b 20 6d 69 6c 6c 69  ds_since + milli
0590: 73 65 63 6f 6e 64 73 3b 0a 0a 20 20 20 20 2f 2f  seconds;..    //
05a0: 20 77 61 69 74 20 77 68 69 6c 65 20 75 6e 74 69   wait while unti
05b0: 6c 20 6e 65 65 64 65 64 20 74 69 6d 65 20 63 6f  l needed time co
05c0: 6d 65 73 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20  mes.    do {.   
05d0: 20 20 20 20 20 6d 69 6c 6c 69 73 65 63 6f 6e 64       millisecond
05e0: 73 5f 73 69 6e 63 65 20 3d 20 63 6c 6f 63 6b 28  s_since = clock(
05f0: 29 20 2a 20 31 30 30 30 20 2f 20 43 4c 4f 43 4b  ) * 1000 / CLOCK
0600: 53 5f 50 45 52 5f 53 45 43 3b 0a 20 20 20 20 7d  S_PER_SEC;.    }
0610: 20 77 68 69 6c 65 20 28 6d 69 6c 6c 69 73 65 63   while (millisec
0620: 6f 6e 64 73 5f 73 69 6e 63 65 20 3c 3d 20 65 6e  onds_since <= en
0630: 64 29 3b 0a 7d 0a 0a 0a 69 6e 74 20 6d 61 69 6e  d);.}...int main
0640: 28 76 6f 69 64 29 0a 7b 0a 0a 20 20 20 20 49 6e  (void).{..    In
0650: 69 74 41 75 64 69 6f 44 65 76 69 63 65 28 29 3b  itAudioDevice();
0660: 20 20 20 20 20 20 2f 2f 20 49 6e 69 74 69 61 6c        // Initial
0670: 69 7a 65 20 61 75 64 69 6f 20 64 65 76 69 63 65  ize audio device
0680: 0a 0a 20 20 20 20 53 6f 75 6e 64 20 66 78 57 61  ..    Sound fxWa
0690: 76 20 3d 20 4c 6f 61 64 53 6f 75 6e 64 28 22 4d  v = LoadSound("M
06a0: 75 73 69 63 2f 4b 69 63 6b 30 31 2e 77 61 76 22  usic/Kick01.wav"
06b0: 29 3b 0a 20 20 20 20 53 6f 75 6e 64 20 66 78 57  );.    Sound fxW
06c0: 61 76 32 20 3d 20 4c 6f 61 64 53 6f 75 6e 64 28  av2 = LoadSound(
06d0: 22 4d 75 73 69 63 2f 43 6c 61 70 30 31 2e 77 61  "Music/Clap01.wa
06e0: 76 22 29 3b 0a 0a 20 20 20 20 69 6e 74 20 62 70  v");..    int bp
06f0: 6d 3b 0a 20 20 20 20 70 72 69 6e 74 66 28 22 45  m;.    printf("E
0700: 6e 74 65 72 20 62 70 6d 3a 20 22 29 3b 0a 20 20  nter bpm: ");.  
0710: 20 20 73 63 61 6e 66 28 22 25 64 22 2c 20 26 62    scanf("%d", &b
0720: 70 6d 29 3b 0a 20 20 20 20 66 6c 6f 61 74 20 74  pm);.    float t
0730: 69 6d 65 5f 70 65 72 5f 62 65 61 74 20 3d 20 28  ime_per_beat = (
0740: 36 30 2e 30 20 2f 20 62 70 6d 29 20 2a 20 34 3b  60.0 / bpm) * 4;
0750: 0a 20 20 20 20 69 6e 74 20 64 65 6c 61 79 20 3d  .    int delay =
0760: 20 28 74 69 6d 65 5f 70 65 72 5f 62 65 61 74 20   (time_per_beat 
0770: 2a 20 31 30 30 30 29 20 2f 20 31 36 3b 0a 20 20  * 1000) / 16;.  
0780: 20 20 70 72 69 6e 74 66 28 22 25 64 5c 6e 22 2c    printf("%d\n",
0790: 20 64 65 6c 61 79 29 3b 0a 0a 20 20 20 20 77 68   delay);..    wh
07a0: 69 6c 65 28 31 29 20 7b 0a 0a 20 20 20 20 20 20  ile(1) {..      
07b0: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 20    int i;.       
07c0: 20 66 6f 72 20 28 69 20 3d 20 31 3b 20 69 20 3c   for (i = 1; i <
07d0: 3d 20 31 36 3b 20 69 2b 2b 29 20 7b 0a 20 20 20  = 16; i++) {.   
07e0: 20 20 20 20 20 20 20 20 20 69 66 20 28 28 69 20           if ((i 
07f0: 3d 3d 20 31 29 20 7c 7c 20 28 69 20 3d 3d 20 35  == 1) || (i == 5
0800: 29 20 7c 7c 20 28 69 20 3d 3d 20 39 29 20 7c 7c  ) || (i == 9) ||
0810: 20 20 28 69 20 3d 3d 20 31 33 29 29 20 7b 0a 20    (i == 13)) {. 
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 50                 P
0830: 6c 61 79 53 6f 75 6e 64 28 66 78 57 61 76 29 3b  laySound(fxWav);
0840: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20  .            }. 
0850: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 28 28             if ((
0860: 69 20 3d 3d 20 35 29 20 7c 7c 20 20 28 69 20 3d  i == 5) ||  (i =
0870: 3d 20 31 33 29 29 20 7b 0a 20 20 20 20 20 20 20  = 13)) {.       
0880: 20 20 20 20 20 20 20 20 20 50 6c 61 79 53 6f 75           PlaySou
0890: 6e 64 28 66 78 57 61 76 32 29 3b 0a 20 20 20 20  nd(fxWav2);.    
08a0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
08b0: 20 20 20 20 20 20 73 65 74 54 69 6d 65 6f 75 74        setTimeout
08c0: 28 64 65 6c 61 79 29 3b 0a 20 20 20 20 20 20 20  (delay);.       
08d0: 20 7d 0a 20 20 20 20 7d 0a 0a 0a 20 20 20 20 55   }.    }...    U
08e0: 6e 6c 6f 61 64 53 6f 75 6e 64 28 66 78 57 61 76  nloadSound(fxWav
08f0: 29 3b 20 20 20 20 20 2f 2f 20 55 6e 6c 6f 61 64  );     // Unload
0900: 20 73 6f 75 6e 64 20 64 61 74 61 0a 20 20 20 20   sound data.    
0910: 55 6e 6c 6f 61 64 53 6f 75 6e 64 28 66 78 57 61  UnloadSound(fxWa
0920: 76 32 29 3b 20 20 20 20 20 2f 2f 20 55 6e 6c 6f  v2);     // Unlo
0930: 61 64 20 73 6f 75 6e 64 20 64 61 74 61 0a 0a 20  ad sound data.. 
0940: 20 20 20 43 6c 6f 73 65 41 75 64 69 6f 44 65 76     CloseAudioDev
0950: 69 63 65 28 29 3b 20 20 20 20 20 2f 2f 20 43 6c  ice();     // Cl
0960: 6f 73 65 20 61 75 64 69 6f 20 64 65 76 69 63 65  ose audio device
0970: 0a 0a 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b  ...    return 0;
0980: 0a 7d 0a 60 60 60 0a 0a 23 23 20 45 6c 65 6d 65  .}.```..## Eleme
0990: 6e 74 61 72 79 0a 0a 45 6c 65 6d 65 6e 74 61 72  ntary..Elementar
09a0: 79 20 69 73 20 61 20 6a 61 76 61 73 63 72 69 70  y is a javascrip
09b0: 74 20 72 75 6e 74 69 6d 65 20 2d 20 3c 68 74 74  t runtime - <htt
09c0: 70 73 3a 2f 2f 67 69 74 68 75 62 2e 63 6f 6d 2f  ps://github.com/
09d0: 6e 69 63 6b 2d 74 68 6f 6d 70 73 6f 6e 2f 65 6c  nick-thompson/el
09e0: 65 6d 65 6e 74 61 72 79 3e 2e 20 0a 0a 54 68 65  ementary>. ..The
09f0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 61 20   following is a 
0a00: 62 61 73 69 63 20 69 6e 63 6f 6d 70 6c 65 74 65  basic incomplete
0a10: 20 65 78 61 6d 70 6c 65 20 74 68 61 74 20 6d 61   example that ma
0a20: 6b 65 73 20 75 73 65 20 6f 66 20 74 68 65 20 73  kes use of the s
0a30: 61 6d 70 6c 65 2e 20 4e 65 65 64 20 74 6f 20 75  ample. Need to u
0a40: 70 64 61 74 65 20 69 74 20 74 6f 20 74 68 65 20  pdate it to the 
0a50: 6c 61 74 65 73 74 20 45 6c 65 6d 65 6e 74 61 72  latest Elementar
0a60: 79 20 76 65 72 73 69 6f 6e 20 74 6f 20 73 69 6d  y version to sim
0a70: 70 6c 69 66 79 20 74 69 63 6b 20 6c 6f 67 69 63  plify tick logic
0a80: 2e 0a 0a 60 60 60 6a 73 0a 63 6f 6e 73 74 20 65  ...```js.const e
0a90: 6c 20 3d 20 72 65 71 75 69 72 65 28 27 40 6e 69  l = require('@ni
0aa0: 63 6b 2d 74 68 6f 6d 70 73 6f 6e 2f 65 6c 65 6d  ck-thompson/elem
0ab0: 65 6e 74 61 72 79 27 29 3b 0a 0a 63 6f 6e 73 74  entary');..const
0ac0: 20 6b 69 63 6b 30 32 20 3d 20 27 2e 2f 4d 75 73   kick02 = './Mus
0ad0: 69 63 2f 4b 69 63 6b 30 31 2e 77 61 76 27 3b 0a  ic/Kick01.wav';.
0ae0: 63 6f 6e 73 74 20 68 68 30 32 20 3d 20 27 2e 2f  const hh02 = './
0af0: 4d 75 73 69 63 2f 48 48 30 32 2e 77 61 76 27 3b  Music/HH02.wav';
0b00: 0a 63 6f 6e 73 74 20 63 6c 61 70 30 31 20 3d 20  .const clap01 = 
0b10: 27 2e 2f 4d 75 73 69 63 2f 43 6c 61 70 30 31 2e  './Music/Clap01.
0b20: 77 61 76 27 3b 0a 0a 6c 65 74 20 76 6f 69 63 65  wav';..let voice
0b30: 73 20 3d 20 7b 0a 20 20 27 36 30 27 3a 20 7b 67  s = {.  '60': {g
0b40: 61 69 6e 3a 20 31 2e 30 2c 20 67 61 74 65 3a 20  ain: 1.0, gate: 
0b50: 30 2e 30 2c 20 70 61 74 68 3a 20 6b 69 63 6b 30  0.0, path: kick0
0b60: 32 2c 20 6b 65 79 3a 20 27 76 31 27 7d 2c 0a 20  2, key: 'v1'},. 
0b70: 20 27 36 31 27 3a 20 7b 67 61 69 6e 3a 20 31 2e   '61': {gain: 1.
0b80: 30 2c 20 67 61 74 65 3a 20 30 2e 30 2c 20 70 61  0, gate: 0.0, pa
0b90: 74 68 3a 20 68 68 30 32 2c 20 6b 65 79 3a 20 27  th: hh02, key: '
0ba0: 76 32 27 7d 2c 0a 20 20 27 36 32 27 3a 20 7b 67  v2'},.  '62': {g
0bb0: 61 69 6e 3a 20 30 2e 36 2c 20 67 61 74 65 3a 20  ain: 0.6, gate: 
0bc0: 30 2e 30 2c 20 70 61 74 68 3a 20 63 6c 61 70 30  0.0, path: clap0
0bd0: 31 2c 20 6b 65 79 3a 20 27 76 33 27 7d 2c 0a 7d  1, key: 'v3'},.}
0be0: 3b 0a 0a 66 75 6e 63 74 69 6f 6e 20 75 70 64 61  ;..function upda
0bf0: 74 65 56 6f 69 63 65 53 74 61 74 65 28 65 29 20  teVoiceState(e) 
0c00: 7b 0a 20 20 69 66 20 28 65 20 26 26 20 65 2e 68  {.  if (e && e.h
0c10: 61 73 4f 77 6e 50 72 6f 70 65 72 74 79 28 27 74  asOwnProperty('t
0c20: 79 70 65 27 29 20 26 26 20 65 2e 74 79 70 65 20  ype') && e.type 
0c30: 3d 3d 3d 20 27 6e 6f 74 65 4f 6e 27 29 20 7b 0a  === 'noteOn') {.
0c40: 20 20 20 20 69 66 20 28 76 6f 69 63 65 73 2e 68      if (voices.h
0c50: 61 73 4f 77 6e 50 72 6f 70 65 72 74 79 28 65 2e  asOwnProperty(e.
0c60: 6e 6f 74 65 4e 75 6d 62 65 72 29 29 20 7b 0a 20  noteNumber)) {. 
0c70: 20 20 20 20 20 76 6f 69 63 65 73 5b 65 2e 6e 6f       voices[e.no
0c80: 74 65 4e 75 6d 62 65 72 5d 2e 67 61 74 65 20 3d  teNumber].gate =
0c90: 20 31 2e 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   1.0;.    }.  }.
0ca0: 0a 20 20 69 66 20 28 65 20 26 26 20 65 2e 68 61  .  if (e && e.ha
0cb0: 73 4f 77 6e 50 72 6f 70 65 72 74 79 28 27 74 79  sOwnProperty('ty
0cc0: 70 65 27 29 20 26 26 20 65 2e 74 79 70 65 20 3d  pe') && e.type =
0cd0: 3d 3d 20 27 6e 6f 74 65 4f 66 66 27 29 20 7b 0a  == 'noteOff') {.
0ce0: 20 20 20 20 69 66 20 28 76 6f 69 63 65 73 2e 68      if (voices.h
0cf0: 61 73 4f 77 6e 50 72 6f 70 65 72 74 79 28 65 2e  asOwnProperty(e.
0d00: 6e 6f 74 65 4e 75 6d 62 65 72 29 29 20 7b 0a 20  noteNumber)) {. 
0d10: 20 20 20 20 20 76 6f 69 63 65 73 5b 65 2e 6e 6f       voices[e.no
0d20: 74 65 4e 75 6d 62 65 72 5d 2e 67 61 74 65 20 3d  teNumber].gate =
0d30: 20 30 2e 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   0.0;.    }.  }.
0d40: 7d 0a 0a 66 75 6e 63 74 69 6f 6e 20 73 61 6d 70  }..function samp
0d50: 6c 65 72 56 6f 69 63 65 28 76 6f 69 63 65 29 20  lerVoice(voice) 
0d60: 7b 0a 20 20 6c 65 74 20 67 61 74 65 20 3d 20 65  {.  let gate = e
0d70: 6c 2e 63 6f 6e 73 74 28 7b 6b 65 79 3a 20 76 6f  l.const({key: vo
0d80: 69 63 65 2e 6b 65 79 2c 20 76 61 6c 75 65 3a 20  ice.key, value: 
0d90: 76 6f 69 63 65 2e 67 61 74 65 7d 29 3b 0a 20 20  voice.gate});.  
0da0: 72 65 74 75 72 6e 20 65 6c 2e 6d 75 6c 28 76 6f  return el.mul(vo
0db0: 69 63 65 2e 67 61 69 6e 2c 20 65 6c 2e 73 61 6d  ice.gain, el.sam
0dc0: 70 6c 65 28 7b 70 61 74 68 3a 20 76 6f 69 63 65  ple({path: voice
0dd0: 2e 70 61 74 68 7d 2c 20 67 61 74 65 29 29 3b 0a  .path}, gate));.
0de0: 7d 0a 0a 65 6c 65 6d 65 6e 74 61 72 79 2e 63 6f  }..elementary.co
0df0: 72 65 2e 6f 6e 28 27 6c 6f 61 64 27 2c 20 66 75  re.on('load', fu
0e00: 6e 63 74 69 6f 6e 28 29 20 7b 0a 20 20 20 20 20  nction() {.     
0e10: 20 20 20 6c 65 74 20 69 20 3d 20 30 3b 0a 20 20     let i = 0;.  
0e20: 20 20 20 20 20 20 6c 65 74 20 73 74 65 70 20 3d        let step =
0e30: 20 30 3b 0a 20 20 20 20 20 20 20 20 66 75 6e 63   0;.        func
0e40: 74 69 6f 6e 20 66 75 6e 63 74 69 6f 6e 32 28 29  tion function2()
0e50: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 73   {.            s
0e60: 74 65 70 20 3d 20 69 20 25 20 31 36 3b 0a 20 20  tep = i % 16;.  
0e70: 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 6f 6c            consol
0e80: 65 2e 6c 6f 67 28 73 74 65 70 29 0a 20 20 20 20  e.log(step).    
0e90: 20 20 20 20 20 20 20 20 69 66 20 28 69 20 25 20          if (i % 
0ea0: 34 20 3d 3d 20 30 29 20 7b 0a 20 20 20 20 20 20  4 == 0) {.      
0eb0: 20 20 20 20 20 20 20 20 75 70 64 61 74 65 56 6f          updateVo
0ec0: 69 63 65 53 74 61 74 65 28 7b 74 79 70 65 3a 20  iceState({type: 
0ed0: 27 6e 6f 74 65 4f 6e 27 2c 20 6e 6f 74 65 4e 75  'noteOn', noteNu
0ee0: 6d 62 65 72 3a 20 27 36 30 27 7d 29 3b 0a 20 20  mber: '60'});.  
0ef0: 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65            } else
0f00: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
0f10: 20 75 70 64 61 74 65 56 6f 69 63 65 53 74 61 74   updateVoiceStat
0f20: 65 28 7b 74 79 70 65 3a 20 27 6e 6f 74 65 4f 66  e({type: 'noteOf
0f30: 66 27 2c 20 6e 6f 74 65 4e 75 6d 62 65 72 3a 20  f', noteNumber: 
0f40: 27 36 30 27 7d 29 3b 0a 20 20 20 20 20 20 20 20  '60'});.        
0f50: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 20      }..         
0f60: 20 20 20 69 66 20 28 28 69 20 21 3d 3d 20 30 29     if ((i !== 0)
0f70: 20 26 26 20 28 69 20 25 20 38 20 3d 3d 20 30 29   && (i % 8 == 0)
0f80: 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) {.            
0f90: 20 20 75 70 64 61 74 65 56 6f 69 63 65 53 74 61    updateVoiceSta
0fa0: 74 65 28 7b 74 79 70 65 3a 20 27 6e 6f 74 65 4f  te({type: 'noteO
0fb0: 6e 27 2c 20 6e 6f 74 65 4e 75 6d 62 65 72 3a 20  n', noteNumber: 
0fc0: 27 36 32 27 7d 29 3b 0a 20 20 20 20 20 20 20 20  '62'});.        
0fd0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
0fe0: 20 20 20 20 20 20 20 20 20 20 20 75 70 64 61 74             updat
0ff0: 65 56 6f 69 63 65 53 74 61 74 65 28 7b 74 79 70  eVoiceState({typ
1000: 65 3a 20 27 6e 6f 74 65 4f 66 66 27 2c 20 6e 6f  e: 'noteOff', no
1010: 74 65 4e 75 6d 62 65 72 3a 20 27 36 32 27 7d 29  teNumber: '62'})
1020: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a  ;.            }.
1030: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 65 74  .            let
1040: 20 6f 75 74 20 3d 20 65 6c 2e 61 64 64 28 4f 62   out = el.add(Ob
1050: 6a 65 63 74 2e 6b 65 79 73 28 76 6f 69 63 65 73  ject.keys(voices
1060: 29 2e 6d 61 70 28 66 75 6e 63 74 69 6f 6e 28 6e  ).map(function(n
1070: 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) {.            
1080: 20 20 20 20 72 65 74 75 72 6e 20 73 61 6d 70 6c      return sampl
1090: 65 72 56 6f 69 63 65 28 76 6f 69 63 65 73 5b 6e  erVoice(voices[n
10a0: 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ]);.            
10b0: 7d 29 29 3b 0a 0a 20 20 20 20 20 20 20 20 20 20  }));..          
10c0: 20 20 6c 65 74 20 66 69 6c 74 65 72 65 64 20 3d    let filtered =
10d0: 20 65 6c 2e 6c 6f 77 70 61 73 73 28 31 38 30 30   el.lowpass(1800
10e0: 2c 20 31 2e 34 31 34 2c 20 6f 75 74 29 3b 0a 20  , 1.414, out);. 
10f0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 65 6d 65             eleme
1100: 6e 74 61 72 79 2e 63 6f 72 65 2e 72 65 6e 64 65  ntary.core.rende
1110: 72 28 66 69 6c 74 65 72 65 64 2c 20 66 69 6c 74  r(filtered, filt
1120: 65 72 65 64 29 3b 0a 20 20 20 20 20 20 20 20 20  ered);.         
1130: 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 20 20     i++;.        
1140: 7d 0a 20 20 20 20 20 20 20 20 73 65 74 49 6e 74  }.        setInt
1150: 65 72 76 61 6c 28 66 75 6e 63 74 69 6f 6e 32 2c  erval(function2,
1160: 20 36 30 30 30 30 20 2f 20 31 32 30 2e 30 20 2f   60000 / 120.0 /
1170: 20 32 29 3b 0a 7d 29 3b 0a 60 60 60 0a 0a 0a      2);.});.```...