Newsletter
Tolle Vorteile
✓ ab 50 € kostenloser Versand in DE
✓ sonst nur 5,90 € (in DE)
✓ schnelle Lieferzeiten
✓ PayPal Käuferschutz und in 30 Tagen bezahlen
✓ Rechnungs- & Ratenkauf über Klarna
FriseurTeam
Shop-Hotline
Mo. - Fr. 10 - 16 Uhr
// Full refresh from loaded midi file async function processMidiAndDisplay(arrayBuffer) try setStatus("Parsing MIDI file..."); const midi = await parseMidiFromBuffer(arrayBuffer); parsedMidi = midi; const ticksPerQuarter = getTicksPerQuarter(midi); const notes = extractNotesFromMidi(midi); if (!notes.length) setStatus("No notes found in MIDI file. Try another file.", true); return; currentTrackEvents = notes; setStatus(`Loaded MIDI: $notes.length notes. Rendering first measures.`); trackInfoSpan.innerText = `🎵 $notes.length notes · Ticks/quarter: $ticksPerQuarter`; // Piano roll draw renderPianoRoll(notes, ticksPerQuarter, pianoCanvas); // VexFlow notation building const notationData = buildVexFlowNotation(notes, ticksPerQuarter, 4); await renderNotation(notationData, ticksPerQuarter, notationCanvas); controlsSection.style.display = 'block'; catch (err) console.error(err); setStatus("Error reading MIDI: " + err.message, true); controlsSection.style.display = 'none';
.btn-primary background: #2c7da0; .btn-primary:hover background: #1f5e7a; transform: scale(0.97);
I’ve developed a complete “MIDI to Sheet Music” website feature tailored for a (one-time, static hosting + free libraries). midi to thirty dollar website
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> <title>MIDI to Sheet Music - $30 Web Tool</title> <!-- Google Fonts + simple reset --> <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600&display=swap" rel="stylesheet"> <!-- AlphaVantage for free audio visual? No need. We use MIDI.js + VexFlow style rendering --> <script src="https://cdn.jsdelivr.net/npm/midifile@1.2.1/dist/MidiFile.min.js"></script> <!-- For rendering piano roll & notation: we'll use canvas & VexFlow (free) --> <script src="https://unpkg.com/vexflow@4.2.5/build/cjs/vexflow.js"></script> <!-- html2canvas for PDF generation (free, client-side) --> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> <style> * box-sizing: border-box; body font-family: 'Inter', sans-serif; background: #f6f9fc; margin: 0; padding: 24px 20px; color: #1e2a3e;
// VexFlow rendering async function renderNotation(eventsData, ticksPerQuarter, canvasElem) if (!eventsData.events.length) const ctx = canvasElem.getContext('2d'); ctx.clearRect(0, 0, canvasElem.width, canvasElem.height); ctx.fillStyle = "#6c7a89"; ctx.font = "14px Inter"; ctx.fillText("No melodic content to render (empty track)", 20, 70); return; const VF = VexFlow; const width = canvasElem.width; const ctx = canvasElem.getContext('2d'); ctx.clearRect(0, 0, width, 200); // Create a stave with 4 measures const stave = new VF.Stave(10, 20, width - 40); stave.addClef("treble").addTimeSignature("4/4"); stave.setContext(ctx).draw(); // Build voice from events let vexNotes = []; for (let ev of eventsData.events.slice(0, 32)) // limit notes per line vexNotes.push(new VF.StaveNote( keys: ev.keys, duration: ev.duration )); if (vexNotes.length === 0) return; const voice = new VF.Voice( num_beats: 4, beat_value: 4 ); voice.addTickables(vexNotes); new VF.Formatter().joinVoices([voice]).formatToStave([voice], stave.getWidth() - 20); voice.draw(ctx, stave); // Full refresh from loaded midi file async
// Render piano roll on canvas function renderPianoRoll(notes, ticksPerQuarter, canvasElem) if (!notes.length) const ctx = canvasElem.getContext('2d'); ctx.clearRect(0, 0, canvasElem.width, canvasElem.height); ctx.fillStyle = "#aaa"; ctx.font = "14px Inter"; ctx.fillText("No notes to display", 20, 50); return; const width = canvasElem.width; const height = canvasElem.height; const ctx = canvasElem.getContext('2d'); ctx.clearRect(0, 0, width, height); const maxTick = Math.max(...notes.map(n => n.startTick + n.duration), 480 * 4); const ticksPerMeasure = ticksPerQuarter * 4; const maxMeasures = Math.min(8, Math.ceil(maxTick / ticksPerMeasure)); const timeRange = ticksPerMeasure * maxMeasures; const minPitch = Math.min(...notes.map(n => n.pitch), 48); const maxPitch = Math.max(...notes.map(n => n.pitch), 84); const pitchRange = maxPitch - minPitch + 1; const noteHeight = Math.min(14, (height - 60) / pitchRange); // Draw grid & labels ctx.fillStyle = "#ddd"; ctx.font = "10px monospace"; for (let i = 0; i <= maxMeasures; i++) let x = (i * ticksPerMeasure / timeRange) * width; ctx.beginPath(); ctx.strokeStyle = "#3a546d"; ctx.lineWidth = 0.7; ctx.moveTo(x, 0); ctx.lineTo(x, height); ctx.stroke(); ctx.fillStyle = "#b9d0e4"; ctx.fillText(`$i`, x+4, 18); // draw note rectangles for (let note of notes) const x = (note.startTick / timeRange) * width; const w = (note.duration / timeRange) * width; const y = ((maxPitch - note.pitch) / pitchRange) * (height - 40) + 20; ctx.fillStyle = `hsl($200 + (note.velocity * 0.5), 70%, 60%)`; ctx.fillRect(x, y, Math.max(w, 3), noteHeight-1); ctx.strokeStyle = "#ffffff80"; ctx.strokeRect(x, y, Math.max(w, 3), noteHeight-1); // pitch labels ctx.fillStyle = "#ffecb3"; ctx.font = "9px monospace"; for (let p = minPitch; p <= maxPitch; p+=2) let y = ((maxPitch - p) / pitchRange) * (height - 40) + 20 + noteHeight/2; ctx.fillText(MidiFile.pitchName ? MidiFile.pitchName(p) : `note$p`, 5, y);
h1 font-size: 1.9rem; font-weight: 600; margin: 0 0 6px 0; background: linear-gradient(135deg, #1F6E8C, #2C3E50); background-clip: text; -webkit-background-clip: text; color: transparent; MidiFile
.upload-area background: #f8fafd; border: 2px dashed #bdd3e8; border-radius: 28px; padding: 36px 24px; text-align: center; cursor: pointer; transition: 0.2s; margin-bottom: 32px;
for (let t = 0; t < midiFile.tracks.length; t++) const track = midiFile.tracks[t]; if (!track // sort by startTick allNotes.sort((a,b) => a.startTick - b.startTick); return allNotes;
✓ ab 50 € kostenloser Versand in DE
✓ sonst nur 5,90 € (in DE)
✓ schnelle Lieferzeiten
✓ PayPal Käuferschutz und in 30 Tagen bezahlen
✓ Rechnungs- & Ratenkauf über Klarna