daw-audio-workstation / lib /api /audio-processing-api.ts
OnyxMunk's picture
๐Ÿš€ Deploy AudioForge: AI-Powered Digital Audio Workstation
46c3324
/**
* Audio Processing API Client
* Handles communication with the FastAPI backend
*/
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
export interface StemSeparationResult {
status: string;
model: string;
format: string;
stems: Record<string, {
filename: string;
path: string;
size: number;
}>;
}
export interface MIDIExtractionResult {
status: string;
method: string;
midi_file: {
filename: string;
path: string;
size: number;
};
parameters?: Record<string, number>;
note?: string;
}
export interface AudioAnalysisResult {
status: string;
filename: string;
file_size: number;
analysis_type: string;
metadata?: {
duration?: number;
sample_rate?: number;
channels?: number;
format?: string;
subtype?: string;
};
tempo?: {
bpm: number;
confidence: number;
};
key?: {
key: string;
confidence: number;
};
chords?: any[];
}
export interface AgenticWorkflowResult {
workflow: string;
original_file: string;
steps: string[];
analysis?: AudioAnalysisResult;
stems?: StemSeparationResult;
midi?: MIDIExtractionResult;
}
export class AudioProcessingAPI {
private baseUrl: string;
constructor(baseUrl: string = API_BASE_URL) {
this.baseUrl = baseUrl;
}
/**
* Separate audio into stems
*/
async separateStems(
file: File,
options: {
model?: string;
stems?: string[];
format?: string;
} = {}
): Promise<StemSeparationResult> {
const formData = new FormData();
formData.append("file", file);
if (options.model) formData.append("model", options.model);
if (options.stems) {
options.stems.forEach(stem => formData.append("stems", stem));
}
if (options.format) formData.append("format", options.format);
const response = await fetch(`${this.baseUrl}/api/process/stem-separation`, {
method: "POST",
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || "Stem separation failed");
}
return response.json();
}
/**
* Extract MIDI from audio
*/
async extractMIDI(
file: File,
options: {
method?: string;
threshold?: number;
min_note_duration?: number;
} = {}
): Promise<MIDIExtractionResult> {
const formData = new FormData();
formData.append("file", file);
if (options.method) formData.append("method", options.method);
if (options.threshold !== undefined) {
formData.append("threshold", options.threshold.toString());
}
if (options.min_note_duration !== undefined) {
formData.append("min_note_duration", options.min_note_duration.toString());
}
const response = await fetch(`${this.baseUrl}/api/process/midi-extraction`, {
method: "POST",
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || "MIDI extraction failed");
}
return response.json();
}
/**
* Analyze audio file
*/
async analyzeAudio(
file: File,
analysisType: string = "full"
): Promise<AudioAnalysisResult> {
const formData = new FormData();
formData.append("file", file);
formData.append("analysis_type", analysisType);
const response = await fetch(`${this.baseUrl}/api/process/analyze`, {
method: "POST",
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || "Audio analysis failed");
}
return response.json();
}
/**
* Run complete agentic workflow
*/
async runAgenticWorkflow(
file: File,
workflow: string = "full-production",
options?: Record<string, any>
): Promise<AgenticWorkflowResult> {
const formData = new FormData();
formData.append("file", file);
formData.append("workflow", workflow);
if (options) {
formData.append("options", JSON.stringify(options));
}
const response = await fetch(`${this.baseUrl}/api/process/agentic-workflow`, {
method: "POST",
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || "Workflow execution failed");
}
return response.json();
}
/**
* Get file from server
*/
getFileUrl(path: string): string {
return `${this.baseUrl}/api/files/${path}`;
}
/**
* Download file as blob
*/
async downloadFile(path: string): Promise<Blob> {
const response = await fetch(`${this.baseUrl}/api/files/${path}`);
if (!response.ok) {
throw new Error("File download failed");
}
return response.blob();
}
/**
* Delete file from server
*/
async deleteFile(path: string): Promise<void> {
const response = await fetch(`${this.baseUrl}/api/files/${path}`, {
method: "DELETE",
});
if (!response.ok) {
throw new Error("File deletion failed");
}
}
/**
* Health check
*/
async healthCheck(): Promise<{ status: string }> {
const response = await fetch(`${this.baseUrl}/health`);
if (!response.ok) {
throw new Error("API health check failed");
}
return response.json();
}
}
export const audioProcessingAPI = new AudioProcessingAPI();