def ref_cal(duration=1, averages=2, ref_freq=1e3, ref_level=93.8, gain=20, fft=False, mode='conv'): ''' Calibrates measuring microphone against a known reference (e.g. a pistonphone). Typically this is the B&K microphone, but certainly could be any microphone that is felt to produce a flat frequency response across the range of frequencies of interest. TODO: Update this so it incorporates the actual B&K calibration file (where do we get this?). level Output of reference in dB SPL frequency Frequency of reference in Hz verbose Returns signal and FFT so it can be plotted ''' circuit_path = join(get_config('RCX_ROOT'), 'play_record.rcx') circuit = DSPCircuit(circuit_path, 'RZ6') circuit.start(1) samples = circuit.convert(duration, 's', 'nPow2') # Important, rec_delay must be at least 1 or the circuit will not work circuit.set_tags(play_duration=0, rec_duration=samples, rec_delay=1) mic_buffer = circuit.get_buffer('mic', 'r') mic_data = mic_buffer.acquire_samples(1, samples, 1) print rms(mic_data) print tone_frequency(circuit.fs, mic_data[0].ravel(), 1e3) from pylab import plot, show plot(mic_data[0].ravel()[:5e3]) show() return print mic_data.shape if circuit.get_tag('clipped'): print 'Clipping occured' for m in mic_data: #rms = np.mean(m.ravel()**2)**0.5 magnitude, phase = tone_frequency(circuit.fs, m, 1e3) print magnitude/dbspltopa(ref_level+gain) #plot(mic_data[0].ravel()) #show() return mic_data #print mic_data.shape return # Do the calibration! #result = tone_power(device, samples, averages=averages, freq=ref_freq, # fft=fft, mode=mode) log.debug('Measured %.2f Vrms at %.2f Hz from the pistonphone' % \ (result[0], ref_freq)) sens = result[0] / dbtopa(ref_level) debug_mesg = 'Using the pistonphone reference of %.2f dB SPL, ' + \ 'microphone sensitivity is %.4f Vrms/Pa' log.debug(debug_mesg % (ref_level, sens)) # Phase is meaningless since we have little control over the pistonphone, so # we do not return this, just microphone sensitivity. if fft: return sens, result[-1] else: return sens