Skip to content
Merged
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
4 changes: 2 additions & 2 deletions src/viam/components/audio_in/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from viam.media.audio import AudioCodec
from viam.proto.common import AudioInfo
from viam.resource.registry import Registry, ResourceRegistration

from viam.proto.common import AudioInfo
from viam.media.audio import AudioCodec
from .audio_in import AudioIn
from .client import AudioInClient
from .service import AudioInRPCService
Expand Down
11 changes: 4 additions & 7 deletions src/viam/components/audio_in/audio_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
import sys
from typing import Final, Optional

from viam.streams import Stream

from viam.proto.common import GetPropertiesResponse
from viam.proto.component.audioin import GetAudioResponse
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
from viam.streams import Stream

from ..component_base import ComponentBase

Expand All @@ -32,12 +31,10 @@ class AudioIn(ComponentBase):
AudioResponse: "TypeAlias" = GetAudioResponse
AudioStream = Stream[AudioResponse]


@abc.abstractmethod
async def get_audio(self, codec: str,
duration_seconds: float,
previous_timestamp_ns:int,
*, timeout: Optional[float] = None, **kwargs) -> AudioStream:
async def get_audio(
self, codec: str, duration_seconds: float, previous_timestamp_ns: int, *, timeout: Optional[float] = None, **kwargs
) -> AudioStream:
"""
Get a stream of audio from the device

Expand Down
47 changes: 22 additions & 25 deletions src/viam/components/audio_in/client.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
from typing import Any, Dict, List, Mapping, Optional
import uuid
from typing import Any, Dict, List, Mapping, Optional

from grpclib.client import Channel

from viam.proto.component.audioin import GetAudioRequest, GetAudioResponse
from viam.proto.common import (
DoCommandRequest,
DoCommandResponse,
GetPropertiesRequest,
Geometry)
from grpclib.client import Stream as ClientStream
from viam.proto.component.audioin import AudioInServiceStub

from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetPropertiesRequest
from viam.proto.component.audioin import AudioInServiceStub, GetAudioRequest, GetAudioResponse
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
from viam.streams import StreamWithIterator
from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict

from .audio_in import AudioIn
from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict


class AudioInClient(AudioIn, ReconfigurableResourceRPCClientBase):

def __init__(self, name: str, channel: Channel) -> None:
self.channel = channel
self.client = AudioInServiceStub(channel)
super().__init__(name)

async def get_audio(
self,
codec: str,
duration_seconds: float,
previous_timestamp_ns: int,
*,
extra: Optional[Dict[str, Any]] = None,
**kwargs,
):
request = GetAudioRequest(
name=self.name,
codec=codec,
duration_seconds=duration_seconds,
previous_timestamp_nanoseconds=previous_timestamp_ns,
request_id=str(uuid.uuid4()),
extra=dict_to_struct(extra),
)

async def get_audio(self,
codec:str,
duration_seconds: float,
previous_timestamp_ns:int,
*,
extra: Optional[Dict[str, Any]] = None,
**kwargs,
):
request = GetAudioRequest(name=self.name, codec = codec,
duration_seconds=duration_seconds,
previous_timestamp_nanoseconds = previous_timestamp_ns,
request_id = str(uuid.uuid4()),
extra=dict_to_struct(extra))
async def read():
md = kwargs.get("metadata", self.Metadata()).proto
audio_stream: ClientStream[GetAudioRequest, GetAudioResponse]
Expand All @@ -52,7 +50,6 @@ async def read():

return StreamWithIterator(read())


async def get_properties(
self,
*,
Expand Down
24 changes: 11 additions & 13 deletions src/viam/components/audio_in/service.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
from grpclib.server import Stream
from h2.exceptions import StreamClosedError


from viam.logging import getLogger
from viam.proto.common import (
DoCommandRequest,
DoCommandResponse,
GetGeometriesRequest,
GetGeometriesResponse,
GetPropertiesRequest,
GetPropertiesResponse,
GetGeometriesRequest,
GetGeometriesResponse
)
from viam.proto.component.audioin import (
AudioInServiceBase,
GetAudioRequest,
GetAudioResponse
)
from viam.proto.component.audioin import AudioInServiceBase, GetAudioRequest, GetAudioResponse
from viam.resource.rpc_service_base import ResourceRPCServiceBase
from viam.utils import dict_to_struct, struct_to_dict

from .audio_in import AudioIn

LOGGER = getLogger(__name__)


class AudioInRPCService(AudioInServiceBase, ResourceRPCServiceBase[AudioIn]):
"""
gRPC Service for a generic audio in.
"""

RESOURCE_TYPE = AudioIn


async def GetAudio(self, stream: Stream[GetAudioRequest, GetAudioResponse]) -> None:
request = await stream.recv_message()
assert request is not None
name = request.name
audio_in = self.get_resource(name)
audio_stream = await audio_in.get_audio(codec=request.codec, duration_seconds=request.duration_seconds,
previous_timestamp_ns=request.previous_timestamp_nanoseconds, metadata=stream.metadata)
audio_stream = await audio_in.get_audio(
codec=request.codec,
duration_seconds=request.duration_seconds,
previous_timestamp_ns=request.previous_timestamp_nanoseconds,
metadata=stream.metadata,
)
async for response in audio_stream:
try:
response.request_id = request.request_id
Expand All @@ -48,7 +47,6 @@ async def GetAudio(self, stream: Stream[GetAudioRequest, GetAudioResponse]) -> N
LOGGER.error(e)
return


async def GetProperties(self, stream: Stream[GetPropertiesRequest, GetPropertiesResponse]) -> None:
request = await stream.recv_message()
assert request is not None
Expand All @@ -65,7 +63,7 @@ async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) -
request = await stream.recv_message()
assert request is not None
name = request.name
audio_in= self.get_resource(name)
audio_in = self.get_resource(name)
timeout = stream.deadline.time_remaining() if stream.deadline else None
result = await audio_in.do_command(
command=struct_to_dict(request.command),
Expand Down
2 changes: 1 addition & 1 deletion src/viam/components/audio_input/audio_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


class AudioInput(ComponentBase, StreamSource[Audio]):
""" DEPRECATED: AudioInput is deprecated, use AudioIn instead
"""DEPRECATED: AudioInput is deprecated, use AudioIn instead
AudioInput represents a component that can capture audio.

This acts as an abstract base class for any drivers representing specific
Expand Down
5 changes: 2 additions & 3 deletions src/viam/components/audio_input/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Any, AsyncIterator, Dict, List, Mapping, Optional, Union
import warnings
from typing import Any, AsyncIterator, Dict, List, Mapping, Optional, Union

from grpclib.client import Channel

Expand Down Expand Up @@ -28,8 +28,7 @@ class AudioInputClient(AudioInput, ReconfigurableResourceRPCClientBase):

def __init__(self, name: str, channel: Channel):
warnings.warn(
"AudioInputClient is deprecated and will be removed in a future release. "
"Use AudioIn instead.",
"AudioInputClient is deprecated and will be removed in a future release. " "Use AudioIn instead.",
DeprecationWarning,
stacklevel=2,
)
Expand Down
5 changes: 2 additions & 3 deletions src/viam/components/audio_input/service.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import wave
import warnings
import wave
from datetime import timedelta
from io import BytesIO

Expand Down Expand Up @@ -32,8 +32,7 @@ class AudioInputRPCService(AudioInputServiceBase, ResourceRPCServiceBase[AudioIn

def __init__(self, *args, **kwargs):
warnings.warn(
"AudioInput is deprecated and will be removed in a future release. "
"Use AudioIn instead.",
"AudioInput is deprecated and will be removed in a future release. " "Use AudioIn instead.",
DeprecationWarning,
stacklevel=2,
)
Expand Down
4 changes: 2 additions & 2 deletions src/viam/components/audio_out/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from viam.media.audio import AudioCodec
from viam.proto.common import AudioInfo
from viam.resource.registry import Registry, ResourceRegistration

from viam.proto.common import AudioInfo
from viam.media.audio import AudioCodec
from .audio_out import AudioOut
from .client import AudioOutClient
from .service import AudioOutRPCService
Expand Down
22 changes: 10 additions & 12 deletions src/viam/components/audio_out/audio_out.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ class AudioOut(ComponentBase):
Properties: "TypeAlias" = GetPropertiesResponse

@abc.abstractmethod
async def play(self,
data: bytes,
info: Optional[AudioInfo] = None,
*,
extra: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
**kwargs) -> None:
async def play(
self,
data: bytes,
info: Optional[AudioInfo] = None,
*,
extra: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
**kwargs,
) -> None:
"""
Play the given audio data.

