Skip to content

Commit

Permalink
Merge pull request psychopy#6838 from TEParsons/dev-enh-mic-response
Browse files Browse the repository at this point in the history
ENH: Device responses should indicate which device they came from
  • Loading branch information
TEParsons authored Sep 10, 2024
2 parents fe5cfd3 + df228e5 commit e2f82bb
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 15 deletions.
49 changes: 38 additions & 11 deletions psychopy/hardware/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class BaseResponse:
# list of fields known to be a part of this response type
fields = ["t", "value"]

def __init__(self, t, value):
def __init__(self, t, value, device=None):
self.device = device
self.t = t
self.value = value

Expand All @@ -35,14 +36,32 @@ def __repr__(self):
attrs.append(f"{key}={getattr(self, key)}")
attrs = ", ".join(attrs)
# construct
return f"<{type(self).__name__}: {attrs}>"
return f"<{type(self).__name__} from {self.getDeviceName()}: {attrs}>"

def getDeviceName(self):
# if device isn't a device, and this method isn't overloaded, return None
if not hasattr(self.device, "getDeviceProfile"):
return None
# get profile
deviceProfile = self.device.getDeviceProfile()
# get name from profile
if "deviceName" in deviceProfile:
return deviceProfile['deviceName']
else:
# if profile doesn't include name, use class name
return type(self.device).__name__

def getJSON(self):
import json
# get device profile
deviceProfile = None
if hasattr(self.device, "getDeviceProfile"):
deviceProfile = self.device.getDeviceProfile()
# construct message as dict
message = {
'type': "hardware_response",
'class': type(self).__name__,
'device': deviceProfile,
'data': {}
}
# add all fields to "data"
Expand All @@ -60,6 +79,9 @@ class BaseDevice:
"""
Base class for device interfaces, includes support for DeviceManager and adding listeners.
"""
# start off with no cached profile
_profile = None

def __init_subclass__(cls, aliases=None):
from psychopy.hardware.manager import DeviceManager
# handle no aliases
Expand Down Expand Up @@ -91,15 +113,20 @@ def getDeviceProfile(self):
dict
Dictionary representing this device
"""
# get class string
cls = type(self)
mro = inspect.getmodule(cls).__name__ + "." + cls.__name__
# iterate through available devices for this class
for profile in self.getAvailableDevices():
if self.isSameDevice(profile):
# if current profile is this device, add deviceClass and return it
profile['deviceClass'] = mro
return profile
# only iteratively find it if we haven't done so already
if self._profile is None:
# get class string
cls = type(self)
mro = inspect.getmodule(cls).__name__ + "." + cls.__name__
# iterate through available devices for this class
for profile in self.getAvailableDevices():
if self.isSameDevice(profile):
# if current profile is this device, add deviceClass and return it
profile['deviceClass'] = mro
self._profile = profile
break

return self._profile

def getJSON(self, asString=True):
"""
Expand Down
10 changes: 6 additions & 4 deletions psychopy/hardware/microphone.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,9 +817,6 @@ def poll(self):
# figure out what to do with this other information
audioData, absRecPosition, overflow, cStartTime = \
self._stream.get_audio_data()
# log how many samples we got if debugging
if not len(audioData):
logging.debug(f"Polled samples from microphone {self.index} and none were returned")

if overflow:
logging.warning(
Expand Down Expand Up @@ -931,12 +928,17 @@ def dispatchMessages(self, clear=True):
If True, will clear the recording up until now after dispatching the volume. This is
useful if you're just sampling volume and aren't wanting to store the recording.
"""
# if mic is not recording, there's nothing to dispatch
if not self.isStarted:
return

# poll the mic now
self.poll()
# create a response object
message = MicrophoneResponse(
logging.defaultClock.getTime(),
self.getCurrentVolume()
self.getCurrentVolume(),
device=self,
)
# clear recording if requested (helps with continuous running)
if clear and self.isRecBufferFull:
Expand Down

0 comments on commit e2f82bb

Please sign in to comment.