File size: 5,204 Bytes
46c3324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client";

import { useState } from "react";
import { FileAudio, X, Music } from "lucide-react";
import { AudioUpload } from "./AudioUpload";
import { StemSeparationPanel } from "./StemSeparationPanel";
import { MIDIExtractionPanel } from "./MIDIExtractionPanel";
import { AgenticWorkflowPanel } from "./AgenticWorkflowPanel";
import { MusicGenerator } from "./MusicGenerator";
import { useAudioStore } from "@/store/audio-store";

export function AudioProcessingPanel() {
  const loadGeneratedMIDI = useAudioStore((state) => state.loadGeneratedMIDI);
  const [uploadedFile, setUploadedFile] = useState<File | null>(null);
  const [activeTab, setActiveTab] = useState<"upload" | "workflow" | "stems" | "midi" | "music">(
    "upload"
  );

  const handleFileUploaded = (file: File, audioBuffer: AudioBuffer) => {
    setUploadedFile(file);
    setActiveTab("workflow"); // Switch to workflow tab after upload
  };

  const tabs = [
    { id: "upload" as const, label: "Upload", icon: FileAudio },
    { id: "workflow" as const, label: "Workflow", icon: FileAudio },
    { id: "stems" as const, label: "Stems", icon: FileAudio },
    { id: "midi" as const, label: "MIDI", icon: FileAudio },
    { id: "music" as const, label: "Generate", icon: Music },
  ];

  return (
    <div className="w-full h-full flex flex-col bg-gray-950">
      {/* Tab Navigation */}
      <div className="flex border-b border-gray-800">
        {tabs.map((tab) => {
          const Icon = tab.icon;
          return (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`
                flex items-center gap-2 px-4 py-3 text-sm font-medium transition-colors
                ${
                  activeTab === tab.id
                    ? "text-blue-500 border-b-2 border-blue-500"
                    : "text-gray-400 hover:text-gray-300"
                }
              `}
            >
              <Icon className="w-4 h-4" />
              {tab.label}
            </button>
          );
        })}
      </div>

      {/* Content */}
      <div className="flex-1 overflow-y-auto p-4">
        {activeTab === "upload" && (
          <div className="space-y-4">
            <div className="flex items-center justify-between">
              <h2 className="text-xl font-semibold text-white">Audio Upload</h2>
              {uploadedFile && (
                <button
                  onClick={() => setUploadedFile(null)}
                  className="text-gray-400 hover:text-white"
                >
                  <X className="w-5 h-5" />
                </button>
              )}
            </div>
            <AudioUpload
              onFileUploaded={handleFileUploaded}
              maxSize={200}
            />
            {uploadedFile && (
              <div className="bg-gray-900 rounded-lg p-4">
                <p className="text-sm text-gray-400">Uploaded:</p>
                <p className="text-white font-medium">{uploadedFile.name}</p>
                <p className="text-xs text-gray-500 mt-1">
                  {(uploadedFile.size / (1024 * 1024)).toFixed(2)} MB
                </p>
              </div>
            )}
          </div>
        )}

        {activeTab === "workflow" && (
          <div className="space-y-4">
            <h2 className="text-xl font-semibold text-white">Agentic Workflow</h2>
            <AgenticWorkflowPanel
              audioFile={uploadedFile}
              onWorkflowComplete={(result) => {
                console.log("Workflow complete:", result);
              }}
            />
          </div>
        )}

        {activeTab === "stems" && (
          <div className="space-y-4">
            <h2 className="text-xl font-semibold text-white">Stem Separation</h2>
            <StemSeparationPanel
              audioFile={uploadedFile}
              onStemsSeparated={(result) => {
                console.log("Stems separated:", result);
              }}
            />
          </div>
        )}

        {activeTab === "midi" && (
          <div className="space-y-4">
            <h2 className="text-xl font-semibold text-white">MIDI Extraction</h2>
            <MIDIExtractionPanel
              audioFile={uploadedFile}
              onMIDIExtracted={(result) => {
                console.log("MIDI extracted:", result);
              }}
            />
          </div>
        )}

        {activeTab === "music" && (
          <div className="space-y-4">
            <h2 className="text-xl font-semibold text-white">AI Music Generation</h2>
            <MusicGenerator
              onTrackGenerated={async (midiFile, audioFile) => {
                console.log("Music generated:", { midiFile, audioFile });

                try {
                  if (midiFile) {
                    const trackId = await loadGeneratedMIDI(midiFile, "AI Generated Music");
                    console.log("Added generated MIDI to track:", trackId);
                  }
                } catch (error) {
                  console.error("Failed to load generated MIDI:", error);
                }
              }}
            />
          </div>
        )}
      </div>
    </div>
  );
}