def generate_trial_waveform(self): # Use BBN seed = self.get_current_value("seed") depth = self.get_current_value("modulation_depth") direction = self.get_current_value("modulation_direction") fm = self.get_current_value("fm") duration = self.get_current_value("trial_duration") t = signal.time(self.iface_behavior.fs, duration) # Save the actual seed that's used to generate the trial waveform if seed == -1: seed = int(time.time()) self.set_current_value("seed", seed) # Do not use the self.random_generator for generating the seed. This # generator is for use only for generating the intertrial waveform. state = np.random.RandomState(seed) waveform = state.uniform(low=-1, high=1, size=len(t)) # Since we are drawing samples from a uniform distribution and we wish # to normalize for the RMS voltage, we need to divide by 0.5 which is # the RMS value of the waveform. We could recompute the RMS value on # each cycle; however, I think it's better to use the same value each # time. The RMS of the waveform over time will compute to 0.5 (because # the samples are unformly distributed between -1 and 1). waveform = waveform / 0.5 eq_phase = signal.sam_eq_phase(depth, direction) eq_power = signal.sam_eq_power(depth) envelope = depth / 2.0 * np.cos(2 * np.pi * fm * t + eq_phase) + 1 - depth / 2.0 envelope *= 1 / eq_power return waveform * envelope
def _get_sam_envelope(self): # This part is not as CPU-intensive, but serves a good example of how to # cache the pieces for generating the final token. if not self._sam_envelope_valid: log.debug('recomputing sam envelope') fm = self.get_current_value('fm') depth = self.get_current_value('modulation_depth') delay = self.get_current_value('modulation_onset') direction = self.get_current_value('modulation_direction') t = self._get_time() if delay == 0: eq_phase = -np.pi else: eq_phase = wave.sam_eq_phase(depth, direction) envelope = depth/2*np.cos(2*np.pi*fm*t+eq_phase)+1-depth/2 # Ensure that we scale the waveform so that the total power remains # equal to that of an unmodulated token. envelope *= 1.0/wave.sam_eq_power(depth) delay_n = int(delay*self.iface_behavior.fs) if delay_n > 0: delay_envelope = np.ones(delay_n) envelope = np.concatenate((delay_envelope, envelope[:-delay_n])) self._sam_envelope = envelope self._sam_envelope_valid = True return self._sam_envelope
def _update_am(self): am_direction = self.get_current_value('am_direction') am_depth = self.get_current_value('am_depth') am_amplitude = am_depth/2.0 am_shift = 1-am_amplitude am_phase = sam_eq_phase(am_depth, am_direction) am_sf = 1.0/sam_eq_power(am_depth) self.iface_behavior.set_tag('am_amplitude', am_amplitude) self.iface_behavior.set_tag('am_shift', am_shift) self.iface_behavior.set_tag('am_phase', am_phase) self.iface_behavior.set_tag('am_sf', am_sf)