Expand All @@ -55,11 +57,7 @@ async def play(self,
"""

@abc.abstractmethod
async def get_properties(self,
*,
extra: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
**kwargs) -> Properties:
async def get_properties(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> Properties:
"""
Get the audio output device's properties.

Expand Down
42 changes: 15 additions & 27 deletions src/viam/components/audio_out/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,12 @@

from grpclib.client import Channel

from viam.proto.common import (
DoCommandRequest,
DoCommandResponse,
GetPropertiesRequest,
GetPropertiesResponse,
Geometry
)
from viam.proto.component.audioout import (
AudioOutServiceStub,
PlayRequest
)


from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetPropertiesRequest, GetPropertiesResponse
from viam.proto.component.audioout import AudioOutServiceStub, PlayRequest
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase

from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict

from .audio_out import AudioOut, AudioInfo
from .audio_out import AudioInfo, AudioOut


class AudioOutClient(AudioOut, ReconfigurableResourceRPCClientBase):
Expand All @@ -30,13 +18,15 @@ def __init__(self, name: str, channel: Channel) -> None:
self.client = AudioOutServiceStub(channel)
super().__init__(name)

async def play(self,
data: bytes,
info: Optional[AudioInfo] = None,
*,
extra: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
**kwargs) -> None:
async def play(
self,
data: bytes,
info: Optional[AudioInfo] = None,
*,
extra: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
**kwargs,
) -> None:
if extra is None:
extra = {}

Expand All @@ -49,11 +39,9 @@ async def play(self,
)
await self.client.Play(request, timeout=timeout, metadata=md)

async def get_properties(self,
*,
extra: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
**kwargs) -> AudioOut.Properties:
async def get_properties(
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
) -> AudioOut.Properties:
if extra is None:
extra = {}

Expand Down
1 change: 1 addition & 0 deletions src/viam/media/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Audio:
AudioReader = StreamReader[Audio]
AudioStream = Stream[Audio]


class AudioCodec(str, Enum):
"""Common audio codec identifiers.

Expand Down
6 changes: 1 addition & 5 deletions src/viam/resource/easy_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,11 @@ def __init__(self, name: str):
@classmethod
def new(cls, config: ComponentConfig, dependencies: Mapping[ResourceName, ResourceBase]):
"""
This is passed to register_resource_creator; the default implementation calls reconfigure()
This is passed to register_resource_creator. The default implementation only sets the resource name
when an instance of your model is instantiated. You can override this in your subclass.
"""
self = cls(config.name)
logger.debug("created %s %s %s", cls.API, cls.MODEL, config.name)
self.reconfigure(config, dependencies)
return self

@classmethod
Expand Down Expand Up @@ -148,6 +147,3 @@ def register(cls):
cls.MODEL,
ResourceCreatorRegistration(cls.new, cls.validate_config), # pyright: ignore [reportArgumentType]
)

def reconfigure(self, config: ComponentConfig, dependencies: Mapping[ResourceName, ResourceBase]):
logger.debug("reconfigure %s %s", self.API, self.MODEL)
Loading
Loading