python perekaman audio pyaudio
Saya mencoba merekam audio dari mikrofon dengan Python. Dan saya memiliki kode berikut:
import pyaudio
import wave
import threading
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
CHUNK = 1024
WAVE_OUTPUT_FILENAME = "file.wav"
stop_ = False
audio = pyaudio.PyAudio()
stream = audio.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK)
def stop():
global stop_
while True:
if not input('Press Enter >>>'):
print('exit')
stop_ = True
t = threading.Thread(target=stop, daemon=True).start()
frames = []
while True:
data = stream.read(CHUNK)
frames.append(data)
if stop_:
break
stream.stop_stream()
stream.close()
audio.terminate()
waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()
Kode saya berfungsi dengan baik, tetapi ketika saya memutar rekaman saya, saya tidak mendengar suara apa pun di file keluaran akhir saya ( file.wav).
Mengapa masalah terjadi di sini dan bagaimana cara memperbaikinya?
Jawaban
Kode Anda berfungsi dengan baik. Masalah yang Anda hadapi adalah karena hak admin. File audio memiliki data 0 konstan, oleh karena itu, Anda tidak dapat mendengarkan suara dalam file wav yang dihasilkan. Saya kira perangkat mikrofon Anda terpasang dan berfungsi dengan baik. Jika Anda tidak yakin tentang status penginstalan audio, maka sesuai sistem operasi lakukan langkah-langkah ini:
MAC OS: System Preferences-> Sound-> Input dan di sana Anda dapat memvisualisasikan bilah sebagai membuat beberapa suara. Pastikan jenis perangkat yang dipilih adalah Built-in.
Windos OS: Pengaturan suara dan uji Mikrofon dengan klik dengarkan perangkat ini, Anda dapat menghapus centang nanti karena itu akan memutar kembali suara Anda ke speaker dan akan membuat suara besar.
Kemungkinan besar Anda menggunakan Mac OS. Saya mengalami masalah serupa, karena saya menggunakan editor Atom untuk menjalankan kode python. Coba jalankan kode Anda dari terminal Mac OS (atau Power Shell jika Anda menggunakan windows), (jika popup muncul untuk mengakses mikrofon di Mac OS, tekan Ok). Itu dia! kode Anda akan merekam dengan baik. Sebagai penguji, jalankan kode di bawah ini untuk memeriksa apakah Anda dapat memvisualisasikan suara, dan pastikan untuk menjalankannya melalui Terminal (Tanpa editor atau IDE).
import queue
import sys
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
import numpy as np
import sounddevice as sd
# Lets define audio variables
# We will use the default PC or Laptop mic to input the sound
device = 0 # id of the audio device by default
window = 1000 # window for the data
downsample = 1 # how much samples to drop
channels = [1] # a list of audio channels
interval = 30 # this is update interval in miliseconds for plot
# lets make a queue
q = queue.Queue()
# Please note that this sd.query_devices has an s in the end.
device_info = sd.query_devices(device, 'input')
samplerate = device_info['default_samplerate']
length = int(window*samplerate/(1000*downsample))
# lets print it
print("Sample Rate: ", samplerate)
# Typical sample rate is 44100 so lets see.
# Ok so lets move forward
# Now we require a variable to hold the samples
plotdata = np.zeros((length,len(channels)))
# Lets look at the shape of this plotdata
print("plotdata shape: ", plotdata.shape)
# So its vector of length 44100
# Or we can also say that its a matrix of rows 44100 and cols 1
# next is to make fig and axis of matplotlib plt
fig,ax = plt.subplots(figsize=(8,4))
# lets set the title
ax.set_title("PyShine")
# Make a matplotlib.lines.Line2D plot item of color green
# R,G,B = 0,1,0.29
lines = ax.plot(plotdata,color = (0,1,0.29))
# We will use an audio call back function to put the data in queue
def audio_callback(indata,frames,time,status):
q.put(indata[::downsample,[0]])
# now we will use an another function
# It will take frame of audio samples from the queue and update
# to the lines
def update_plot(frame):
global plotdata
while True:
try:
data = q.get_nowait()
except queue.Empty:
break
shift = len(data)
plotdata = np.roll(plotdata, -shift,axis = 0)
# Elements that roll beyond the last position are
# re-introduced
plotdata[-shift:,:] = data
for column, line in enumerate(lines):
line.set_ydata(plotdata[:,column])
return lines
ax.set_facecolor((0,0,0))
# Lets add the grid
ax.set_yticks([0])
ax.yaxis.grid(True)
""" INPUT FROM MIC """
stream = sd.InputStream( device = device, channels = max(channels), samplerate = samplerate, callback = audio_callback)
""" OUTPUT """
ani = FuncAnimation(fig,update_plot, interval=interval,blit=True)
with stream:
plt.show()
Simpan file ini sebagai voice.py ke folder (katakanlah AUDIO). Kemudian cd ke folder AUDIO dari perintah terminal dan kemudian jalankan menggunakan:
python3 voice.py
atau
python voice.py
tergantung pada nama env python Anda.
Dengan menggunakan print(sd.query_devices()), saya melihat daftar perangkat seperti di bawah ini:
- Microsoft Sound Mapper - Input, MME (2 masuk, 0 keluar)
- Mikrofon (AudioHubNano2D_V1.5, MME (2 in, 0 out)
- Mikrofon Internal (Conexant S, MME (2 masuk, 0 keluar)
- ...
Namun, jika saya menggunakan device = 0, saya masih dapat menerima suara dari mikrofon USB, yaitu perangkat nomor 1. Apakah secara default, semua sinyal audio masuk ke Sound Mapper? Itu berarti jika saya menggunakan device = 0, saya akan mendapatkan semua sinyal audio dari semua input audio; dan jika saya hanya ingin input audio dari satu perangkat tertentu, saya harus memilih nomornya x sebagai device = x.
Saya punya pertanyaan lain: apakah mungkin menangkap sinyal audio dari perangkat 1 dan 2 dalam satu aplikasi tetapi secara terpisah?