Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 6,216 Bytes
6678fa1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
/**
* Auto-import test samples on startup
*
* Checks for test continuation samples in data/test_ai_continuations/
* and imports any that aren't already in the database.
* Also imports pre-analyzed results if available.
*/
import fs from "fs/promises";
import path from "path";
import * as db from "./db";
import { saveTrackFile } from "./localStorage";
const TEST_SAMPLES_DIR = path.join(process.cwd(), "data/test_ai_continuations");
const MANIFEST_FILE = path.join(TEST_SAMPLES_DIR, "manifest.json");
const RESULTS_FILE = path.join(TEST_SAMPLES_DIR, "preanalyzed_results.json");
// Demo user ID (used when no real users exist)
const DEMO_USER_ID = 1;
interface ManifestSample {
continuation_file: string;
source_title: string;
source_artist: string;
source_track_id: string;
total_duration_sec?: number;
}
interface Manifest {
samples: ManifestSample[];
}
interface ChunkMatch {
trackId: string;
title: string;
artist: string;
similarity: number;
matchType: "exact" | "style";
}
interface ChunkResult {
chunkIndex: number;
startTime: number;
endTime: number;
matches: ChunkMatch[];
}
interface PreanalyzedResult {
filename: string;
sourceTrackId: string;
sourceTitle: string;
sourceArtist: string;
duration: number;
chunks: ChunkResult[];
}
interface PreanalyzedResults {
results: PreanalyzedResult[];
}
export async function importTestSamples(): Promise<void> {
try {
// Check if test samples directory exists
try {
await fs.access(TEST_SAMPLES_DIR);
} catch {
console.log("[ImportTestSamples] No test samples directory found, skipping");
return;
}
// Check if manifest exists
try {
await fs.access(MANIFEST_FILE);
} catch {
console.log("[ImportTestSamples] No manifest.json found, skipping");
return;
}
// Load manifest
const manifestData = await fs.readFile(MANIFEST_FILE, "utf-8");
const manifest: Manifest = JSON.parse(manifestData);
if (!manifest.samples || manifest.samples.length === 0) {
console.log("[ImportTestSamples] No samples in manifest");
return;
}
// Load pre-analyzed results if available
let preanalyzed: PreanalyzedResults | null = null;
try {
const resultsData = await fs.readFile(RESULTS_FILE, "utf-8");
preanalyzed = JSON.parse(resultsData);
console.log(`[ImportTestSamples] Found ${preanalyzed?.results?.length || 0} pre-analyzed results`);
} catch {
console.log("[ImportTestSamples] No pre-analyzed results found");
}
// Create lookup map for pre-analyzed results
const resultsMap = new Map<string, PreanalyzedResult>();
if (preanalyzed?.results) {
for (const result of preanalyzed.results) {
resultsMap.set(result.filename, result);
}
}
console.log(`[ImportTestSamples] Found ${manifest.samples.length} test samples`);
// Get existing tracks to avoid duplicates
const existingTracks = await db.getUserTracks(DEMO_USER_ID);
const existingTitles = new Set(existingTracks.map(t => t.title));
let imported = 0;
let resultsImported = 0;
for (const sample of manifest.samples) {
const title = `[TEST] ${sample.source_title}`;
// Skip if already imported
if (existingTitles.has(title)) {
continue;
}
const filePath = path.join(TEST_SAMPLES_DIR, sample.continuation_file);
// Check if file exists
try {
await fs.access(filePath);
} catch {
console.log(`[ImportTestSamples] File not found: ${sample.continuation_file}`);
continue;
}
// Check if we have pre-analyzed results for this sample
const preResult = resultsMap.get(sample.continuation_file);
const hasResults = !!preResult;
// Read file
const fileData = await fs.readFile(filePath);
// Save to uploads
const { fileKey, fileUrl } = await saveTrackFile(
DEMO_USER_ID,
sample.continuation_file,
fileData
);
// Create track record
// Set to "completed" if we have pre-analyzed results, otherwise "pending"
const trackId = await db.createTrack({
userId: DEMO_USER_ID,
title,
artist: sample.source_artist,
trackType: "ai_generated",
fileKey,
fileUrl,
fileSize: fileData.length,
mimeType: "audio/wav",
duration: preResult?.duration || sample.total_duration_sec || null,
status: hasResults ? "completed" : "pending",
});
// Import pre-analyzed attribution results
if (preResult && trackId) {
for (const chunk of preResult.chunks) {
for (const match of chunk.matches) {
// Use method based on matchType for consistency with live analysis
const isExact = match.matchType === "exact";
await db.createAttributionResult({
aiTrackId: trackId,
aiStemId: null,
trainingTrackId: 0, // Not linked to DB track, just for display
trainingStemId: null,
method: isExact ? "mert_exact" : "style",
score: match.similarity,
confidence: match.similarity,
metadata: {
chunkIndex: chunk.chunkIndex,
startTime: chunk.startTime,
endTime: chunk.endTime,
matchedTrackId: match.trackId,
matchedTitle: match.title,
matchedArtist: match.artist,
method: "mert",
matchType: match.matchType,
},
});
}
}
resultsImported++;
}
imported++;
console.log(`[ImportTestSamples] Imported: ${title}${hasResults ? " (with results)" : ""}`);
}
if (imported > 0) {
console.log(`[ImportTestSamples] Imported ${imported} test samples (${resultsImported} with pre-analyzed results)`);
} else {
console.log("[ImportTestSamples] All test samples already imported");
}
} catch (error) {
console.error("[ImportTestSamples] Error:", error);
// Don't throw - this is non-critical startup task
}
}
|