-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathaudio.js
More file actions
82 lines (75 loc) · 3.35 KB
/
Copy pathaudio.js
File metadata and controls
82 lines (75 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
const fs = require("fs");
const Ciseaux = require("ciseaux/node");
const Tape = require("ciseaux/lib/tape");
const beatswap = (options) => {
const {
inFilePath,
outFilePath,
beatLength,
sequenceOrder,
startPoint,
useSilence,
} = options;
// create a tape instance from the filepath
console.log('Attempting to read file from:', inFilePath);
Ciseaux.from(inFilePath).then((originalTape) => {
console.log('Done.');
const measureCount = originalTape.duration / beatLength;
// Create a blank Tape to append to
let runningTape = new Tape();
// Split all of the tapes out by the number of beats there are. Bump by the startPoint, too.
let allSlices = originalTape.slice(startPoint).split(measureCount);
console.log('Processing', allSlices.length, 'beats...');
let currentSequenceIndex = 0;
// The index of the set of audio clips that will be picked
// from to populate the current sequence
let currentSequenceFrame = 0;
for (let i = 0; i < allSlices.length; i++) {
// This is the beat in the sequence we want to put in this slot
const beatTarget = sequenceOrder[currentSequenceIndex];
// This is the adjustment we want to make for the current sequence frame,
// given the sequence length
const sequenceFrameOffset = currentSequenceFrame * sequenceOrder.length;
// Is the target actually null, indicating a beat omission?
if (beatTarget === null) {
// If we set useSilence to true, then replace the beat drop with silence.
if (useSilence) {
runningTape = runningTape.concat(Ciseaux.silence(beatLength));
}
// Otherwise, we omit adding the slice, resulting in a shorter file.
} else {
// This is the clip we actually want to get
const clipTargetIndex = sequenceFrameOffset + beatTarget;
// Is there nothing to grab because we're at the end? Then just pop in
// the current clip.
if (clipTargetIndex > allSlices.length - 1) {
runningTape = runningTape.concat(allSlices[i]);
} else {
// Otherwise, just grab that dang clip and put it in there.
runningTape = runningTape.concat(allSlices[clipTargetIndex]);
}
}
// Wrap around the sequence index when we're at the end and then bump the frame
// so we target the clips for the next sequence
currentSequenceIndex++;
if (currentSequenceIndex > sequenceOrder.length - 1) {
currentSequenceIndex = 0;
currentSequenceFrame++;
}
}
return runningTape.render();
}).then(legacyBuffer => {
// Ciseaux seems to return an old-style buffer that doesn't write out
// properly so we just rewrap it.
const buffer = Buffer.from(legacyBuffer);
return new Promise(resolve => {
console.log('Writing beatswapped file to:', outFilePath);
fs.writeFile(outFilePath, buffer, resolve);
}).then(() => {
console.log('Done. Enjoy!');
});
});
};
module.exports = {
beatswap: beatswap,
};