サンプル
使用方法
htmlを開いてローカルのmp3などを選択すると再生が始まります。
Level の数値がどこでマークを出すか を示しています。
つまり静かめの曲だとこのLevel値を下げないとマークが出てきません。
対象のmp3自体のゲインにもよります。
別に200を超えても問題はないです。
不具合
- 2曲続けてプレイができない
Uncaught (in promise) TypeError: Failed to execute
を解除できてない。リロードするしかない。
清々しさがない。 - 曲全体のレベルピーク検出を自動でしてない
全体の長さをn秒として 4分のnくらいで平均のピークとBPM算出したらよさそう - audioタグを2つ用意してない のでマークが出てから太鼓を叩くまでのラグが演出できてない
- 1分くらいで演奏停止に持っていきたい。
- フーリエ変換の組み込みがまだ。 = カッ の未追加
- 現状3% 残り97% 遠い道のり
Ver0.03ソース
drum_masters.0.03.htm
<html>
<head>
<style>
.block1{background-color:#ff0000;
width:26px;
height:26px;
left:300px;
border-style:solid;
border-width:2px;
border-radius: 15px 15px 15px 15px;
border-color:#FFFFFF;
}
.block2{
width:30px;
height:30px;
left:300px;
position: absolute;
border-style:solid;
border-width:2px;
border-radius: 15px 15px 15px 15px;
border-color:#000000;
box-shadow: 4px 4px 8px -4px #333333;
-moz-box-shadow: 4px 4px 8px -4px #333333;
-webkit-box-shadow: 4px 4px 8px -4px #333333;
}
.box{
width:300px;
height:60px;
position: relative;
overflow:hidden;
}
</style>
</head>
<body>
Level <input type="text" id="int_peak" value="200" size="3"> 200 大=易---------小=難 20<br />
<input type="file" id="file_slct"><br />
<audio id="auo" ></audio><br />
<input type="hidden" id="blk_count" value="0">
<div class="box" id="box"></div>
</body>
<footer>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
<script>
var str_id = 0
var int_wait=0
//****************************
async function put_red_mark1(){
var div2 = document.createElement('div');
div2.classList.add('block2');
div2.innerHTML="<div class='block1'></div>"
div2.id="b" + str_id
box.appendChild(div2);
$("#b" + str_id).animate({"left": "-=340px"}, 2000,"linear",function(){$(this).remove();});
str_id=parseInt(blk_count.value)+1
blk_count.value=str_id
int_wait=1
await sleep(200);
int_wait=0
}
//****************************
var wm = new WeakMap();
var audioSource;
//********************************************************
//const file_slct = document.querySelector('#file_slct');
async function convertAudioFileToDataUrl(file) {
const reader = new FileReader();
const loadPromise = new Promise((resolve, reject) => {
reader.onload = (event) => {
resolve(event.target.result);
};
});
reader.readAsDataURL(file);
return loadPromise;
}
//*************************************//
function sleep(m_second) {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, m_second)
})
console.log("slpx")
}
//******************************
file_slct.addEventListener('change', async (event) => {
var audioctx = new AudioContext();
const file = file_slct.files[0];
auo.src = await convertAudioFileToDataUrl(file);
audioSource = audioctx.createMediaElementSource(auo);
auo.play()
//timer_intvl=setInterval(timer_handler, 1000 ) ;
var processor = audioctx.createScriptProcessor(256,1,1);
audioSource.connect(processor);
processor.connect(audioctx.destination);
audioSource.connect(audioctx.destination);
var int_peak=0
processor.onaudioprocess = function(e){
if (int_wait==0){
var amp = e.inputBuffer.getChannelData(0);
const reducer = (accumulator, currentValue) => accumulator + Math.abs(currentValue);
int_peak=amp.reduce(reducer) / amp.length * 800
//document.getElementById('bar').style.width = '' + (int_peak) + 'px';
if(auo.paused){
processor.disconnect();
audioSource.disconnect();
auo.src='';
}else{
if(int_peak > document.getElementById("int_peak").value){
//log出力
//console.log(int_peak)
put_red_mark1("b" + blk_count.value);
}
}
}
};
})
</script>
</footer>
</html>