首先,这是我正在研究的实时应用程序:turbo_synth
我正在使用 VueJS 制作它,但是,我相信这个问题与 Vue 无关。
问题:一切都很好,除了尝试演奏某些音符组合时,例如,尝试弹奏键 Q、W 和 2。您会注意到最后一个音符没有被播放,甚至没有显示为按下,而您可以同时播放 Q、W、E、R 和 Y。所以似乎没有限制,就像我之前想的那样?
代码:我正在使用 vue-keypress 轻松处理全局关键事件。
模板部件
<template>
<div id="app">
<h1>Basic oscillator test</h1>
<label for="waveType">Choose a wave type:</label>
<select
name="waveType"
id="waveType"
v-model="wave"
>
<option value="sine">sine</option>
<option value="square">square</option>
<option value="triangle">triangle</option>
<option value="sawtooth">sawtooth</option>
</select>
<hr>
<ul class="keyboard">
<li
v-for="note in testBoard"
:key="note.id"
:class="[note.class, getKeyByValue(testBoard, note).charAt(0), {'pressed': pressedNotes.includes(note.freq)}]"
@mousedown="playSound(note.freq, 1)"
>
<p>{{getKeyByValue(testBoard, note).replace('s', '#')}}</p>
<p>{{String.fromCharCode(note.keycode)}}</p>
</li>
</ul>
<Keypress
v-for="note in testBoard"
:key="note.id"
key-event="keydown"
:key-code="note.keycode"
@success="playSound(note.freq)"
/>
<Keypress
v-for="note in testBoard"
:key="note.id"
key-event="keyup"
:key-code="note.keycode"
@success="removeNote(note.freq)"
/>
</div>
</template>
脚本部分:
<script>
import { noteValues, testBoard } from './assets/notevalues.js';
export default {
name: 'App',
data() {
return {
noteValues,
testBoard,
selectedNote: null,
wave: 'sine',
pressedNotes: [],
}
},
components: {
Keypress: () => import('vue-keypress')
},
methods: {
getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
,
playSound(note, clicked) {
if (this.pressedNotes.includes(note)) {
return;
} else {
this.pressedNotes.push(note);
const context = new AudioContext();
const o = context.createOscillator();
const g = context.createGain();
o.connect(g);
g.connect(context.destination);
o.type = this.wave;
const frequency = note;
o.frequency.value = frequency;
o.start(0);
o.stop(context.currentTime + 1)
g.gain.exponentialRampToValueAtTime(
0.00001, context.currentTime + 2.5
);
setTimeout(() => {
context.close();
}, 1000);
if (clicked === 1) {
setTimeout(() => {
this.removeNote(note);
}, 50)
}
}
},
removeNote(note) {
const index = this.pressedNotes.indexOf(note);
if (index > -1) {
this.pressedNotes.splice(index, 1);
}
}
},
}
</script>
以下是注释列表:
export let testBoard = {
'C3': { keycode: 81, freq: 130.81, class: 'white' },
'Cs3': { keycode: 50, freq: 138.59, class: 'black' },
'D3': { keycode: 87, freq: 146.83, class: 'white' },
'Ds3': { keycode: 51, freq: 155.56, class: 'black' },
'E3': { keycode: 69, freq: 164.81, class: 'white' },
'F3': { keycode: 82, freq: 174.61, class: 'white' },
'Fs3': { keycode: 53, freq: 185.00, class: 'black' },
'G3': { keycode: 84, freq: 196.00, class: 'white' },
'Gs3': { keycode: 54, freq: 207.65, class: 'black' },
'A3': { keycode: 89, freq: 220.00, class: 'white' },
'As3': { keycode: 55, freq: 233.08, class: 'black' },
'B3': { keycode: 85, freq: 246.94, class: 'white' },
'C4': { keycode: 90, freq: 261.63, class: 'white' },
'Cs4': { keycode: 83, freq: 277.18, class: 'black' },
'D4': { keycode: 88, freq: 293.66, class: 'white' },
'Ds4': { keycode: 68, freq: 311.13, class: 'black' },
'E4': { keycode: 67, freq: 329.63, class: 'white' },
'F4': { keycode: 86, freq: 349.23, class: 'white' },
'Fs4': { keycode: 71, freq: 369.99, class: 'black' },
'G4': { keycode: 66, freq: 392.00, class: 'white' },
'Gs4': { keycode: 72, freq: 415.30, class: 'black' },
'A4': { keycode: 78, freq: 440.00, class: 'white' },
'As4': { keycode: 74, freq: 466.16, class: 'black' },
'B4': { keycode: 77, freq: 493.88, class: 'white' }
}
我也尝试过其他人用vue或其他技术制作的钢琴,总是有类似的问题。 我可能错过了一些重要的东西,谁知道呢,但我找不到我需要的信息。
谢谢一堆
你的代码没有问题,你也无能为力——这是许多键盘的硬件限制。
首先,将键盘布置为矩形网格(换句话说,1、Q、A和Z位于同一列中,即使它们通常不直接位于彼此上方(。
限制是不能同时识别形成矩形三个角的三个键。如果连续按住两个键,则第三个键不能与前两个键中的任何一个位于同一列中。如果按住列中的两个键,则第三个键不能与前两个键中的任何一个位于同一行。如果按住Q和Z,则以A开头的行上的任何键都可以正常工作,但W、E、X、C等都将被锁定。
或者,有些机器可能会在矩形的第四角给你"幽灵"按键——按住Q和Z并按 E 将注册一个E键,但同时也会注册一个 C 键,即使没有人按C。
所有这些都与键盘的电子构建方式有关,您在软件中对此无能为力。有些键盘没有此限制,但你不能指望你的用户拥有它们。