Add altSort method for alternate patterns other than 1:1. AAAND check for sox before executing.

This commit is contained in:
mmcwilliams 2019-05-31 17:46:24 -04:00
parent 4d6d4eabd6
commit d324a3e924
5 changed files with 148 additions and 40 deletions

View File

@ -47,7 +47,5 @@ Options:
## TODO ## TODO
* Fix alternate sort pattern features
* Check for sox before executing
* Generate example audiofiles automatically * Generate example audiofiles automatically
* Publish example audio files * Publish example audio files

View File

@ -11,6 +11,7 @@ let TMPPATH;
let EXE = `sox`; let EXE = `sox`;
let IDENTIFY = `soxi`; let IDENTIFY = `soxi`;
let SLICE = (1000 / 24) + ''; let SLICE = (1000 / 24) + '';
let RATE = 48000; //standardize all to rate
/** /**
* Shells out to execute a command with async/await. * Shells out to execute a command with async/await.
* Async wrapper to exec module. * Async wrapper to exec module.
@ -176,7 +177,7 @@ async function slices(file, len, order) {
console.log(`Exporting ${file} as ${total} slices ${SLICE}ms long...`); console.log(`Exporting ${file} as ${total} slices ${SLICE}ms long...`);
for (i = 0; i < total; i++) { for (i = 0; i < total; i++) {
tmpoutput = path.join(TMPPATH, `export-${zeroPad(i)}_${order}.${ext}`); tmpoutput = path.join(TMPPATH, `export-${zeroPad(i)}_${order}.${ext}`);
cmd = `${exe} "${file}" "${tmpoutput}" trim ${offset(i, slice)} ${parseFloat(slice) / 1000}`; cmd = `${exe} "${file}" "${tmpoutput}" rate ${RATE} trim ${offset(i, slice)} ${parseFloat(slice) / 1000}`;
try { try {
console.log(cmd); console.log(cmd);
await exec(cmd); await exec(cmd);
@ -236,8 +237,6 @@ async function weave(pattern, realtime, random) {
} }
} }
else if (alt) { else if (alt) {
console.warn('This feature is not ready, please check https://github.com/sixteenmillimeter/audioloom.git');
process.exit(10);
try { try {
seq = await altSort(slices, pattern, realtime); seq = await altSort(slices, pattern, realtime);
} }
@ -261,34 +260,69 @@ async function weave(pattern, realtime, random) {
async function altSort(list, pattern, realtime) { async function altSort(list, pattern, realtime) {
let groups = []; let groups = [];
let newList = []; let newList = [];
let loops = 0;
let patternIndexes = [];
let sliceCount = 0; let sliceCount = 0;
let skipCount;
let skip;
let oldName;
let oldPath; let oldPath;
let newName; let newName;
let newPath; let newPath;
let ext = path.extname(list[0]); let ext = path.extname(list[0]);
for (let g of pattern) { let x;
let i;
for (x = 0; x < pattern.length; x++) {
groups.push([]); groups.push([]);
for (let i = 0; i < pattern[x]; i++) {
patternIndexes.push(x);
}
} }
for (let i = 0; i < list.length; i++) { for (i = 0; i < list.length; i++) {
groups[i % pattern.length].push(list[i]); groups[i % pattern.length].push(list[i]);
} }
for (let x = 0; x < list.length; x++) { loops = Math.ceil(list.length / patternIndexes.length);
for (let g of pattern) { if (realtime) {
for (let i = 0; i < g; i++) { skip = false;
/*oldPath = path.join(TMPPATH, list[i]); skipCount = patternIndexes.length + 1;
newName = `./render_${zeroPad(sliceCount)}${ext}`; }
newPath = path.join(TMPPATH, newName); for (x = 0; x < loops; x++) {
for (i = 0; i < patternIndexes.length; i++) {
console.log(`Renaming ${list[i]} -> ${newName}`); if (realtime) {
skipCount--;
if (skipCount === 0) {
skip = !skip;
skipCount = pattern.length;
}
}
if (typeof groups[patternIndexes[i]][0] === 'undefined') {
continue;
}
oldName = String(groups[patternIndexes[i]][0]);
oldPath = path.join(TMPPATH, oldName);
groups[patternIndexes[i]].shift();
if (skip) {
console.log(`Skipping ${oldName}`);
try { try {
//await fs.move(oldPath, newPath, { overwrite: true }) await fs.unlink(oldPath);
newList.push(newName); }
} catch (err) { catch (err) {
console.error(err); console.log('Error deleting slice', err);
}*/ }
continue;
}
newName = `./render_${zeroPad(sliceCount)}${ext}`;
newPath = path.join(TMPPATH, newName);
console.log(`Renaming ${oldName} -> ${newName}`);
try {
await fs.move(oldPath, newPath);
newList.push(newName);
sliceCount++; sliceCount++;
} }
catch (err) {
console.log('Error renaming slice', err);
return process.exit(10);
}
} }
} }
return newList; return newList;
@ -455,6 +489,7 @@ async function main(arg) {
let random = false; let random = false;
let allSlices; let allSlices;
let len; let len;
let exists;
console.time('audioloom'); console.time('audioloom');
if (input.length < 2) { if (input.length < 2) {
console.error('Must provide more than 1 input'); console.error('Must provide more than 1 input');
@ -488,6 +523,21 @@ async function main(arg) {
pattern.push(1); pattern.push(1);
} }
} }
if (pattern.length !== input.length) {
console.error(`Number of inputs (${input.length}) doesn't match the pattern length (${pattern.length})`);
process.exit(10);
}
try {
exists = await exec(`which ${EXE}`);
}
catch (err) {
console.error(`Error checking for ${EXE}`);
process.exit(11);
}
if (!exists || exists === '' || exists.indexOf(EXE) === -1) {
console.error(`${EXE} is required and is not installed. Please install ${EXE} to use audioloom.`);
process.exit(12);
}
if (arg.realtime) if (arg.realtime)
realtime = true; realtime = true;
TMPPATH = path.join(TMPDIR, 'audioloom'); TMPPATH = path.join(TMPDIR, 'audioloom');

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "audioloom", "name": "audioloom",
"version": "1.0.0", "version": "1.0.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "audioloom", "name": "audioloom",
"version": "1.0.0", "version": "1.0.1",
"description": "Node script for interweaving audio files together", "description": "Node script for interweaving audio files together",
"main": "audioloom", "main": "audioloom",
"scripts": { "scripts": {

View File

@ -15,6 +15,7 @@ let TMPPATH : string
let EXE : string = `sox` let EXE : string = `sox`
let IDENTIFY : string = `soxi` let IDENTIFY : string = `soxi`
let SLICE : string = (1000 / 24) + '' let SLICE : string = (1000 / 24) + ''
let RATE : number = 48000 //standardize all to rate
/** /**
* Shells out to execute a command with async/await. * Shells out to execute a command with async/await.
@ -183,7 +184,7 @@ async function slices (file : string, len : number, order : number) {
for (i = 0; i < total; i++) { for (i = 0; i < total; i++) {
tmpoutput = path.join(TMPPATH, `export-${zeroPad(i)}_${order}.${ext}`) tmpoutput = path.join(TMPPATH, `export-${zeroPad(i)}_${order}.${ext}`)
cmd = `${exe} "${file}" "${tmpoutput}" trim ${offset(i, slice)} ${parseFloat(slice) / 1000}` cmd = `${exe} "${file}" "${tmpoutput}" rate ${RATE} trim ${offset(i, slice)} ${parseFloat(slice) / 1000}`
try { try {
console.log(cmd) console.log(cmd)
await exec(cmd) await exec(cmd)
@ -241,8 +242,6 @@ async function weave (pattern : number[], realtime : boolean, random : boolean)
console.error('Error sorting slices') console.error('Error sorting slices')
} }
} else if (alt) { } else if (alt) {
console.warn('This feature is not ready, please check https://github.com/sixteenmillimeter/audioloom.git')
process.exit(10)
try { try {
seq = await altSort(slices, pattern, realtime) seq = await altSort(slices, pattern, realtime)
} catch (err) { } catch (err) {
@ -265,39 +264,82 @@ async function weave (pattern : number[], realtime : boolean, random : boolean)
async function altSort (list : string[], pattern : number[], realtime : boolean) { async function altSort (list : string[], pattern : number[], realtime : boolean) {
let groups : any[] = [] let groups : any[] = []
let newList : string[] = [] let newList : string[] = []
let loops : number = 0
let patternIndexes : number[] = []
let sliceCount : number = 0 let sliceCount : number = 0
let skipCount : number
let skip : boolean
let oldName : string
let oldPath : string let oldPath : string
let newName : string let newName : string
let newPath : string let newPath : string
let ext : string = path.extname(list[0]) let ext : string = path.extname(list[0])
let x : number
let i : number
for (let g of pattern) { for (x = 0; x < pattern.length; x++) {
groups.push([]) groups.push([])
for (let i : number = 0; i < pattern[x]; i++) {
patternIndexes.push(x)
}
} }
for (let i = 0; i < list.length; i++) {
for (i = 0; i < list.length; i++) {
groups[i % pattern.length].push(list[i]) groups[i % pattern.length].push(list[i])
} }
for (let x : number = 0; x < list.length; x++) {
for (let g of pattern) {
for (let i = 0; i < g; i++) {
/*oldPath = path.join(TMPPATH, list[i]); loops = Math.ceil(list.length / patternIndexes.length)
newName = `./render_${zeroPad(sliceCount)}${ext}`;
newPath = path.join(TMPPATH, newName);
console.log(`Renaming ${list[i]} -> ${newName}`); if (realtime) {
skip = false
skipCount = patternIndexes.length + 1
}
for (x = 0; x < loops; x++) {
for (i = 0; i < patternIndexes.length; i++) {
if (realtime) {
skipCount--;
if (skipCount === 0) {
skip = !skip;
skipCount = pattern.length
}
}
if (typeof groups[patternIndexes[i]][0] === 'undefined') {
continue
}
oldName = String(groups[patternIndexes[i]][0])
oldPath = path.join(TMPPATH, oldName)
groups[patternIndexes[i]].shift()
if (skip) {
console.log(`Skipping ${oldName}`)
try { try {
//await fs.move(oldPath, newPath, { overwrite: true }) await fs.unlink(oldPath)
newList.push(newName);
} catch (err) { } catch (err) {
console.error(err); console.log('Error deleting slice', err)
}*/ }
continue
}
newName = `./render_${zeroPad(sliceCount)}${ext}`
newPath = path.join(TMPPATH, newName)
console.log(`Renaming ${oldName} -> ${newName}`)
try {
await fs.move(oldPath, newPath)
newList.push(newName)
sliceCount++ sliceCount++
} catch (err) {
console.log('Error renaming slice', err)
return process.exit(10)
} }
} }
} }
return newList return newList
} }
/** /**
@ -484,6 +526,7 @@ async function main (arg : any) {
let random : boolean = false let random : boolean = false
let allSlices : string [] let allSlices : string []
let len : number let len : number
let exists : any
console.time('audioloom') console.time('audioloom')
if (input.length < 2) { if (input.length < 2) {
@ -524,6 +567,23 @@ async function main (arg : any) {
} }
} }
if (pattern.length !== input.length) {
console.error(`Number of inputs (${input.length}) doesn't match the pattern length (${pattern.length})`)
process.exit(10)
}
try {
exists = await exec(`which ${EXE}`)
} catch (err) {
console.error(`Error checking for ${EXE}`)
process.exit(11)
}
if (!exists || exists === '' || exists.indexOf(EXE) === -1) {
console.error(`${EXE} is required and is not installed. Please install ${EXE} to use audioloom.`)
process.exit(12)
}
if (arg.realtime) realtime = true if (arg.realtime) realtime = true
TMPPATH = path.join(TMPDIR, 'audioloom') TMPPATH = path.join(TMPDIR, 'audioloom')