Here’s a quick tool I made, I’m sharing it in case it might interest you.
You need to save it within a folder, then copy a sound file within the same folder, adjust the top variables so they fit your needs.
Main parameter is freq
. Once started, it will divide it by two until it is just above 20HZ, then will play the sound file and split each octave according to the freq: you will get one sound file between 20HZ and freq, one sound file between freq and freq * 2, between freq * 2 and freq * 4, etc, up to frequencies between freq * 256 and 20KHZ (i.e. 10 bands, first and last not being an octave wide).
Notes:
- This is real-time recording, so you need to wait the sound file duration before it’s done.
- I’m using LPF + HPF to act as a bandpass. This will introduce phase shifting, different for each recording.
- You will lose volume at the frequency breaking points (see bottom code). So you might want to split octaves somewhere spectrally not important (e.g. root tritone on tonal music).
- Only stereo here, but this is easy to adapt.
The code:
(
var freq = 66.midicps;
var fileName = "file_name.wav";
var targetName = "file_name";
var format = "wav";
var sampleFormat = "int32";
var sampleRate = 48000;
var cwd = thisProcess.nowExecutingPath.dirname;
var fileBuffer;
var buffers = Array.newClear(10);
var onSynthFree = {
buffers.do({ |buffer, index|
buffer.write(
cwd +/+ targetName ++ "_oct" ++ index ++ "." ++ format,
format,
sampleFormat
);
buffer.free;
});
fileBuffer.free;
"Octave splitting done".postln;
};
var onFileLoaded = {
10.do({ |i|
buffers[i] = Buffer.alloc(
s,
fileBuffer.numFrames + sampleRate,
2
);
});
SynthDef(\octaveSplitter, { |in, freq,
b1, b2, b3, b4, b5, b6, b7, b8, b9, b10|
var snd = PlayBuf.ar(2, in);
var oct1 = LPF.ar(HPF.ar(snd, 20), freq);
var oct2 = LPF.ar(HPF.ar(snd, freq), freq * 2);
var oct3 = LPF.ar(HPF.ar(snd, freq * 2), freq * 4);
var oct4 = LPF.ar(HPF.ar(snd, freq * 4), freq * 8);
var oct5 = LPF.ar(HPF.ar(snd, freq * 8), freq * 16);
var oct6 = LPF.ar(HPF.ar(snd, freq * 16), freq * 32);
var oct7 = LPF.ar(HPF.ar(snd, freq * 32), freq * 64);
var oct8 = LPF.ar(HPF.ar(snd, freq * 64), freq * 128);
var oct9 = LPF.ar(HPF.ar(snd, freq * 128), freq * 256);
var oct10 = LPF.ar(HPF.ar(snd, freq * 256), 20000);
RecordBuf.ar(oct1, b1);
RecordBuf.ar(oct2, b2);
RecordBuf.ar(oct3, b3);
RecordBuf.ar(oct4, b4);
RecordBuf.ar(oct5, b5);
RecordBuf.ar(oct6, b6);
RecordBuf.ar(oct7, b7);
RecordBuf.ar(oct8, b8);
RecordBuf.ar(oct9, b9);
RecordBuf.ar(oct10, b10);
EnvGen.kr(
Env([0, 0], [BufDur.kr(in) + 1]),
doneAction: Done.freeSelf;
);
})
.play(
args: [
\in, fileBuffer,
\freq, freq,
\b1, buffers[0],
\b2, buffers[1],
\b3, buffers[2],
\b4, buffers[3],
\b5, buffers[4],
\b6, buffers[5],
\b7, buffers[6],
\b8, buffers[7],
\b9, buffers[8],
\b10, buffers[9]
])
.onFree({ onSynthFree.value; });
};
while { (freq / 2) > 20 } {
freq = freq / 2;
};
fileBuffer = Buffer.read(
s,
cwd +/+ fileName,
action: { |buffer|
fileBuffer = buffer;
onFileLoaded.value;
}
);
)
Use a spectrogram to see how frequencies are attenuated at freq
multiples:
(
SynthDef(\osfr, { |freq = 24|
var snd = PinkNoise.ar(0.1);
var oct1 = LPF.ar(HPF.ar(snd, 20), freq);
var oct2 = LPF.ar(HPF.ar(snd, freq), freq * 2);
var oct3 = LPF.ar(HPF.ar(snd, freq * 2), freq * 4);
var oct4 = LPF.ar(HPF.ar(snd, freq * 4), freq * 8);
var oct5 = LPF.ar(HPF.ar(snd, freq * 8), freq * 16);
var oct6 = LPF.ar(HPF.ar(snd, freq * 16), freq * 32);
var oct7 = LPF.ar(HPF.ar(snd, freq * 32), freq * 64);
var oct8 = LPF.ar(HPF.ar(snd, freq * 64), freq * 128);
var oct9 = LPF.ar(HPF.ar(snd, freq * 128), freq * 256);
var oct10 = LPF.ar(HPF.ar(snd, freq * 256), 20000);
snd = oct1 + oct2 + oct3 + oct5 + oct6 + oct7 + oct8 + oct9 + oct10;
Out.ar(0, snd);
}).play;
)
Have fun,
Simon