def start(self, send=True, receive=True): """ Start audio I/O stream and processing thread """ if receive: sd.check_input_settings(device=self.input_device, channels=1, dtype=self.sample_size, samplerate=self.sdk.sample_rate) self.processing = AudioProcessingThread(parent=self) self.input_stream = sd.RawInputStream(device=self.input_device, channels=1, samplerate=int( self.sdk.sample_rate), dtype=self.sample_size, blocksize=self.block_size, callback=self.process_input) self.input_stream.start() if send: sd.check_output_settings(device=self.output_device, channels=self.output_channels, dtype=self.sample_size, samplerate=self.sdk.sample_rate) self.output_stream = sd.RawOutputStream( device=self.output_device, channels=self.output_channels, samplerate=int(self.sdk.sample_rate), dtype=self.sample_size, blocksize=self.block_size, callback=self.process_output) self.output_stream.start()
def checkfs(): """ Verify the sample frequencies supported by the sound card and the API. Many systems have a high, fixed frequency, but some (ex: Mac OSX) also can provide down-sampled data Parameters ---------- None Returns ------- supported samplerates, as a list that is a subset of the possible sample rates """ possibleSamplerates = [1000, 2000, 4000, 8000, 11025, 22050, 32000, 44100, 48000, 96000, 128000] device = sd.default.device[0] supported_samplerates = [] for fs in possibleSamplerates: try: sd.check_input_settings(device=device, samplerate=int(fs), channels=NChannels) except Exception as e: print(fs, e) else: supported_samplerates.append(fs) return supported_samplerates
def test_rates(rates): for r in rates: try: sounddevice.check_input_settings(samplerate=int(r*1000)) print('\t%.1f kHz OK' % r) except sounddevice.PortAudioError: print('\t%.1f kHz not supported!' % r)
def single_measurement(self, type=None): # little workaround of a problem with using ASIO from multiple threads # https://stackoverflow.com/questions/39858212/python-sounddevice-play-on-threads default_device = sd.query_devices(sd.default.device[0]) default_api = sd.query_hostapis(default_device['hostapi']) if default_api['name'] == 'ASIO': sd._terminate() sd._initialize() self.recorded_sweep_l = [] self.recorded_sweep_r = [] self.feedback_loop = [] if type is 'hpc': excitation = self.excitation_hpc else: excitation = self.excitation if not self.dummy_debugging: time.sleep(0.3) try: sd.check_input_settings(channels=self.num_input_channels_used) sd.check_output_settings(channels=self.num_output_channels_used) except: print( "Audio hardware error! Too many channels or unsupported samplerate" ) return # do measurement recorded = sd.playrec(excitation, channels=self.num_input_channels_used) sd.wait() # get the recorded signals if self.channel_layout_input[0] >= 0: self.recorded_sweep_l = recorded[:, self.channel_layout_input[0]] else: self.recorded_sweep_l = np.zeros(np.size(recorded, 0)) if self.channel_layout_input[1] >= 0: self.recorded_sweep_r = recorded[:, self.channel_layout_input[1]] else: self.recorded_sweep_r = np.zeros(np.size(recorded, 0)) if self.feedback_loop_used: self.feedback_loop = recorded[:, self.channel_layout_input[2]] if abs(self.feedback_loop.max()) < 0.0001: self.feedback_loop = np.random.random_sample( self.feedback_loop.shape ) * 0.000001 # to avoid zero-division errors else: # if no FB loop, copy from original excitation sweep if type is 'hpc': self.feedback_loop = self.sweep_hpc_mono[:, 0] else: self.feedback_loop = self.sweep_mono[:, 0]
def bound_sample_rate(self) -> None: try: # can't find min/max sample rate allowed so just catch the exception sd.check_input_settings(device=self._device_number, samplerate=self._sample_rate_sps) except sd.PortAudioError: self._error += f"Unsupported audio source sample rate {self._sample_rate_sps/1e6}Msps, setting 0.048Msps" logger.error(self._error) self._sample_rate_sps = 48000.0
def __init__(self, device = None, rate = None, updates_per_second = 1000, n_channels = 1, sample_type = np.float32, buffer_seconds = 1.0, buffer_fold = 0.5, verbose = False): self.verbose = verbose self.lock = threading.Lock() self.sample_type = sample_type self.device_dict = sd.query_devices() try: sd.check_input_settings(device=device, channels=n_channels, dtype=sample_type, extra_settings=None, samplerate=rate) except: rate = device = n_channels = sample_type = None self.rate = rate if rate is not None: sd.default.samplerate = rate self.device = device if device is not None: sd.default.device = device self.wav_data = None self.update_window_n_frames = int((self.rate / updates_per_second + 1)//2*2) self.stream = sd.InputStream( samplerate=self.rate, blocksize=self.update_window_n_frames, device=self.device, channels=n_channels, dtype=sample_type, latency='low', extra_settings=None, callback=self.non_blocking_stream_read) self.rate = self.stream.samplerate self.device = self.stream.device self.updates_per_second = self.rate / self.update_window_n_frames self.array_length = int(self.rate * buffer_seconds + 0.5) self.info = '' self.new_data = False self.device_latency = self.device_dict[self.device]['default_low_input_latency'] self.infos = {'overview': str(sd.query_devices()).splitlines(), 'device_list': list(sd.query_devices())} self.wav_time = None # always starts from zero super().__init__(self.stream._channels, self.array_length, fold_portion=buffer_fold, dtype=self.sample_type)
def __init__(self): try: sd.check_input_settings('wm8960') except ValueError: raise AIModuleFaultsException( "AI Mic not found! Please contact our CS team.") self.RATE = 44100 for idx, device in enumerate(sd.query_devices()): if 'wm8960' in device: sd.default.device = idx break
def test_soundcard(i="default",o="default", fs=fs, ch=2): dummy1sec = zeros(int(fs)) print( 'Trying:' ) print(f' {sd.query_devices(i, kind="input" )["name"]}') print(f' {sd.query_devices(o, kind="output")["name"]}') try: sd.default.device = i, o except Exception as e: print( f'(!) Error accesing devices [{i},{o}]: {e}' ) return e try: chk_rec = sd.check_input_settings (i, channels=ch, samplerate=float(fs)) chk_pb = sd.check_output_settings(o, channels=ch, samplerate=float(fs)) print( f'Sound card parameters OK' ) except Exception as e: print( f'(!) Sound card [{i},{o}] ERROR: {e}' ) return e try: dummy = sd.playrec(dummy1sec, samplerate=fs, channels=ch) print( 'Sound device settings are supported' ) except Exception as e: print( f'(!) FAILED to playback and recording on selected device: {e}' ) return e return 'ok'
def setup_audio_devices(self, sample_rate): input_devices = [] output_devices = [] for device in sd.query_devices(): # Check if valid input try: sd.check_input_settings(device=device["name"], samplerate=sample_rate) input_devices.append(device["name"]) except: pass # Check if valid output try: sd.check_output_settings(device=device["name"], samplerate=sample_rate) output_devices.append(device["name"]) except Exception as e: # Log a warning only if the device is not an input if not device["name"] in input_devices: warn( "Unsupported output device %s for the sample rate: %d \nError: %s" % (device["name"], sample_rate, str(e))) if len(input_devices) == 0: self.log("No audio input device detected. Recording may not work.") self.audio_in_devices_cb.addItems(["None"]) self.audio_in_devices_cb.setDisabled(True) else: self.audio_in_devices_cb.clear() self.audio_in_devices_cb.addItems(input_devices) self.audio_in_devices_cb.currentTextChanged.connect( self.set_audio_device) if len(output_devices) == 0: self.log( "No supported output audio devices were found! Audio output may not work." ) self.audio_out_devices_cb.addItems(["None"]) self.audio_out_devices_cb.setDisabled(True) else: self.audio_out_devices_cb.clear() self.audio_out_devices_cb.addItems(output_devices) self.audio_out_devices_cb.currentTextChanged.connect( self.set_audio_device) self.set_audio_device()
def log_supported_input_formats(self, device): samplerates = [22050, 44100, 48000, 96000] dtypes = [float32, int16, int8] supported_formats = [] for samplerate in samplerates: for dtype in dtypes: try: sounddevice.check_input_settings( device=device['index'], channels=device['max_input_channels'], dtype=dtype, extra_settings=None, samplerate=samplerate) supported_formats += [f"{samplerate} Hz, {np.dtype(dtype).name}"] except Exception: pass # check_input_settings throws when the format is not supported api = sounddevice.query_hostapis(device['hostapi'])['name'] self.logger.info(f"Supported formats for '{device['name']}' on '{api}': {supported_formats}")
def captureSegment(self, duration=1.0): """ Read a segment of input from the sound card. Blocks until the input is complete. Parameters ---------- duration : float (default: 1.0) seconds duration of segment to record Returns ------- Nothing """ if self.device is not None: try: sd.check_input_settings(self.device, samplerate=int(self.fs), channels=self.NChannels) except: raise ValueError('Invalid sample rate for input device') self.currentSegment = sd.rec(int(duration * self.fs), samplerate=int(self.fs), blocking=True, channels=2) self.currentSegment = scipy.signal.decimate(self.currentSegment[:,1], self.decimate) self.sampleFreq = (self.fs)/self.decimate self.lastTimes = np.linspace(0, duration, self.currentSegment.shape[0]) else: # read from adruino/olimex Ard.send_command('a') time.sleep(Ard.sampleduration*2.+0.2) Ard.wait_response(timeout=2.) b = Ard.read_data_buffer() if len(b) == 0: return b = '[' + b + ']' ib = np.array(eval(b)) self.currentSegment = ib # scipy.signal.decimate(ib, self.decimate) self.currentSegment = self.currentSegment - np.mean(self.currentSegment) self.sampleFreq = (1./self.fs)# /self.decimate print self.sampleFreq self.lastTimes = np.linspace(0, duration, len(self.currentSegment))
def get_device(name='CABLE Input', kind='output', api=0): if isinstance(name, int): return name, sd.query_devices(name) devices = sd.query_devices() matching_devices = [] for device_id in range(len(devices)): if name.lower() in devices[device_id].get('name').lower(): try: if kind == 'input': sd.check_input_settings(device_id) elif kind == 'output': sd.check_output_settings(device_id) else: print('Invalid kind') return None matching_devices.append((device_id, devices[device_id])) except: pass if not matching_devices: print("Unable to find device matching name", name, 'of kind', kind) return None found = False if isinstance(api, int): api = sd.query_hostapis(api).get('name') for device_id, device in matching_devices: if api in sd.query_hostapis(int( device.get('hostapi'))).get('name'): found = True break if not found: print("Unable to find device matching host api", api, 'using first available...') return matching_devices[0] else: return device_id, device
def set_input_device(self, index): """Attempts to set the audio input device. Parameters ---------- index : int The application's index of the input device Notes ----- Emits the `input_device_changed_signal` with the index of the current audio input device. """ if index != self.get_current_input_device_index(): device = self._input_devices[index] try: sound.check_input_settings(device=device['name']) sound.default.device[0] = device['name'] except ValueError: self._logger.push("Input device not supported") self.input_device_changed_success_signal.emit(self.get_current_input_device_index())
def update_available_samplerates(self): # define supported samplerates samplerates = [44100, 48000, 88200, 96000] # add the current devices default samplerate default_input_device = sd.query_devices(sd.default.device[0]) default_output_device = sd.query_devices(sd.default.device[1]) try: samplerates.append(int(default_input_device['default_samplerate'])) samplerates.append(int( default_output_device['default_samplerate'])) except: pass samplerates = list(set(samplerates)) samplerates.sort() # check if both devices support the samplerates for i in range(np.size(samplerates)): try: sd.check_input_settings(samplerate=samplerates[i]) sd.check_input_settings(samplerate=samplerates[i]) except sd.PortAudioError: samplerates.remove(samplerates[i]) if len(samplerates) == 0: print( "Audio device does not support samplerates 44.1, 48, 88.2 or 96" ) self.samplerate_box.clear() for fs in samplerates: self.samplerate_box.addItem(str(fs)) if 48000 in samplerates: self.samplerate_box.setCurrentText(str(48000)) else: self.samplerate_box.setCurrentText(str(samplerates[0]))
def __init__(self, args): def audio_callback(indata, outdata, frames, time, status): '''Called by audio stream for each new buffer.''' indataQ.append(indata[::, LEFT]) if self.out_enable: outdata[:, LEFT] = self.out_sig else: outdata.fill(0) self.cumulated_status |= status return None self.args = args self.out_enable = False sd.default.device = [args.input_dev, args.output_dev] sd.default.channels = 2 sd.default.dtype = None sd.default.latency = None sd.default.samplerate = args.sample_rate sd.default.blocksize = args.buff_size sd.default.clip_off = True sd.default.dither_off = args.dither sd.default.never_drop_input = None sd.default.prime_output_buffers_using_stream_callback = None # Checks will throw errors for invalid settings. sd.check_input_settings() sd.check_output_settings() # Will store sounddevice status flags on buffer under/overflows, etc. self.cumulated_status = sd.CallbackFlags() # Will store data to write to output buffer. self.out_sig = None # Create the stream self.audio_stream = sd.Stream(callback=audio_callback)
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Amazon Software License (the "License"). You may not # use this file except in compliance with the License. A copy of the # License is located at: # http://aws.amazon.com/asl/ # or in the "license" file accompanying this file. This file is distributed # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, expressi # or implied. See the License for the specific language governing permissions # and limitations under the License. import sounddevice as sd samplerates = 16000, 32000, 44100, 48000, 96000, 128000 device = 2 supported_samplerates = [] for fs in samplerates: try: sd.check_input_settings(device=device, samplerate=fs) except Exception as e: print(fs, e) else: supported_samplerates.append(fs) print(supported_samplerates)
# p.terminate() import sounddevice as sd import pyaudio samplerates = 16000, 32000, 44100, 48000, 96000, 128000 #device = 3 #print(sd.query_devices()) for device in sd.query_devices(): supported_samplerates = [] for fs in samplerates: try: sd.check_input_settings(device=device['name'], samplerate=fs) except Exception as e: pass #print(fs, e) else: supported_samplerates.append(fs) if len(supported_samplerates) > 0: print(device) print(supported_samplerates) print("----") # p = pyaudio.PyAudio() # info = p.get_host_api_info_by_index(0) # numdevices = info.get('deviceCount') # for i in range(0, numdevices): # if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0: # print("Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name'))
import stimulus as stim import _parseargs as parse import utils as utils # --- Parse command line arguments and check defaults flag_defaultsInitialized = parse._checkdefaults() args = parse._parse() parse._defaults(args) # ------------------------------- if flag_defaultsInitialized == True: if args.listdev == True: print(sd.query_devices()) sd.check_input_settings() sd.check_output_settings() print("Default input and output device: ", sd.default.device) elif args.defaults == True: aa = np.load('_data/defaults.npy', allow_pickle=True).item() for i in aa: print(i + " => " + str(aa[i])) elif args.setdev == True: sd.default.device[0] = args.inputdevice sd.default.device[1] = args.outputdevice sd.check_input_settings() sd.check_output_settings() print(sd.query_devices())
args.samplerate = int(device_info['default_samplerate']) model = vosk.Model(args.model) if args.filename: dump_fn = open(args.filename, "wb") else: dump_fn = None print("Available devices are:") print(sd.query_devices()) print("Default device is: " + str(sd.default.device)) print("Checking device %s ..." % str(args.device)) print( sd.check_input_settings(device=args.device, channels=1, dtype='int16', samplerate=args.samplerate)) with sd.RawInputStream(samplerate=args.samplerate, blocksize=16000, device=args.device, dtype='int16', channels=1, callback=callback): print('#' * 80) print('Press Ctrl+C to stop the recording') print('#' * 80) rec = vosk.KaldiRecognizer(model, args.samplerate) while True: data = q.get()
def check(self, dev): sounddevice.check_input_settings(device=dev.index, dtype=self.format, samplerate=self.rate)
def __init__(self, device = None, rate = None, updates_per_second = 1000, FFT_window_size = None, verbose = False): print("Available audio devices:") device_dict = sd.query_devices() print(device_dict) try: sd.check_input_settings(device=device, channels=1, dtype=np.float32, extra_settings=None, samplerate=rate) except: print("Input sound settings for device %s and samplerate %s Hz not supported, using defaults..." %(str(device), str(rate))) rate = None device = None self.rate = rate if rate is not None: sd.default.samplerate = rate self.device = device if device is not None: sd.default.device = device self.verbose = verbose self.data_buffer = None # This part is a bit hacky, need better solution for this: # Determine what the optimal buffer shape is by streaming some test audio self.optimal_data_lengths = [] with sd.InputStream(samplerate=self.rate, blocksize=0, device=self.device, channels=1, dtype=np.float32, latency='low', callback=self.test_stream_read): time.sleep(0.2) self.update_window_n_frames = max(self.optimal_data_lengths) del self.optimal_data_lengths #Alternative: #self.update_window_n_frames = round_up_to_even(44100 / updates_per_second) self.stream = sd.InputStream( samplerate=self.rate, blocksize=self.update_window_n_frames, device=None, channels=1, dtype=np.float32, latency='low', extra_settings=None, callback=self.non_blocking_stream_read) self.rate = self.stream.samplerate self.device = self.stream.device self.updates_per_second = self.rate / self.update_window_n_frames self.info = '' self.data_capture_delays = deque(maxlen=20) self.new_data = False if self.verbose: self.data_capture_delays = deque(maxlen=20) self.num_data_captures = 0 self.device_latency = device_dict[self.device]['default_low_input_latency'] print("\n##################################################################################################") print("\nDefaulted to using first working mic, Running on mic %s with properties:" %str(self.device)) print(device_dict[self.device]) print('Which has a latency of %.2f ms' %(1000*self.device_latency)) print("\n##################################################################################################") print('Recording audio at %d Hz\nUsing (non-overlapping) data-windows of %d samples (updating at %.2ffps)' %(self.rate, self.update_window_n_frames, self.updates_per_second))