fix structure

This commit is contained in:
2025-10-22 16:32:58 +02:00
parent da001a491b
commit 40e10d1692
4 changed files with 74 additions and 99 deletions
+7 -13
View File
@@ -15,7 +15,6 @@ const STRUCTURE_PROMPT_LABELS = {
refrain: "refrain", refrain: "refrain",
short_intro: "introduction instrumentale courte", short_intro: "introduction instrumentale courte",
long_intro: "introduction instrumentale longue", long_intro: "introduction instrumentale longue",
pre_chorus: "pré-refrain",
pre_refrain_instrumental: "pré-refrain instrumental", pre_refrain_instrumental: "pré-refrain instrumental",
pont: "pont", pont: "pont",
solo_de_guitare: "solo de guitare", solo_de_guitare: "solo de guitare",
@@ -39,11 +38,12 @@ const STRUCTURE_ALIASES = {
"long intro": "long_intro", "long intro": "long_intro",
"introduction instrumentale longue": "long_intro", "introduction instrumentale longue": "long_intro",
"intro instrumentale longue": "long_intro", "intro instrumentale longue": "long_intro",
"pré-refrain": "pre_chorus", "pré-refrain": "pre_refrain_instrumental",
"pre-refrain": "pre_chorus", "pre-refrain": "pre_refrain_instrumental",
"pre chorus": "pre_chorus", "pre_refrain": "pre_refrain_instrumental",
"pre-chorus": "pre_chorus", "pre chorus": "pre_refrain_instrumental",
prechorus: "pre_chorus", "pre-chorus": "pre_refrain_instrumental",
prechorus: "pre_refrain_instrumental",
"pré-refrain instrumental": "pre_refrain_instrumental", "pré-refrain instrumental": "pre_refrain_instrumental",
"pre-refrain instrumental": "pre_refrain_instrumental", "pre-refrain instrumental": "pre_refrain_instrumental",
"instrumental pre-chorus": "pre_refrain_instrumental", "instrumental pre-chorus": "pre_refrain_instrumental",
@@ -85,14 +85,8 @@ const sanitizeStructureEntries = (structure = []) => {
output.push(normalized); output.push(normalized);
return; return;
} }
if (normalized === "pre_chorus") {
if (!output.includes("pre_chorus")) output.push("pre_chorus");
return;
}
if (normalized === "pre_refrain_instrumental") { if (normalized === "pre_refrain_instrumental") {
if (!output.includes("pre_refrain_instrumental")) { output.push("pre_refrain_instrumental");
output.push("pre_refrain_instrumental");
}
return; return;
} }
if ( if (
+22 -4
View File
@@ -31,6 +31,12 @@ import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
import Style, { gutters, size } from "../../styles/Style"; import Style, { gutters, size } from "../../styles/Style";
import { getArtistDisplayName } from "../../utils/artistName"; import { getArtistDisplayName } from "../../utils/artistName";
import {
formatStructureLabel,
getPromptLabelForStructure,
getSegmentMeta,
normalizeStructureType,
} from "../../utils/songStructure";
// 20 secondes // 20 secondes
const timeBeforeIncrement = 20000; const timeBeforeIncrement = 20000;
@@ -363,6 +369,14 @@ const MusicDetails = ({ route }) => {
let type = "section"; let type = "section";
if (lower.includes("refrain") || lower.includes("chorus")) type = "refrain"; if (lower.includes("refrain") || lower.includes("chorus")) type = "refrain";
else if (lower.includes("couplet") || lower.includes("verse")) type = "couplet"; else if (lower.includes("couplet") || lower.includes("verse")) type = "couplet";
else if (
lower.includes("pré") ||
lower.includes("prechorus") ||
lower.includes("pre-chorus") ||
lower.includes("pre chorus") ||
lower.includes("pre-refrain")
)
type = "pre_refrain_instrumental";
else if (lower.includes("pont") || lower.includes("bridge")) type = "pont"; else if (lower.includes("pont") || lower.includes("bridge")) type = "pont";
else if (lower.includes("intro")) type = "intro"; else if (lower.includes("intro")) type = "intro";
const indexMatch = label.match(/(\d+)/); const indexMatch = label.match(/(\d+)/);
@@ -371,10 +385,14 @@ const MusicDetails = ({ route }) => {
}; };
const formatSectionLabel = (type, index, fallback) => { const formatSectionLabel = (type, index, fallback) => {
if (fallback) return fallback; if (fallback) return fallback;
if (type === "refrain") return index > 1 ? `Refrain ${index}` : "Refrain"; const normalized = normalizeStructureType(type);
if (type === "couplet") return index > 1 ? `Couplet ${index}` : "Couplet"; const meta = getSegmentMeta(normalized);
if (type === "pont") return index > 1 ? `Pont ${index}` : "Pont"; if (meta) {
if (type === "intro") return "Intro"; const label = formatStructureLabel(normalized, index);
if (label) return label;
}
const prompt = getPromptLabelForStructure(normalized);
if (prompt) return prompt;
return index > 1 ? `Section ${index}` : "Section"; return index > 1 ? `Section ${index}` : "Section";
}; };
+1 -7
View File
@@ -444,7 +444,7 @@ const MusicDetails = ({ route }) => {
lower.includes("pre chorus") || lower.includes("pre chorus") ||
lower.includes("pre-refrain") lower.includes("pre-refrain")
) )
type = "pre_chorus"; type = "pre_refrain_instrumental";
else if (lower.includes("pont") || lower.includes("bridge")) type = "pont"; else if (lower.includes("pont") || lower.includes("bridge")) type = "pont";
else if (lower.includes("intro")) { else if (lower.includes("intro")) {
if (lower.includes("long")) type = "long_intro"; if (lower.includes("long")) type = "long_intro";
@@ -464,12 +464,6 @@ const MusicDetails = ({ route }) => {
} }
const prompt = getPromptLabelForStructure(normalized); const prompt = getPromptLabelForStructure(normalized);
if (prompt) return prompt; if (prompt) return prompt;
if (normalized === "refrain")
return index > 1 ? `Refrain ${index}` : "Refrain";
if (normalized === "couplet")
return index > 1 ? `Couplet ${index}` : "Couplet";
if (type === "pont") return index > 1 ? `Pont ${index}` : "Pont";
if (type === "intro") return index > 1 ? `Intro ${index}` : "Intro";
return index > 1 ? `Section ${index}` : "Section"; return index > 1 ? `Section ${index}` : "Section";
}; };
+44 -75
View File
@@ -65,26 +65,6 @@ export const STRUCTURE_SEGMENTS = {
"intro instrumentale longue", "intro instrumentale longue",
], ],
}, },
// pre_chorus: {
// label: "Pré-refrain",
// promptLabel: "Pré-refrain",
// showIndex: false,
pre_chorus: {
label: "Pré-refrain",
promptLabel: "Pré-refrain",
showIndex: false,
allowMultiple: false,
optional: true,
inputHeight: 150,
requiresLyrics: true,
aliases: [
"pré-refrain",
"pre-refrain",
"prechorus",
"pre chorus",
"pré chorus",
],
},
pre_refrain_instrumental: { pre_refrain_instrumental: {
label: "Pré-refrain instrumental", label: "Pré-refrain instrumental",
promptLabel: "Pré-refrain instrumental", promptLabel: "Pré-refrain instrumental",
@@ -94,7 +74,7 @@ export const STRUCTURE_SEGMENTS = {
inputHeight: 150, inputHeight: 150,
exclusiveGroup: "pre_chorus", exclusiveGroup: "pre_chorus",
requiresLyrics: false, requiresLyrics: false,
aliases: ["instrumental_pre_chorus"], aliases: [],
}, },
pont: { pont: {
label: "Pont", label: "Pont",
@@ -103,8 +83,8 @@ export const STRUCTURE_SEGMENTS = {
allowMultiple: true, allowMultiple: true,
optional: true, optional: true,
inputHeight: 225, inputHeight: 225,
requiresLyrics: true, requiresLyrics: false,
aliases: ["bridge"], aliases: [],
}, },
solo_de_guitare: { solo_de_guitare: {
label: "Solo de guitare", label: "Solo de guitare",
@@ -114,7 +94,7 @@ export const STRUCTURE_SEGMENTS = {
optional: true, optional: true,
inputHeight: 150, inputHeight: 150,
requiresLyrics: false, requiresLyrics: false,
aliases: ["guitar_solo", "solo_guitare"], aliases: [],
}, },
solo_de_guitare_electrique: { solo_de_guitare_electrique: {
label: "Solo de guitare électrique", label: "Solo de guitare électrique",
@@ -124,7 +104,7 @@ export const STRUCTURE_SEGMENTS = {
optional: true, optional: true,
inputHeight: 150, inputHeight: 150,
requiresLyrics: false, requiresLyrics: false,
aliases: ["electric_guitar_solo", "solo_guitare_electrique"], aliases: [],
}, },
solo_de_batterie: { solo_de_batterie: {
label: "Solo de batterie", label: "Solo de batterie",
@@ -134,7 +114,7 @@ export const STRUCTURE_SEGMENTS = {
optional: true, optional: true,
inputHeight: 150, inputHeight: 150,
requiresLyrics: false, requiresLyrics: false,
aliases: ["drum_solo", "solo_batterie"], aliases: [],
}, },
solo_de_saxophone: { solo_de_saxophone: {
label: "Solo de saxophone", label: "Solo de saxophone",
@@ -144,7 +124,7 @@ export const STRUCTURE_SEGMENTS = {
optional: true, optional: true,
inputHeight: 150, inputHeight: 150,
requiresLyrics: false, requiresLyrics: false,
aliases: ["sax_solo", "solo_saxo"], aliases: [],
}, },
solo_de_violon: { solo_de_violon: {
label: "Solo de violon", label: "Solo de violon",
@@ -154,7 +134,7 @@ export const STRUCTURE_SEGMENTS = {
optional: true, optional: true,
inputHeight: 150, inputHeight: 150,
requiresLyrics: false, requiresLyrics: false,
aliases: ["violin_solo", "solo_violon"], aliases: [],
}, },
break: { break: {
label: "Break", label: "Break",
@@ -184,7 +164,7 @@ export const STRUCTURE_SEGMENTS = {
optional: true, optional: true,
inputHeight: 150, inputHeight: 150,
requiresLyrics: false, requiresLyrics: false,
aliases: ["melodic_interlude"], aliases: [],
}, },
final_apogee: { final_apogee: {
label: "Final apogée", label: "Final apogée",
@@ -195,7 +175,7 @@ export const STRUCTURE_SEGMENTS = {
inputHeight: 170, inputHeight: 170,
exclusiveGroup: "outro", exclusiveGroup: "outro",
requiresLyrics: false, requiresLyrics: false,
aliases: ["grand_finale"], aliases: [],
}, },
arret_net: { arret_net: {
label: "Arrêt net", label: "Arrêt net",
@@ -206,7 +186,7 @@ export const STRUCTURE_SEGMENTS = {
inputHeight: 150, inputHeight: 150,
exclusiveGroup: "outro", exclusiveGroup: "outro",
requiresLyrics: false, requiresLyrics: false,
aliases: ["sudden_stop"], aliases: [],
}, },
fade_out: { fade_out: {
label: "Fade out", label: "Fade out",
@@ -228,7 +208,7 @@ export const STRUCTURE_SEGMENTS = {
inputHeight: 150, inputHeight: 150,
exclusiveGroup: "outro", exclusiveGroup: "outro",
requiresLyrics: false, requiresLyrics: false,
aliases: ["soft_transition"], aliases: [],
}, },
}; };
@@ -243,6 +223,32 @@ const ALIAS_TO_KEY = Object.entries(STRUCTURE_SEGMENTS).reduce(
{} {}
); );
const LEGACY_STRUCTURE_ALIASES = {
pre_chorus: "pre_refrain_instrumental",
"pré-refrain": "pre_refrain_instrumental",
"pre-refrain": "pre_refrain_instrumental",
"pre_refrain": "pre_refrain_instrumental",
prechorus: "pre_refrain_instrumental",
"pre chorus": "pre_refrain_instrumental",
"pre-chorus": "pre_refrain_instrumental",
instrumental_pre_chorus: "pre_refrain_instrumental",
bridge: "pont",
guitar_solo: "solo_de_guitare",
electric_guitar_solo: "solo_de_guitare_electrique",
drum_solo: "solo_de_batterie",
sax_solo: "solo_de_saxophone",
violin_solo: "solo_de_violon",
melodic_interlude: "interlude_melodique",
grand_finale: "final_apogee",
sudden_stop: "arret_net",
soft_transition: "transition_douce",
};
Object.entries(LEGACY_STRUCTURE_ALIASES).forEach(([alias, target]) => {
const key = String(alias).toLowerCase();
ALIAS_TO_KEY[key] = target;
});
const sanitizeToken = (value) => const sanitizeToken = (value) =>
String(value || "") String(value || "")
.trim() .trim()
@@ -281,7 +287,6 @@ export const normalizeStructureType = (value) => {
export const sanitizeStructureList = (structure = []) => { export const sanitizeStructureList = (structure = []) => {
if (!Array.isArray(structure)) return []; if (!Array.isArray(structure)) return [];
const output = []; const output = [];
let shouldInjectPreChorus = false;
let shouldInjectInstrumentalPreChorus = false; let shouldInjectInstrumentalPreChorus = false;
structure.forEach((segment) => { structure.forEach((segment) => {
@@ -306,10 +311,6 @@ export const sanitizeStructureList = (structure = []) => {
} }
} }
if (type === "pre_chorus") {
shouldInjectPreChorus = true;
return;
}
if (type === "pre_refrain_instrumental") { if (type === "pre_refrain_instrumental") {
shouldInjectInstrumentalPreChorus = true; shouldInjectInstrumentalPreChorus = true;
return; return;
@@ -320,54 +321,22 @@ export const sanitizeStructureList = (structure = []) => {
let result = output; let result = output;
if (shouldInjectPreChorus) { if (shouldInjectInstrumentalPreChorus) {
const baseWithoutPre = result.filter((item) => item !== "pre_chorus");
const hasRefrain = baseWithoutPre.some((item) => item === "refrain");
const expanded = []; const expanded = [];
let hasRefrain = false;
baseWithoutPre.forEach((item, idx) => { result.forEach((item) => {
if (item === "refrain") { if (item === "refrain") {
hasRefrain = true;
const previous = expanded[expanded.length - 1]; const previous = expanded[expanded.length - 1];
if (previous !== "pre_chorus") { if (previous !== "pre_refrain_instrumental") {
expanded.push("pre_chorus"); expanded.push("pre_refrain_instrumental");
} }
} }
expanded.push(item); expanded.push(item);
}); });
if (!hasRefrain) { if (!hasRefrain) {
expanded.push("pre_chorus");
}
result = expanded;
}
if (shouldInjectInstrumentalPreChorus) {
const baseWithoutInstrumental = result.filter(
(item) => item !== "pre_refrain_instrumental"
);
const expanded = [];
baseWithoutInstrumental.forEach((item) => {
if (item === "pre_chorus") {
const previous = expanded[expanded.length - 1];
if (previous !== "pre_refrain_instrumental") {
expanded.push("pre_refrain_instrumental");
}
}
if (item === "refrain") {
const previous = expanded[expanded.length - 1];
if (
previous !== "pre_refrain_instrumental" &&
previous !== "pre_chorus"
) {
expanded.push("pre_refrain_instrumental");
}
}
expanded.push(item);
});
if (!expanded.includes("pre_refrain_instrumental")) {
expanded.push("pre_refrain_instrumental"); expanded.push("pre_refrain_instrumental");
} }