def tone_cal(freq, duration=.25, rec_delay=0.1, mic_sens=0.0015, atten=10, fft=False, **kw): if not rec_delay > 0: raise ValueError("Delay of recording must be greater than zero") # We need to initialize device so we can obtain certain parameters from it # (specifically the sampling frequency). device = DAQ.init_device(**DAQ_SETTINGS) samples = device.convert('s', 'nPow2', duration) rec_delay_samples = device.convert('s', 'n', rec_delay) play_samples = samples + rec_delay_samples * 2 play_dur = device.convert('s', 'n', play_samples) tone = Tone(frequency=freq, fs=device.fs, duration=play_dur, amplitude=1) device.configure(play_duration=play_samples, rec_duration=samples, rec_delay=rec_delay_samples, signal=tone.signal) # Prepare equipment for recording equipment.dsp().PA5.SetAtten(atten) result = tone_power(device, samples, freq=freq, fft=fft, **kw) spl = patodb(result[0] / mic_sens) + atten if len(result) == 3: phase, fft_data = result[-2:] fft_data['power'] = patodb(fft_data['power'] / mic_sens) return spl, phase, fft_data else: return spl, result[1]
def __init__(self): self.dsp = equipment.dsp() self.circuit = self.dsp.load('RepeatPlay_v2','RX6') #self.samplingFrequency = self.circuit.fsvalue self.samplingFrequency = self.circuit.fs self.maxBufferSize = self.circuit.sig_n.value self.circuit.start()
def __init__(self, waveGenerator, uploadBlockSize, minBufferSize=None): self.waveGenerator = waveGenerator self.uploadBlockSize = uploadBlockSize self.minBufferSize = uploadBlockSize if minBufferSize == None else minBufferSize self.dsp = equipment.dsp() self.circuit = self.dsp.load('RepeatPlayRecord','RX6') self.samplingFrequency = self.circuit.fs self.maxBufferSize = self.circuit.sig_n.value #self.circuit.play_dur_n.set(1, src_unit='s') self.circuit.start() self.waveGenerator.reset() self.waveGenerator.setSamplingFrequency(self.samplingFrequency) self.waveGenerator.setSamplingSize(self.uploadBlockSize) self.listener = Listener.Listener(self.uploadNextBlock, self.checkForNextUpload, 0.1) self.filledBufferPosition = 0 self.uploadNextBlock()
def demo_preset_sequence(backend='TDT'): ''' This demo explores how we would generate and upload a preset sequence to the DSP. This was mainly motivated out of my concern for ensuring that we could present a very rapid sequence of pips (e.g. ABRs are 10 ms pips presented at 40/sec) with the appropriate event times. In essence, the way this works is we chain together the waveforms for the sequence, upload it as one segment, and generate an array of event times for TTL1 that fires at the start of each pip. ''' circuit = equipment.dsp(backend).load('output-sequence', 'RX6') fs = circuit.fs token_duration = 0.005 trial_duration = 0.010 from numpy import zeros, concatenate signal_sequence = [] trial_triggers = [] sequence_triggers = [] silence = zeros(int((trial_duration-token_duration)*fs)) # Generate the sequence of pips for i in range(50): n_ramp = 2 tone = cos2taper(Tone(duration=token_duration, fs=fs).signal, n_ramp) signal_sequence.append(tone) signal_sequence.append(silence) noise = cos2taper(Noise(duration=token_duration, fs=fs).signal, n_ramp) signal_sequence.append(noise) signal_sequence.append(silence) # Ensure that the trigger fires at the start of each pip trial_triggers.append(len(tone)+len(silence)) trial_triggers.append(len(noise)+len(silence)) signal_sequence.append(zeros(int(fs))) # Concatenate the sequence into a single waveform to be uploaded full_waveform = concatenate(signal_sequence) sequence_triggers.append(len(full_waveform)) circuit.start() # Upload the data circuit.DAC1a.set(full_waveform) circuit.TTL1a.set(trial_triggers) circuit.TTL3a.set(sequence_triggers) # Start running circuit.trigger(1) # While circuit is playing out first sequence, prepare second sequence signal_sequence = [] trial_triggers = [] sequence_triggers = [] silence = zeros(int(1*fs)) for i in range(25): signal = cos2taper(AMNoise(duration=1, env_fm=5, env_depth=1, fs=fs).signal, 250) signal_sequence.append(signal) trial_triggers.append(len(noise)+len(silence)) full_waveform = concatenate(signal_sequence) sequence_triggers.append(len(full_waveform)) # Write data to reserve buffers circuit.DAC1b.set(full_waveform) circuit.TTL1b.set(trial_triggers) circuit.TTL3b.set(sequence_triggers) # Tell circuit to switch to buffer b and play the new waveform when it's # done with the current buffer (i.e. when TTL3 fires). Note that TTL3 has a # bitmask of 000100. The integer representation of this bitmask is 4. circuit.switch.set(4) circuit.trigger(4) # When a DSP circuit is first loaded, it registers a program exit hook. # When the program exits, it calls this hook to properly shut down the DSP. raw_input("Enter to quit")
from cns import equipment from cns.pipeline import acquire from cns.signal.type import Tone from cns.util.signal import rfft, dbtopa, patodb from traits.api import HasTraits, String, CFloat from scipy.signal import butter, filtfilt, hann import logging import numpy as np log = logging.getLogger(__name__) DAQ = equipment.dsp() DAQ_SETTINGS = { 'circuit': 'PlayRecord', 'device': 'RX6', 'ch_DAC': DAQ.RX6_OUT1, 'ch_ADC': DAQ.RX6_IN2, } def fft_analyze(signals, fs, mic_sens=None, filter=None): if filter is not None: signals = [filtfilt(x=s, **filter) for s in signals] transforms = [rfft(fs, s) for s in signals] freq, power, phase = zip(*transforms) signal = np.array(signals).mean(0) if mic_sens is not None: power = patodb(np.array(power).mean(0) / mic_sens) else: power = np.array(power).mean(0)