feat: MusicBrainz BPM enrichment + improved AI prompts
- lookupRecordingWithTags, extractBpmFromTags, extractTimeSigFromTags, getMusicBrainzRecording added to MB client - upsertSong preserves existing BPM via COALESCE on conflict - updateSongBpm helper for async enrichment writes - AnalysisInput gains confirmedBpm / confirmedTimeSigNum fields - POST /api/analyze fetches confirmed BPM from DB then MB tags before generation - All three AI providers use confirmedBpm as authoritative and build enriched userMessage - POST /api/tracks auto-registration now fetches tags via getMusicBrainzRecording - Updated User-Agent and MB client fallback URL to Gitea Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,8 +38,17 @@ export const openaiProvider: AnalysisProvider = {
|
||||
|
||||
const baseUrl = process.env.OPENAI_BASE_URL ?? "https://api.openai.com/v1";
|
||||
const model = process.env.OPENAI_MODEL ?? "gpt-4o";
|
||||
const { bpm, duration, title, artist, mbid, contributed_by } = input;
|
||||
const approxBars = Math.round((duration * bpm) / 60 / 4);
|
||||
const { bpm, duration, title, artist, mbid, contributed_by, confirmedBpm, confirmedTimeSigNum } = input;
|
||||
const effectiveBpm = confirmedBpm ?? bpm;
|
||||
const approxBars = Math.round((duration * effectiveBpm) / 60 / 4);
|
||||
|
||||
const bpmLine = confirmedBpm
|
||||
? `Confirmed BPM (from MusicBrainz community tags — treat as authoritative): ${confirmedBpm}\nDetected BPM (audio analysis): ${bpm}`
|
||||
: `Detected BPM (audio analysis): ${bpm}`;
|
||||
|
||||
const timeSigHint = confirmedTimeSigNum
|
||||
? `\nConfirmed time signature numerator: ${confirmedTimeSigNum}`
|
||||
: "";
|
||||
|
||||
const userMessage = `\
|
||||
Generate a CTP document for the following song:
|
||||
@@ -47,11 +56,11 @@ Generate a CTP document for the following song:
|
||||
Title: ${title ?? "Unknown Title"}
|
||||
Artist: ${artist ?? "Unknown Artist"}
|
||||
MusicBrainz ID: ${mbid ?? "unknown"}
|
||||
Detected BPM: ${bpm}
|
||||
${bpmLine}${timeSigHint}
|
||||
Duration: ${duration.toFixed(1)} seconds (~${approxBars} bars at 4/4)
|
||||
Contributed by: ${contributed_by}
|
||||
|
||||
Create a plausible section layout for this song. If this is a well-known song, use your knowledge of its actual arrangement. If not, use a sensible generic structure.`;
|
||||
If you recognise this song, use your training knowledge of its actual arrangement — section names, bar counts, time signature, and any tempo changes. If you do not recognise it, use a sensible generic structure based on the BPM and duration above.`;
|
||||
|
||||
const response = await fetch(`${baseUrl}/chat/completions`, {
|
||||
method: "POST",
|
||||
|
||||
Reference in New Issue
Block a user