본문 바로가기
데이터&AI/LLM

[realtime GPT를 쓰기위한 사전학습]pyaudio이해하기① (마이크 음성을 데이터로 전환!!!)

by 일등박사 2024. 10. 22.
728x90

python 기반의 realtime GPT쓰기를 위한 학습작업!!

 

2024.10.15 - [데이터&AI/기타개발] - [realtime GPT를 쓰기위한 사전학습] threading의 이해 (python의 멀티태스킹!)

 

[realtime GPT를 쓰기위한 사전학습] threading의 이해 (python의 멀티태스킹!)

최근 공개된 GPT realtime모델!!!2024.10.12 - [데이터&AI/LLM] - gpt realtime console로 사용해보기 gpt realtime console로 사용해보기24년 9월 25일!! chatgpt advanced voice 모드가 공개되서 많이 환영을 받았습니다!그리

drfirst.tistory.com

2024.10.15 - [데이터&AI/기타개발] - [realtime GPT를 쓰기위한 사전학습] queue 의 이해 (python. 줄을 서시오!! FIFO)

 

[realtime GPT를 쓰기위한 사전학습] queue 의 이해 (python. 줄을 서시오!! FIFO)

지난 포스팅에이어2024.10.15 - [데이터&AI/기타개발] - [realtime GPT를 쓰기위한 사전학습] threading의 이해 (python의 멀티태스킹!)realtime GPT를 쓰기위한 사전학습, python의 queue에 대하여 알아보겠습니다!!

drfirst.tistory.com

 

GPT와 대화해야하니, 우리의 컴퓨터 마이크를 통해 대화해야겠지요?ㅎㅎ

그래서!! 지난 포스팅에 이어!! 오늘은 pyaudio, 그중에서도 목소리를 데이터화하는것을 이해해보도록 하겠습니다!!


1. PyAudio란?

PyAudio는 Python에서 오디오를 캡처하고 재생할 수 있게 해주는 PortAudio의 파이썬 버젼입니다!!!

주요 기능을 요악하면 아래와 같지요!!

  • 마이크에서 오디오 입력 수집
  • 스피커를 통한 오디오 출력
  • 오디오 스트림 실시간 처리

 

2. PyAudio 설치하기

pip을 통하여 아래와 같이 간단히 설치해볼까요!?

pip install pyaudio

 

 

 

3. 녹음 테스트

pip을 통하여 아래와 같이 간단히 설치해볼까요!?

import pyaudio
import wave

# PyAudio 초기화
p = pyaudio.PyAudio()

# 오디오 스트림 설정
stream = p.open(format=pyaudio.paInt16,  # 16비트 오디오
                channels=1,              # 모노 채널
                rate=44100,              # 샘플링 레이트 (Hz)
                input=True,              # 입력 장치 사용
                frames_per_buffer=1024)   # 버퍼 크기

print("녹음을 시작합니다...")

frames = []  # 오디오 데이터를 저장할 리스트

# 5초 동안 오디오 수집
for i in range(0, int(44100 / 1024 * 5)):
    data = stream.read(1024)
    frames.append(data)

print("녹음이 끝났습니다.")

# 스트림 종료
stream.stop_stream()
stream.close()
p.terminate()

# WAV 파일로 저장
wf = wave.open("text_pyaudio.wav", 'wb')
wf.setnchannels(1)  # 모노
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(44100)
wf.writeframes(b''.join(frames))
wf.close()

 

그럼!! 결과적으로 text_pyaudio.wav파일이 잘 저장됨을 확인할 수 있습니다!!

 

 

4. 목소리를 데이터 바꾸기!

이번엔 단순 녹음이 아니라! 내 목소리를 데이터벡터로 바꾸어보곘습니다!

 

import pyaudio
import numpy as np

# PyAudio 초기화
p = pyaudio.PyAudio()

# 오디오 스트림 설정
stream = p.open(format=pyaudio.paInt16,  # 16비트 오디오
                channels=1,              # 모노 채널
                rate=44100,              # 샘플링 레이트 (Hz)
                input=True,              # 입력 장치 사용
                frames_per_buffer=1024)   # 버퍼 크기

print("녹음을 시작합니다. 마이크에 대고 말하세요...")

