import numpy as np import sounddevice as sd import time from collections import defaultdict # Set this to your sound card as appropriate sd.default.device = "Focusrite USB ASIO" sample_rates=[44100,48000] wave_tables = defaultdict(dict) def generate_wavetables(): """ Generate a series of 32bit floating point sine waves with a fade in and fade out to avoid pops and clicks 40% of full scale, which translates to ~ -15dB on meter reading :return: """ duration = 2 volume = 0.4 # 0.4 Should give ~ -15dB reading at zero gain for sample_rate in sample_rates: fade_time = int(sample_rate / 10) fade_in = np.arange(0., 1., 1 / fade_time) fade_out = np.arange(1., 0., -1 / fade_time) sine_wave = (volume * np.sin(2 * np.pi * np.arange(sample_rate * duration) * 997 / sample_rate)).astype( np.float32) sine_wave[:fade_time] = np.multiply(sine_wave[:fade_time], fade_in) sine_wave[-fade_time:] = np.multiply(sine_wave[-fade_time:], fade_out) wave_tables[sample_rate][997] = sine_wave def play_and_get_level(sample_rate=44100, freq=997, channels=2, inputs=2, check_locked=False): sd.default.channels = 1 sd.default.latency = 'low' out_channels = np.linspace(1, channels, channels, dtype=int) note = wave_tables[sample_rate][freq] print("About to play a sound of {}Hz at sample rate {}Hz".format(freq, sample_rate)) try: sd.play(note, mapping=out_channels, blocking = True) except Exception as e: print ("bang {}".format(e)) return None print ("Getting levels") # this is where subprocess would launch external exe #readings = get_levels(1, inputs) readings = [-20,-20] return readings generate_wavetables() for i in range(100): levels = play_and_get_level() if levels is not None: for level in levels: print ("Loop {} {}".format(i, level))