def generate_waveform(waveform, trial_dur, trial_env_dur, int_trial_dur,
                      trial_reps, int_set_dur, set_reps):

    # Note that the waveform simply reflects the *envelope* of the trial
    # waveform.  It does not represent the *actual* trial waveform itself.  The
    # trial waveform may be more nuanced than this.

    trial_waveform = cos2taper(waveform, trial_env_dur*fs)
    int_trial_waveform = np.zeros(int_trial_dur*fs)
    int_set_waveform = np.zeros(int_set_dur*fs)

    trial_triggers = []
    set_triggers = []

    set = []
    for i in range(trial_reps):
        trial_triggers.append(len(set))
        set.extend(trial_waveform)
        set.extend(int_trial_waveform)

    final = []
    for i in range(set_reps):
        n = len(final)
        trial_triggers.extend([t+n for t in trial_triggers[:trial_reps]])
        set_triggers.append(n)
        final.extend(set)
        final.extend(int_set_waveform)

    waveform = np.array(final)
    t = np.arange(len(waveform))/fs
    return t, waveform, trial_triggers, set_triggers
Beispiel #2
0
    def set_signal(signal):
        from numpy import zeros, r_, array

        # Apply tapered envelope to minimize spectral splatter
        signal = cos2taper(signal.signal, int(0.1*fs))
        pad_pre = zeros(int(token_delay*fs))
        pad_post = zeros(int((trial_duration-token_delay-token_duration)*fs))

        # First, check to see which buffer is current and write data to the
        # reserve buffer.  Once the data is written, send a software trigger 
        # to tell the circuit to switch to the new buffer.  When mode == 3,
        # circuit switches immediately, when mode == 4, circuit switches when
        # switch condition is met.

        if circuit.get_tag('buffer') == 1:
            DACA1.set(signal)
            #TTL1a.set([len(signal)]) # Fire TTL1 at end of waveform
        else:
            DACA2.set(signal)
            #TTL1b.set([len(signal)]) # Fire TTL1 at end of waveform
        circuit.trigger(1) 
Beispiel #3
0
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")