Python/Python - 오디오
마이크를 사용하여 녹음하는 Python 예제
webnautes
2024. 10. 3. 21:55
반응형
마이크를 사용하여 녹음하는 Python 예제 코드입니다.
2024. 10. 3 최초작성
다음 패키지를 설치해야 합니다.
pip install pyaudio scipy librosa
실행하면 녹음 후, output.wav 파일에 저장됩니다.
녹음 시작...
녹음 완료.
녹음이 output.wav에 저장되었습니다.
전체 코드입니다.
import pyaudio import wave import numpy as np from scipy import signal import librosa # 오디오 설정 CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 44100 RECORD_SECONDS = 5 WAVE_OUTPUT_FILENAME = "output.wav" def apply_bandpass_filter(data, lowcut, highcut, fs, order=5): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = signal.butter(order, [low, high], btype='band') return signal.lfilter(b, a, data) def apply_subtle_equalizer(data, sr): # 부드러운 이퀄라이징 S = librosa.stft(data) S_db = librosa.amplitude_to_db(np.abs(S)) # 주파수 대역별 게인 조정 (매우 약하게) S_db[:20] += 1 # 저주파 약간 부스트 S_db[20:50] += 0.5 # 중저주파 매우 약간 부스트 S_boosted = librosa.db_to_amplitude(S_db) * np.exp(1j * np.angle(S)) return librosa.istft(S_boosted) def apply_gentle_compression(data, threshold_db=-20, ratio=2): # 매우 부드러운 압축 db = librosa.amplitude_to_db(np.abs(data)) compressed = np.where(db > threshold_db, threshold_db + (db - threshold_db) / ratio, db) return librosa.db_to_amplitude(compressed) * np.sign(data) def reduce_noise_gently(data, noise_thresh=-50): # 매우 약한 노이즈 감소 S = librosa.stft(data) S_db = librosa.amplitude_to_db(np.abs(S)) mask = S_db > noise_thresh S_clean = S * mask return librosa.istft(S_clean) def normalize_audio(data): return librosa.util.normalize(data) # PyAudio 객체 생성 p = pyaudio.PyAudio() # 스트림 열기 stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("녹음 시작...") frames = [] # 녹음 시작 for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) print("녹음 완료.") # 스트림 정지 및 종료 stream.stop_stream() stream.close() p.terminate() # 오디오 데이터를 numpy array로 변환 audio_data = np.frombuffer(b''.join(frames), dtype=np.int16).astype(np.float32) audio_data = audio_data / 32768.0 # 정규화 # 신호 처리 (매우 부드럽게) audio_data = apply_bandpass_filter(audio_data, 80, 10000, RATE) # 주파수 범위 확장 audio_data = apply_subtle_equalizer(audio_data, RATE) audio_data = reduce_noise_gently(audio_data, noise_thresh=-50) # 노이즈 임계값 낮춤 audio_data = apply_gentle_compression(audio_data, threshold_db=-15, ratio=1.5) audio_data = normalize_audio(audio_data) # 다시 int16으로 변환 audio_data = np.clip(audio_data, -1, 1) * 32767 audio_data = audio_data.astype(np.int16) # WAV 파일로 저장 wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(audio_data.tobytes()) wf.close() print(f"녹음이 {WAVE_OUTPUT_FILENAME}에 저장되었습니다.") |
반응형