簡易自動演奏Webアプリの開発の忘備録です
<!DOCTYPE html>
<html lang="ja">
<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>Web簡易ピアノ</title>
<style>
.piano {
width: 600px;
height:300px;
margin-top:20px;
background-color:#FFF;
padding-top:20px;
}
.piano .music {
width:400px;
height:100px;
background-color: #F799FF;
padding-top:30px;
margin-top:20px;
margin:auto;
}
.music #display {
width:95%;
text-align:center;
font-size:40px;
color:#0031FF;
}
.keyboard {
width:490px;
height:80px;
background-color:#FFF;
margin:20px auto;
display:flex;
}
.keyboard .key {
width:calc(100% / 6 - 10px);
height:40px;
padding-top:10px;
margin-left:5px;
margin-right:5px;
border-radius:2px #00F;
background-color:#FAA;
text-align: center;
font-size:18px;
}
.button1 {
width:300px;
height:50px;
background-color:#FFF;
margin:10px auto;
display:flex;
}
.button1 .but1 {
width:calc(100% - 20px);
height:35px;
padding-top:8px;
padding-left:8px;
margin-left:5px;
margin-right:5px;
border-radius:2px #000;
background-color:#0AA;
color:#80F;
text-align: center;
font-size:15px;
}
</style>
</head>
<body>
<!-- 簡易ピアノ -->
<div class="piano">
<!-- 音名表示 -->
<div class="music">
<h1 id="display"></h1>
</div>
<!-- キーボード表示 -->
<div class="keyboard">
<div id="C4" class="key">ド</div>
<div id="D4" class="key">レ</div>
<div id="E4" class="key">ミ</div>
<div id="F4" class="key">ファ</div>
<div id="G4" class="key">ソ</div>
<div id="A4" class="key">ラ</div>
<div id="B4" class="key">シ</div>
</div>
<div class="button1">
<input type="button" id="autoplay" name="autoplay" class="but1" value="自動演奏">
<input type="button" id="autostop" name="autostop" class="but1" value="演奏中止">
</div>
</div>
<script>
// AudioContext オブジェクトを新しく作成
var audioCtx;
// ド(C4)~ド(B5)までのIDからオブジェクトを取得する
const C4 = document.getElementById('C4');
const D4 = document.getElementById('D4');
const E4 = document.getElementById('E4');
const F4 = document.getElementById('F4');
const G4 = document.getElementById('G4');
const A4 = document.getElementById('A4');
const B4 = document.getElementById('B4');
// 自動演奏ボタンの定義
const autoplay = document.getElementById('autoplay');
// 演奏中止ボタンのオブジェクトを取得する
const autostop = document.getElementById('autostop');
autostop.style.display = 'none';
// 音階を格納する配列を定義する
const sound_array = ['ド','レ','ミ','ファ','ソ','ラ','シ'];
// 周波数を格納する配列を定義する
const hz_array = [261,293,329,349,392,440,493,1];
// 音階表示エリアのオブジェクトを定義する
const display = document.getElementById('display');
// タイマー変数の定義
let timer;
// 作動時間の制御
let work_time = 0;
// 音を鳴らす時間の設定
let playing_seconds = 1500;
// 音階を表示する時間
let display_seconds = 1000;
// きらきら星の音階
const kirakira = [
'0/500',
'7/500',
'0/500',
'7/500',
'4/500',
'7/500',
'4/500',
'7/500',
'5/500',
'7/500',
'5/500',
'7/500',
'4/2000',
'3/500',
'7/500',
'3/500',
'7/500',
'2/500',
'7/500',
'2/500',
'7/500',
'1/500',
'7/500',
'1/500',
'7/500',
'0/2000',
'4/500',
'7/500',
'4/500',
'7/500',
'3/500',
'7/500',
'3/500',
'7/500',
'2/500',
'7/500',
'2/500',
'7/500',
'1/2000',
'4/500',
'7/500',
'4/500',
'7/500',
'3/500',
'7/500',
'3/500',
'7/500',
'2/500',
'7/500',
'2/500',
'7/500',
'1/2000',
'0/500',
'7/500',
'0/500',
'7/500',
'4/500',
'7/500',
'4/500',
'7/500',
'5/500',
'7/500',
'5/500',
'7/500',
'4/2000',
'3/500',
'7/500',
'3/500',
'7/500',
'2/500',
'7/500',
'2/500',
'7/500',
'1/500',
'7/500',
'1/500',
'7/500',
'1/4000'
];
// チューリップの音階
const tyuri = [
'0/500',
'1/500',
'2/1000',
'0/500',
'1/500',
'2/1000',
'4/500',
'2/500',
'1/500',
'0/500',
'1/500',
'2/500',
'1/1000',
'0/500',
'1/500',
'2/1000',
'0/500',
'1/500',
'2/1000',
'4/500',
'2/500',
'1/500',
'0/500',
'1/500',
'2/500',
'0/1000',
'4/250',
'7/250',
'4/250',
'7/250',
'2/250',
'7/250',
'4/250',
'7/250',
'5/250',
'7/250',
'5/250',
'7/250',
'4/1000',
'2/250',
'7/250',
'2/250',
'7/250',
'1/250',
'7/250',
'1/250',
'7/250',
'0/4000'
];
//作業用配列
var array3;
function play(music1,hz,test_time){
audioCtx = new AudioContext();
// 正弦波の音を作成
let osc = audioCtx.createOscillator();
//ヘルツ(周波数)指定
osc.frequency.value = parseInt(hz);
//音の出力先
var audioDestination = audioCtx.destination;
//出力先のスピーカーに接続
osc.connect(audioDestination);
timer = setInterval(osc.start(),250);
if (music1 !== null){
display.textContent = music1;
setTimeout(function() {
display.textContent = "";
},display_seconds);
}
sleep(test_time);
clearInterval(timer);
osc.stop();
}
function sleep(time1) {
const d1 = new Date();
while (true){
const d2 = new Date();
if (d2 - d1 >= time1){
break;
}
}
}
// ピアノの音階をクリック
C4.addEventListener('click',function() {
const d = sound_array[0];
const h = hz_array[0];
play(d,h,playing_seconds);
},false);
D4.addEventListener('click',function() {
const d = sound_array[1];
const h = hz_array[1];
play(d,h,playing_seconds);
},false);
E4.addEventListener('click',function() {
const d = sound_array[2];
const h = hz_array[2];
play(d,h,playing_seconds);
},false);
F4.addEventListener('click',function() {
const d = sound_array[3];
const h = hz_array[3];
play(d,h,playing_seconds);
},false);
G4.addEventListener('click',function() {
const d = sound_array[4];
const h = hz_array[4];
play(d,h,playing_seconds);
},false);
A4.addEventListener('click',function() {
const d = sound_array[5];
const h = hz_array[5];
play(d,h,playing_seconds);
},false);
B4.addEventListener('click',function() {
const d = sound_array[6];
const h = hz_array[6];
play(d,h,playing_seconds);
},false);
autoplay.addEventListener('click',function() {
C4.style.visibility = 'hidden';
D4.style.visibility = 'hidden';
E4.style.visibility = 'hidden';
F4.style.visibility = 'hidden';
G4.style.visibility = 'hidden';
A4.style.visibility = 'hidden';
B4.style.visibility = 'hidden';
display.textContent = "自動演奏";
autoplay1();
},false);
function autoplay1() {
const random = Math.floor(Math.random() * 2);
if (random == 0){
array3 = kirakira;
} else {
array3 = tyuri;
}
for(let j=0;j<array3.length;j++){
const array4 = array3[j].split('/');
const number = array4[0];
const playsec = array4[1];
play(sound_array[number],hz_array[number],playsec);
}
C4.style.visibility = 'visible';
D4.style.visibility = 'visible';
E4.style.visibility = 'visible';
F4.style.visibility = 'visible';
G4.style.visibility = 'visible';
A4.style.visibility = 'visible';
B4.style.visibility = 'visible';
}
function autostop1() {
AudioContext().createOscillator().stop();
clearInterval(timer);
}
</script>
</body>
</html>
現在処理が重く、ブラウザの待機が大量に発生しています。