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}에 저장되었습니다.")




반응형