简体   繁体   English

Mac OS El Capitan用python录制声音

[英]Mac os El Capitan recording sound with python

I'm trying to record sound from mic. 我正试图从麦克风中录制声音。 Firstly as used PyAudio then sounddevice but both failed. 首先使用PyAudio然后声音设备,但都失败了。

Here is code for PyAudio: 这是PyAudio的代码:

import pyaudio


def _recording_loop(samples_queue, running, stream, chunk_size):
    stream.start_stream()

    while running.is_set():
        samples_queue.put(stream.read(chunk_size))

    stream.stop_stream()


class Recoder:

    def __init__(self, frame_rate, period):
        self.proc = None
        self.running = Event()
        self.samples_queue = Queue()
        self.frame_rate = frame_rate
        self.chunk_size = (frame_rate*period) / 1000
        self.channels = 1

        self._pa = pyaudio.PyAudio()
        self._stream = None

    def start(self):
        if self.proc is None:
            self._stream = self._pa.open(format=pyaudio.paInt8,
                                         channels=self.channels,
                                         rate=self.frame_rate,
                                         input=True,
                                         frames_per_buffer=self.chunk_size)

            self.running.set()
            self.proc = Process(target=_recording_loop, args=[self.samples_queue, self.running, self._stream,
                                                              self.chunk_size])
            self.proc.start()

    def stop(self):
        if self.proc is not None:
            self.running.clear()
            self.proc.join()

        self._stream.close()
        self._pa.terminate()

    def empty(self):
        return self.samples_queue.empty()

    def read(self):
        res = []
        while not self.samples_queue.empty():
            res.append(self.samples_queue.get())
    return res

It gives me a warning: Python[21648:645093] 13:42:01.242 WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h. 它给了我一个警告: Python[21648:645093] 13:42:01.242 WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h. Python[21648:645093] 13:42:01.242 WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h. and nothing is ever recorded. 并没有记录任何东西。

As I understand it's something with El Capitan and not solved yet. 据我所知,这与El Capitan有关,尚未解决。 But maybe I'm wrong? 但也许我错了?

So I decided to switch library to sounddevice: 所以我决定将库切换到sounddevice:

from multiprocessing import Process, Queue, Event
import sounddevice as sd


def _recording_loop(samples_queue, running, frame_rate, chunk_size):
    while running.is_set():
        samples_queue.put(sd.rec(chunk_size, samplerate=frame_rate, channels=1,
                                 dtype='int8', blocking=True))


class Recoder:

    def __init__(self, frame_rate, period):

        self.proc = None
        self.running = Event()
        self.samples_queue = Queue()
        self.frame_rate = frame_rate
        self.period = period

        self.chunk_size = (frame_rate * period) / 1000

    def start(self):
        if self.proc is None:
            self.running.set()
            self.proc = Process(target=_recording_loop, args=[self.samples_queue, self.running, self.frame_rate,
                                                              self.chunk_size])
            self.proc.start()

    def stop(self):
        if self.proc is not None:
            self.running.clear()
            self.proc.join()

    def empty(self):
        return self.samples_queue.empty()

    def read(self):
        res = []
        while not self.samples_queue.empty():
            res.append(self.samples_queue.get())

        return res

And it says: 它说:

||PaMacCore (AUHAL)|| Warning on line 530: err=''who?'', msg=Audio Hardware: Unknown Property
||PaMacCore (AUHAL)|| Warning on line 534: err=''who?'', msg=Audio Hardware: Unknown Property
||PaMacCore (AUHAL)|| Warning on line 445: err=''who?'', msg=Audio Hardware: Unknown Property

And again nothing is recorded. 再也没有记录。 What I'm doing wrong? 我做错了什么?

sounddevice.rec() is not meant to be used like that. sounddevice.rec()不应该像那样使用。 You just call it with the number of frames you want to record and that's it (see the example from the docs ): 你只需要用你想要记录的帧数来调用它( 就是文档中例子 ):

import sounddevice as sd

fs = 44100
duration = 10  # seconds
myrecording = sd.rec(duration * fs, samplerate=fs, channels=2,
                     blocking=True)

That's it. 而已。 You don't need half a page of code just to record some sound. 您只需记录一些声音就不需要半页代码。

BTW, you can ignore the warning for now, see https://github.com/spatialaudio/python-sounddevice/issues/10 . 顺便说一句,您现在可以忽略该警告,请参阅https://github.com/spatialaudio/python-sounddevice/issues/10

Yesterday I ran into similar problem. 昨天我遇到了类似的问题。 It seems that it's caused by using multiprocessing with sounddevice. 它似乎是由使用声音设备的多处理引起的。 When I do import sounddevice at the top of the module I get ||PaMacCore (AUHAL)|| Warning on line 530: err=''who?'', msg=Audio Hardware: Unknown Property 当我在模块的顶部import sounddevice时,我得到||PaMacCore (AUHAL)|| Warning on line 530: err=''who?'', msg=Audio Hardware: Unknown Property ||PaMacCore (AUHAL)|| Warning on line 530: err=''who?'', msg=Audio Hardware: Unknown Property and then the app just hangs while creating sounddevice.RawInputStream . ||PaMacCore (AUHAL)|| Warning on line 530: err=''who?'', msg=Audio Hardware: Unknown Property ,然后应用程序在创建sounddevice.RawInputStream挂起。 When I import sounddevice in my run() method (I am creating a new class based on multiprocessing.Process ) it works fine. 当我在run()方法中导入sounddevice时(我正在创建一个基于multiprocessing.Process的新类),它工作正常。 For me it seems that sounddevice does something to initialise itself right after being imported and this must happen in the same process that will use it. 对我来说,似乎sounddevice在导入后会立即初始化,这必须在使用它的同一个进程中发生。 Edit: instead of Multiprocessing use Threading . 编辑:而不是Multiprocessing使用Threading

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM