Je cherche un logiciel de type snapshot pour lancer sur scène des réglages sur différents synthés.
- 2 réponses
- 2 participants
- 190 vues
- 3 followers
rouldug
248
Posteur·euse AFfiné·e
Membre depuis 20 ans
Sujet de la discussion Posté le 17/10/2025 à 19:22:47Je cherche un logiciel de type snapshot pour lancer sur scène des réglages sur différents synthés.
Bonjour à tous, ami(e) du midi.
J'ai un vieux stock de synthés hardware que je viens de finir de restaurer et que je voudrais utiliser en temps réel sans passer par une logiciel type DAW ou séquencer car je cherche uniquement à programmer des codes sysex ou programs changes par canal/port midi en passant par deux multiports midi 4x4.
L'idéal serait de pouvoir sauvegarder ensuite ces réglages sous format sysex de manière à les réutiliser ensuite dans un de mes DAW (Reaper ou Cakewalk).
Quelqu'un(e) aurait une idée de logiciel PC éditeur capable de faire le job ?
S'il pouvait dans la foulée "patcher" les entrées / sorties des ports et envoyer des sysex genre MidiOX, ce serait top.
Merci d'avance.
PS : je dispose du logiciel SoundQuest (éditeur de synthé), il ne marche pas bien. Les fichiers sysex qu'il édite ne fonctionnent pas et il ne travaille pas en multiport.
J'ai un vieux stock de synthés hardware que je viens de finir de restaurer et que je voudrais utiliser en temps réel sans passer par une logiciel type DAW ou séquencer car je cherche uniquement à programmer des codes sysex ou programs changes par canal/port midi en passant par deux multiports midi 4x4.
L'idéal serait de pouvoir sauvegarder ensuite ces réglages sous format sysex de manière à les réutiliser ensuite dans un de mes DAW (Reaper ou Cakewalk).
Quelqu'un(e) aurait une idée de logiciel PC éditeur capable de faire le job ?
S'il pouvait dans la foulée "patcher" les entrées / sorties des ports et envoyer des sysex genre MidiOX, ce serait top.
Merci d'avance.
PS : je dispose du logiciel SoundQuest (éditeur de synthé), il ne marche pas bien. Les fichiers sysex qu'il édite ne fonctionnent pas et il ne travaille pas en multiport.
[ Dernière édition du message le 19/10/2025 à 04:42:54 ]
rouldug
248
Posteur·euse AFfiné·e
Membre depuis 20 ans
2 Posté le 23/01/2026 à 16:45:09
+1000
0
Mini-Maxi
338
Posteur·euse AFfamé·e
Membre depuis 1 an
3 Posté le 24/01/2026 à 02:40:03
Quelque chose dans cet esprit?

Un MIDI manager qui permet d'envoyer des Program Change.
C'est une page html qu'on ouvre avec Chrome, ça fonctionne chez moi.
Pour les explications de comment j'ai "fabriqué" ça, c'est ici:
https://fr.audiofanzine.com/mao/forums/t.832343,ia-google-gemini-generer-un-instrument-virtuel-en-30secondes.html
C'est donc une page html à exécuter en local (pas besoin de connexion internet), il faut autoriser Chrome à se connecter aux ports MIDI. Je suis sur mac et ça fonctionne, à voir comment ça se comporte sur pc, il y a sûrement des autorisations à configurer.
Pour l'utiliser, il suffit de copier/coller le code qui suit dans un fichier .txt
Puis sauver et renommer le "fichier.txt" en "fichier.html".
Cliquer dessus pour l'ouvrir avec le navigateur. Chrome, Edge ou Opera sont conseillés.
On peut choisir parmi 50 scènes, l'appli détecte automatiquement les ports MIDI et offre la possibilité d'envoyer un Program Change pour chacun des 16canaux.
Le bouton "Sauvegarder" permet de sauver la configuration de l'intégralité des scènes. Le fichier est placé dans le dossier de téléchargement.
C'est un peu limité, ça ne fait pas de sysex mais ça peut être utile.

