Esempio n. 1
0
def validate_cut(c: Cut, read_data: bool = False) -> None:
    # Validate MixedCut
    if isinstance(c, MixedCut):
        assert len(
            c.tracks
        ) > 0, f'MonoCut {c.id}: Mixed cut must have at least one track.'
        for idx, track in enumerate(c.tracks):
            validate_cut(track.cut, read_data=read_data)
            assert track.offset >= 0, f'MonoCut: {c.id}: track {idx} has a negative offset.'
        return

    # Validate MonoCut and PaddingCut
    assert c.start >= 0, f'MonoCut {c.id}: start must be 0 or greater (got {c.start})'
    assert c.duration > 0, f'MonoCut {c.id}: duration must be greater than 0 (got {c.duration})'
    assert c.sampling_rate > 0, f'MonoCut {c.id}: sampling_rate must be greater than 0 (got {c.sampling_rate})'
    assert c.has_features or c.has_recording, f'MonoCut {c.id}: must have either Features or Recording attached.'

    # The rest pertains only to regular Cuts
    if isinstance(c, PaddingCut):
        return

    # Conditions related to features
    if c.has_features:
        validate_features(c.features)
        assert c.channel == c.features.channels
        if read_data:
            # We are not passing "read_data" to "validate_features" to avoid loading feats twice;
            # we'll just validate the subset of the features relevant for the cut.
            feats = c.load_features()
            n_fr, n_ft = feats.shape
            assert c.num_frames == n_fr, f'MonoCut {c.id}: expected num_frames: {c.num_frames}, actual: {n_fr}'
            assert c.num_features == n_ft, f'MonoCut {c.id}: expected num_features: {c.num_features}, actual: {n_ft}'

    # Conditions related to recording
    if c.has_recording:
        validate_recording(c.recording)
        assert c.channel in c.recording.channel_ids
        if read_data:
            # We are not passing "read_data" to "validate_recording" to avoid loading audio twice;
            # we'll just validate the subset of the recording relevant for the cut.
            samples = c.load_audio()
            assert c.num_samples == samples.shape[1], \
                f'MonoCut {c.id}: expected {c.num_samples} samples, got {samples.shape[1]}'

    # Conditions related to supervisions
    for s in c.supervisions:
        validate_supervision(s)
        assert s.recording_id == c.recording_id, \
            f'MonoCut {c.id}: supervision {s.id} has a mismatched recording_id ' \
            f'(expected {c.recording_id}, supervision has {s.recording_id})'
        assert s.channel == c.channel, \
            f'MonoCut {c.id}: supervision {s.id} has a mismatched channel ' \
            f'(expected {c.channel}, supervision has {s.channel})'
Esempio n. 2
0
def _read_features(cut: Cut) -> torch.Tensor:
    return torch.from_numpy(cut.load_features())
Esempio n. 3
0
def validate_cut(c: Cut, read_data: bool = False) -> None:
    # Validate MixedCut
    if isinstance(c, MixedCut):
        assert (len(c.tracks) >
                0), f"MonoCut {c.id}: Mixed cut must have at least one track."
        for idx, track in enumerate(c.tracks):
            validate_cut(track.cut, read_data=read_data)
            assert (track.offset >=
                    0), f"MonoCut: {c.id}: track {idx} has a negative offset."
        return

    # Validate MonoCut and PaddingCut
    assert c.start >= 0, f"MonoCut {c.id}: start must be 0 or greater (got {c.start})"
    assert (
        c.duration > 0
    ), f"MonoCut {c.id}: duration must be greater than 0 (got {c.duration})"
    assert (
        c.sampling_rate > 0
    ), f"MonoCut {c.id}: sampling_rate must be greater than 0 (got {c.sampling_rate})"
    assert (
        c.has_features or c.has_recording
    ), f"MonoCut {c.id}: must have either Features or Recording attached."

    # The rest pertains only to regular Cuts
    if isinstance(c, PaddingCut):
        return

    # Conditions related to features
    if c.has_features:
        validate_features(c.features)
        assert c.channel == c.features.channels
        if read_data:
            # We are not passing "read_data" to "validate_features" to avoid loading feats twice;
            # we'll just validate the subset of the features relevant for the cut.
            feats = c.load_features()
            n_fr, n_ft = feats.shape
            assert (
                c.num_frames == n_fr
            ), f"MonoCut {c.id}: expected num_frames: {c.num_frames}, actual: {n_fr}"
            assert (
                c.num_features == n_ft
            ), f"MonoCut {c.id}: expected num_features: {c.num_features}, actual: {n_ft}"

    # Conditions related to recording
    if c.has_recording:
        validate_recording(c.recording)
        assert c.channel in c.recording.channel_ids
        if read_data:
            # We are not passing "read_data" to "validate_recording" to avoid loading audio twice;
            # we'll just validate the subset of the recording relevant for the cut.
            samples = c.load_audio()
            assert (
                c.num_samples == samples.shape[1]
            ), f"MonoCut {c.id}: expected {c.num_samples} samples, got {samples.shape[1]}"

    # Conditions related to supervisions
    for s in c.supervisions:
        validate_supervision(s)
        assert s.recording_id == c.recording_id, (
            f"MonoCut {c.id}: supervision {s.id} has a mismatched recording_id "
            f"(expected {c.recording_id}, supervision has {s.recording_id})")
        assert s.channel == c.channel, (
            f"MonoCut {c.id}: supervision {s.id} has a mismatched channel "
            f"(expected {c.channel}, supervision has {s.channel})")

    # Conditions related to custom fields
    if c.custom is not None:
        assert isinstance(
            c.custom, dict
        ), f"MonoCut {c.id}: custom field has to be set to a dict or None."
        for key, value in c.custom.items():
            if isinstance(value, Array):
                validate_array(value, read_data=read_data)
            elif isinstance(value, TemporalArray):
                validate_temporal_array(value, read_data=read_data)
                if not isclose(c.duration, value.duration):
                    logging.warning(
                        f"MonoCut {c.id}: possibly mismatched "
                        f"duration between cut ({c.duration}s) and temporal array "
                        f"in custom field '{key}' (num_frames={value.num_frames} * "
                        f"frame_shift={value.frame_shift} == duration={value.duration})."
                    )