ホーム > カテゴリ > HTML5・JavaScript >

MP3/OGG/AAC/FLACファイルをWaveファイルに変換する [WAVE.js]

WAVE.jsを使用してMP3/OGG/AAC/FLAC/WAVなどの音声ファイルを「Wave形式に変換」します。WAVE.jsはオープンソースなのでどなたでもご利用可能です。

WAVE.js

https://github.com/TakeshiOkamoto/WAVE.js

DEMO (Japanese)

https://www.petitmonte.com/labo/convert-wave/

DEMO Source (Japanese)

convert_wave.zip

DEMOではWAVE.wasm.js(v1.00)を使用しています。次章の「ソースコード (WAVE.js用)」で上手く変換が出来ない場合はこちらをご使用ください。

※ローカルでは実行できません。サーバーにアップして下さい。
※GitHubにあるWAVE.wasm.jsは「v1.02」なのでご注意ください。

ソースコード (WAVE.js用)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src ="WAVE.js"></script>
<script>
var audioCtx;
var firstFlag = true;

function onDragOver(event){ 
  event.preventDefault(); 
} 
  
function onDrop(event){
  onAddFile(event);
  event.preventDefault(); 
}  

function onAddFile(event) {
  var files;
  var reader = new FileReader();
  
  if(event.target.files){
    files = event.target.files;
  }else{ 
    files = event.dataTransfer.files;   
  }    

  reader.onload = function (event) {

    if(firstFlag){
      audioCtx =  new AudioContext(); 
      firstFlag = false;     
    }    
    
    var bits = parseInt(document.getElementById("lst_bits").value,10);

      // Acquire raw data
      audioCtx.decodeAudioData(reader.result).then(function(source) {
      
        console.log(source);
        
        var data={},val;
        data.L=[],data.R=[];        
        
        // L    
        var tmpL = source.getChannelData(0);
        if(bits == 8){
          for(var i=0; i<tmpL.length;i++){
            if(tmpL[i] >= 0){
              val = tmpL[i] * 127;                      
            }else{
              val = tmpL[i] * 128;
            }        
            data.L[i] = WAV_SetUint8(val);
          }
        }else if(bits == 16){
          for(var i=0; i<tmpL.length;i++){
            if(tmpL[i] >= 0){
              val = tmpL[i] * 32767;                      
            }else{
              val = tmpL[i] * 32768;
            }        
            data.L[i] = WAV_SetUint16(val);
          }
        }else if(bits == 24){
          for(var i=0; i<tmpL.length;i++){
            if(tmpL[i] >= 0){
              val = tmpL[i] * 8388607;                      
            }else{
              val = tmpL[i] * 8388608;
            }        
            data.L[i] = WAV_SetUint24(val);
          }        
        }else if(bits == 32){                
          for(var i=0; i<tmpL.length;i++){
            if(tmpL[i] >= 0){
              val = tmpL[i] * 2147483647;                      
            }else{
              val = tmpL[i] * 2147483648;
            }        
            data.L[i] = WAV_SetUint32(val);
          }        
        }

        // R
        if(source.numberOfChannels == 2){
          var tmpR = source.getChannelData(1);        
          if(bits == 8){
            for(var i=0; i<tmpR.length;i++){
              if(tmpR[i] >= 0){
                val = tmpR[i] * 127;                      
              }else{
                val = tmpR[i] * 128;
              }        
              data.R[i] = WAV_SetUint8(val);
            }
          }else if(bits == 16){
            for(var i=0; i<tmpR.length;i++){
              if(tmpR[i] >= 0){
                val = tmpR[i] * 32767;                      
              }else{
                val = tmpR[i] * 32768;
              }        
              data.R[i] = WAV_SetUint16(val);
            }
          }else if(bits == 24){
            for(var i=0; i<tmpR.length;i++){
              if(tmpR[i] >= 0){
                val = tmpR[i] * 8388607;                      
              }else{
                val = tmpR[i] * 8388608;
              }        
              data.R[i] = WAV_SetUint24(val);
            }        
          }else if(bits == 32){                
            for(var i=0; i<tmpR.length;i++){
              if(tmpR[i] >= 0){
                val = tmpR[i] * 2147483647;                      
              }else{
                val = tmpR[i] * 2147483648;
              }        
              data.R[i] = WAV_SetUint32(val);
            }        
          }    
        }           
        
        // フォーマット      
        var WaveFomat ={};
        
        WaveFomat.wFormatTag = 1;    
        WaveFomat.wBitsPerSample = bits;  // 8/16/24/32bit optional     
        WaveFomat.nSamplesPerSec = source.sampleRate;
        
        WaveFomat.nChannels = source.numberOfChannels;
        
        WaveFomat.nBlockAlign = WaveFomat.wBitsPerSample * WaveFomat.nChannels / 8;
        WaveFomat.nAvgBytesPerSec = WaveFomat.nSamplesPerSec * WaveFomat.nBlockAlign; 
        
        var F = new TFileStream();  
              
        // RIFFヘッダ     
        F.WriteString("RIFF");
         
        // ファイルの全体サイズ
        // ※波形データのサイズ + 36byteのヘッダ情報
        F.WriteDWord((data.L.length + data.R.length) * (WaveFomat.wBitsPerSample/ 8) + 36);

        // RIFFの種類(WAVE)
        F.WriteString("WAVE");
       
          // fmtチャンク
          F.WriteString("fmt ");
          
          // チャンクのバイト数
          F.WriteDWord(16);     
                        
          // 種類(1:リニアPCM)
          F.WriteWord(WaveFomat.wFormatTag);
          // チャンネル数(1:モノラル 2:ステレオ)   
          F.WriteWord(WaveFomat.nChannels);
          // サンプリングレート(44100=44.1kHzなど)
          F.WriteDWord(WaveFomat.nSamplesPerSec);
          // 平均データ転送レート(byte/sec) 
          // ※PCMの場合はnSamplesPerSec * nBlockAlign        
          F.WriteDWord(WaveFomat.nAvgBytesPerSec);
          // ブロックサイズ 
          // ※PCMの場合はwBitsPerSample * nChannels / 8         
          F.WriteWord(WaveFomat.nBlockAlign);
          // サンプルあたりのビット数 (bit/sample) 
          // ※PCMの場合は8bit=8, 16bit =16           
          F.WriteWord(WaveFomat.wBitsPerSample);

          // dataチャンク
          F.WriteString("data");
          
          // 波形データのバイト数    
          F.WriteDWord((data.L.length + data.R.length) * (WaveFomat.wBitsPerSample/ 8));

          // 波形データ
          if(WaveFomat.wBitsPerSample == 8){
            if(data.R.length == 0){
              for (var i=0;i< data.L.length; i++){
                F.WriteByte(data.L[i]);      
              }     
            }else{
              for (var i=0;i< data.L.length; i++){
                F.WriteByte(data.L[i]);      
                F.WriteByte(data.R[i]);      
              }     
            }        
          }else if(WaveFomat.wBitsPerSample == 16){
            if(data.R.length == 0){
              for (var i=0;i< data.L.length; i++){
                F.WriteWord(data.L[i]);      
              }              
            }else{        
              for (var i=0;i< data.L.length; i++){
                F.WriteWord(data.L[i]);      
                F.WriteWord(data.R[i]);      
              }     
            }  
          }else if(WaveFomat.wBitsPerSample == 24){
            if(data.R.length == 0){
              for (var i=0;i< data.L.length; i++){
                F.WriteByte((data.L[i] & 0x0000FF) );  
                F.WriteByte((data.L[i] & 0x00FF00) >> 8);  
                F.WriteByte((data.L[i] & 0xFF0000) >>16);      
              }              
            }else{        
              for (var i=0;i< data.L.length; i++){
                F.WriteByte((data.L[i] & 0x0000FF) );  
                F.WriteByte((data.L[i] & 0x00FF00) >> 8);  
                F.WriteByte((data.L[i] & 0xFF0000) >>16);  
                
                F.WriteByte((data.R[i] & 0x0000FF) );  
                F.WriteByte((data.R[i] & 0x00FF00) >> 8);  
                F.WriteByte((data.R[i] & 0xFF0000) >>16); 
              }     
            }            
          }else if(WaveFomat.wBitsPerSample == 32){
            if(data.R.length == 0){
              for (var i=0;i< data.L.length; i++){
                F.WriteDWord(data.L[i]);      
              }            
            }else{                
              for (var i=0;i< data.L.length; i++){
                F.WriteDWord(data.L[i]);      
                F.WriteDWord(data.R[i]);      
              }  
            }
          }
      
          F.SaveToFile("test.wav","audio/wav");          
        
      }).catch(function(e){
        alert("It is a format not supported.\n"+e);
      });     
  };
  
  if (files[0]){    
    reader.readAsArrayBuffer(files[0]); 
    document.getElementById("inputfile").value = "";
  }
}      
</script>

</head>
<body ondrop="onDrop(event);" ondragover="onDragOver(event);">  
<h1>From "MP3/OGG/AAC/FLAC etc" to "WAV"</h1>
<p></p>
  <table>
   <tr><th>Audio File</th><td>&nbsp;<input type="file" id="inputfile" onchange="onAddFile(event);"></td></tr>
  </table>    
  <p></p> 
  <table>   
  <tr><th>Bit</th>
     <td><select id="lst_bits">
               <option value="8">unsigned 8-bit [PCM]</option>
               <option value="16" selected="selected">Signed 16-bit [PCM]</option>
               <option value="24">Signed 24-bit [PCM]</option>
               <option value="32">Signed 32-bit [PCM]</option>
             </select></td></tr>   
  </table>   
</body>
</html> 





関連記事



公開日:2019年03月05日 最終更新日:2019年11月25日
記事NO:02741