//In order to run in terminal insert the following code to activate localhost: npx parcel src/index.html
import { chordType, transpose , note } from '@tonaljs/tonal';
import { chord } from '@tonaljs/chord';
import { entries } from '@tonaljs/chord-dictionary';
import { Howler, howl } from 'howler';
const sound = new Howl({
src: ['assets/pianosprite.mp3'],
onload() {
console.log('Sound file has been loaded. Do something here!');
soundEngine.init();
},
onloaderror(e, msg) {
console.log('Error', e, msg);
}
});
const startNotes = ['C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'F', 'F#', 'Gb', 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B'];
const startNoteSelector = document.querySelector('#start-note');
const octaveSelector = document.querySelector('#octave');
const buttons = document.querySelector('.buttons');
const intervalsInChord = document.querySelector('.intervals-in-chord');
const notesInChord = document.querySelector('.notes-in-chord');
let selectedStartNote = 'C';
let selectedOctave = '1';
let selectedChord;
const app = {
init() {
this.setupStartNotes();
this.setupOctaves();
this.setupButtons();
this.setupEventListeners();
},
setupStartNotes() {
startNotes.forEach(noteName => {
let noteNameOption = this.createElement('option', noteName);
startNoteSelector.appendChild(noteNameOption);
});
},
setupOctaves() {
for (let i = 1; i <= 4; i ) {
let octaveNumber = this.createElement('option', i);
octaveSelector.appendChild(octaveNumber);
}
},
setupButtons() {
const chordNames = entries().map(entry => {
return entry.aliases[0];
});
chordNames.forEach(chordName => {
let chordButton = this.createElement('button', chordName);
buttons.appendChild(chordButton);
});
},
setupEventListeners() {
startNoteSelector.addEventListener('change', () => {
selectedStartNote = startNoteSelector.value;
});
octaveSelector.addEventListener('change', () => {
selectedOctave = octaveSelector.value;
});
buttons.addEventListener('click', (event) => {
if (event.target.classList.contains('buttons')) {
return;
}
selectedChord = event.target.innerText;
this.displayAndPlayChord(selectedChord);
});
},
displayAndPlayChord(selectedChord) {
let chordIntervals = chord(selectedChord).intervals;
intervalsInChord.innerText = chordIntervals.join(' - ');
const startNoteWithOctave = selectedStartNote selectedOctave;
let chordNotes = chordIntervals.map(val => {
return transpose(startNoteWithOctave, val);
});
notesInChord.innerText = chordNotes.join(' - ');
soundEngine.play(chordNotes);
},
createElement(elementName, content) {
let element = document.createElement(elementName);
element.innerHTML = content;
return element;
}
}
const soundEngine = {
init() {
const lengthOfNote = 2400;
let timeIndex = 0;
for (let i = 24; i <= 96; i ) {
sound['_sprite'][i] = [timeIndex, lengthOfNote];
timeIndex = lengthOfNote;
}
},
play(soundSequence) {
const buttons =
document.querySelector(".buttons");
const chordNameTable = {
"5": " perfect fifth",
"M7#5sus4": "major seven augmented fifth suspended fourth",
"7#5sus4": "dominant seven augmented fifth suspended fourth",
"sus4": "suspended fourth",
"M7sus4": "major seven suspended fourth",
"7sus4": "dominant seven suspended fourth",
"7no5": "dominant seven no fifth",
"aug": "Augmented",
"M7b6": "major seven minor sixth",
"maj7#5": "major seven augmented fifth",
"7#5": "dominant seven augmented fifth"
}
buttons.addEventListener("click", (event) => {
const sayThis = chordNameTable[event.target.textContent];
textToSpeech(sayThis, event.target.textContent);
})
function textToSpeech(message, chord) {
const speech = new SpeechSynthesisUtterance();
speech.lang = "en-US";
speech.text = message;
speech.volume = 1;
speech.rate = 1;
speech.pitch = 1;
window.speechSynthesis.speak(speech);
// When speaking has finished
speech.onend = function() {
playChord(chord);
}
}
function playChord(chord) {
// Wait a second (1000 miliseconds) before playing the chord
setTimeout(() => {
// Play the chord here
console.log("Chord to be played", chord);
}, 100000);
}
const chordMidiNumbers = soundSequence.map(noteName => {
return note(noteName).midi;
});
sound.volume(0.05);
chordMidiNumbers.forEach(noteMidiNumber => {
sound.play(noteMidiNumber.toString());
});
}
}
app.init();
app.init();
const allChordNames = entries()
chordEntries.map(entry => {
return entry.aliases[0];
})
console.log(Array.isArray (allChordNames));//In order to run in terminal insert the following code to activate localhost: npx parcel src/index.html
import { chordType, transpose , note } from '@tonaljs/tonal';
import { chord } from '@tonaljs/chord';
import { entries } from '@tonaljs/chord-dictionary';
import { Howler, howl } from 'howler';
const sound = new Howl({
src: ['assets/pianosprite.mp3'],
onload() {
console.log('Sound file has been loaded. Do something here!');
soundEngine.init();
},
onloaderror(e, msg) {
console.log('Error', e, msg);
}
});
const startNotes = ['C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'F', 'F#', 'Gb', 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B'];
const startNoteSelector = document.querySelector('#start-note');
const octaveSelector = document.querySelector('#octave');
const buttons = document.querySelector('.buttons');
const intervalsInChord = document.querySelector('.intervals-in-chord');
const notesInChord = document.querySelector('.notes-in-chord');
let selectedStartNote = 'C';
let selectedOctave = '1';
let selectedChord;
const app = {
init() {
this.setupStartNotes();
this.setupOctaves();
this.setupButtons();
this.setupEventListeners();
},
setupStartNotes() {
startNotes.forEach(noteName => {
let noteNameOption = this.createElement('option', noteName);
startNoteSelector.appendChild(noteNameOption);
});
},
setupOctaves() {
for (let i = 1; i <= 4; i ) {
let octaveNumber = this.createElement('option', i);
octaveSelector.appendChild(octaveNumber);
}
},
setupButtons() {
const chordNames = entries().map(entry => {
return entry.aliases[0];
});
chordNames.forEach(chordName => {
let chordButton = this.createElement('button', chordName);
buttons.appendChild(chordButton);
});
},
setupEventListeners() {
startNoteSelector.addEventListener('change', () => {
selectedStartNote = startNoteSelector.value;
});
octaveSelector.addEventListener('change', () => {
selectedOctave = octaveSelector.value;
});
buttons.addEventListener('click', (event) => {
if (event.target.classList.contains('buttons')) {
return;
}
selectedChord = event.target.innerText;
this.displayAndPlayChord(selectedChord);
});
},
displayAndPlayChord(selectedChord) {
let chordIntervals = chord(selectedChord).intervals;
intervalsInChord.innerText = chordIntervals.join(' - ');
const startNoteWithOctave = selectedStartNote selectedOctave;
let chordNotes = chordIntervals.map(val => {
return transpose(startNoteWithOctave, val);
});
notesInChord.innerText = chordNotes.join(' - ');
soundEngine.play(chordNotes);
},
createElement(elementName, content) {
let element = document.createElement(elementName);
element.innerHTML = content;
return element;
}
}
const soundEngine = {
init() {
const lengthOfNote = 2400;
let timeIndex = 0;
for (let i = 24; i <= 96; i ) {
sound['_sprite'][i] = [timeIndex, lengthOfNote];
timeIndex = lengthOfNote;
}
},
play(soundSequence) {
const buttons =
document.querySelector(".buttons");
const chordNameTable = {
"5": " perfect fifth",
"M7#5sus4": "major seven augmented fifth suspended fourth",
"7#5sus4": "dominant seven augmented fifth suspended fourth",
"sus4": "suspended fourth",
"M7sus4": "major seven suspended fourth",
"7sus4": "dominant seven suspended fourth",
"7no5": "dominant seven no fifth",
"aug": "Augmented",
"M7b6": "major seven minor sixth",
"maj7#5": "major seven augmented fifth",
"7#5": "dominant seven augmented fifth"
}
buttons.addEventListener("click", (event) => {
const sayThis = chordNameTable[event.target.textContent];
textToSpeech(sayThis, event.target.textContent);
})
function textToSpeech(message, chord) {
const speech = new SpeechSynthesisUtterance();
speech.lang = "en-US";
speech.text = message;
speech.volume = 1;
speech.rate = 1;
speech.pitch = 1;
window.speechSynthesis.speak(speech);
// When speaking has finished
speech.onend = function() {
playChord(chord);
}
}
function playChord(chord) {
// Wait a second (1000 miliseconds) before playing the chord
setTimeout(() => {
// Play the chord here
console.log("Chord to be played", chord);
}, 100000);
}
const chordMidiNumbers = soundSequence.map(noteName => {
return note(noteName).midi;
});
sound.volume(0.05);
chordMidiNumbers.forEach(noteMidiNumber => {
sound.play(noteMidiNumber.toString());
});
}
}
app.init();
app.init();
const allChordNames = entries()
chordEntries.map(entry => {
return entry.aliases[0];
})
console.log(Array.isArray (allChordNames));
body {
font-family: Lato, Sans-serif;
color: #fff;
background: #000000
}
.controls{
display: flex;
justify-content: center;
}
.controls select {
margin: 0 10px;
}
.chord-notes {
display: flex;
flex-direction: column;
align-items: center;
font-size: 1.5em;
}
.chord-notes p {
margin: 10px 0;
}
/*width makes the page more condensed towards the left*/
.buttons {
display: flex;
flex-wrap: wrap;
width: 60%;
}
/*min-width divides columns into 3 instead of 4, max-width creates a set size for the button*/
.buttons button{
flex-grow: 1;
min-width: 20%;
max-width: 20%;
height: 50px;
font-size: 1em;
background: #7200CC;
border: none;
color: #fff;
margin: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chord Dictionary</title>
<link rel="stylesheet" href="styles.css">
<head>
<style>
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
background-color: #A400DD;
}
</style>
</head>
</head>
<ul>
<li><a class="active" href="#home">Home</a></li>
<li><a href="#lessons">Lessons</a></li>
<li><a href="#practice">Practice</a></li>
<li><a href="#test">Test</a></li>
<li><a href="#sign up">Sign Up</a></li>
<li><a href="#login">Login</a></li>
</ul>
</head>
<body>
<div class="controls">
<label for="start-note">Start note:</label>
<select name="start note" id="start-note">
</select>
<label for="octave">Octave: </label>
<select name="Octave" id="octave">
</select>
</div>
<div class="chord-notes">
<p class="notes-in-chord">C3 - D3 - E3 - F#3 - A3</p>
<p class="intervals-in-chord">P1 - M3 - P5 - M7</p>
</div>
<div class="buttons">
</div>
<script type="module" src="mock.index.js"></script>
</body>
</html>
I have initially created a chord library that plays many different chords at the click of a button, and even implemented a function in which the code will also say the name of the chord. Now the issue I have run into has been that in order for the chord library to work setTimeout has been implemented which is not working at the moment. Ideally I would like for the chord library to first say the name of the chord and then play the chord. Unfortunately instead of the chord library running those actions, the chord library will say the name of the chord and play the chord at the same time with the voice that says the name of the chord repeating the name of the chord multiple times. Where exactly am I doing things wrong with this code?
const soundEngine = {
init() {
const lengthOfNote = 2400;
let timeIndex = 0;
for (let i = 24; i <= 96; i ) {
sound['_sprite'][i] = [timeIndex, lengthOfNote];
timeIndex = lengthOfNote;
}
},
play(soundSequence) {
const buttons =
document.querySelector(".buttons");
const chordNameTable = {
"5": " perfect fifth",
"M7#5sus4": "major seven augmented fifth suspended fourth",
"7#5sus4": "dominant seven augmented fifth suspended fourth",
"sus4": "suspended fourth",
"M7sus4": "major seven suspended fourth",
"7sus4": "dominant seven suspended fourth",
"7no5": "dominant seven no fifth",
"aug": "Augmented",
"M7b6": "major seven minor sixth",
"maj7#5": "major seven augmented fifth",
"7#5": "dominant seven augmented fifth"
}
buttons.addEventListener("click", (event) => {
const sayThis = chordNameTable[event.target.textContent];
textToSpeech(sayThis, event.target.textContent);
})
function textToSpeech(message, chord) {
const speech = new SpeechSynthesisUtterance();
speech.lang = "en-US";
speech.text = message;
speech.volume = 1;
speech.rate = 1;
speech.pitch = 1;
window.speechSynthesis.speak(speech);
// When speaking has finished
speech.onend = function() {
playChord(chord);
}
}
function playChord(chord) {
// Wait a second (1000 miliseconds) before playing the chord
setTimeout(() => {
// Play the chord here
console.log("Chord to be played", chord);
}, 100000);
}
uj5u.com熱心網友回復:
感謝您更新問題,現在問題很清楚了。
在setupEventListeners你說的話,任何時候在里面的東西一個用戶點擊<div >,要運行displayAndPlayChord:
buttons.addEventListener('click', (event) => {
if (event.target.classList.contains('buttons')) {
return;
}
selectedChord = event.target.innerText;
this.displayAndPlayChord(selectedChord);
});
在displayAndPlayChord,你正在做一些作業然后運行soundEngine.play
該play方法正在做一些事情:
- 創建函式的本地副本
textToSpeech和playChord - 尋找
<div >并說當他們被點擊時他們會運行textToSpeech - 并且,立即彈奏和弦
soundSequence(因為它在其他函式宣告之后。函式僅被創建,此時未運行)
當textToSpeech運行時,它會說出和弦的名稱,然后一旦完成運行playChord。
playChord 此時等待一秒鐘,然后什么也不做。
這里的問題是,你現在有兩個點擊處理程式.buttons,所以當你點擊一個按鈕,displayAndPlayChord和textToSpeech兩個運行,這就是為什么他們會在同一時間發生。
更糟糕的是,現在您擁有三個點擊處理程式button!!
所以要修復,您想洗掉addEventListenerfrom play,這樣它就不會每次都添加更多的點擊處理程式,而是直接運行textToSpeech。
并且您想將播放和弦的代碼移動到 setTimeout 中,playChord以便它不會立即運行。
uj5u.com熱心網友回復:
更新:我已經能夠解決這個問題,暫停在代碼中,重復從代碼中消失了我從底部洗掉了 app.init,因為它在那里兩次,然后將事件添加到 soundEngine.play 中, displayAndPlayChord 和 this.displayAndPlayChord。
現在進入下一部分,我將嘗試創建一個下拉選單,根據從下拉選單中選擇的次數,可以在其中播放 1-5 次和弦。對此有何想法?
//In order to run in terminal insert the following code to activate localhost: npx parcel src/mock.index.html
import { chordType, transpose, note } from '@tonaljs/tonal';
import { chord } from '@tonaljs/chord';
import { entries } from '@tonaljs/chord-dictionary';
import { Howler, howl } from 'howler';
const sound = new Howl({
src: ['assets/pianosprite.mp3'],
onload() {
console.log('Sound file has been loaded. Do something here!');
soundEngine.init();
},
onloaderror(e, msg) {
console.log('Error', e, msg);
}
});
const startNotes = ['C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'F', 'F#', 'Gb', 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B'];
const startNoteSelector = document.querySelector('#start-note');
const octaveSelector = document.querySelector('#octave');
const buttons = document.querySelector('.buttons');
const intervalsInChord = document.querySelector('.intervals-in-chord');
const notesInChord = document.querySelector('.notes-in-chord');
let selectedStartNote = 'C';
let selectedOctave = '1';
let selectedChord;
const app = {
init() {
this.setupStartNotes();
this.setupOctaves();
this.setupButtons();
this.setupEventListeners();
},
setupStartNotes() {
startNotes.forEach(noteName => {
let noteNameOption = this.createElement('option', noteName);
startNoteSelector.appendChild(noteNameOption);
});
},
setupOctaves() {
for (let i = 1; i <= 4; i ) {
let octaveNumber = this.createElement('option', i);
octaveSelector.appendChild(octaveNumber);
}
},
setupButtons() {
const chordNames = entries().map(entry => {
return entry.aliases[0];
});
chordNames.forEach(chordName => {
let chordButton = this.createElement('button', chordName);
buttons.appendChild(chordButton);
});
},
setupEventListeners() {
startNoteSelector.addEventListener('change', () => {
selectedStartNote = startNoteSelector.value;
});
octaveSelector.addEventListener('change', () => {
selectedOctave = octaveSelector.value;
});
buttons.addEventListener('click', (event) => {
if (event.target.classList.contains('buttons')) {
return;
}
selectedChord = event.target.innerText;
this.displayAndPlayChord(selectedChord, event);
});
},
displayAndPlayChord(selectedChord, event) {
let chordIntervals = chord(selectedChord).intervals;
intervalsInChord.innerText = chordIntervals.join(' - ');
const startNoteWithOctave = selectedStartNote selectedOctave;
let chordNotes = chordIntervals.map(val => {
return transpose(startNoteWithOctave, val);
});
notesInChord.innerText = chordNotes.join(' - ');
soundEngine.play(chordNotes, event);
},
createElement(elementName, content) {
let element = document.createElement(elementName);
element.innerHTML = content;
return element;
}
}
const soundEngine = {
init() {
const lengthOfNote = 2400;
let timeIndex = 0;
for (let i = 24; i <= 96; i ) {
sound['_sprite'][i] = [timeIndex, lengthOfNote];
timeIndex = lengthOfNote;
}
},
play(soundSequence, event) {
const buttons =
document.querySelector(".buttons");
const chordNameTable = {
"5": " perfect fifth",
"M7#5sus4": "major seven augmented fifth suspended fourth",
"7#5sus4": "dominant seven augmented fifth suspended fourth",
"sus4": "suspended fourth",
"M7sus4": "major seven suspended fourth",
"7sus4": "dominant seven suspended fourth",
"7no5": "dominant seven no fifth",
"aug": "Augmented",
"M7b6": "major seven minor sixth",
"maj7#5": "major seven augmented fifth",
"7#5": "dominant seven augmented fifth",
"7b13": "dominant seven minor thirteenth"
}
buttons.addEventListener("click", (event) => {
})
function textToSpeech(message, chord) {
const speech = new SpeechSynthesisUtterance();
speech.lang = "en-US";
speech.text = message;
speech.volume = 1;
speech.rate = 1;
speech.pitch = 1;
window.speechSynthesis.speak(speech);
// When speaking has finished
speech.onend = function() {
playChord(chord);
}
}
function playChord(chord) {
// Wait a second (1000 miliseconds) before playing the chord
setTimeout(() => {
const chordMidiNumbers = soundSequence.map(noteName => {
return note(noteName).midi;
});
sound.volume(0.05);
chordMidiNumbers.forEach(noteMidiNumber => {
sound.play(noteMidiNumber.toString());
});
console.log("Chord to be played", chord);
}, 500);
}
const sayThis = chordNameTable[event.target.textContent];
textToSpeech(sayThis, event.target.textContent);
}
}
app.init();
const allChordNames = entries()
chordEntries.map(entry => {
return entry.aliases[0];
})
console.log(Array.isArray (allChordNames));
body {
font-family: Lato, Sans-serif;
color: #fff;
background: #000000
}
.controls{
display: flex;
justify-content: center;
}
.controls select {
margin: 0 10px;
}
.chord-notes {
display: flex;
flex-direction: column;
align-items: center;
font-size: 1.5em;
}
.chord-notes p {
margin: 10px 0;
}
/*width makes the page more condensed towards the left*/
.buttons {
display: flex;
flex-wrap: wrap;
width: 60%;
}
/*min-width divides columns into 3 instead of 4, max-width creates a set size for the button*/
.buttons button{
flex-grow: 1;
min-width: 20%;
max-width: 20%;
height: 50px;
font-size: 1em;
background: #7200CC;
border: none;
color: #fff;
margin: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chord Dictionary</title>
<link rel="stylesheet" href="styles.css">
<head>
<style>
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
background-color: #A400DD;
}
</style>
</head>
</head>
<ul>
<li><a class="active" href="#home">Home</a></li>
<li><a href="#lessons">Lessons</a></li>
<li><a href="#practice">Practice</a></li>
<li><a href="#test">Test</a></li>
<li><a href="#sign up">Sign Up</a></li>
<li><a href="#login">Login</a></li>
</ul>
</head>
<body>
<div class="controls">
<label for="start-note">Start note:</label>
<select name="start note" id="start-note">
</select>
<label for="octave">Octave: </label>
<select name="Octave" id="octave">
</select>
</div>
<div class="chord-notes">
<p class="notes-in-chord">C3 - D3 - E3 - F#3 - A3</p>
<p class="intervals-in-chord">P1 - M3 - P5 - M7</p>
</div>
<div class="buttons">
</div>
<script type="module" src="mock.index.js"></script>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/388352.html
標籤:javascript user-interface settimeout howler.js
上一篇:如何修復自定義輪播的尺寸
下一篇:顫振異步等待未按預期作業
