Audio trial maker#
This demo illustrates the use of a trial maker in an audio experiment. Trial makers provide a standardized way to administer trials to the participant that can save you some effort compared to implementing the required logic manually.
These trials involve recording audio from the participant. This is achieved using the
AudioRecordControl
class.
Source: demos/static_audio
import psynet.experiment
from psynet.asset import CachedFunctionAsset, LocalStorage, S3Storage # noqa
from psynet.bot import Bot
from psynet.consent import NoConsent
from psynet.modular_page import (
AudioMeterControl,
AudioPrompt,
AudioRecordControl,
ModularPage,
)
from psynet.page import InfoPage, SuccessfulEndPage, VolumeCalibration
from psynet.timeline import ProgressDisplay, ProgressStage, Timeline
from psynet.trial.static import StaticNode, StaticTrial, StaticTrialMaker
from .custom_synth import synth_prosody
##########################################################################################
# Stimuli
##########################################################################################
def synth_stimulus(path, frequencies):
synth_prosody(vector=frequencies, output_path=path)
nodes = [
StaticNode(
definition={
"frequency_gradient": frequency_gradient,
"start_frequency": start_frequency,
"frequencies": [start_frequency + i * frequency_gradient for i in range(5)],
},
assets={
"stimulus": CachedFunctionAsset(
function=synth_stimulus,
extension=".wav",
)
},
)
for frequency_gradient in [-100, 0, 100]
for start_frequency in [-100, 0, 100]
]
class CustomTrial(StaticTrial):
_time_trial = 3
_time_feedback = 2
time_estimate = _time_trial + _time_feedback
wait_for_feedback = True
def show_trial(self, experiment, participant):
stimulus_duration = 0.393
record_duration = 2.0
return ModularPage(
"imitation",
AudioPrompt(
self.assets["stimulus"],
"Please imitate the spoken word as closely as possible.",
),
AudioRecordControl(
duration=record_duration,
bot_response_media="example-bier.wav",
auto_advance=True,
),
time_estimate=self._time_trial,
start_trial_automatically=False,
show_start_button=True,
show_next_button=False,
progress_display=ProgressDisplay(
stages=[
ProgressStage([0.0, stimulus_duration], color="grey"),
ProgressStage(
[stimulus_duration, stimulus_duration + record_duration],
caption="Recording...",
color="red",
),
ProgressStage(
[
stimulus_duration + record_duration,
stimulus_duration + record_duration + stimulus_duration,
],
caption="Uploading, please wait...",
color="grey",
),
],
),
)
def show_feedback(self, experiment, participant):
return ModularPage(
"feedback",
AudioPrompt(
self.assets["imitation"],
"Listen back to your recording. Did you do a good job?",
),
time_estimate=self._time_feedback,
)
class Exp(psynet.experiment.Experiment):
label = "Static audio demo"
asset_storage = S3Storage(
"psynet-tests", "static-audio"
) # We use this S3Storage for the CI tests
# asset_storage = LocalStorage()
timeline = Timeline(
NoConsent(),
VolumeCalibration(),
ModularPage(
"record_calibrate",
"""
Please speak into your microphone and check that the sound is registered
properly. If the sound is too quiet, try moving your microphone
closer or increasing the input volume on your computer.
""",
AudioMeterControl(),
time_estimate=5,
),
InfoPage(
"""
In this experiment you will hear some words. Your task will be to repeat
them back as accurately as possible.
""",
time_estimate=5,
),
StaticTrialMaker(
id_="static_audio",
trial_class=CustomTrial,
nodes=nodes,
expected_trials_per_participant=len(nodes),
target_n_participants=3,
recruit_mode="n_participants",
),
SuccessfulEndPage(),
)
def test_check_bot(self, bot: Bot, **kwargs):
assert len(bot.alive_trials) == len(nodes)