def multiProc(): def f(indata, q): indata = indata[:, 0] indata = librosa.core.resample(indata, 44100, 16000) fs = 16000 nfft = 512 n_fft = 128 _, _, spectrogram = sp.signal.stft(indata, fs=fs, nfft=n_fft, nperseg=n_fft) q.put(np.abs(spectrogram)) def clean(processes): for i in range(len(processes)): if processes and not processes[0].is_alive(): p = processes.pop(0) p.terminate() return processes try: import sounddevice as sd q = Queue() processes = [] plt.ion() callback_status = sd.CallbackFlags() def callback(indata, outdata, frames, time, status): global callback_status #callback_status |= status p = Process(target=f, args=( indata, q, )) processes.append(p) p.start() plt.imshow(q.get()) plt.show() plt.pause(0.0001) clean(processes) with sd.Stream(callback=callback, channels=1, samplerate=44100, blocksize=44100): print("#" * 80) print("press Return to quit") print("#" * 80) input() if callback_status: logging.warning(str(callback_status)) except BaseException as e: # This avoids printing the traceback, especially if Ctrl-C is used. raise SystemExit(str(e))
def __init__(self, device, attack, release): if attack <= 0 or release <= 0: raise ValueError("attack and release have to be positive " "and different from zero") self._stream = sd.OutputStream(device=device, callback=self._callback, channels=2) self._attack = np.round(_seconds2samples(attack / 1000)).astype(int) self._release = np.round(_seconds2samples(release / 1000)).astype(int) self._last_gain = 0 self._channel = 0 self._index = 0 target_gain = 0 slope = 0 freq = 0 self._callback_parameters = target_gain, slope, freq self._target_gain = target_gain self._callback_status = sd.CallbackFlags() self._stream.start()
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)
# latency (float): latency in seconds latency = None sendIp = ("18.85.25.231", 12341) # sendIp=("26.67.222.83", 12341) # for d in devices: print(d['name'], d['max_input_channels'], d['max_output_channels']) input_device = 3 output_device = 7 print('input: ' + devices[input_device]['name']) print('output: ' + devices[output_device]['name']) try: cumulated_status = sd.CallbackFlags() size = 128 * 1024 * 120 * 16 print('duration in minutes: {0}'.format(float(size) / samplerate / 60)) osc_io = StretchIO(sendIp) input_buffer = AnnotatedRing(size / 512, 512) stretch_group = StretchGroup(input_buffer, osc_io) shape = (0, 0) frames_elapsed = 0 samples_elapsed = 0 previous_energy = 0 last_activation = -99999999999 def button_callback(button, state): # touchOSC buttons index at one if button > len(stretch_group.stretches_list): return
def callback(indata, outdata, samples, time, status): nonlocal v try: if status: print(status) status_remaining = status # Store Recording # =============== if v.rec_position + samples > len(v.rec_pcm): raise Exception( "Insufficient space in recording buffer. We've taken too long." ) v.rec_pcm[v.rec_position:v.rec_position + samples] = indata[:] v.rec_position += samples # Analysis # ======== assert v.rec_pcm is v.fft_analyser._pcm analyses = v.fft_analyser.run(v.rec_position) #print(tones_level_list) # # Clear the first half second of the recording buffer if we've # # recorded more than one second # if v.rec_position > v.samples_per_second: # seconds_to_clear = 0.5 # seconds # samples_to_clear = int(seconds_to_clear * v.samples_per_second) # v.rec_pcm = numpy.roll(v.rec_pcm, -samples_to_clear, axis=0) # v.rec_position -= samples_to_clear # v.fft_analyser._pos -= samples_to_clear # Transitions # =========== previous_state = v.process_state if v.process_state == ProcessState.RESET: v.process_state = ProcessState.WARMUP_STREAM elif v.process_state == ProcessState.WARMUP_STREAM: if v.warmup_stream_start_time is not None: if time.currentTime - v.warmup_stream_start_time > v.warmup_stream_duration: v.process_state = ProcessState.MEASURE_SILENCE elif v.process_state == ProcessState.MEASURE_SILENCE: if v.silence_mean is not None and \ v.silence_sd is not None: if any(v.silence_mean < v.silence_mean_threshold): raise Exception( "Implausibly low mean level detected for silence; aborting." ) v.process_state = ProcessState.ABORTED elif any(v.silence_sd < v.silence_sd_threshold): raise Exception( "Implausibly low standard deviation detected for silence; aborting." ) v.process_state = ProcessState.ABORTED else: # No reason not to continue v.process_state = ProcessState.FADEIN_TONE0 v.non_silence_abort_start_time = time.currentTime print( "About to play tone. Please increase system volume until the tone is detected." ) if time.currentTime - v.state_start_time > v.silence_max_time_in_state: raise Exception("Spent too long listening to silence.") v.process_state = ProcessState.ABORTED elif v.process_state == ProcessState.FADEIN_TONE0: v.process_state = ProcessState.DETECT_TONE0 elif v.process_state == ProcessState.DETECT_TONE0: if v.non_silence_detected: v.process_state = ProcessState.MEASURE_TONE0 print( "Base tone detected. Please do not adjust system volume nor position" ) print("of microphone or speakers") if time.currentTime - v.state_start_time > v.non_silence_max_time_in_state: raise Exception( "Spent too long listening for non-silence.") v.process_state = ProcessState.ABORTED elif v.process_state == ProcessState.MEASURE_TONE0: if v.tone0_mean is not None and \ v.tone0_sd is not None: v.process_state = ProcessState.FADEOUT_TONE0 elif v.process_state == ProcessState.FADEOUT_TONE0: v.process_state = ProcessState.DETECT_SILENCE elif v.process_state == ProcessState.DETECT_SILENCE: if v.detect_silence_detected: print("Moving to MEASURE_SILENCE2") v.process_state = ProcessState.MEASURE_SILENCE2 if time.currentTime - v.state_start_time > v.detect_silence_max_time_in_state: raise Exception( "Spent too long listening for silence (the second time)." ) v.process_state = ProcessState.ABORTED elif v.process_state == ProcessState.MEASURE_SILENCE2: if v.silence_abs_pcm_mean is not None and \ v.silence_abs_pcm_sd is not None: v.process_state = ProcessState.COMPLETED elif v.process_state == ProcessState.COMPLETING: v.process_state = ProcessState.COMPLETED elif v.process_state == ProcessState.COMPLETED: pass # Set state start time if previous_state != v.process_state: v.state_start_time = time.currentTime # States # ====== if v.process_state == ProcessState.RESET: if status: print(status, "in RESET state; ignoring") # Clear all bits status_remaining = sd.CallbackFlags() # It's a requirement that outdata is always actively # filled outdata.fill(0) elif v.process_state == ProcessState.WARMUP_STREAM: # It's a requirement that outdata is always actively # filled outdata.fill(0) if status: print(status, "in WARMUP_STREAM state; ignoring") # Clear all bits status_remaining = sd.CallbackFlags() # Reset timer v.warmup_stream_start_time = None else: if v.warmup_stream_start_time == None: print("Starting warmup timer") v.warmup_stream_start_time = time.currentTime elif v.process_state == ProcessState.MEASURE_SILENCE: # It's a requirement that outdata is always actively # filled outdata.fill(0) # Ensure that we've got valid data if status.input_underflow: print(indata) assert numpy.all(indata[:] == 0) print(status, "in MEASURE_SILENCE state; ignoring") # Clear input underflow bit status_remaining.input_underflow = False # Check if the sample is acceptable: for sample_analysis in analyses: tones_level = sample_analysis["freq_levels"] # Check if levels are aceptable if tones_level is not None and all(tones_level > 0): # Check if we've listened to enough silence if len(v.silence_levels) < v.silence_threshold_samples: # Record this level v.silence_levels.append(tones_level) else: # We've now collected enough sample levels; # calculate the mean and standard deviation of the # samples taken. v.silence_mean = numpy.mean(v.silence_levels, axis=0) v.silence_sd = numpy.std(v.silence_levels, axis=0) print("silence_mean:", v.silence_mean) print("silence_sd:", v.silence_sd) print("sample size of silence:", len(v.silence_levels)) # We don't need to process the remaining levels break else: print( "Sample was either None or the levels were negative. Sample ignored." ) elif v.process_state == ProcessState.FADEIN_TONE0: print("Fading in tone #0") v.tones[0].fadein(v.fadein_tone0_duration) v.tones[0].output(outdata) elif v.process_state == ProcessState.DETECT_TONE0: if status.input_underflow: print(status, "in DETECT_TONE0 state; ignoring") status_remaining.input_underflow = False # Continue playing tone #0 v.tones[0].output(outdata) for analysis in analyses: tones_level = analysis["freq_levels"] # Calculate the number of standard deviations from silence num_sd = (tones_level[0] - v.silence_mean[0]) / v.silence_sd[0] if abs(num_sd) > v.non_silence_threshold_num_sd: # We've measured non-silence v.non_silence_samples += 1 if v.non_silence_samples > v.non_silence_threshold_samples: print("Non-silence detected") v.non_silence_detected = True else: # Reset counter v.non_silence_samples = 0 elif v.process_state == ProcessState.MEASURE_TONE0: # Continue playing tone #0 v.tones[0].output(outdata) # TODO: Should we check that we've got non-silence? for analysis in analyses: tones_level = analysis["freq_levels"] abs_pcm_mean = analysis["abs_pcm_mean"] # Save the frequency levels because we assume we're # hearing tone #0 v.tone0_levels.append(tones_level) v.tone0_abs_pcm_means.append(abs_pcm_mean) if len(v.tone0_levels) >= v.tone0_threshold_samples: # We've now collected enough samples v.tone0_mean = numpy.mean(v.tone0_levels, axis=0) v.tone0_sd = numpy.std(v.tone0_levels, axis=0) print("tone0_mean:", v.tone0_mean) print("tone0_sd:", v.tone0_sd) print("tone0 number of samples:", len(v.tone0_levels)) # Also calculate the PCM levels v.tone0_abs_pcm_mean = numpy.mean( v.tone0_abs_pcm_means) v.tone0_abs_pcm_sd = numpy.std(v.tone0_abs_pcm_means) print("tone0_abs_pcm_mean:", v.tone0_abs_pcm_mean) print("tone0_abs_pcm_sd:", v.tone0_abs_pcm_sd) print("number of samples:", len(v.tone0_abs_pcm_means)) # We don't need to process the remaining samples break elif v.process_state == ProcessState.FADEOUT_TONE0: # Fadeout tone #0 over the length of the frame fadeout_duration = samples / v.samples_per_second print("FADING OUT TONE0 over {:f} seconds".format( fadeout_duration)) v.tones[0].fadeout(fadeout_duration) v.tones[0].output(outdata) elif v.process_state == ProcessState.DETECT_SILENCE: # Actively fill the output buffer outdata.fill(0) for analysis in analyses: tones_level = analysis["freq_levels"] # Calculate the number of standard deviations from tone0 num_sd = (tones_level - v.tone0_mean) / v.tone0_sd #print(num_sd) if all(abs(num_sd) > v.detect_silence_threshold_num_sd): v.detect_silence_samples += 1 if v.detect_silence_samples >= v.detect_silence_threshold_samples: print("Silence detected") v.detect_silence_detected = True # Clear the initial measurement of silence v.silence_levels = [] else: # Reset timer #print("Resetting silence counter") v.detect_silence_samples = 0 elif v.process_state == ProcessState.MEASURE_SILENCE2: # Actively fill the output buffer outdata.fill(0) for analysis in analyses: tones_level = analysis["freq_levels"] abs_pcm_mean = analysis["abs_pcm_mean"] # Save the levels because we assume we're hearing silence v.silence_levels.append(tones_level) v.measure_silence2_abs_pcm_means.append(abs_pcm_mean) v.measure_silence2_samples += 1 # Check if we've seen sufficient samples if v.measure_silence2_samples >= v.measure_silence2_threshold_samples: # Calculate the mean and std dev v.silence_abs_pcm_mean = numpy.mean( v.measure_silence2_abs_pcm_means) v.silence_abs_pcm_sd = numpy.std( v.measure_silence2_abs_pcm_means) print("silence_abs_pcm_mean:", v.silence_abs_pcm_mean) print("silence_abs_pcm_sd:", v.silence_abs_pcm_sd) print("number of samples:", len(v.measure_silence2_abs_pcm_means)) v.silence_mean = numpy.mean(v.silence_levels, axis=0) v.silence_sd = numpy.std(v.silence_levels, axis=0) print("silence_mean:", v.silence_mean) print("silence_sd:", v.silence_sd) print("number of samples:", len(v.silence_levels)) # We do not need to process the remaining samples break elif v.process_state == ProcessState.COMPLETED: # Actively fill the output buffer outdata.fill(0) print("Successfully completed measuring levels") raise sd.CallbackStop elif v.process_state == ProcessState.ABORTED: outdata.fill(0) print("Aborting measuring levels: " + v.error) raise sd.CallbackAbort # DEBUG # Save outdata for analysis v.out_pcm[v.out_pcm_pos:v.out_pcm_pos + samples] = outdata[:] v.out_pcm_pos += samples if v.out_pcm_pos > len(v.out_pcm): v.error = "Buffer for PCM of output is full" raise sd.CallbackAbort if stream.cpu_load > 0.25: print("High CPU usage:", round(stream.cpu_load, 3)) # Handle overflow/underflow errors if status_remaining: print(status_remaining, "in", v.process_state, "; aborting") raise Exception( "Status indicated an unacceptable issue with audio") except sd.CallbackAbort: raise except sd.CallbackStop: raise except Exception as exception: v.error = "Exception raised within callback: " + str(exception) v.exception = exception raise sd.CallbackAbort
if args.list_devices: print(sd.query_devices()) print('test: ', args.device, sd.query_devices(sd.default.device['input'])) parser.exit() if args.device is None: args.device = sd.default.device['input'] samplerate = sd.query_devices(args.device)['default_samplerate'] # print("samplerate: ", samplerate) delta_f = (high - low) / (args.columns - 1) fftsize = np.ceil(samplerate / delta_f).astype(int) low_bin = int(np.floor(low / delta_f)) statuses = sd.CallbackFlags() data = def callback(indata, frames, time, status): global statuses statuses |= status if any(indata): magnitude = np.abs(np.fft.rfft(indata[:, 0], n=fftsize)) magnitude *= args.gain / fftsize # print( "low: high = ", low_bin, args.columns) print(indata, len(indata)) 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', flush=True) else:
def start(self, thres=0, timeout=5, process=None, startpadding=10, endpadding=20, fullfilename=None, partfilename=None): if process != None: if not callable(process): raise TypeError('process must be function not called.') else: self.fnc = process self.startpadding = startpadding self.endpadding = endpadding self.fullfilename = fullfilename self.partfilename = partfilename self.starttime = time.time() self.avg_rms = [] self.recording = False self.stopper = False self.start_count = 0 self.end_count = 0 self.thres = thres global cumulated_status try: cumulated_status = sd.CallbackFlags() with sd.InputStream(device=None, channels=1, callback=self.callback, blocksize=int(self.samplerate * self.DURATION / 1000), samplerate=self.samplerate): while True: if self.stopper: break self.endtime = time.time() if timeout > 0: if (self.endtime - self.starttime) >= timeout: if process != None: self.pred_process() if partfilename != None: self.write_to_file(self, partfilename) break #await asyncio.sleep(0.1) #time.sleep(0.1) #break if self.fullfilename != None: soundfile.write(self.fullfilename, self.audiodata, int(self.samplerate)) if cumulated_status: logging.warning(str(cumulated_status)) except Exception as e: logging.info("=====================CRASH AT THIS=listen.py start") logging.debug(e) print(e)
parser.add_argument("-o", "--output-device", type=int, help="output device ID") parser.add_argument("-c", "--channels", type=int, default=2, help="number of channels") parser.add_argument("-t", "--dtype", help="audio data type") parser.add_argument("-s", "--samplerate", type=float, help="sampling rate") parser.add_argument("-b", "--blocksize", type=int, help="block size") parser.add_argument("-l", "--latency", type=float, help="latency in seconds") args = parser.parse_args() try: import sounddevice as sd callback_status = sd.CallbackFlags() def callback(indata, outdata, frames, time, status): global callback_status callback_status |= status outdata[:] = indata with sd.Stream(device=(args.input_device, args.output_device), samplerate=args.samplerate, blocksize=args.blocksize, dtype=args.dtype, latency=args.latency, channels=args.channels, callback=callback): print("#" * 80) print("press Return to quit")
def multiProc(): model_dir = '/home/felix/rirnet/foorir_felix/models' model = Model(model_dir) def f(indata, q, model): indata = indata[:, 0] fs = 16384 indata = librosa.core.resample(indata, 44100, fs) n_fft = 128 _, _, spectrogram = sp.signal.stft(indata, fs=fs, nfft=n_fft, nperseg=n_fft) spectrogram = spectrogram[:, :225] rir = model.forward(spectrogram) q.put(rir) print('left result') def clean(processes): for i in range(len(processes)): if processes and not processes[0].is_alive(): p = processes.pop(0) p.terminate() return processes try: import sounddevice as sd q = Queue() q.put([[0], [0]]) processes = [] plt.ion() callback_status = sd.CallbackFlags() def callback(indata, outdata, frames, time, status): rir = q.get() print(rir) plt.imshow(rir) plt.draw() plt.pause(0.01) global callback_status p = Process(target=f, args=( indata, q, model, )) processes.append(p) p.start() clean(processes) with sd.Stream(callback=callback, channels=1, samplerate=44100, blocksize=44100): print("#" * 80) print("press Return to quit") print("#" * 80) input() if callback_status: logging.warning(str(callback_status)) except BaseException as e: # This avoids printing the traceback, especially if Ctrl-C is used. raise SystemExit(str(e))
def record(length=1, reclength=1, filename=None, thres=0): """ Merekam suara secara stream dan metode callback """ global cumulated_status, end_count, start_count, recording, magnitudo, audiodata, predicting, i_quit, listening predicting = False listening = True end_count = False start_count = 0 recording = False magnitudo = [] audiodata = [] try: import sounddevice as sd #samplerate = sd.query_devices(args.device, 'input')['default_samplerate'] samplerate = 16000.0 delta_f = (high - low) / screenwidth fftsize = np.ceil(samplerate / delta_f).astype(int) low_bin = int(np.floor(low / delta_f)) cumulated_status = sd.CallbackFlags() def callback(indata, frames, time, status): global cumulated_status, audiodata, magnitudo, end_count, start_count, recording, smodel, predicting, i_quit cumulated_status |= status if any(indata): magnitude = np.abs(np.fft.rfft(indata[:, 0], n=fftsize)) magnitude *= gain / fftsize rms = librosa.feature.rmse(S=indata) rms = int(rms * 32768) start_count += 1 if rms >= thres: if not recording: #and not end_count #print("Start record") recording = True start_count = 0 if recording: audiodata.extend(itertools.chain(indata.tolist())) magnitudo.append(magnitude) if start_count == int(samplerate / (samplerate * DURATION / 1000)): #print("End record") start_count = 0 end_count = True recording = False try: if not predicting: print("Predict") soundfile.write("temp.wav", audiodata, 16000) predict("temp.wav", model=smodel) predicting = False pass except: pass audiodata = [] with sd.InputStream(device=None, channels=1, callback=callback, blocksize=int(samplerate * DURATION / 1000), samplerate=samplerate): while True: #response = input() #if response in ('', 'q', 'Q'): if listening == False: #time.sleep(length) break if filename != None: soundfile.write(filename, audiodata, 16000) if cumulated_status: logging.warning(str(cumulated_status)) except Exception as e: print(e)