Tutorial: Membuat Aplikasi Pengenal Chord Gitar Menggunakan Machine Learning
Pendahuluan
Halo, teman-teman! Pada kesempatan kali ini, kita akan belajar cara membuat aplikasi keren yang bisa mengenali chord gitar dari rekaman audio. Aplikasi ini akan menggunakan Flutter untuk front-end dan Flask untuk back-end, serta bantuan Machine Learning untuk mengenali chord gitar. Yuk, kita mulai!
Menyiapkan Dataset
Pertama-tama, kita perlu menyiapkan dataset yang akan digunakan untuk melatih model Machine Learning kita. Berikut adalah struktur direktori yang kita perlukan untuk dataset:
dataset/├── A/│ ├── audio1.wav│ ├── audio2.wav│ └── ...├── Am/│ ├── audio1.wav│ ├── audio2.wav│ └── ...├── C/│ ├── audio1.wav│ ├── audio2.wav│ └── ......
Setiap folder di dalam direktori dataset berisi file audio (.wav) dari chord yang sesuai dengan nama folder. Pastikan semua file audio tersimpan dengan benar di folder masing-masing chord.
Membuat Aplikasi Mobile dengan Flutter
Aplikasi mobile kita akan dibangun menggunakan Flutter. Aplikasi ini akan merekam audio dari pengguna saat mereka memainkan chord gitar, lalu mengirim file audio tersebut ke server untuk dianalisis.
Kode untuk Merekam Audio
Berikut adalah contoh kode untuk merekam audio menggunakan Flutter:
class ChordDetailPage extends StatefulWidget { const ChordDetailPage({Key? key}) : super(key: key);
@override _ChordDetailPageState createState() => _ChordDetailPageState();}
class _ChordDetailPageState extends State<ChordDetailPage> { final FlutterSoundRecorder _recorder = FlutterSoundRecorder(); bool _isRecording = false; String _filePath = '';
@override void initState() { super.initState(); _requestPermissions(); _openRecorder(); }
Future<void> _requestPermissions() async { var status = await Permission.microphone.status; if (!status.isGranted) { await Permission.microphone.request(); } status = await Permission.storage.status; if (!status.isGranted) { await Permission.storage.request(); } }
Future<void> _openRecorder() async { await _recorder.openAudioSession(); }
void _startRecording() async { var tempDir = await getTemporaryDirectory(); _filePath = '${tempDir.path}/temp.wav'; await _recorder.startRecorder(toFile: _filePath); setState(() { _isRecording = true; }); }
void _stopRecording() async { await _recorder.stopRecorder(); setState(() { _isRecording = false; _sendFile(); }); }
void _sendFile() async { var uri = Uri.parse('$baseURL/upload'); var request = http.MultipartRequest('POST', uri) ..files.add(await http.MultipartFile.fromPath('audio', _filePath)); var response = await request.send(); if (response.statusCode == 200) { var responseData = await http.Response.fromStream(response); var responseBody = json.decode(responseData.body); String recognizedChord = responseBody['recognized_chord']; if (recognizedChord != null) { _showAlert(context, recognizedChord == chordName ? 'Correct' : 'Wrong'); } } }
void _showAlert(BuildContext context, String title) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text(title, textAlign: TextAlign.center), actions: <Widget>[ TextButton( child: Text('Ok'), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, ); }
@override Widget build(BuildContext context) { return Scaffold( // Kode UI ); }}
Membuat Backend dengan Flask
Backend kita akan dibangun menggunakan Flask dan akan bertanggung jawab untuk memproses file audio yang dikirim oleh aplikasi mobile serta mengenali chord menggunakan model Machine Learning.
Kode untuk Ekstraksi Fitur Audio
Server kita akan menggunakan librosa untuk memproses file audio dan mengekstrak fitur chroma.
@app.route('/upload', methods=['POST'])def upload_audio(): if 'audio' not in request.files: return jsonify({'error': 'No audio file provided'}), 400
audio_file = request.files['audio'] file_path = os.path.join('C:\\temp', audio_file.filename) audio_file.save(file_path)
y, sr = librosa.load(file_path) chroma = librosa.feature.chroma_stft(y=y, sr=sr) chroma_mean = np.mean(chroma, axis=1) recognized_chord = recognize_chord_svm(chroma_mean)
os.remove(file_path)
if recognized_chord: return jsonify({'recognized_chord': recognized_chord})
return jsonify({'recognized_chord': None, 'error': 'Chord not recognized'})
Kode Model Machine Learning: Support Vector Machine (SVM)
Model SVM akan digunakan untuk mengenali chord dari fitur chroma yang diekstraksi dari file audio.
def load_svm_model(): model_path = 'svm_model.pkl' if os.path.exists(model_path): return joblib.load(model_path) return None
svm_model = load_svm_model()
def recognize_chord_svm(chroma_mean): if svm_model: chord_label = svm_model.predict([chroma_mean]) return chord_label[0] return None
Melatih Model Machine Learning
Selanjutnya, kita akan melatih model SVM menggunakan dataset yang sudah disiapkan. Berikut adalah langkah-langkah untuk melatih model:
Kode Pelatihan Model
import osimport numpy as npfrom sklearn import svmfrom sklearn.preprocessing import StandardScalerfrom sklearn.pipeline import make_pipelineimport joblibimport librosa
def extract_chroma_features(file_path): y, sr = librosa.load(file_path) chroma = librosa.feature.chroma_stft(y=y, sr=sr) chroma_mean = np.mean(chroma, axis=1) return chroma_mean
chords = ['C','A','Dm','Em','F','G','Am','D','E']
# Load datasetX = []y = []dataset_dir = os.path.abspath('dataset') # Path to your datasetprint(f"Dataset directory: {dataset_dir}")
for chord in chords: chord_dir = os.path.join(dataset_dir, chord) print(f"Checking directory: {chord_dir}")
if not os.path.exists(chord_dir): print(f"Directory {chord_dir} does not exist. Please create it and add audio files.") continue
files = [file_name for file_name in os.listdir(chord_dir) if file_name.endswith('.wav')] if len(files) == 0: print(f"No audio files found in directory {chord_dir}") continue print(f"Found {len(files)} files in directory {chord_dir}")
for file_name in files: file_path = os.path.join(chord_dir, file_name) print(f"Processing file: {file_path}")
if not os.path.exists(file_path): print(f"File {file_path} does not exist.") continue
chroma_features = extract_chroma_features(file_path) X.append(chroma_features) y.append(chord)
# Convert to numpy arraysX = np.array(X)y = np.array(y)
# Check if we have more than one classunique_classes = np.unique(y)print(f"Unique classes found: {unique_classes}")
if len(unique_classes) <= 1: raise ValueError(f"The number of classes has to be greater than one; got {len(unique_classes)} class")
# Train SVM modelsvm_model = make_pipeline(StandardScaler(), svm.SVC(kernel='linear'))svm_model.fit(X, y)
# Save the trained modeljoblib.dump(svm_model, 'svm_model.pkl')print("Model has been trained and saved as svm_model.pkl")
Penjelasan Fungsi-Fungsi
extract_chroma_features(file_path): Fungsi ini menggunakanlibrosauntuk memuat file audio dan mengekstrak fitur chroma, kemudian menghitung rata-rata dari fitur chroma.chords: Daftar chord yang akan dikenali oleh model.Xdany: List yang menyimpan fitur chroma dan label chord yang sesuai.dataset_dir: Path ke direktori dataset yang berisi folder-folder chord.svm_model = make_pipeline(StandardScaler(), svm.SVC(kernel='linear')): Membuat pipeline yang terdiri dari scaler dan model SVM dengan kernel linear.svm_model.fit(X, y): Melatih model SVM menggunakan dataset.joblib.dump(svm_model, 'svm_model.pkl'): Menyimpan model yang telah dilatih ke dalam filesvm_model.pkl.
Kesimpulan
Dengan mengikuti langkah-langkah dalam tutorial ini, kalian bisa membuat aplikasi yang mampu mengenali chord gitar dari rekaman audio. Aplikasi ini menggunakan kombinasi Flutter untuk front-end, Flask untuk back-end, dan model Machine Learning SVM yang telah dilatih dengan dataset yang sesuai. Selamat mencoba dan semoga berhasil!