Un MIDI manager qui permet d'envoyer des Program Change.
C'est une page html qu'on ouvre avec Chrome, ça fonctionne chez moi.
Pour les explications de comment j'ai "fabriqué" ça, c'est ici:
https://fr.audiofanzine.com/mao/forums/t.832343,ia-google-gemini-generer-un-instrument-virtuel-en-30secondes.html
C'est donc une page html à exécuter en local (pas besoin de connexion internet), il faut autoriser Chrome à se connecter aux ports MIDI. Je suis sur mac et ça fonctionne, à voir comment ça se comporte sur pc, il y a sûrement des autorisations à configurer.
Pour l'utiliser, il suffit de copier/coller le code qui suit dans un fichier .txt
Spoiler - Cliquer ici pour lire la suite
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Expert MIDI Scene Manager</title>
<script src="[url]https://cdn.tailwindcss.com"></script>[/url]
<style>
.scene-grid {
display: grid;
grid-template-columns: repeat(10, 1fr);
gap: 4px;
}
@media (max-width: 640px) {
.scene-grid { grid-template-columns: repeat(5, 1fr); }
}
.active-scene {
background-color: #3b82f6 !important;
color: white;
border-color: #2563eb;
}
.custom-scroll::-webkit-scrollbar {
width: 8px;
}
.custom-scroll::-webkit-scrollbar-track {
background: #f1f1f1;
}
.custom-scroll::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
</style>
</head>
<body class="bg-gray-900 text-gray-100 min-h-screen p-4 font-sans">
<div class="max-w-6xl mx-auto bg-gray-800 rounded-xl shadow-2xl border border-gray-700 overflow-hidden">
<!-- Header Section -->
<div class="p-6 border-b border-gray-700 bg-gray-850">
<h1 class="text-2xl font-bold text-blue-400 mb-4 flex items-center gap-2">
<svg xmlns="[url]https://www.w3.org/2000/svg"[/url] class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3" />
</svg>
Mini-MIDI-Maxi Program Change Manager
</h1>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-400 mb-2">Sélection de la Scène. (Cliquer pour charger la scène et envoyer les Program Change correspondants). </label>
<div id="sceneSelector" class="scene-grid">
<!-- Scenes 1-50 generated by JS -->
</div>
</div>
<div class="flex flex-wrap gap-4 items-center justify-between">
<div class="flex gap-2">
<button id="saveBtn" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded font-semibold transition-colors flex items-center gap-2">
<span>Sauvegarder</span>
</button>
<label class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded font-semibold transition-colors cursor-pointer flex items-center gap-2">
<span>Charger</span>
<input type="file" id="loadInput" class="hidden" accept=".json">
</label>
</div>
<button id="allNotesOffBtn" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded font-semibold transition-colors">
ALL NOTES OFF
</button>
</div>
</div>
<!-- MIDI Devices Section -->
<div id="midiContainer" class="p-6 overflow-x-auto custom-scroll">
<div id="noMidiMsg" class="text-center py-10 text-gray-500">
<p>Initialisation du système MIDI...</p>
<p class="text-sm mt-2">Veuillez autoriser l'accès MIDI dans votre navigateur.</p>
</div>
<div id="deviceList" class="space-y-8 hidden">
<!-- Device blocks generated by JS -->
</div>
</div>
<div class="p-4 bg-gray-900 border-t border-gray-700 text-xs text-gray-500 flex justify-between">
<span id="midiStatus">Statut : Déconnecté</span>
<span>Expert Mode - v1.1 (Affichage 1-128)</span>
</div>
</div>
<script>
/**
* MIDI Scene Manager Logic
* Architecture:
* - state.data: Map { sceneIndex: { outputId: { channel: programValue } } }
* - Program Change value: -1 for 'Off', 0-127 for PC (Internal).
* - Display value: value + 1 (1-128).
*/
const STATE = {
currentScene: 1,
maxScenes: 50,
devices: [], // Array of MIDIOutput
data: {} // Storage for PC settings
};
const sceneSelector = document.getElementById('sceneSelector');
const deviceList = document.getElementById('deviceList');
const noMidiMsg = document.getElementById('noMidiMsg');
const midiStatus = document.getElementById('midiStatus');
const allNotesOffBtn = document.getElementById('allNotesOffBtn');
const saveBtn = document.getElementById('saveBtn');
const loadInput = document.getElementById('loadInput');
// --- Initialization ---
async function initMIDI() {
try {
const access = await navigator.requestMIDIAccess();
access.onstatechange = () => updateDevices(access);
updateDevices(access);
midiStatus.textContent = "Statut : MIDI Opérationnel";
midiStatus.classList.add('text-green-500');
} catch (err) {
noMidiMsg.innerHTML = `<span class="text-red-500 italic font-bold">Erreur : Web MIDI non supporté ou refusé.</span>`;
console.error(err);
}
}
function updateDevices(access) {
STATE.devices = Array.from(access.outputs.values()).sort((a, b) => a.name.localeCompare(b.name));
if (STATE.devices.length > 0) {
noMidiMsg.classList.add('hidden');
deviceList.classList.remove('hidden');
renderDevices();
} else {
noMidiMsg.classList.remove('hidden');
deviceList.classList.add('hidden');
}
}
function initScenes() {
for (let i = 1; i <= STATE.maxScenes; i++) {
const btn = document.createElement('button');
btn.textContent = i;
btn.className = "border border-gray-600 bg-gray-700 py-2 text-sm font-medium hover:bg-gray-600 transition-colors";
btn.onclick = () => selectScene(i);
btn.id = `scene-btn-${i}`;
sceneSelector.appendChild(btn);
// Init empty data for this scene
STATE.data[i] = {};
}
selectScene(1);
}
// --- Core Logic ---
function selectScene(index) {
// Update UI
document.querySelectorAll('#sceneSelector button').forEach(b => b.classList.remove('active-scene'));
document.getElementById(`scene-btn-${index}`).classList.add('active-scene');
STATE.currentScene = index;
renderDevices(); // Refresh inputs with scene data
// Trigger MIDI transmission for the selected scene
sendCurrentSceneMIDI();
}
function renderDevices() {
deviceList.innerHTML = '';
STATE.devices.forEach(device => {
const card = document.createElement('div');
card.className = "bg-gray-750 border border-gray-700 rounded-lg p-4 bg-opacity-50";
const title = document.createElement('h3');
title.className = "text-lg font-semibold text-blue-300 mb-4 border-b border-gray-700 pb-2 flex justify-between";
title.innerHTML = `<span>${device.name}</span> <span class="text-xs text-gray-500 font-normal">ID: ${device.id}</span>`;
card.appendChild(title);
const grid = document.createElement('div');
grid.className = "grid grid-cols-2 sm:grid-cols-4 md:grid-cols-8 gap-3";
// 16 Channels
for (let ch = 1; ch <= 16; ch++) {
const chBox = document.createElement('div');
chBox.className = "flex flex-col gap-1";
const label = document.createElement('label');
label.className = "text-[10px] uppercase text-gray-500 font-bold";
label.textContent = `CH ${ch}`;
const select = document.createElement('select');
select.className = "bg-gray-900 border border-gray-600 text-white text-xs rounded p-1 outline-none focus:border-blue-500";
// Option Off
const offOpt = document.createElement('option');
offOpt.value = "-1";
offOpt.textContent = "Off";
select.appendChild(offOpt);
// Options 0-127 (Internal) displayed as 1-128
for (let pc = 0; pc <= 127; pc++) {
const opt = document.createElement('option');
opt.value = pc;
opt.textContent = pc + 1; // User-friendly display (1-128)
select.appendChild(opt);
}
// Set value from State
const currentVal = (STATE.data[STATE.currentScene][device.id] || {})[ch] ?? -1;
select.value = currentVal;
// Event: Change
select.onchange = (e) => {
const val = parseInt(e.target.value);
updateState(device.id, ch, val);
// Immediate send if we just changed something on active scene
sendSinglePC(device.id, ch, val);
};
chBox.appendChild(label);
chBox.appendChild(select);
grid.appendChild(chBox);
}
card.appendChild(grid);
deviceList.appendChild(card);
});
}
function updateState(deviceId, channel, value) {
if (!STATE.data[STATE.currentScene][deviceid]) {
STATE.data[STATE.currentScene][deviceid] = {};
}
STATE.data[STATE.currentScene][deviceid][channel] = value;
}
// --- MIDI Transmission ---
function sendSinglePC(deviceId, channel, value) {
if (value === -1) return;
const device = STATE.devices.find(d => d.id === deviceId);
if (!device) return;
// MIDI PC: 0xC0 | (channel - 1), Value (0-127)
const status = 0xC0 | (channel - 1);
device.send([status, value]);
}
function sendCurrentSceneMIDI() {
const sceneData = STATE.data[STATE.currentScene];
STATE.devices.forEach(device => {
const deviceConfig = sceneData[device.id];
if (deviceConfig) {
for (let ch = 1; ch <= 16; ch++) {
if (deviceConfig[ch] !== undefined && deviceConfig[ch] !== -1) {
sendSinglePC(device.id, ch, deviceConfig[ch]);
}
}
}
});
}
allNotesOffBtn.onclick = () => {
STATE.devices.forEach(device => {
for (let ch = 0; ch < 16; ch++) {
// CC 123 (All Notes Off) et CC 120 (All Sound Off)
device.send([0xb0 | ch, 123, 0]);
device.send([0xb0 | ch, 120, 0]);
}
});
// Notification visuelle rapide
allNotesOffBtn.classList.remove('bg-red-600');
allNotesOffBtn.classList.add('bg-white', 'text-black');
setTimeout(() => {
allNotesOffBtn.classList.add('bg-red-600');
allNotesOffBtn.classList.remove('bg-white', 'text-black');
}, 200);
};
// --- Save / Load ---
saveBtn.onclick = () => {
const blob = new Blob([JSON.stringify(STATE.data, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `midi_scenes_backup_${new Date().toISOString().slice(0,10)}.json`;
a.click();
URL.revokeObjectURL(url);
};
loadInput.onchange = (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (event) => {
try {
const imported = JSON.parse(event.target.result);
STATE.data = imported;
selectScene(STATE.currentScene);
alert("Configuration chargée avec succès.");
} catch (err) {
alert("Erreur lors de la lecture du fichier.");
}
};
reader.readAsText(file);
};
// Initial Start
window.onload = () => {
initScenes();
initMIDI();
};
</script>
</body>
</html>
Puis sauver et renommer le "fichier.txt" en "fichier.html".
Cliquer dessus pour l'ouvrir avec le navigateur. Chrome, Edge ou Opera sont conseillés.
On peut choisir parmi 50 scènes, l'appli détecte automatiquement les ports MIDI et offre la possibilité d'envoyer un Program Change pour chacun des 16canaux.
Le bouton "Sauvegarder" permet de sauver la configuration de l'intégralité des scènes. Le fichier est placé dans le dossier de téléchargement.
C'est un peu limité, ça ne fait pas de sysex mais ça peut être utile.
0
[ Dernière édition du message le 24/01/2026 à 14:24:45 ]
- < Liste des sujets
- Charte