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)
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> <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