Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions lhotse/recipes/babel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
It has about 25 languages with 40h - 160h of training recordings and ~20h
of development set recordings.
"""

import logging
import re
from collections import defaultdict
Expand All @@ -21,7 +22,6 @@
SupervisionSet,
validate_recordings_and_supervisions,
)
from lhotse.manipulation import combine
from lhotse.qa import (
remove_missing_recordings_and_supervisions,
trim_supervisions_to_recordings,
Expand Down Expand Up @@ -77,7 +77,8 @@ def prepare_single_babel_language(
if there is more than once, it picks the first one (and emits a warning)
- then, it will try to find `dev`, `eval`, and `training` splits inside
(if any of them is not present, it will skip it with a warning)
- finally, it scans the selected location for SPHERE audio files and transcripts.
- finally, it scans the selected location for SPHERE and WAV audio files
and transcripts.

:param corpus_dir: Path to the root of the LDC package with a BABEL language.
:param output_dir: Path where the manifests are stored.json
Expand Down Expand Up @@ -107,13 +108,11 @@ def prepare_single_babel_language(

for split in ("dev", "eval", "training"):
audio_dir = corpus_dir / f"conversational/{split}/audio"
sph_recordings = RecordingSet.from_recordings(
Recording.from_file(p) for p in audio_dir.glob("*.sph")
)
wav_recordings = RecordingSet.from_recordings(
Recording.from_file(p) for p in audio_dir.glob("*.wav")
recordings = RecordingSet.from_recordings(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this change functionally identical?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The original code only matched *.sph, so WAV recordings were omitted. This change discovers both *.sph and *.wav files in one per-split RecordingSet and adds mixed-format regression coverage.

Recording.from_file(p)
for pattern in ("*.sph", "*.wav")
for p in audio_dir.glob(pattern)
)
recordings = combine(sph_recordings, wav_recordings)
if len(recordings) == 0:
if split == "eval" and no_eval_ok:
continue
Expand All @@ -137,8 +136,8 @@ def prepare_single_babel_language(
lines = p.read_text().splitlines() + [""]
lines = [
prev_l
for prev_l, l in sliding_window(2, lines)
if not (prev_l.startswith("[") and l.startswith("["))
for prev_l, current_l in sliding_window(2, lines)
if not (prev_l.startswith("[") and current_l.startswith("["))
]
# Add a None at the end so that the last timestamp is only used as "next_timestamp"
# and ends the iretation (otherwise we'd lose the last segment).
Expand Down
44 changes: 44 additions & 0 deletions test/recipes/test_babel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from pathlib import Path

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the test file - we don't add tests for recipes in this repo

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. I’ll address this in the existing pull request and rerun the focused validation.


from lhotse import AudioSource, Recording
from lhotse.recipes.babel import prepare_single_babel_language


def test_prepare_single_babel_language_includes_sph_and_wav(monkeypatch, tmp_path):
stems_and_suffixes = (
("BABEL_BP_401_10001_20111024_205740_inLine", ".sph"),
("BABEL_BP_401_10002_20111024_205740_inLine", ".wav"),
)
for split in ("dev", "training"):
audio_dir = tmp_path / "conversational" / split / "audio"
text_dir = tmp_path / "conversational" / split / "transcription"
audio_dir.mkdir(parents=True)
text_dir.mkdir(parents=True)

for stem, suffix in stems_and_suffixes:
audio_path = audio_dir / f"{stem}{suffix}"
audio_path.touch()
(text_dir / f"{stem}.txt").write_text("[0.0]\nhello\n[1.0]\n")

def fake_recording_from_file(path):
path = Path(path)
return Recording(
id=path.stem,
sources=[AudioSource(type="file", channels=[0], source=str(path))],
sampling_rate=8000,
num_samples=8000,
duration=1.0,
)

monkeypatch.setattr(Recording, "from_file", staticmethod(fake_recording_from_file))

manifests = prepare_single_babel_language(tmp_path, no_eval_ok=True)

for split in ("dev", "training"):
recordings = manifests[split]["recordings"]
assert not recordings.is_lazy
assert set(recordings.ids) == {stem for stem, _ in stems_and_suffixes}
assert {Path(r.sources[0].source).suffix for r in recordings} == {
".sph",
".wav",
}