mirror of
https://github.com/huggingface/lerobot.git
synced 2026-07-25 10:46:01 +00:00
feat(init audio buffers): adding correct audio buffer initialization with actually recorded background noise instead of pure silence
This commit is contained in:
@@ -41,6 +41,7 @@ def decode_audio(
|
|||||||
audio_path: Path | str,
|
audio_path: Path | str,
|
||||||
timestamps: list[float],
|
timestamps: list[float],
|
||||||
duration: float,
|
duration: float,
|
||||||
|
start_time_s: float | None = 0.0,
|
||||||
backend: str | None = "torchcodec",
|
backend: str | None = "torchcodec",
|
||||||
) -> torch.Tensor:
|
) -> torch.Tensor:
|
||||||
"""
|
"""
|
||||||
@@ -57,9 +58,9 @@ def decode_audio(
|
|||||||
Currently supports torchaudio.
|
Currently supports torchaudio.
|
||||||
"""
|
"""
|
||||||
if backend == "torchcodec":
|
if backend == "torchcodec":
|
||||||
return decode_audio_torchcodec(audio_path, timestamps, duration)
|
return decode_audio_torchcodec(audio_path, timestamps, duration, start_time_s)
|
||||||
elif backend == "torchaudio":
|
elif backend == "torchaudio":
|
||||||
return decode_audio_torchaudio(audio_path, timestamps, duration)
|
return decode_audio_torchaudio(audio_path, timestamps, duration, start_time_s)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported video backend: {backend}")
|
raise ValueError(f"Unsupported video backend: {backend}")
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ def decode_audio_torchcodec(
|
|||||||
audio_path: Path | str,
|
audio_path: Path | str,
|
||||||
timestamps: list[float],
|
timestamps: list[float],
|
||||||
duration: float,
|
duration: float,
|
||||||
|
start_time_s: float | None = 0.0,
|
||||||
log_loaded_timestamps: bool = False,
|
log_loaded_timestamps: bool = False,
|
||||||
) -> torch.Tensor:
|
) -> torch.Tensor:
|
||||||
# TODO(CarolinePascal) : add channels selection
|
# TODO(CarolinePascal) : add channels selection
|
||||||
@@ -77,6 +79,9 @@ def decode_audio_torchcodec(
|
|||||||
# TODO(CarolinePascal) : assert ts < total record duration
|
# TODO(CarolinePascal) : assert ts < total record duration
|
||||||
|
|
||||||
audio_chunks = []
|
audio_chunks = []
|
||||||
|
timestamps = [
|
||||||
|
timestamp + start_time_s for timestamp in timestamps
|
||||||
|
] # Add an offset of start_time_s to each timestamp
|
||||||
for ts in timestamps:
|
for ts in timestamps:
|
||||||
current_audio_chunk = audio_decoder.get_samples_played_in_range(
|
current_audio_chunk = audio_decoder.get_samples_played_in_range(
|
||||||
start_seconds=max(0.0, ts - duration), stop_seconds=ts
|
start_seconds=max(0.0, ts - duration), stop_seconds=ts
|
||||||
@@ -118,6 +123,7 @@ def decode_audio_torchaudio(
|
|||||||
audio_path: Path | str,
|
audio_path: Path | str,
|
||||||
timestamps: list[float],
|
timestamps: list[float],
|
||||||
duration: float,
|
duration: float,
|
||||||
|
start_time_s: float | None = 0.0,
|
||||||
log_loaded_timestamps: bool = False,
|
log_loaded_timestamps: bool = False,
|
||||||
) -> torch.Tensor:
|
) -> torch.Tensor:
|
||||||
# TODO(CarolinePascal) : add channels selection
|
# TODO(CarolinePascal) : add channels selection
|
||||||
@@ -137,6 +143,9 @@ def decode_audio_torchaudio(
|
|||||||
)
|
)
|
||||||
|
|
||||||
audio_chunks = []
|
audio_chunks = []
|
||||||
|
timestamps = [
|
||||||
|
timestamp + start_time_s for timestamp in timestamps
|
||||||
|
] # Add an offset of start_time_s to each timestamp
|
||||||
for ts in timestamps:
|
for ts in timestamps:
|
||||||
reader.seek(max(0.0, ts - duration)) # Default to closest audio sample. Needs to be non-negative !
|
reader.seek(max(0.0, ts - duration)) # Default to closest audio sample. Needs to be non-negative !
|
||||||
status = reader.fill_buffer()
|
status = reader.fill_buffer()
|
||||||
|
|||||||
@@ -482,6 +482,7 @@ class LeRobotDatasetMetadata:
|
|||||||
if not self.features[key].get("info", None):
|
if not self.features[key].get("info", None):
|
||||||
audio_path = self.root / self.audio_path.format(audio_key=key, chunk_index=0, file_index=0)
|
audio_path = self.root / self.audio_path.format(audio_key=key, chunk_index=0, file_index=0)
|
||||||
self.info["features"][key]["info"] = get_audio_info(audio_path)
|
self.info["features"][key]["info"] = get_audio_info(audio_path)
|
||||||
|
self.info["features"][key]["info"]["start_time_s"] = DEFAULT_AUDIO_CHUNK_DURATION
|
||||||
|
|
||||||
def update_chunk_settings(
|
def update_chunk_settings(
|
||||||
self,
|
self,
|
||||||
@@ -1154,7 +1155,10 @@ class LeRobotDataset(torch.utils.data.Dataset):
|
|||||||
shifted_query_ts = [from_timestamp + ts for ts in query_ts]
|
shifted_query_ts = [from_timestamp + ts for ts in query_ts]
|
||||||
|
|
||||||
audio_path = self.root / self.meta.get_audio_file_path(ep_idx, audio_key)
|
audio_path = self.root / self.meta.get_audio_file_path(ep_idx, audio_key)
|
||||||
audio_chunk = decode_audio(audio_path, shifted_query_ts, query_duration, self.audio_backend)
|
start_time_s = self.meta.features[audio_key]["info"].get("start_time_s", 0.0)
|
||||||
|
audio_chunk = decode_audio(
|
||||||
|
audio_path, shifted_query_ts, query_duration, start_time_s, self.audio_backend
|
||||||
|
)
|
||||||
item[audio_key] = audio_chunk.squeeze(0)
|
item[audio_key] = audio_chunk.squeeze(0)
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|||||||
@@ -343,6 +343,10 @@ def record_loop(
|
|||||||
else:
|
else:
|
||||||
async_microphones_start_recording(robot.microphones)
|
async_microphones_start_recording(robot.microphones)
|
||||||
|
|
||||||
|
# Fill audio buffers if needed
|
||||||
|
if robot.microphones:
|
||||||
|
busy_wait(DEFAULT_AUDIO_CHUNK_DURATION)
|
||||||
|
|
||||||
timestamp = 0
|
timestamp = 0
|
||||||
start_episode_t = time.perf_counter()
|
start_episode_t = time.perf_counter()
|
||||||
while timestamp < control_time_s:
|
while timestamp < control_time_s:
|
||||||
|
|||||||
Reference in New Issue
Block a user