데시벨을 기준으로 음성 파일을 나누자!

Apic·2023년 9월 29일
0

심심한 프로젝트

목록 보기
18/18

영단어 공부

나는 영단어 공부를 하는데 Anki라는 프로그램을 사용한다.

그리고 그 Anki프로그램은 텍스트 뿐 만 아니라 이미지, 음성파일도 넣을 수 있다.

영어 발음을 넣기 위해 처음에는 해당 단어를 검색, 음성 데이터를 크롤링해 다운로드 하는 코드를 짜서 이용했으나, 가끔 다른 단어의 발음이 들어갈 때가 있고, 검색이 되지 않을 때가 있다.

그래서 찾아봤는데, 이 영단어 책에서 제공해주는 영어 발음 영상이 있었고, 이 영상을 이용해 영단어만 추출하여 사용하면 되겠다는 생각을 했다.

환경 및 계획

  • 환경

    • OS: Ubuntu-20.04(wsl)
    • Language: Python
    • Version: 3.10.13
    • Editor: VSCode
  • 계획

    1. 해당 발음 영상 파일 다운로드 후 음성 파일로 변환

    2. 음성 데이터에서 지정한 데시벨(무음)이상인 부분만 따로 추출하여 저장
      (예시)

    3. 해당 음성 파일 중 1.5초 이상, 1초 미만인 음성 파일은 제거

    4. 추출한 음성 파일을 읽어 텍스트를 추출, 추출한 텍스트를 파일 이름으로 지정한다.

    5. 필요 없는 파일들 확인 후 제거

음성 파일 로드

먼저 음성 파일을 읽고 해당 음성 파일을 그래프로 표현해 보았다.

원본 길이가 약 5분정도 되는데, 이 상태로 하면 처리 시간도 좀 걸리고, 그래프로 그렸을 때 알아보기가 힘드므로, 먼저 약 20초 정도로 자르고 해당 파일을 가지고 진행

# 음성 파일 위치
input_audio_file = './audio_files/sample.wav'

# 음성 파일 읽기
y, sr = librosa.load(input_audio_file)

# 그래프로 그리기
pd.Series(y).plot(
                    figsize=(20,5),
                    title= 'sound sample',
                    lw=1
                )
plt.show()

# jupyter notebook에서 음성 파일 실행하기
ipd.Audio(input_audio_file)

Decibel 계산하기

먼저 데시벨 계산식은 아래와 같다.

이 수식을 이용하기 위해 오디오 db를 구해야 한다.

# 스펙트로그램 계산
frame_length = 1024  # 프레임 길이
hop_length = 512     # 프레임 간격
n_fft = 1024         # FFT 크기

stft = librosa.stft(y, n_fft=n_fft, hop_length=hop_length)

# 스펙트로그램을 dB로 변환
stft_db = librosa.amplitude_to_db(np.abs(stft))

# 음성 파일의 시간
times = librosa.times_like(stft_db, sr=sr)

그리고 일정 데시벨 미만일 경우 해당 부분을 잘라 오디오로 저장한다.

# 시작 지점, 끝 지점
start_time, end_time = None, None
for time_line in range(len(stft_db[0])):
    # 0초에서의 dB 값을 출력
    decibel = 20 * math.log10(np.sqrt(np.mean(stft_db[:, time_line] ** 2)))

    # 시작 부분
    if decibel < 31.6:
        if start_time == None:
            start_time = times[time_line]
        
    # 끝 부분
    elif decibel >= 31.6:
        if not start_time == None:
            if end_time == None:
                end_time = times[time_line]
                
                # 오디오 자르기
                new_audio = y[int(start_time * sr) : int(end_time * sr)]
                
                # 0.7초 ~ 1.5초 사이의 음성 파일만 저장
                audio_time = end_time - start_time
                
                if (audio_time > 0.7) and (audio_time < 1.5):
                    # 오디오 저장
                    sf.write(f'./audio/{time_line}.wav', new_audio, sr)
                    print(audio_time)
                    print(f'{time_line} 파일 저장')
                    
                
                # 시작 지점, 끝 지점 초기화
                start_time, end_time = None, None

파일 이름 변경

ChatGpt를 이용해여 코드를 만들어 실행해 보았다.

import speech_recognition as sr

# 음성 인식기 초기화
recognizer = sr.Recognizer()

# 음성 파일 경로 지정
audio_file = "./audio/366.wav"  # 음성 파일 경로를 지정하세요

# 음성 파일 읽기
with sr.AudioFile(audio_file) as source:
    audio_data = recognizer.record(source)

try:
    # Google Web Speech API를 사용하여 음성을 텍스트로 변환
    recognized_text = recognizer.recognize_google(audio_data, language="en-CA")  # 음성 파일의 언어에 맞게 설정하세요
    print("음성에서 추출된 텍스트:")
    print(recognized_text)
except sr.UnknownValueError:
    print("음성을 인식할 수 없습니다.")
except sr.RequestError as e:
    print(f"Google Web Speech API 요청 오류: {e}")

하지만 제대로 인식하지 못했다.

award 단어를 인식하지 못해 'a'만 출력한다.

일단 오디오만 자르고, 파일 이름을 바꾸는 것은 일일이 바꾸거나, 다른 방법을 찾아봐야 할 것 같다.

profile
코딩 공부하는 사람

0개의 댓글