Signed-off-by: Sysy <1370724210@qq.com> Signed-off-by: sy03 <137072421@qq.com> Co-authored-by: sy03 <137072421@qq.com>
74 lines
2.5 KiB
Python
74 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import base64
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
from vllm_omni.experimental.fullduplex.nemotron_voicechat.input import (
|
|
NemotronVoiceChatPcmAppendBuffer,
|
|
)
|
|
|
|
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
|
|
|
|
|
|
def _payload(samples: np.ndarray, *, sample_rate_hz: int = 16000, fmt: str = "pcm_f32le") -> dict[str, object]:
|
|
return {
|
|
"type": "audio",
|
|
"audio": base64.b64encode(np.asarray(samples, dtype=np.float32).tobytes()).decode("ascii"),
|
|
"format": fmt,
|
|
"sample_rate_hz": sample_rate_hz,
|
|
}
|
|
|
|
|
|
def _append(buffer, samples, operation_id):
|
|
return buffer.prepare_append(
|
|
_payload(np.asarray(samples, dtype=np.float32)),
|
|
operation_id=operation_id,
|
|
chunk_period_ms=80,
|
|
allow_emit=True,
|
|
)
|
|
|
|
|
|
def test_irregular_browser_packets_emit_exact_ordered_80ms_frame() -> None:
|
|
buffer = NemotronVoiceChatPcmAppendBuffer()
|
|
assert _append(buffer, np.arange(1000), "packet-1") is None
|
|
|
|
reservation = _append(buffer, np.arange(1000, 1280), "packet-2")
|
|
|
|
assert reservation is not None
|
|
assert reservation.operation_id == "packet-2"
|
|
decoded = np.frombuffer(base64.b64decode(reservation.payload["audio"]), dtype=np.float32)
|
|
np.testing.assert_array_equal(decoded, np.arange(1280, dtype=np.float32))
|
|
assert buffer.pending_byte_count == 0
|
|
|
|
|
|
def test_append_rejects_invalid_frame_contract() -> None:
|
|
cases = (
|
|
(1281, 16000, "pcm_f32le", 0.0, "at most 1280"),
|
|
(1, 8000, "pcm_f32le", 0.0, "sample_rate_hz"),
|
|
(1, 16000, "audio/pcm", 0.0, "format"),
|
|
(1, 16000, "pcm_f32le", np.nan, "finite"),
|
|
)
|
|
for samples, sample_rate_hz, fmt, value, message in cases:
|
|
with pytest.raises(ValueError, match=message):
|
|
NemotronVoiceChatPcmAppendBuffer().prepare_append(
|
|
_payload(np.full(samples, value, dtype=np.float32), sample_rate_hz=sample_rate_hz, fmt=fmt),
|
|
operation_id="invalid",
|
|
chunk_period_ms=80,
|
|
allow_emit=True,
|
|
)
|
|
|
|
|
|
def test_terminal_commit_rejects_more_than_one_frame_tail() -> None:
|
|
buffer = NemotronVoiceChatPcmAppendBuffer()
|
|
for index, samples in enumerate((1000, 281)):
|
|
buffer.prepare_append(
|
|
_payload(np.zeros(samples, dtype=np.float32)),
|
|
operation_id=f"tail-{index}",
|
|
chunk_period_ms=80,
|
|
allow_emit=False,
|
|
)
|
|
with pytest.raises(ValueError, match="more than one 80 ms frame"):
|
|
buffer.prepare_commit(operation_id="commit", chunk_period_ms=80)
|