来自麦克风的输入以产生频谱图

Input from microphone to produce spectrogram

我正在尝试从麦克风获取输入并从音频块中生成频谱图。 然而,这行代码 stream = self.pa.open(format = self.pa.get_format_from_width(2,False), channels = 1, rate = RATE, input = True, input_device_index = device_index) 给我一个错误提示“[Errno -9996] 无效输入设备(无默认输出设备)”。我正在录音的麦克风是我的 HP ProBook 上的默认麦克风,我使用的是 Windows 10。另外,我 运行 使用 Google collab 的代码。有什么问题的建议吗?

import pyaudio
import struct
import math
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import time
from scipy.io.wavfile import write

THRESHOLD = 0 # dB
RATE = 44100
INPUT_BLOCK_TIME = 1 # 30 ms
INPUT_FRAMES_PER_BLOCK = int(RATE * INPUT_BLOCK_TIME)
INPUT_FRAMES_PER_BLOCK_BUFFER = int(RATE * INPUT_BLOCK_TIME)

def get_rms(block):
  return np.sqrt(np.mean(np.square(block)))

class AudioHandler(object):
  def __init__(self):
    self.pa = pyaudio.PyAudio()
    self.stream = self.open_mic_stream()
    self.threshold = THRESHOLD
    self.plot_counter = 0

  def stop(self):
    self.stream.close()

  def find_input_device(self):
    device_index = None
    for i in range( self.pa.get_device_count() ):
      devinfo = self.pa.get_device_info_by_index(i)
      print('Device %{}: %{}'.format(i, devinfo['name']))

      for keyword in ['mic','input']:
        if keyword in devinfo['name'].lower():
          print('Found an input: device {} - {}'.format(i, devinfo['name']))
          device_index = i
          return device_index

    if device_index == None:
      print('No preferred input found; using default input device.')

    return device_index

  def open_mic_stream(self):
    device_index = self.find_input_device()
    stream = self.pa.open(format = self.pa.get_format_from_width(2,False), channels = 1, rate = RATE, input = True, input_device_index = device_index)
    stream.start_stream()
    return stream

  def processBlock(self, snd_block):
    f, t, Sxx = signal.spectrogram(snd_block, RATE)
    zmin = Sxx.min()
    zmax = Sxx.max()
    plt.pcolormesh(t, f, Sxx, cmap='RdBu', norm=LogNorm(vmin=zmin, vmax=zmax))
    plt.ylabel('Frequency [Hz]')
    plt.xlabel('Time [sec]')
    plt.axis([t.min(), t.max(), f.min(), f.max()])
    plt.colorbar()
    plt.savefig('data/spec{}.png'.format(self.plot_counter), bbox_inches='tight')
    plt.close()
    write('data/audio{}.wav'.format(self.plot_counter),RATE,snd_block)
    self.plot_counter += 1

  def listen(self):
    try:
      print ("start"), self.stream.is_active(), self.stream.is_stopped() 
      total = 0
      t_snd_block = []
      while total < INPUT_FRAMES_PER_BLOCK:
        while self.stream.get_read_available() <= 0:
          print ('waiting')
          time.sleep(0.01)
        while self.stream.get_read_available() > 0 and total < INPUT_FRAMES_PER_BLOCK:
          raw_block = self.stream.read(self.stream.get_read_available(), exception_on_overflow = False)
          count = len(raw_block) / 2
          total = total + count
          print ("done"), total,count
          format = '%dh' % (count)
          t_snd_block.append(np.fromstring(raw_block,dtype=np.int16))
          snd_block = np.hstack(t_snd_block)
    except Exception as e:
      print('Error recording: {}'.format(e))
      return

    self.processBlock(snd_block)

if __name__ == '__main__':
  audio = AudioHandler()
  for i in range(0,5):
    audio.listen()

google 协作代码不会 运行 在 你的 计算机上:它 运行 在 google 服务器上,并且仅通过浏览器中 呈现的内容 与您的计算机交互,并使用键盘输入文本,然后浏览器发送它(它不发送按键事件,只发送最终文本)。

无法从 Google Collab 使用旨在与您计算机上的硬件集成的库,例如从您计算机上的设备获取音频、视频等...。

虽然浏览器应用程序可以使用您计算机上的设备,但 Google 基于 Jupyter 笔记本的 Collab 不会 翻译替代输入进入事件到 Python 应用 运行ning 就可以了。它必须创建一个虚拟化层,并且包必须将这些 'virtual devices' 识别为外围设备 - 它或多或少会重新创建世界。

因此,运行 您的本地代码,在您的计算机上并查看您获得的结果。