try:
    while True:
        # 마이크에서 1024 샘플만큼 데이터를 읽음
        data = stream.read(1024)
        
        # 데이터를 numpy 배열로 변환 (16비트 정수)
        audio_data = np.frombuffer(data, dtype=np.int16)
        
        # 오디오 데이터를 출력
        print("내가 한말이에요!!!")
        print(audio_data)
        print('-'*100)
except KeyboardInterrupt:
    print("녹음이 중단되었습니다.")

# 스트림 종료
stream.stop_stream()
stream.close()
p.terminate()

 

이를 통해서!! 내가 한 말이 아래와 같이 숫자의 벡터로 변환됨을 확인할 수 있습니다!!

 

 

5. in_data이해하기!!

PyAudio가 마이크에서 데이터를 읽으면!!, 이 데이터를 in_data라는 파라미터로 콜백 함수에 전달합니다.

콜백이란!!?
콜백 함수는 특정 이벤트나 작업이 발생했을 때 호출되는 함수입니다!
보통 프로그램 흐름을 제어하는 방법 중 하나로, 프로그래머가 미리 정의해놓은 함수를 특정 상황이 발생했을 때 시스템이나 라이브러리가 알아서 실행하도록 하는 방식입니다.

 

조금 어렵죠? 코드로 봐보겠습니다!!

## 콜백함수 선언!!!
def _mic_callback(in_data, frame_count, time_info, status):
    """마이크로부터 들어온 오디오 데이터를 처리하는 콜백 함수."""
    print(f"Received {len(in_data)} bytes of audio data")
    
    # in_data에는 마이크로부터 읽은 바이너리 오디오 데이터가 들어있다.
    # 데이터를 읽어서 필요한 처리를 할 수 있음.
    print(f"First 10 bytes of in_data: {in_data[:10]}")
    
    return (None, pyaudio.paContinue)


# 오디오 스트림 시작 (마이크에서 입력을 받음)
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK,
                stream_callback=_mic_callback)

# 스트림 시작
stream.start_stream()

 

위 부분이 핵심인데요!!
pyaudio의 객채인 p 가 시작될떄!!stream_callback를 _mic_callback으로 미리 지정해두었구요!!

그렇기에!!  _mic_callback으로 데이터가 들어갑니다!

이떄 목소리의 데이터가 in_data로 들어가기로  협의가된것이지요!!

(pyaudio 코드가 만들어지면서 in_data로 되기로 정해짐!)

 

이제 전체 코드를 봐볼까요!?

import pyaudio

# 기본 설정 값
FORMAT = pyaudio.paInt16  # 16비트 오디오
CHANNELS = 1              # 모노 채널
RATE = 44100              # 샘플링 레이트 (44100Hz)
CHUNK = 1024              # 버퍼 크기

def _mic_callback(in_data, frame_count, time_info, status):
    """마이크로부터 들어온 오디오 데이터를 처리하는 콜백 함수."""
    print(f"Received {len(in_data)} bytes of audio data")
    
    # in_data에는 마이크로부터 읽은 바이너리 오디오 데이터가 들어있다.
    # 데이터를 읽어서 필요한 처리를 할 수 있음.
    print(f"First 10 bytes of in_data: {in_data}")
    
    return (None, pyaudio.paContinue)

# PyAudio 초기화
p = pyaudio.PyAudio()

# 오디오 스트림 시작 (마이크에서 입력을 받음)
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK,
                stream_callback=_mic_callback)

# 스트림 시작
stream.start_stream()

print("마이크로부터 데이터를 받고 있습니다. 마이크에 대고 말해보세요...")

try:
    while stream.is_active():
        pass  # 스트림이 활성화된 동안 기다림 (Ctrl+C로 종료 가능)
except KeyboardInterrupt:
    print("스트림을 종료합니다.")

# 스트림 종료
stream.stop_stream()
stream.close()
p.terminate()

 

이 코드를 실행해보면!!?

이렇게!! 

Received 2048 bytes of audio data 데이터를 잘 받음을 알 수 있습니다!!

+ 2048인 이유는?

pyaudio.paInt16로 설정되어 있습니다. 이는 각 오디오 샘플이 16비트(2바이트) 이며

frames_per_buffer = chunk이며 chunk가  1024 이기에!!

2 X  1024 인 2048 bytes 의 데이터를 받는것 이지요!!

 

이렇게해서! 지금까지 마이크로 들어오는 음성을데이터로 전환하는 방법에 대하여 알아보았습니다!

728x90

댓글