def __init__(self, cfg: ChannelConfig, corr_cfg: "Config"): self.cfg = cfg # Create a Wave object. wave = Wave( abspath(cfg.wav_path), amplification=coalesce(cfg.amplification, corr_cfg.amplification), ) # Flatten wave stereo for trigger and render. tflat = coalesce(cfg.trigger_stereo, corr_cfg.trigger_stereo) rflat = coalesce(cfg.render_stereo, corr_cfg.render_stereo) self.trigger_wave = wave.with_flatten(tflat, return_channels=False) self.render_wave = wave.with_flatten(rflat, return_channels=True) # `subsampling` increases `stride` and decreases `nsamp`. # `width` increases `stride` without changing `nsamp`. tsub = corr_cfg.trigger_subsampling tw = cfg.trigger_width rsub = corr_cfg.render_subsampling rw = cfg.render_width # nsamp = orig / subsampling # stride = subsampling * width def calculate_nsamp(width_ms, sub): width_s = width_ms / 1000 return round(width_s * wave.smp_s / sub) trigger_samp = calculate_nsamp(corr_cfg.trigger_ms, tsub) self.render_samp = calculate_nsamp(corr_cfg.render_ms, rsub) self.trigger_stride = tsub * tw self.render_stride = rsub * rw # Create a Trigger object. if isinstance(cfg.trigger, ITriggerConfig): tcfg = cfg.trigger elif isinstance( cfg.trigger, (CommentedMap, dict)): # CommentedMap may/not be subclass of dict. tcfg = attr.evolve(corr_cfg.trigger, **cfg.trigger) elif cfg.trigger is None: tcfg = corr_cfg.trigger else: raise CorrError( f"invalid per-channel trigger {cfg.trigger}, type={type(cfg.trigger)}, " f"must be (*)TriggerConfig, dict, or None") self.trigger = tcfg( wave=self.trigger_wave, tsamp=trigger_samp, stride=self.trigger_stride, fps=corr_cfg.fps, )
def test_stereo_flatten_modes( flatten: Flatten, return_channels: bool, path: str, nchan: int, peaks: Sequence[float], ): """Ensures all Flatten modes are handled properly for stereo and mono signals.""" # return_channels=False <-> triggering. # flatten=stereo -> rendering. # These conditions do not currently coexist. # if not return_channels and flatten == Flatten.Stereo: # return assert nchan == len(peaks) wave = Wave(path) if flatten not in Flatten.modes: with pytest.raises(CorrError): wave.with_flatten(flatten, return_channels) return else: wave = wave.with_flatten(flatten, return_channels) nsamp = wave.nsamp data = wave[:] # wave.data == 2-D array of shape (nsamp, nchan) if flatten == Flatten.Stereo: assert data.shape == (nsamp, nchan) for chan_data, peak in zip(data.T, peaks): assert_full_scale(chan_data, peak) else: if return_channels: assert data.shape == (nsamp, 1) else: assert data.shape == (nsamp, ) # If DiffAvg and in-phase, L-R=0. if flatten == Flatten.DiffAvg: if len(peaks) >= 2 and peaks[0] == peaks[1]: np.testing.assert_equal(data, 0) else: pass # If SumAvg, check average. else: assert flatten == Flatten.SumAvg assert_full_scale(data, np.mean(peaks))
def __init__(self, cfg: ChannelConfig, corr_cfg: "Config", channel_idx: int = 0): """channel_idx counts from 0.""" self.cfg = cfg self.label = cfg.label if not self.label: if corr_cfg.default_label is DefaultLabel.FileName: self.label = Path(cfg.wav_path).stem elif corr_cfg.default_label is DefaultLabel.Number: self.label = str(channel_idx + 1) # Create a Wave object. wave = Wave( abspath(cfg.wav_path), amplification=coalesce(cfg.amplification, corr_cfg.amplification), ) # Flatten wave stereo for trigger and render. tflat = coalesce(cfg.trigger_stereo, corr_cfg.trigger_stereo) rflat = coalesce(cfg.render_stereo, corr_cfg.render_stereo) self.trigger_wave = wave.with_flatten(tflat, return_channels=False) self.render_wave = wave.with_flatten(rflat, return_channels=True) # `subsampling` increases `stride` and decreases `nsamp`. # `width` increases `stride` without changing `nsamp`. tsub = corr_cfg.trigger_subsampling tw = cfg.trigger_width rsub = corr_cfg.render_subsampling rw = cfg.render_width # nsamp = orig / subsampling # stride = subsampling * width def calculate_nsamp(width_ms, sub): width_s = width_ms / 1000 return round(width_s * wave.smp_s / sub) trigger_samp = calculate_nsamp(corr_cfg.trigger_ms, tsub) self._render_samp = calculate_nsamp(corr_cfg.render_ms, rsub) self._trigger_stride = tsub * tw self.render_stride = rsub * rw # Create a Trigger object. if isinstance(cfg.trigger, MainTriggerConfig): tcfg = cfg.trigger elif isinstance( cfg.trigger, (CommentedMap, dict) ): # CommentedMap may/not be subclass of dict. tcfg = evolve_compat(corr_cfg.trigger, **cfg.trigger) elif cfg.trigger is None: tcfg = corr_cfg.trigger else: raise CorrError( f"invalid per-channel trigger {cfg.trigger}, type={type(cfg.trigger)}, " f"must be (*)TriggerConfig, dict, or None" ) self.trigger = tcfg( wave=self.trigger_wave, tsamp=trigger_samp, stride=self._trigger_stride, fps=corr_cfg.fps, wave_idx=channel_idx, )