rags/.config/ags/cava.js (view raw)
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 83 84 85 86 87 88 89 90 91 92 |
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
const confPath = `/tmp/ags/cava.conf`;
async function readCavaAsync(barNumber, bitFormat, callback, onError) {
try {
const conf =
`[general]
framerate = 30
bars = ${barNumber}
[output]
method = raw
bit_format = ${bitFormat}`;
Utils.writeFileSync(conf, confPath);
const cava = Gio.Subprocess.new(
[`cava`, `-p`, confPath],
Gio.SubprocessFlags.STDOUT_PIPE |
Gio.SubprocessFlags.STDERR_PIPE,
);
const pipe = cava.get_stdout_pipe();
if (!pipe) {
onError(Error(`cava stdout pipe is null`));
return null;
}
const read8bit = (stream) => {
stream.read_bytes_async(barNumber, GLib.PRIORITY_LOW, null, (stream, res) => {
try {
let data = stream.read_bytes_finish(res).get_data();
const output = new Float64Array(data).map(d => d / 255);
callback(output);
read8bit(stream);
} catch (e) {
onError(e);
}
});
};
const read16bit = (stream) => {
stream.read_bytes_async(barNumber * 2, GLib.PRIORITY_LOW, null, (stream, res) => {
try {
const data = stream.read_bytes_finish(res).get_data();
const output = new Float64Array(new Uint16Array(data.buffer)).map(d => d / 65535);
callback(output);
read16bit(stream);
} catch (e) {
onError(e);
}
});
};
if (bitFormat === '8bit') {
read8bit(pipe);
} else if (bitFormat === '16bit'){
read16bit(pipe);
}
} catch (e) {
logError(e);
return null;
}
}
export class Cava extends Service {
static {
Service.register(this, {}, {
'bar-value': ['float[]', 'r'],
});
}
#barValues = [];
get bar_value() {
return this.#barValues;
}
constructor(barNumber, bitFormat) {
super();
readCavaAsync(
barNumber, bitFormat, (barValues) => {
this.#barValues = barValues;
this.#onChange();
}
)
}
#onChange() {
this.emit('changed');
this.notify('bar-value');
}
}
|