부트캠프에서 자바를 배우며 객체지향적으로 만드는 걸 배웠는 데 머신러닝 프로젝트에서도 적용 해보자.
IDE - Pycharm
python - 3.11
stack - librosa, pytorch, pandas, anaconda
vocal_classification_using_CNN/
├── configs/
├── data/
├── src/
│ ├── evaluations/
│ ├── models/
│ └── preprocessing/
│ └── convert_to_wav.py
└── tests/
├── evaluations/
├── models/
└── preprocessing/
└── test_convert_to_wav.py
import os
import torchaudio
class ConvertToWav:
def __init__(self, file_path, folder_path):
self.file_path = file_path
self.folder_path = folder_path
def convert_and_save(self):
waveform, sr = torchaudio.load(self.file_path)
wav_file_path = os.path.splitext(self.file_path)[0] + ".wav"
torchaudio.save(wav_file_path, waveform, sr)
def is_supported_file(self, file_name):
supported_extensions = ['.mp3', '.mp4', '.wav', '.flac', '.ogg']
return any(file_name.lower().endswith(ext) for ext in supported_extensions)
def convert_files(self):
if not os.path.exists(self.folder_path):
raise ValueError(f"{self.folder_path}은(는) 폴더가 아닙니다.")
file_list = os.listdir(self.folder_path)
for file in file_list:
file_path = os.path.join(self.folder_path, file)
if os.path.isfile(file_path) and self.is_supported_file(file):
self.file_path = file_path
self.convert_and_save()
소스 코드는 저번에 작성한 모든 음원을 wav파일로 바꾸는 코드를 객체지향적으로 바꾸려 노력했다.
클래스는 wav파일로 바꾸는 단 하나의 책임을 가진다.
각각의 코드는
1. 단위 파일을 wav로 바꾸고 저장
2. 폴더 안에 음원이 있는지 확인
3. 폴더안의 파일에 1.을 적용
import sys
import os
import unittest
import wave
import numpy as np
# 현재 파일의 경로에서 src 디렉토리까지의 절대 경로를 sys.path에 추가
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../src')))
# ConvertToWav 클래스를 import
from preprocessing.convert_to_wav import ConvertToWav
# 간단한 WAV 파일 생성 함수
def create_test_wav(filename):
sample_rate = 44100 # 44.1 kHz
duration = 1 # 1 second
frequency = 440.0 # 440 Hz (A4)
with wave.open(filename, 'w') as wav_file:
n_channels = 1
sampwidth = 2
n_frames = sample_rate * duration
comptype = "NONE"
compname = "not compressed"
wav_file.setparams((n_channels, sampwidth, sample_rate, n_frames, comptype, compname))
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
data = (np.sin(2 * np.pi * frequency * t) * 32767).astype(np.int16)
wav_file.writeframes(data.tobytes())
class TestConvertToWav(unittest.TestCase):
def test_convert_to_wav(self):
test_dir = "test_directory"
temp_file_path = os.path.join(test_dir, "test_audio.mp3")
# Create a directory for the test if it does not exist
if not os.path.exists(test_dir):
os.makedirs(test_dir)
# Create a temporary test audio file
create_test_wav(temp_file_path)
# Create an instance of ConvertToWav
converter = ConvertToWav(file_path=temp_file_path, folder_path=test_dir)
# Call the convert_and_save method
converter.convert_and_save()
# Assert that the WAV file has been created
wav_file_path = os.path.splitext(temp_file_path)[0] + ".wav"
self.assertTrue(os.path.exists(wav_file_path))
# Clean up: Delete the temporary test files
os.remove(temp_file_path)
os.remove(wav_file_path)
os.rmdir(test_dir)
if __name__ == "__main__":
unittest.main()
테스트 코드의 wav 파일 생성 매서드는 아마 재사용할 것 같은데 일단을 저기에 박아놨다. 추후에 테스트 코드에 코드 재사용하는 법을 익히고 분리할 것 이다.
https://github.com/B-Singularity/Vocal-Classification-Using-CNN/tree/feat/preprocessing
앞으로 올린 모든 코드는 위 저장소에 있다.