Implement complete search results + dual player UI
Backend Enhancements: - Add ParsedMIDIInfo with track analysis and quality issues - New /api/midi/parse endpoint for MIDI metadata extraction - Enhanced MIDIService with parseMIDI method MIDI Preview Player: - Complete MIDIPlayer class with polyphonic playback - Basic oscillator mapping (bass=square, mid=triangle, high=sine) - Lookahead scheduling with proper cleanup - Automatic stopping when MIDI ends New UI Flow: 1. Search → Results table with metadata 2. Select MIDI → Shows parsed info (duration, tracks, tempo) 3. Dual transport: Preview Original vs Generate Motif 4. Try Next Result button for easy A/B testing Search Results Table: - Title, source, confidence bar, duration, track count - Quality issues display (short duration, few notes, etc.) - Auto-select best result, manual selection available - Visual confidence bars and issue warnings This makes the project feel "real" - you can now: - See exactly what MIDI was found - Verify it's the right song via preview - Compare original vs procedural synthesis - Easily try different results 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import express from 'express';
|
||||
import cors from 'cors';
|
||||
import { MIDISearchService } from './services/MIDISearchService.js';
|
||||
import { MIDIFetchService } from './services/MIDIFetchService.js';
|
||||
import { MIDIParseService } from './services/MIDIParseService.js';
|
||||
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3001;
|
||||
@@ -11,6 +12,7 @@ app.use(express.json());
|
||||
|
||||
const searchService = new MIDISearchService();
|
||||
const fetchService = new MIDIFetchService();
|
||||
const parseService = new MIDIParseService();
|
||||
|
||||
// Search for MIDI files
|
||||
app.get('/api/midi/search', async (req, res) => {
|
||||
@@ -53,6 +55,29 @@ app.get('/api/midi/fetch', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Parse MIDI metadata
|
||||
app.get('/api/midi/parse', async (req, res) => {
|
||||
try {
|
||||
const url = req.query.u as string;
|
||||
if (!url) {
|
||||
return res.status(400).json({ error: 'URL parameter "u" is required' });
|
||||
}
|
||||
|
||||
console.log(`Parsing MIDI metadata: ${url}`);
|
||||
const result = await fetchService.fetch(url);
|
||||
|
||||
if (result.success && result.data) {
|
||||
const metadata = parseService.parseMIDI(result.data);
|
||||
res.json(metadata);
|
||||
} else {
|
||||
res.status(404).json({ error: result.error || 'Failed to fetch MIDI' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Parse error:', error);
|
||||
res.status(500).json({ error: 'Parse failed' });
|
||||
}
|
||||
});
|
||||
|
||||
// Health check
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||
|
||||
Reference in New Issue
Block a user