Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
import argparse
import logging
log = logging.getLogger(__name__)
# To use, cd into helpers directory, run >> python demo/sound_card_demo.py "filename"
# Example: python demo/sound_card_demo.py "../static/sounds/chime.wav"
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("filename", help="audio file to be played back")
parser.add_argument("-d", "--device", type=int, help="device ID")
args = parser.parse_args()
try:
import sounddevice as sd
import soundfile as sf
devices = sd.query_devices()
print(devices)
data, fs = sf.read(args.filename, dtype='float32')
sd.play(data, fs, device=args.device, blocking=True)
status = sd.get_status()
if status:
log.warning(str(status))
except BaseException as e:
# This avoids printing the traceback, especially if Ctrl-C is used.
raise SystemExit(str(e))
if any(c < 1 for c in args.channels):
parser.error("argument CHANNEL: must be >= 1")
mapping = [c - 1 for c in args.channels] # Channel numbers start with 1
q = queue.Queue()
try:
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
import numpy as np
import sounddevice as sd
if args.list_devices:
print(sd.query_devices())
parser.exit(0)
if args.samplerate is None:
device_info = sd.query_devices(args.device, "input")
args.samplerate = device_info["default_samplerate"]
length = int(args.window * args.samplerate / (1000 * args.downsample))
plotdata = np.zeros((length, len(args.channels)))
fig, ax = plt.subplots()
lines = ax.plot(plotdata)
if len(args.channels) > 1:
ax.legend(
["channel {}".format(c) for c in args.channels],
loc="lower left",
ncol=len(args.channels),
)
ax.axis((0, len(plotdata), -1, 1))
ax.set_yticks([0])
ax.yaxis.grid(True)
import sounddevice as sd
self.recording_paused_changed.clear()
if input_device is None:
input_device = self.input_device
if input_device is None:
input_device = self._get_default_device('input')
if output_device is None:
output_device = self.output_device
if output_device is None:
output_device = self._get_default_device('output')
if sample_rate is None:
dev_info = sd.query_devices(input_device, 'input')
sample_rate = int(dev_info['default_samplerate'])
if blocksize is None:
blocksize = self.output_blocksize
def audio_callback(indata, outdata, frames, time, status):
while self._get_recording_state() == RecordingState.PAUSED:
self.recording_paused_changed.wait()
if status:
self.logger.warning('Recording callback status: {}'.format(
str(status)))
outdata[:] = indata
host_api_names = get_host_api_names()
for i in range(len(host_api_names)):
host_api_names[i] = host_api_names[i].replace('Windows ', '')
if host_api is not None:
host_api = host_api.replace('Windows ', '')
# Host API check pattern
host_api_pattern = f'({"|".join([re.escape(name) for name in host_api_names])})$'
# Find with the given name
device = None
if re.search(host_api_pattern, device_name):
# Host API in the name, this should return only one device
device = sd.query_devices(device_name, kind=kind)
if device[f'max_{kind}_channels'] < min_channels:
# Channel count not satisfied
raise DeviceNotFoundError(f'Found {kind} device "{device["name"]} {host_api_names[device["hostapi"]]}"" '
f'but minimum number of channels is not satisfied. 1')
elif not re.search(host_api_pattern, device_name) and host_api is not None:
# Host API not specified in the name but host API is given as parameter
try:
# This should give one or zero devices
device = sd.query_devices(f'{device_name} {host_api}', kind=kind)
except ValueError:
# Zero devices
raise DeviceNotFoundError(f'No device found with name "{device_name}" and host API "{host_api}". ')
if device[f'max_{kind}_channels'] < min_channels:
# Channel count not satisfied
raise DeviceNotFoundError(f'Found {kind} device "{device["name"]} {host_api_names[device["hostapi"]]}" '
f'but minimum number of channels is not satisfied.')
def get_input_devices(self):
devices = sounddevice.query_devices()
# early exit if there is no input device. Otherwise query_devices(kind='input') fails
input_devices = [device for device in devices if device['max_input_channels'] > 0]
if len(input_devices) == 0:
return []
try:
default_input_device = sounddevice.query_devices(kind='input')
except sounddevice.PortAudioError:
self.logger.exception("Failed to query the default input device")
default_input_device = None
input_devices = []
if default_input_device is not None:
# start by the default input device
channels = None
if duration_min < max(attack, release):
raise ValueError('minimum duration is too short')
fade_in = np.linspace(0, 1, num=int(samplerate * attack))
fade_out = np.linspace(1, 0, num=int(samplerate * release))
r = np.random.RandomState(seed)
bleeplist = []
if channels is None:
channels = sd.default.channels['output']
if channels is None:
channels = sd.query_devices(device, 'output')['max_output_channels']
for _ in range(bleeps):
duration = r.uniform(duration_min, duration_max)
amplitude = r.uniform(amplitude_min, amplitude_max)
pitch = r.uniform(pitch_min, pitch_max)
# Convert MIDI pitch (https://en.wikipedia.org/wiki/MIDI_Tuning_Standard)
frequency = 2 ** ((pitch - 69) / 12) * 440
t = np.arange(int(samplerate * duration)) / samplerate
bleep = amplitude * np.sin(2 * np.pi * frequency * t, dtype='float32')
bleep[:len(fade_in)] *= fade_in
bleep[-len(fade_out):] *= fade_out
# Note: Arrays must be 32-bit float and C contiguous!
assert bleep.dtype == 'float32'
assert bleep.flags.c_contiguous
bleeplist.append(bleep)
parser.error('HIGH must be greater than LOW')
# Create a nice output gradient using ANSI escape sequences.
# Stolen from https://gist.github.com/maurisvh/df919538bcef391bc89f
colors = 30, 34, 35, 91, 93, 97
chars = ' :%#\t#%:'
gradient = []
for bg, fg in zip(colors, colors[1:]):
for char in chars:
if char == '\t':
bg, fg = fg, bg
else:
gradient.append('\x1b[{};{}m{}'.format(fg, bg + 10, char))
try:
samplerate = sd.query_devices(args.device, 'input')['default_samplerate']
delta_f = (high - low) / (args.columns - 1)
fftsize = math.ceil(samplerate / delta_f)
low_bin = math.floor(low / delta_f)
def callback(indata, frames, time, status):
if status:
text = ' ' + str(status) + ' '
print('\x1b[34;40m', text.center(args.columns, '#'),
'\x1b[0m', sep='')
if any(indata):
magnitude = np.abs(np.fft.rfft(indata[:, 0], n=fftsize))
magnitude *= args.gain / fftsize
line = (gradient[int(np.clip(x, 0, 1) * (len(gradient) - 1))]
for x in magnitude[low_bin:low_bin + args.columns])
print(*line, sep='', end='\x1b[0m\n')
def execute(self):
self.use_custom_color = True
self.useNetworkColor = False
self.color = (0.85,1,0.85)
inpDev = int(self.modeI)
outDev = int(self.modeO)
channI = sd.query_devices(int(inpDev)).get('max_input_channels')
channO = sd.query_devices(int(outDev)).get('max_output_channels')
streamI = sd.InputStream(device=inpDev,latency='low')
self.chans = streamI.channels
if self.runSD:
if not streamI.active:
streamI.start()
self.message = str(streamI)
myTuple = streamI.read(1)
l_chan = round(myTuple[0][0][0] * self.multI,5)
if self.chans == 2:
r_chan = round(myTuple[0][0][1] * self.multI,5)
else:
r_chan = 0
else:
if streamI.active:
# Shtdown Stream and close SD
streamI.abort(ignore_errors=True)