const MSADPCM = require("./msadpcm"); const Popnchart = require("./popnchart"); const Twodx = require("./twodx"); const child_process = require("child_process"); const fs = require("fs"); const path = require("path"); const SampleRate = require("node-libsamplerate"); const wav = require("wav"); if (process.argv.length < 3) { console.log("Usage: node popntowav ifs_file"); process.exit(); } let arg1 = process.argv[2]; let outputFilename = process.argv[3]; child_process.execSync(`ifstools ${arg1}`); const ifsname = path.basename(arg1).slice(0, -4); let twodxPath = `${ifsname}_ifs/${ifsname}.2dx`; let chartPath = `${ifsname}_ifs/${ifsname}_op.bin`; if (!fs.existsSync(chartPath)) { chartPath = `${ifsname}_ifs/${ifsname}_hp.bin`; } let cleanUp = true; let soundContainer = new Twodx(twodxPath); let chart = new Popnchart(chartPath, !soundContainer.late_bg); //The sound container is full of MSADPCM keysounds, so each one needs decoded. let decodedKeysounds = soundContainer.keysounds.map((keysound) => MSADPCM.decodeKeysoundOut(keysound.data, keysound.unk2)); if (cleanUp) fs.rmdirSync(path.basename(arg1).slice(0, -4)+"_ifs", {recursive: true}); let highestSample = 0; //Outputting stereo 44.1Khz regardless. const channels = 2; const samplingRate = 44100; //Because Int32. const bytes = 4; //After loading in all the keysounds, we need to find ones that //aren't 44.1KHz, since they'll mess everything up. //Best resampling option I could find was node-libsamplerate. //I'm sure other people have better suggestions. for (var i = 0; i buffSize) { buffSize = off + (keysound.data.length*2); } } } //Creating a buffer to store Int32s. //This is overcompensating to deal with overflow from digital summing. //Final Timestamp in milliseconds * sampling rate * 2 channels * 4 bytes. const finalBuffer = Buffer.alloc(buffSize); for (const event of chart.playEvents) { const [offset, keysoundNo] = event; //Grabbing the relevant offset for the buffer. const convertedOffset = parseInt((offset*samplingRate)/1000)*channels*bytes; const keysound = decodedKeysounds[keysoundNo]; if (keysound) { const keysoundData = keysound.data; for (var i = 0; i