python perekaman audio pyaudio

Aug 31 2020

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

1 Azr Sep 08 2020 at 03:31

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.

user0814 Sep 15 2020 at 09:00

Dengan menggunakan print(sd.query_devices()), saya melihat daftar perangkat seperti di bawah ini:

  1. Microsoft Sound Mapper - Input, MME (2 masuk, 0 keluar)
  2. Mikrofon (AudioHubNano2D_V1.5, MME (2 in, 0 out)
  3. Mikrofon Internal (Conexant S, MME (2 masuk, 0 keluar)
  4. ...

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?