@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
65 lines • 3.13 kB
JavaScript
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
/**
* The measured audio facts of one audio file, labelled with units, for the
* user's own AI to reason over. Read by pica_audio_inspect (analysis section)
* and pica_recordings_inspect (audio section).
*
* Field names match the directory MCP's `measured` block
* (mcp-server-directory/src/utils/measured.ts): tempo_bpm, key, mode, energy,
* duration_seconds — plus loudness_lufs here, where the analysis version is
* known. Keep the two in step — no test enforces it.
*
* Analyses before railway-1.1 (2026-10-07) measured energy as RMS capped at
* 1, which saturated for most masters, and stored a different loudness
* quantity. `energy_method` says which one a row carries, and loudness_lufs
* is reported only for rows that measured it.
*/
export const MEASURED_AUDIO_BASIS = "Measured from the audio file by PICA's analyser — not entered by a person. " +
"tempo_bpm: beats per minute. key + mode: estimated tonic and major/minor. " +
"energy: 0 to 1 — with energy_method 'integrated_loudness', the file's " +
"ITU-R BS.1770 integrated loudness placed on a quiet-to-loud scale; with " +
"'legacy_rms_capped' an older reading that sits at 1.0 for most masters, " +
"not comparable across tracks. loudness_lufs: integrated loudness in LUFS " +
"(mono downmix). Energy measures loudness, not mood. null means not measured.";
/** First analyser version whose energy comes from integrated loudness. */
const LOUDNESS_ENERGY_VERSION = [1, 1];
function num(v) {
const n = typeof v === "string" && v.trim() !== "" ? Number(v) : v;
return typeof n === "number" && Number.isFinite(n) ? n : null;
}
/** "railway-1.1" → true; "railway-1.0", "1", null → false. */
export function measuresLoudness(version) {
if (typeof version !== "string")
return false;
const m = /^railway-(\d+)\.(\d+)/.exec(version);
if (!m)
return false;
const major = Number(m[1]);
const minor = Number(m[2]);
const [wantMajor, wantMinor] = LOUDNESS_ENERGY_VERSION;
return major > wantMajor || (major === wantMajor && minor >= wantMinor);
}
/** From an audio file row with its analysis satellite flattened onto it. */
export function toMeasuredAudio(file) {
const version = typeof file.analysis_version === "string" ? file.analysis_version : null;
const current = measuresLoudness(version);
const energy = num(file.detected_energy);
const mode = file.musical_mode;
return {
tempo_bpm: num(file.detected_bpm),
key: typeof file.detected_key === "string" && file.detected_key
? file.detected_key
: null,
mode: mode === "major" || mode === "minor" ? mode : null,
energy,
energy_method: energy === null
? null
: current
? "integrated_loudness"
: "legacy_rms_capped",
loudness_lufs: current ? num(file.loudness) : null,
duration_seconds: num(file.duration_seconds),
analysis_version: version,
};
}
//# sourceMappingURL=measured-audio.js.map