I think Pyaudio is the acoustic signal processing module that can be used in Python, but it's hard to use personally! Also, once it became unusable during development on Windows, Pyaudio has a light trauma, and I would like to introduce a Sound device that can control the audio interface based on ASIO.
・ Can control ASIO devices -Easy input / output channel mapping (microphone and speaker distribution) ・ Easy control of WASAPI and core audio ・ Easy to write and easy to use ・ Simultaneous recording / playback is super easy (I'm glad that it is very easy for people who are doing acoustic engineering to measure impulse response)
In this article, I will write about the preparation before using the sound device, the initial setting method for using it, and the basic playback method, recording method, simultaneous recording / playback method, and streaming method on the sound device.
For the channel mapping method (input from your favorite microphone and output from your favorite speaker in a multi-channel environment) and the detailed setting method of ASIO, WASAPI, Core Audio, etc., see the second part Sound signal processing module that can be used with Python Sounddevice ASIO [ Application] I would like to write.
If you installed Sounddevice on macOS or Windows using pip, the PortAudio library will be downloaded automatically. When installing on other platforms, please install each library.
import sounddevice as sd
import numpy as np #NumPy is basically required. Please import.
import wave #Import if you want to work with audio files
Since sounddevice handles data with a basic NumPy array, it is necessary to import NumPy. However, there is also a way to handle data without using NumPy, which will be described later.
With sounddevice, you can also preset the sample rate and number of channels that can be used by default, and the audio interface to be used. Of course, you can set it each time without setting it. In this article, I will describe both the case where the default setting is set and the case where it is not set, but for the time being, I will write how to set the default.
default_fs.py
fs = 44100 #Usually 41000Hz or 48000Hz
sd.default.samplerate = fs
The number of channels to output is automatically set from the data input to the function, but you need to specify the number of input channels yourself.
default_ch.py
channels = 2
sd.default.channels = channels
#sd.default.channels = 1,You can also set the number of channels as 2 respectively
First, get the device ID of the audio system installed or connected to your environment.
default_system.py
sd.query_devices()
When I typed it in the command prompt, I got the following output in my environment:
> 0 Built-in Microphone, Core Audio (2 in, 0 out)
< 1 Built-in Output, Core Audio (0 in, 2 out)
2 Pro Tools Equipment Set, Core Audio (2 in, 2 out)
Currently the input is set to ID 0 and the output is set to ID 1. If you have a machine connected to an ASIO device
3 〇〇Audio system, ASIO (24 in, 24 out)
Is output as. After confirming the device ID you want to use, set as follows.
default_system.py
sd.default.device = 3
# sd.default.device = [4, 5]You can also set each input / output as.
When recording, it is recorded with'float32'by default, but if you want to record with a different data type, set as follows.
default_dtype.py
sd.default.dtype = 'float64'
Cancels the set initial settings
default_reset.py
sd.default.reset()
When executed, the function will return immediately but will continue to play in the background.
playback.py
sd.play(myarray,fs)
# myarray :NumPy array holding audio data
# fs :Sample rate
Arguments can be reduced if the sample rate is initialized.
playback.py
sd.play(myarray)
Here's what the other options look like.
playback.py
sd.play(data,
samplerate=None,
mapping=None, #Channel mapping settings (explained in the second part)
blocking=False, #True to prevent the function from returning (waits during playback)
loop=False, #Loop play with True
**kwargs)
Stop playing the sound.
stop.py
sd.stop()
Record the acquired audio data in a NumPy array. By default, array data is recorded as'float32'. When executed, the function returns immediately, but continues recording in the background.
rec.py
duration = 10.5 #Playback time[Seconds]
recdata = sd.rec(int(duration * fs), samplerate = fs,channels = 2)
#Number of taps, sample rate, number of channels
You can reduce the number of arguments when you make the initial settings.
rec.py
recdata = sd.rec(int(duration * fs))
If you want to know if the recording is complete, use the following function. This function returns immediately if the recording is complete, and returns after the recording is complete if it is not. It can also be used when you want to move on to the next phase after recording is complete.
rec.py
sd.wait()
Other options are as follows
rec.py
recdata = sd.rec(frames=None,#Option: Not required if the number of recorded frames out is specified
samplerate=None,
channels=None,#Number of channels Not required if mapping or out is specified
dtype=None,#Data type setting
out=None,#Write the recorded data to an arbitrary array
mapping=None,#Channel mapping settings (explained in the second part)
blocking=False,#True to wait while recording
**kwargs)
You can play and record the Array at the same time. The number of output channels is automatically set from the given data, but you can set the number of input channels yourself.
playrec.py
recdata = sd.playrec(myarray,fs,channels = 2)
If the default sample rate and the number of channels are set by default, the description can be omitted as usual.
playrec.py
recdata = sd.playrec(myarray)
Click here for other options
playrec.py
recdata = sd.playrec(data,
samplerate=None,
channels=None,#If there is no setting of the number of output channels, it is automatically determined from the data
dtype=None,#Data type setting
out=None,#Write the recorded data to an arbitrary array
input_mapping=None,#Input channel mapping settings
output_mapping=None,#Output channel mapping settings
blocking=False,#True to wait while recording
**kwargs)
The sound captured by the microphone is sent to the speaker as it is.
stream.py
duration = 5.5 # seconds
def callback(indata, outdata, frames, time, status):
if status:
print(status)
outdata[:] = indata
with sd.Stream(channels=2, callback=callback):
sd.sleep(int(duration * 1000))
Also note that sd.sleep here can freeze the next call at any time, but it's not very accurate.
sleep.py
sd.sleep(msec)
I think this is enough for easy usage. For the channel mapping method (input from your favorite microphone and output from your favorite speaker in a multi-channel environment) and the detailed setting method of ASIO, WASAPI, Core Audio, etc., see the second part Sound signal processing module that can be used with Python Sounddevice ASIO [ Application] I would like to write.
Python sound device official Sound signal processing module that can be used with Python Sounddevice ASIO [Application]
Recommended Posts