Hezu06 commited on
Commit
0bb4712
·
verified ·
1 Parent(s): 43ce48c

Upload 41 files

Browse files
Files changed (42) hide show
  1. .gitattributes +18 -0
  2. Dockerfile +24 -0
  3. bio_vibe_backend/__pycache__/main.cpython-311.pyc +0 -0
  4. bio_vibe_backend/__pycache__/main.cpython-313.pyc +0 -0
  5. bio_vibe_backend/biovibe_brain.pth +3 -0
  6. bio_vibe_backend/index.html +219 -0
  7. bio_vibe_backend/main.py +164 -0
  8. bio_vibe_backend/mapping_dict.pkl +3 -0
  9. bio_vibe_backend/music/ai_vibe_101.mid +0 -0
  10. bio_vibe_backend/music/ai_vibe_101.wav +3 -0
  11. bio_vibe_backend/music/ai_vibe_107.mid +0 -0
  12. bio_vibe_backend/music/ai_vibe_107.wav +3 -0
  13. bio_vibe_backend/music/ai_vibe_115.mid +0 -0
  14. bio_vibe_backend/music/ai_vibe_115.wav +3 -0
  15. bio_vibe_backend/music/ai_vibe_75.mid +0 -0
  16. bio_vibe_backend/music/ai_vibe_75.wav +3 -0
  17. bio_vibe_backend/music/ai_vibe_76.mid +0 -0
  18. bio_vibe_backend/music/ai_vibe_76.wav +3 -0
  19. bio_vibe_backend/music/ai_vibe_77.mid +0 -0
  20. bio_vibe_backend/music/ai_vibe_77.wav +3 -0
  21. bio_vibe_backend/music/ai_vibe_79.mid +0 -0
  22. bio_vibe_backend/music/ai_vibe_79.wav +3 -0
  23. bio_vibe_backend/music/ai_vibe_80.mid +0 -0
  24. bio_vibe_backend/music/ai_vibe_80.wav +3 -0
  25. bio_vibe_backend/music/ai_vibe_82.mid +0 -0
  26. bio_vibe_backend/music/ai_vibe_82.wav +3 -0
  27. bio_vibe_backend/music/ai_vibe_84.mid +0 -0
  28. bio_vibe_backend/music/ai_vibe_86.mid +0 -0
  29. bio_vibe_backend/music/ai_vibe_86.wav +3 -0
  30. bio_vibe_backend/music/ai_vibe_89.mid +0 -0
  31. bio_vibe_backend/music/ai_vibe_89.wav +3 -0
  32. bio_vibe_backend/music/ai_vibe_90.mid +0 -0
  33. bio_vibe_backend/music/ai_vibe_90.wav +3 -0
  34. bio_vibe_backend/music/ai_vibe_92.mid +0 -0
  35. bio_vibe_backend/music/ai_vibe_92.wav +3 -0
  36. bio_vibe_backend/notes_corpus.pkl +3 -0
  37. bio_vibe_backend/soundfonts/Piano.SF2 +3 -0
  38. bio_vibe_backend/stems/pad_ambient.wav +3 -0
  39. bio_vibe_backend/stems/piano.wav +3 -0
  40. bio_vibe_backend/stems/rain.wav +3 -0
  41. bio_vibe_backend/stems/violin.wav +3 -0
  42. requirements.txt +6 -0
