Created
December 5, 2019 21:02
-
-
Save mauritslamers/6015a256a2aa51689e3b8f9afd914a4d to your computer and use it in GitHub Desktop.
Revisions
-
mauritslamers created this gist
Dec 5, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,104 @@ // recover from audacity crash // usage: // node audacity_rescue.js [sourcedir] [result_file.wav] [mono|stereo] // the mono or stereo option is optional, the default is mono. // // Description: // This script will sort all files on modification date. // If you create a backup, make sure you use `cp -a` to preserve the modification date // or create a zip. // The resulting file will pretend to be a wave file (because of the .wav extension), but // is in fact a Audacity simple block file. You will have to open the resulting file with // audacity and then export it as a normal file. const fs = require('fs'); const pathLib = require('path'); const pj = pathLib.join; const srcdirname = process.argv[2]; const result_file = process.argv[3]; const type = process.argv[4]; if (!(srcdirname && result_file)) { console.log("Need both a source dir and a target file"); process.exit(1); } if (!type) type = 'mono'; if (! (type === 'mono' || type === 'stereo')) { console.log('invalid audio format'); } console.log('source dir name: ', srcdirname); console.log('result_file', result_file); // we need all files in the subdirectories of dirname // sorted by date const allFiles = []; function readFiles (dir) { const names = fs.readdirSync(dir); names.forEach(n => { const fullPath = pj(dir, n); const stats = fs.statSync(fullPath); if (stats.isDirectory()) { readFiles(fullPath); } else { if (pathLib.extname(n) === ".au") { allFiles.push({ name: fullPath, time: stats.mtime.getTime()}) } } }); } console.log('searching and sorting files by date'); readFiles(srcdirname); allFiles.sort( (a, b) => { return a.time - b.time; }); if (type === 'stereo') { console.log('writing result files'); const f = pathLib.parse(result_file); const left_fn = pathLib.join(f.root, f.dir, f.base + '_L' + f.ext); const right_fn = pathLib.join(f.root, f.dir, f.base + '_R' + f.ext); const fhL = fs.openSync(left_fn, 'w'); const fhR = fs.openSync(right_fn, 'w'); let targetPosL = 0; let targetPosR = 0; const numFiles = allFiles.length; allFiles.forEach( (f, i) => { console.log(`reading ${f.name} (${i} of ${numFiles})`); const buf = fs.readFileSync(f.name); const offset = (i === 0 || i === 1) ? 0: buf.readUInt16LE(4); if (i % 2 === 0) { // assume left targetPosL += fs.writeSync(fhL, buf, offset, buf.length-offset, targetPosL); } else { // assume right targetPosR += fs.writeSync(fhR, buf, offset, buf.length-offset, targetPosR); } }) fs.closeSync(fhL); fs.closeSync(fhR); } else { // now merge all files in the result console.log('writing result file'); const fh = fs.openSync(result_file, 'w'); let targetPos = 0; const numFiles = allFiles.length; allFiles.forEach( (f, i) => { console.log(`reading ${f.name} (${i} of ${numFiles})`); const buf = fs.readFileSync(f.name); const offset = i === 0? 0: buf.readUInt16LE(4); targetPos += fs.writeSync(fh, buf, offset, buf.length-offset, targetPos); }); fs.closeSync(fh); } console.log('Done');