0
1

More than 3 years have passed since last update.

1htmlで手持ちのmp3を太鼓の達人化(疑似自動作譜)

Last updated at Posted at 2021-08-30

サンプル

drum_masters.0.0301.htm

使用方法

htmlを開いてローカルのmp3などを選択すると再生が始まります。
Level の数値がどこでマークを出すか を示しています。
つまり静かめの曲だとこのLevel値を下げないとマークが出てきません。
対象のmp3自体のゲインにもよります。
別に200を超えても問題はないです。
無題の図形描画 (4).png

無題の図形描画 (3).png

不具合

  • 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>
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1