.gitattributes CHANGED
@@ -33,3 +33,21 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ bio_vibe_backend/music/ai_vibe_101.wav filter=lfs diff=lfs merge=lfs -text
37
+ bio_vibe_backend/music/ai_vibe_107.wav filter=lfs diff=lfs merge=lfs -text
38
+ bio_vibe_backend/music/ai_vibe_115.wav filter=lfs diff=lfs merge=lfs -text
39
+ bio_vibe_backend/music/ai_vibe_75.wav filter=lfs diff=lfs merge=lfs -text
40
+ bio_vibe_backend/music/ai_vibe_76.wav filter=lfs diff=lfs merge=lfs -text
41
+ bio_vibe_backend/music/ai_vibe_77.wav filter=lfs diff=lfs merge=lfs -text
42
+ bio_vibe_backend/music/ai_vibe_79.wav filter=lfs diff=lfs merge=lfs -text
43
+ bio_vibe_backend/music/ai_vibe_80.wav filter=lfs diff=lfs merge=lfs -text
44
+ bio_vibe_backend/music/ai_vibe_82.wav filter=lfs diff=lfs merge=lfs -text
45
+ bio_vibe_backend/music/ai_vibe_86.wav filter=lfs diff=lfs merge=lfs -text
46
+ bio_vibe_backend/music/ai_vibe_89.wav filter=lfs diff=lfs merge=lfs -text
47
+ bio_vibe_backend/music/ai_vibe_90.wav filter=lfs diff=lfs merge=lfs -text
48
+ bio_vibe_backend/music/ai_vibe_92.wav filter=lfs diff=lfs merge=lfs -text
49
+ bio_vibe_backend/soundfonts/Piano.SF2 filter=lfs diff=lfs merge=lfs -text
50
+ bio_vibe_backend/stems/pad_ambient.wav filter=lfs diff=lfs merge=lfs -text
51
+ bio_vibe_backend/stems/piano.wav filter=lfs diff=lfs merge=lfs -text
52
+ bio_vibe_backend/stems/rain.wav filter=lfs diff=lfs merge=lfs -text
53
+ bio_vibe_backend/stems/violin.wav filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 1. Chọn hệ điều hành gốc là Linux với Python 3.10
2
+ FROM python:3.10-slim
3
+
4
+ # 2. Cài đặt "nhạc công" FluidSynth sâu vào hệ điều hành
5
+ RUN apt-get update && apt-get install -y \
6
+ fluidsynth \
7
+ && rm -rf /var/lib/apt/lists/*
8
+
9
+ # 3. Tạo không gian làm việc
10
+ WORKDIR /app
11
+
12
+ # 4. Copy file danh sách thư viện và cài đặt
13
+ COPY requirements.txt .
14
+ # Cài đặt PyTorch bản CPU để tiết kiệm dung lượng và tránh lỗi
15
+ RUN pip install --no-cache-dir -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu
16
+
17
+ # 5. Bê toàn bộ code của bạn bỏ vào container
18
+ COPY . .
19
+
20
+ # 6. Mở cửa số 7860 (Hugging Face bắt buộc dùng port này)
21
+ EXPOSE 7860
22
+
23
+ # 7. Ra lệnh bật server FastAPI khi hệ thống chạy
24
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
bio_vibe_backend/__pycache__/main.cpython-311.pyc ADDED
Binary file (8.92 kB). View file
 
bio_vibe_backend/__pycache__/main.cpython-313.pyc ADDED
Binary file (7.6 kB). View file
 
bio_vibe_backend/biovibe_brain.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c7ca670b7a2de2c65271cf0d021381f1ecfd4f894292c818257a1f7edc0a7a46
3
+ size 15971033
bio_vibe_backend/index.html ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="vi">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Bio-Vibe Web</title>
7
+ <link rel="icon" href="data:,">
8
+ <style>
9
+ body {
10
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
11
+ background-color: #1a1a2e;
12
+ color: #e94560;
13
+ display: flex;
14
+ flex-direction: column;
15
+ align-items: center;
16
+ justify-content: center;
17
+ height: 100vh;
18
+ margin: 0;
19
+ }
20
+ .container {
21
+ background-color: #16213e;
22
+ padding: 40px;
23
+ border-radius: 15px;
24
+ text-align: center;
25
+ box-shadow: 0 10px 30px rgba(0,0,0,0.5);
26
+ }
27
+ h1 { color: #fff; margin-bottom: 5px; }
28
+ p { color: #a2a2bd; margin-bottom: 30px; }
29
+
30
+ #bpm-display {
31
+ font-size: 80px;
32
+ font-weight: bold;
33
+ margin: 20px 0;
34
+ text-shadow: 0 0 15px #e94560;
35
+ transition: color 0.3s ease;
36
+ }
37
+
38
+ @keyframes pulse {
39
+ 0% { transform: scale(1); opacity: 1; }
40
+ 50% { transform: scale(1.05); opacity: 0.8; }
41
+ 100% { transform: scale(1); opacity: 1; }
42
+ }
43
+
44
+ .button-group {
45
+ display: flex;
46
+ justify-content: center;
47
+ flex-wrap: wrap;
48
+ gap: 15px;
49
+ max-width: 600px;
50
+ }
51
+
52
+ button {
53
+ background-color: #0f3460;
54
+ color: white;
55
+ border: none;
56
+ padding: 15px 25px;
57
+ font-size: 16px;
58
+ border-radius: 8px;
59
+ cursor: pointer;
60
+ transition: 0.3s;
61
+ font-weight: bold;
62
+ }
63
+ button:hover { background-color: #4ecca3; color: #1a1a2e; }
64
+ button:disabled { background-color: #333; cursor: not-allowed; color: #777; }
65
+
66
+ /* CSS riêng cho nút Dừng nhạc */
67
+ #btn-stop { background-color: #8b0000; }
68
+ #btn-stop:hover { background-color: #ff4d4d; color: white; }
69
+ #btn-stop:disabled { background-color: #333; }
70
+
71
+ #status { margin-top: 20px; color: #4ecca3; font-style: italic; font-size: 14px;}
72
+ </style>
73
+ </head>
74
+ <body>
75
+
76
+ <div class="container">
77
+ <h1>Bio-Vibe 🎧</h1>
78
+ <p>Âm nhạc trị liệu AI theo Nhịp tim</p>
79
+
80
+ <div id="bpm-display">-- BPM</div>
81
+
82
+ <div class="button-group">
83
+ <button id="btn-connect">1. Bắt tay Đồng hồ</button>
84
+ <button id="btn-generate">2. Sinh nhạc AI</button>
85
+ <button id="btn-stop" disabled>3. Dừng nhạc</button>
86
+ </div>
87
+
88
+ <div id="status">Chưa kết nối... Mở nRF Connect trên điện thoại để chuẩn bị!</div>
89
+ </div>
90
+
91
+ <script>
92
+ let currentBpm = 0;
93
+ let currentAudio = null; // Biến toàn cục để quản lý file âm thanh
94
+
95
+ const bpmDisplay = document.getElementById('bpm-display');
96
+ const statusText = document.getElementById('status');
97
+ const btnConnect = document.getElementById('btn-connect');
98
+ const btnGenerate = document.getElementById('btn-generate');
99
+ const btnStop = document.getElementById('btn-stop');
100
+
101
+ // ==========================================
102
+ // 1. BLUETOOTH LOGIC
103
+ // ==========================================
104
+ btnConnect.addEventListener('click', async () => {
105
+ try {
106
+ statusText.innerText = "Đang mở máy quét Bluetooth...";
107
+ const device = await navigator.bluetooth.requestDevice({
108
+ acceptAllDevices: true,
109
+ optionalServices: ['heart_rate']
110
+ });
111
+
112
+ statusText.innerText = `Đã chọn: ${device.name}. Đang kết nối...`;
113
+ const server = await device.gatt.connect();
114
+ const service = await server.getPrimaryService('heart_rate');
115
+ const characteristic = await service.getCharacteristic('heart_rate_measurement');
116
+
117
+ await characteristic.startNotifications();
118
+ characteristic.addEventListener('characteristicvaluechanged', handleHeartRateData);
119
+
120
+ statusText.innerText = "Kết nối thành công! Đang đợi nhịp tim truyền lên...";
121
+ btnConnect.innerText = "✓ Đã kết nối Bluetooth";
122
+ btnConnect.style.backgroundColor = "#4ecca3";
123
+ btnConnect.style.color = "#1a1a2e";
124
+ } catch (error) {
125
+ console.error("Bluetooth Error:", error);
126
+ statusText.innerText = "Hủy kết nối hoặc lỗi thiết bị!";
127
+ statusText.style.color = "#ff4d4d";
128
+ }
129
+ });
130
+
131
+ function handleHeartRateData(event) {
132
+ const value = event.target.value;
133
+ const flags = value.getUint8(0);
134
+
135
+ if ((flags & 0x01) === 0) {
136
+ currentBpm = value.getUint8(1);
137
+ } else {
138
+ currentBpm = value.getUint16(1, true);
139
+ }
140
+
141
+ bpmDisplay.innerText = `${currentBpm} BPM`;
142
+ bpmDisplay.style.color = "#e94560";
143
+ statusText.innerText = "Đang đọc nhịp tim thành công. Sẵn sàng tạo nhạc!";
144
+ statusText.style.color = "#4ecca3";
145
+ }
146
+
147
+ // ==========================================
148
+ // 2. TẠO VÀ PHÁT NHẠC
149
+ // ==========================================
150
+ btnGenerate.addEventListener('click', async () => {
151
+ if (currentBpm === 0) {
152
+ alert("Bạn chưa kết nối Bluetooth hoặc chưa gửi số nhịp tim từ nRF Connect!");
153
+ return;
154
+ }
155
+
156
+ // TÍNH NĂNG MỚI: Tắt ngay bài nhạc cũ (nếu có) trước khi tạo bài mới
157
+ if (currentAudio) {
158
+ currentAudio.pause();
159
+ currentAudio.currentTime = 0; // Tua lại từ đầu
160
+ bpmDisplay.style.animation = "none";
161
+ }
162
+
163
+ statusText.innerText = `Đang gửi ${currentBpm} BPM cho bộ não AI xử lý...`;
164
+ btnGenerate.innerText = "AI đang sáng tác...";
165
+ btnGenerate.disabled = true;
166
+ btnStop.disabled = true;
167
+
168
+ try {
169
+ const response = await fetch('/generate-vibe', {
170
+ method: 'POST',
171
+ headers: { 'Content-Type': 'application/json' },
172
+ body: JSON.stringify({ bpm: currentBpm })
173
+ });
174
+
175
+ const data = await response.json();
176
+
177
+ if (data.status === "success") {
178
+ statusText.innerText = "Sáng tác xong! Đang phát nhạc 🎵";
179
+
180
+ // Gắn file nhạc mới vào biến toàn cục
181
+ currentAudio = new Audio(data.audio_url);
182
+ currentAudio.play();
183
+
184
+ bpmDisplay.style.animation = "pulse 1s infinite";
185
+ btnStop.disabled = false; // Mở khóa nút Dừng
186
+
187
+ // Xử lý khi nhạc tự chạy hết
188
+ currentAudio.onended = () => {
189
+ bpmDisplay.style.animation = "none";
190
+ statusText.innerText = "Bản nhạc đã kết thúc. Sẵn sàng tạo trải nghiệm mới!";
191
+ btnStop.disabled = true;
192
+ };
193
+ } else {
194
+ statusText.innerText = `Lỗi từ Server: ${data.message}`;
195
+ }
196
+ } catch (error) {
197
+ console.error("API Error:", error);
198
+ statusText.innerText = "Mất kết nối với máy chủ AI!";
199
+ } finally {
200
+ btnGenerate.innerText = "2. Sinh nhạc AI";
201
+ btnGenerate.disabled = false;
202
+ }
203
+ });
204
+
205
+ // ==========================================
206
+ // 3. DỪNG NHẠC THỦ CÔNG
207
+ // ==========================================
208
+ btnStop.addEventListener('click', () => {
209
+ if (currentAudio) {
210
+ currentAudio.pause(); // Cắt âm thanh
211
+ currentAudio.currentTime = 0; // Xóa cache phát
212
+ bpmDisplay.style.animation = "none"; // Tắt nhấp nháy
213
+ statusText.innerText = "Đã dừng phát nhạc.";
214
+ btnStop.disabled = true; // Khóa lại nút dừng
215
+ }
216
+ });
217
+ </script>
218
+ </body>
219
+ </html>
bio_vibe_backend/main.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request
2
+ from fastapi.staticfiles import StaticFiles
3
+ from fastapi.responses import FileResponse
4
+ from pydantic import BaseModel
5
+ import torch
6
+ import torch.nn as nn
7
+ import pickle
8
+ import numpy as np
9
+ from music21 import note, chord, stream, instrument
10
+ import os
11
+ os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
12
+ import random
13
+ import subprocess
14
+
15
+ app = FastAPI(title="Bio-Vibe AI Inference")
16
+ os.makedirs("music", exist_ok=True)
17
+ app.mount("/music", StaticFiles(directory="music"), name="music")
18
+
19
+ @app.get("/")
20
+ async def serve_frontend():
21
+ return FileResponse("index.html")
22
+
23
+ class HeartRateData(BaseModel):
24
+ bpm: int
25
+
26
+ # ==========================================
27
+ # 1. KHÔI PHỤC "BỘ NÃO" (PYTORCH MODEL)
28
+ # ==========================================
29
+ # Cấu trúc class phải y hệt lúc train
30
+ class BioVibeAI(nn.Module):
31
+ def __init__(self, vocab_size, embed_size=256, hidden_size=512, num_layers=2):
32
+ super(BioVibeAI, self).__init__()
33
+ self.embedding = nn.Embedding(vocab_size, embed_size)
34
+ self.lstm = nn.LSTM(embed_size, hidden_size, num_layers, batch_first=True)
35
+ self.fc = nn.Linear(hidden_size, vocab_size)
36
+
37
+ def forward(self, x):
38
+ embedded = self.embedding(x)
39
+ out, _ = self.lstm(embedded)
40
+ out = self.fc(out[:, -1, :])
41
+ return out
42
+
43
+ # Nạp từ điển
44
+ with open('mapping_dict.pkl', 'rb') as f:
45
+ int_to_note = pickle.load(f)
46
+ note_to_int = {note: number for number, note in int_to_note.items()}
47
+ vocab_size = len(int_to_note)
48
+
49
+ # Load trọng số mô hình
50
+ device = torch.device("cpu") # Server chạy CPU cho nhẹ
51
+ model = BioVibeAI(vocab_size=vocab_size)
52
+ model.load_state_dict(torch.load("biovibe_brain.pth", map_location=device))
53
+ model.eval() # Chuyển sang chế độ suy luận
54
+
55
+ # Nạp kho dữ liệu cũ để lấy Seed (đoạn nhạc mồi)
56
+ with open('notes_corpus.pkl', 'rb') as f:
57
+ corpus = pickle.load(f)
58
+
59
+ # ==========================================
60
+ # 2. HÀM SÁNG TÁC BẰNG NHIỆT ĐỘ (TEMPERATURE)
61
+ # ==========================================
62
+ def generate_ai_midi(bpm: int, output_file: str, num_notes: int = 60):
63
+ # Logic phản hồi sinh học
64
+ if bpm > 80:
65
+ temperature = 0.7 # An toàn, ổn định
66
+ base_offset = 1.0 # Nốt đánh chậm
67
+ else:
68
+ temperature = 1.0 # Bay bổng, ngẫu hứng
69
+ base_offset = 0.5 # Nốt đánh nhanh hơn một chút
70
+
71
+ # Chọn bừa 100 nốt từ kho dữ liệu để làm "mồi" cho AI
72
+ start_idx = random.randint(0, len(corpus) - 100)
73
+ seed_sequence = corpus[start_idx:start_idx + 100]
74
+ pattern = [note_to_int[char] for char in seed_sequence]
75
+
76
+ generated_notes = []
77
+
78
+ print(f"Đang sáng tác với Temp={temperature}...")
79
+
80
+ # AI bắt đầu dự đoán
81
+ for i in range(num_notes):
82
+ sequence_tensor = torch.tensor([pattern], dtype=torch.long).to(device)
83
+
84
+ with torch.no_grad():
85
+ prediction = model(sequence_tensor)
86
+
87
+ # ÁP DỤNG TEMPERATURE
88
+ prediction = prediction / temperature
89
+ probabilities = torch.softmax(prediction, dim=1).numpy()[0]
90
+
91
+ # Chọn nốt dựa trên phân phối xác suất
92
+ index = np.random.choice(len(probabilities), p=probabilities)
93
+
94
+ result_note = int_to_note[index]
95
+ generated_notes.append(result_note)
96
+
97
+ # Cập nhật cửa sổ trượt (thêm nốt mới, xóa nốt cũ nhất)
98
+ pattern.append(index)
99
+ pattern = pattern[1:]
100
+
101
+ # ==========================================
102
+ # 3. CHUYỂN NGỮ AI THÀNH FILE MIDI
103
+ # ==========================================
104
+ offset = 0
105
+ output_stream = stream.Stream()
106
+ output_stream.append(instrument.Piano()) # Chọn nhạc cụ
107
+
108
+ for pattern_note in generated_notes:
109
+ # Nếu là hợp âm (có dấu chấm, ví dụ '4.7.11')
110
+ if ('.' in pattern_note) or pattern_note.isdigit():
111
+ notes_in_chord = pattern_note.split('.')
112
+ chord_notes = []
113
+ for current_note in notes_in_chord:
114
+ new_note = note.Note(int(current_note))
115
+ new_note.storedInstrument = instrument.Piano()
116
+ chord_notes.append(new_note)
117
+ new_chord = chord.Chord(chord_notes)
118
+ new_chord.offset = offset
119
+ output_stream.append(new_chord)
120
+ # Nếu là nốt đơn (Ví dụ: 'C4')
121
+ else:
122
+ new_note = note.Note(pattern_note)
123
+ new_note.offset = offset
124
+ new_note.storedInstrument = instrument.Piano()
125
+ output_stream.append(new_note)
126
+
127
+ # Tịnh tiến thời gian cho nốt tiếp theo
128
+ offset += base_offset
129
+
130
+ output_stream.write('midi', fp=output_file)
131
+
132
+ # ==========================================
133
+ # 4. API ENDPOINT
134
+ # ==========================================
135
+ @app.post("/generate-vibe")
136
+ async def generate_vibe(data: HeartRateData, request: Request):
137
+ # Đường dẫn file
138
+ midi_file = f"music/ai_vibe_{data.bpm}.mid"
139
+ wav_file = f"music/ai_vibe_{data.bpm}.wav"
140
+ soundfont_path = "soundfonts/Piano.sf2" # Đường dẫn tới file sf2 bạn vừa tải
141
+
142
+ # Bước 1: PyTorch sinh ra cấu trúc nốt nhạc (MIDI)
143
+ # Bước 1: PyTorch sinh ra cấu trúc nốt nhạc (MIDI)
144
+ generate_ai_midi(data.bpm, midi_file)
145
+
146
+ # Bước 2: Tự viết lệnh Render bằng Subprocess chuẩn xác cho FluidSynth 2.5+
147
+ print("Đang render MIDI thành âm thanh Piano...")
148
+ try:
149
+ subprocess.run([
150
+ "fluidsynth",
151
+ "-ni", # Chạy ẩn không cần giao diện
152
+ "-r", "44100", # Chất lượng Sample rate
153
+ "-F", wav_file, # Xuất ra file thay vì phát ra loa laptop!
154
+ soundfont_path, # Dàn nhạc (Soundfont)
155
+ midi_file # Kịch bản (MIDI)
156
+ ], check=True)
157
+ except Exception as e:
158
+ print(f"Lỗi khi render âm thanh: {e}")
159
+ return {"status": "error", "message": "Render failed"}
160
+
161
+ server_url = str(request.base_url).rstrip("/")
162
+
163
+ # Bước 3: Trả về link file âm thanh xịn xò cho App Flutter
164
+ return {"status": "success", "audio_url": f"{server_url}/{wav_file}"}
bio_vibe_backend/mapping_dict.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:86e5ccf6a3a91b52702fb2544a71c67b50ebd7f79bcb73ee4edd03ff646442f2
3
+ size 4327
bio_vibe_backend/music/ai_vibe_101.mid ADDED
Binary file (902 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_101.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aacbbb70d0e8afd65083fe4c6d5e1dd287cbfc06c7913a045801693e38cc9b4d
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_107.mid ADDED
Binary file (902 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_107.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1d374ab92b809d9385d466264a75b78476f2acc70eae4f50fd7b870a4e840883
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_115.mid ADDED
Binary file (846 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_115.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ec35b1b5306b761b5de7b8611800af074f47d15c3ccd6970ca0753a1d7ef792
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_75.mid ADDED
Binary file (614 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_75.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3812aa2f0aa026d14f3f0a76192b25ed341677dc0d0dddb19437113f3aed2007
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_76.mid ADDED
Binary file (718 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_76.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fcde0c15d8024a3e143d5145fa713d81808e0fcbea5b74fd68a3bd80e86db26c
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_77.mid ADDED
Binary file (662 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_77.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7bafb606120655f70c1d25e80cd100d218fafb1d1582f5045b4cc8cd721336ec
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_79.mid ADDED
Binary file (1.57 kB). View file
 
bio_vibe_backend/music/ai_vibe_79.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:595cf26abdf3e5c4e6f1ad4099baa3ebac61502edd79874027f76e0136150635
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_80.mid ADDED
Binary file (614 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_80.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0b9a7830d8583d6cf21fbbc45403410c3cfcef6270aac6c3d3890e43b565b8fb
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_82.mid ADDED
Binary file (2.03 kB). View file
 
bio_vibe_backend/music/ai_vibe_82.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9677262eb3f42855cc42ea3a37a9853991e71a48c7e58c152f35de28f9b1478d
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_84.mid ADDED
Binary file (614 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_86.mid ADDED
Binary file (990 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_86.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:398f14f089c6eafcc16f0db7a2bd14d80d65e50cc2278a565befde91de2e5410
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_89.mid ADDED
Binary file (1.11 kB). View file
 
bio_vibe_backend/music/ai_vibe_89.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:066e7004a0f70949655c40b76fe018bb620b3b6f97d5588fd08f52914911e598
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_90.mid ADDED
Binary file (1.11 kB). View file
 
bio_vibe_backend/music/ai_vibe_90.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:85fbd74adc583584d018e927c4ff897e71b2ad5551384e6d5faf6e37312477e2
3
+ size 5742636
bio_vibe_backend/music/ai_vibe_92.mid ADDED
Binary file (686 Bytes). View file
 
bio_vibe_backend/music/ai_vibe_92.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:de5b792b51f870af2ccef6a1316e9d9a37697da7d7eb4df1b9f8a139a4a0fae8
3
+ size 5742636
bio_vibe_backend/notes_corpus.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a7d771c8771b85f78a16aec81fe4cc7f2fed948d65c3f481ce6b0f0a819abee2
3
+ size 308547
bio_vibe_backend/soundfonts/Piano.SF2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ebe131b54d897d88bf1ed3936c044ba2d0c9282bfbf2ca22aab6c993865889a0
3
+ size 5288994
bio_vibe_backend/stems/pad_ambient.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4fc3827dd054b70975354272b6e0c5fe4b57304d14f1da04ad9798adaa46a85d
3
+ size 15883854
bio_vibe_backend/stems/piano.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d57c1e47b02be9ce5224e51bf7c5cecaa9ed2de407b5b938d5c9841cf2141e2f
3
+ size 23637758
bio_vibe_backend/stems/rain.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8679e872e34d2a1b68f5342d574bf3742794ca86790cd0cb709535f765e179a7
3
+ size 9525772
bio_vibe_backend/stems/violin.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:96136784328c18a64d4d74587e4c1f7693145969be1ceda6f545c36ea7d08895
3
+ size 79092292
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ torch
4
+ pydantic
5
+ music21
6
+ numpy