FJFehr commited on
Commit
11b77dd
·
1 Parent(s): 9c0f1ff

Different colours and polyphony

Browse files
Files changed (3) hide show
  1. keyboard.html +1 -1
  2. static/keyboard.js +13 -2
  3. static/styles.css +24 -0
keyboard.html CHANGED
@@ -10,7 +10,7 @@
10
  <!-- Welcome Header -->
11
  <div class="welcome-header">
12
  <h1 class="neon-text">🎹 VIRTUAL MIDI KEYBOARD</h1>
13
- <p class="subtitle">Play, record, and export your musical ideas Two octaves Multiple instruments • Real-time MIDI monitoring</p>
14
  </div>
15
 
16
  <div id="mainContainer">
 
10
  <!-- Welcome Header -->
11
  <div class="welcome-header">
12
  <h1 class="neon-text">🎹 VIRTUAL MIDI KEYBOARD</h1>
13
+ <p class="subtitle">Play chords & melodies Full polyphony (24 voices)Record & export • Real-time MIDI monitoring</p>
14
  </div>
15
 
16
  <div id="mainContainer">
static/keyboard.js CHANGED
@@ -85,32 +85,38 @@ const pressedKeys = new Set();
85
 
86
  const instruments = {
87
  synth: () => new Tone.PolySynth(Tone.Synth, {
 
88
  oscillator: { type: 'sine' },
89
  envelope: { attack: 0.005, decay: 0.1, sustain: 0.3, release: 1 }
90
  }).toDestination(),
91
 
92
  piano: () => new Tone.PolySynth(Tone.Synth, {
 
93
  oscillator: { type: 'triangle' },
94
  envelope: { attack: 0.001, decay: 0.2, sustain: 0.1, release: 2 }
95
  }).toDestination(),
96
 
97
  organ: () => new Tone.PolySynth(Tone.Synth, {
 
98
  oscillator: { type: 'sine4' },
99
  envelope: { attack: 0.001, decay: 0, sustain: 1, release: 0.1 }
100
  }).toDestination(),
101
 
102
  bass: () => new Tone.PolySynth(Tone.Synth, {
 
103
  oscillator: { type: 'sawtooth' },
104
  envelope: { attack: 0.01, decay: 0.1, sustain: 0.4, release: 1.5 },
105
  filter: { Q: 2, type: 'lowpass', rolloff: -12 }
106
  }).toDestination(),
107
 
108
  pluck: () => new Tone.PolySynth(Tone.Synth, {
 
109
  oscillator: { type: 'triangle' },
110
  envelope: { attack: 0.001, decay: 0.3, sustain: 0, release: 0.3 }
111
  }).toDestination(),
112
 
113
  fm: () => new Tone.PolySynth(Tone.FMSynth, {
 
114
  harmonicity: 3,
115
  modulationIndex: 10,
116
  envelope: { attack: 0.01, decay: 0.2, sustain: 0.2, release: 1 }
@@ -140,7 +146,7 @@ function buildKeyboard() {
140
  keyEl.dataset.midi = midiNote;
141
 
142
  const shortcut = keyShortcuts[midiNote] || '';
143
- const shortcutHtml = shortcut ? `<div style="font-size:10px;opacity:0.5;">${shortcut}</div>` : '';
144
  keyEl.innerHTML = `<div style="padding-bottom:6px;font-size:11px">${shortcutHtml}${k.name}${octaveNum}</div>`;
145
 
146
  keyboardEl.appendChild(keyEl);
@@ -421,7 +427,12 @@ instrumentSelect.addEventListener('change', () => {
421
  });
422
 
423
  keyboardToggle.addEventListener('change', () => {
424
- if (!keyboardToggle.checked) {
 
 
 
 
 
425
  // Release all currently pressed keyboard keys
426
  pressedKeys.forEach(key => {
427
  const midiNote = keyMap[key];
 
85
 
86
  const instruments = {
87
  synth: () => new Tone.PolySynth(Tone.Synth, {
88
+ maxPolyphony: 24,
89
  oscillator: { type: 'sine' },
90
  envelope: { attack: 0.005, decay: 0.1, sustain: 0.3, release: 1 }
91
  }).toDestination(),
92
 
93
  piano: () => new Tone.PolySynth(Tone.Synth, {
94
+ maxPolyphony: 24,
95
  oscillator: { type: 'triangle' },
96
  envelope: { attack: 0.001, decay: 0.2, sustain: 0.1, release: 2 }
97
  }).toDestination(),
98
 
99
  organ: () => new Tone.PolySynth(Tone.Synth, {
100
+ maxPolyphony: 24,
101
  oscillator: { type: 'sine4' },
102
  envelope: { attack: 0.001, decay: 0, sustain: 1, release: 0.1 }
103
  }).toDestination(),
104
 
105
  bass: () => new Tone.PolySynth(Tone.Synth, {
106
+ maxPolyphony: 24,
107
  oscillator: { type: 'sawtooth' },
108
  envelope: { attack: 0.01, decay: 0.1, sustain: 0.4, release: 1.5 },
109
  filter: { Q: 2, type: 'lowpass', rolloff: -12 }
110
  }).toDestination(),
111
 
112
  pluck: () => new Tone.PolySynth(Tone.Synth, {
113
+ maxPolyphony: 24,
114
  oscillator: { type: 'triangle' },
115
  envelope: { attack: 0.001, decay: 0.3, sustain: 0, release: 0.3 }
116
  }).toDestination(),
117
 
118
  fm: () => new Tone.PolySynth(Tone.FMSynth, {
119
+ maxPolyphony: 24,
120
  harmonicity: 3,
121
  modulationIndex: 10,
122
  envelope: { attack: 0.01, decay: 0.2, sustain: 0.2, release: 1 }
 
146
  keyEl.dataset.midi = midiNote;
147
 
148
  const shortcut = keyShortcuts[midiNote] || '';
149
+ const shortcutHtml = shortcut ? `<div class="shortcut-hint">${shortcut}</div>` : '';
150
  keyEl.innerHTML = `<div style="padding-bottom:6px;font-size:11px">${shortcutHtml}${k.name}${octaveNum}</div>`;
151
 
152
  keyboardEl.appendChild(keyEl);
 
427
  });
428
 
429
  keyboardToggle.addEventListener('change', () => {
430
+ if (keyboardToggle.checked) {
431
+ // Show keyboard shortcuts
432
+ keyboardEl.classList.add('shortcuts-visible');
433
+ } else {
434
+ // Hide keyboard shortcuts
435
+ keyboardEl.classList.remove('shortcuts-visible');
436
  // Release all currently pressed keyboard keys
437
  pressedKeys.forEach(key => {
438
  const midiNote = keyMap[key];
static/styles.css CHANGED
@@ -91,6 +91,30 @@ body {
91
  box-shadow:
92
  0 4px 8px rgba(0, 0, 0, 0.3),
93
  inset 0 -2px 5px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
 
96
  .key:hover {
 
91
  box-shadow:
92
  0 4px 8px rgba(0, 0, 0, 0.3),
93
  inset 0 -2px 5px rgba(0, 0, 0, 0.1);
94
+ color: #2a0050;
95
+ font-weight: bold;
96
+ }
97
+
98
+ .key .shortcut-hint {
99
+ font-size: 10px;
100
+ opacity: 0;
101
+ color: #5a00cc;
102
+ font-weight: bold;
103
+ text-shadow: 0 0 2px rgba(90, 0, 204, 0.3);
104
+ transition: opacity 0.2s ease;
105
+ }
106
+
107
+ .key.black {
108
+ color: #00ffff;
109
+ }
110
+
111
+ .key.black .shortcut-hint {
112
+ color: #00ffff;
113
+ text-shadow: 0 0 3px rgba(0, 255, 255, 0.5);
114
+ }
115
+
116
+ .shortcuts-visible .key .shortcut-hint {
117
+ opacity: 1;
118
  }
119
 
120
  .key:hover {