psychopy 2024.2.5__py3-none-any.whl → 2025.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of psychopy might be problematic. Click here for more details.
- psychopy/CHANGELOG.txt +4 -4
- psychopy/GIT_SHA +1 -1
- psychopy/LICENSE.txt +1 -1
- psychopy/VERSION +1 -1
- psychopy/__init__.py +10 -7
- psychopy/alerts/__init__.py +1 -1
- psychopy/alerts/_alerts.py +53 -17
- psychopy/alerts/_errorHandler.py +3 -4
- psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
- psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +8 -1
- psychopy/alerts/alertsCatalogue/alertmsg.py +1 -1
- psychopy/alerts/alerttools.py +0 -16
- psychopy/app/Resources/betasplash.png +0 -0
- psychopy/app/Resources/betasplash@2x.png +0 -0
- psychopy/app/Resources/classic/case.png +0 -0
- psychopy/app/Resources/classic/case@2x.png +0 -0
- psychopy/app/Resources/classic/fileaudio.png +0 -0
- psychopy/app/Resources/classic/fileaudio@2x.png +0 -0
- psychopy/app/Resources/classic/filecss.png +0 -0
- psychopy/app/Resources/classic/filecss@2x.png +0 -0
- psychopy/app/Resources/classic/filecsv.png +0 -0
- psychopy/app/Resources/classic/filecsv@2x.png +0 -0
- psychopy/app/Resources/classic/filedesign.png +0 -0
- psychopy/app/Resources/classic/filedesign@2x.png +0 -0
- psychopy/app/Resources/classic/filefont.png +0 -0
- psychopy/app/Resources/classic/filefont@2x.png +0 -0
- psychopy/app/Resources/classic/filegit.png +0 -0
- psychopy/app/Resources/classic/filegit@2x.png +0 -0
- psychopy/app/Resources/classic/filehtml.png +0 -0
- psychopy/app/Resources/classic/filehtml@2x.png +0 -0
- psychopy/app/Resources/classic/fileimage.png +0 -0
- psychopy/app/Resources/classic/fileimage@2x.png +0 -0
- psychopy/app/Resources/classic/fileinfo.png +0 -0
- psychopy/app/Resources/classic/fileinfo@2x.png +0 -0
- psychopy/app/Resources/classic/filejs.png +0 -0
- psychopy/app/Resources/classic/filejs@2x.png +0 -0
- psychopy/app/Resources/classic/filejson.png +0 -0
- psychopy/app/Resources/classic/filejson@2x.png +0 -0
- psychopy/app/Resources/classic/filepkg.png +0 -0
- psychopy/app/Resources/classic/filepkg@2x.png +0 -0
- psychopy/app/Resources/classic/filepsyexp.png +0 -0
- psychopy/app/Resources/classic/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/classic/filepy.png +0 -0
- psychopy/app/Resources/classic/filepy@2x.png +0 -0
- psychopy/app/Resources/classic/filetxt.png +0 -0
- psychopy/app/Resources/classic/filetxt@2x.png +0 -0
- psychopy/app/Resources/classic/fileunknown.png +0 -0
- psychopy/app/Resources/classic/fileunknown@2x.png +0 -0
- psychopy/app/Resources/classic/filevideo.png +0 -0
- psychopy/app/Resources/classic/filevideo@2x.png +0 -0
- psychopy/app/Resources/classic/find.png +0 -0
- psychopy/app/Resources/classic/find@2x.png +0 -0
- psychopy/app/Resources/classic/loop.png +0 -0
- psychopy/app/Resources/classic/loop@2x.png +0 -0
- psychopy/app/Resources/classic/regex.png +0 -0
- psychopy/app/Resources/classic/regex@2x.png +0 -0
- psychopy/app/Resources/dark/case.png +0 -0
- psychopy/app/Resources/dark/case@2x.png +0 -0
- psychopy/app/Resources/dark/fileaudio.png +0 -0
- psychopy/app/Resources/dark/fileaudio@2x.png +0 -0
- psychopy/app/Resources/dark/filecss.png +0 -0
- psychopy/app/Resources/dark/filecss@2x.png +0 -0
- psychopy/app/Resources/dark/filecsv.png +0 -0
- psychopy/app/Resources/dark/filecsv@2x.png +0 -0
- psychopy/app/Resources/dark/filedesign.png +0 -0
- psychopy/app/Resources/dark/filedesign@2x.png +0 -0
- psychopy/app/Resources/dark/filefont.png +0 -0
- psychopy/app/Resources/dark/filefont@2x.png +0 -0
- psychopy/app/Resources/dark/filegit.png +0 -0
- psychopy/app/Resources/dark/filegit@2x.png +0 -0
- psychopy/app/Resources/dark/filehtml.png +0 -0
- psychopy/app/Resources/dark/filehtml@2x.png +0 -0
- psychopy/app/Resources/dark/fileimage.png +0 -0
- psychopy/app/Resources/dark/fileimage@2x.png +0 -0
- psychopy/app/Resources/dark/fileinfo.png +0 -0
- psychopy/app/Resources/dark/fileinfo@2x.png +0 -0
- psychopy/app/Resources/dark/filejs.png +0 -0
- psychopy/app/Resources/dark/filejs@2x.png +0 -0
- psychopy/app/Resources/dark/filejson.png +0 -0
- psychopy/app/Resources/dark/filejson@2x.png +0 -0
- psychopy/app/Resources/dark/filepkg.png +0 -0
- psychopy/app/Resources/dark/filepkg@2x.png +0 -0
- psychopy/app/Resources/dark/filepsyexp.png +0 -0
- psychopy/app/Resources/dark/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/dark/filepy.png +0 -0
- psychopy/app/Resources/dark/filepy@2x.png +0 -0
- psychopy/app/Resources/dark/filetxt.png +0 -0
- psychopy/app/Resources/dark/filetxt@2x.png +0 -0
- psychopy/app/Resources/dark/fileunknown.png +0 -0
- psychopy/app/Resources/dark/fileunknown@2x.png +0 -0
- psychopy/app/Resources/dark/filevideo.png +0 -0
- psychopy/app/Resources/dark/filevideo@2x.png +0 -0
- psychopy/app/Resources/dark/find.png +0 -0
- psychopy/app/Resources/dark/find@2x.png +0 -0
- psychopy/app/Resources/dark/loop.png +0 -0
- psychopy/app/Resources/dark/loop@2x.png +0 -0
- psychopy/app/Resources/dark/regex.png +0 -0
- psychopy/app/Resources/dark/regex@2x.png +0 -0
- psychopy/app/Resources/light/case.png +0 -0
- psychopy/app/Resources/light/case@2x.png +0 -0
- psychopy/app/Resources/light/fileaudio.png +0 -0
- psychopy/app/Resources/light/fileaudio@2x.png +0 -0
- psychopy/app/Resources/light/filecss.png +0 -0
- psychopy/app/Resources/light/filecss@2x.png +0 -0
- psychopy/app/Resources/light/filecsv.png +0 -0
- psychopy/app/Resources/light/filecsv@2x.png +0 -0
- psychopy/app/Resources/light/filedesign.png +0 -0
- psychopy/app/Resources/light/filedesign@2x.png +0 -0
- psychopy/app/Resources/light/filefont.png +0 -0
- psychopy/app/Resources/light/filefont@2x.png +0 -0
- psychopy/app/Resources/light/filegit.png +0 -0
- psychopy/app/Resources/light/filegit@2x.png +0 -0
- psychopy/app/Resources/light/filehtml.png +0 -0
- psychopy/app/Resources/light/filehtml@2x.png +0 -0
- psychopy/app/Resources/light/fileimage.png +0 -0
- psychopy/app/Resources/light/fileimage@2x.png +0 -0
- psychopy/app/Resources/light/fileinfo.png +0 -0
- psychopy/app/Resources/light/fileinfo@2x.png +0 -0
- psychopy/app/Resources/light/filejs.png +0 -0
- psychopy/app/Resources/light/filejs@2x.png +0 -0
- psychopy/app/Resources/light/filejson.png +0 -0
- psychopy/app/Resources/light/filejson@2x.png +0 -0
- psychopy/app/Resources/light/filepkg.png +0 -0
- psychopy/app/Resources/light/filepkg@2x.png +0 -0
- psychopy/app/Resources/light/filepsyexp.png +0 -0
- psychopy/app/Resources/light/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/light/filepy.png +0 -0
- psychopy/app/Resources/light/filepy@2x.png +0 -0
- psychopy/app/Resources/light/filetxt.png +0 -0
- psychopy/app/Resources/light/filetxt@2x.png +0 -0
- psychopy/app/Resources/light/fileunknown.png +0 -0
- psychopy/app/Resources/light/fileunknown@2x.png +0 -0
- psychopy/app/Resources/light/filevideo.png +0 -0
- psychopy/app/Resources/light/filevideo@2x.png +0 -0
- psychopy/app/Resources/light/find.png +0 -0
- psychopy/app/Resources/light/find@2x.png +0 -0
- psychopy/app/Resources/light/loop.png +0 -0
- psychopy/app/Resources/light/loop@2x.png +0 -0
- psychopy/app/Resources/light/regex.png +0 -0
- psychopy/app/Resources/light/regex@2x.png +0 -0
- psychopy/app/Resources/routine_templates/Basic.psyexp +0 -1
- psychopy/app/Resources/routine_templates/Misc.psyexp +0 -1
- psychopy/app/Resources/routine_templates/Online.psyexp +0 -2
- psychopy/app/Resources/routine_templates/Trials.psyexp +0 -1
- psychopy/app/Resources/splash.png +0 -0
- psychopy/app/Resources/splash@2x.png +0 -0
- psychopy/app/__init__.py +49 -8
- psychopy/app/__main__.py +3 -0
- psychopy/app/_psychopyApp.py +134 -125
- psychopy/app/builder/builder.py +42 -22
- psychopy/app/builder/dialogs/__init__.py +44 -11
- psychopy/app/builder/dialogs/dlgsCode.py +1 -1
- psychopy/app/builder/dialogs/dlgsConditions.py +1 -1
- psychopy/app/builder/dialogs/findDlg.py +106 -20
- psychopy/app/builder/dialogs/paramCtrls.py +42 -1
- psychopy/app/builder/validators.py +1 -1
- psychopy/app/coder/codeEditorBase.py +8 -8
- psychopy/app/coder/coder.py +32 -29
- psychopy/app/coder/fileBrowser.py +68 -22
- psychopy/app/coder/folding.py +1 -1
- psychopy/app/coder/psychoParser.py +1 -1
- psychopy/app/coder/repl.py +1 -1
- psychopy/app/coder/sourceTree.py +1 -1
- psychopy/app/connections/__init__.py +1 -1
- psychopy/app/connections/news.py +1 -1
- psychopy/app/connections/sendusage.py +1 -1
- psychopy/app/connections/updates.py +1 -1
- psychopy/app/console.py +1 -1
- psychopy/app/errorDlg.py +1 -1
- psychopy/app/frametracker.py +1 -1
- psychopy/app/idle.py +1 -1
- psychopy/app/jobs.py +5 -2
- psychopy/app/linuxconfig/__init__.py +1 -1
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +3 -3
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +1 -1
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +3421 -2396
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +3 -3
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +2 -2
- psychopy/app/{builder/localizedStrings.py → localizedStrings.py} +173 -26
- psychopy/app/pavlovia_ui/__init__.py +1 -1
- psychopy/app/pavlovia_ui/_base.py +1 -1
- psychopy/app/pavlovia_ui/functions.py +1 -1
- psychopy/app/pavlovia_ui/menu.py +1 -1
- psychopy/app/pavlovia_ui/project.py +1 -1
- psychopy/app/pavlovia_ui/search.py +1 -1
- psychopy/app/pavlovia_ui/sync.py +1 -1
- psychopy/app/pavlovia_ui/user.py +1 -1
- psychopy/app/plugin_manager/dialog.py +34 -96
- psychopy/app/plugin_manager/packages.py +10 -14
- psychopy/app/plugin_manager/plugins.py +64 -4
- psychopy/app/preferencesDlg.py +12 -37
- psychopy/app/psychopyApp.py +130 -44
- psychopy/app/ribbon.py +1 -0
- psychopy/app/runner/runner.py +19 -7
- psychopy/app/runner/scriptProcess.py +11 -6
- psychopy/app/stdout/stdOutRich.py +9 -2
- psychopy/app/themes/fonts.py +1 -1
- psychopy/app/themes/icons.py +2 -38
- psychopy/app/ui/__init__.py +1 -1
- psychopy/app/utils.py +3 -3
- psychopy/assets/default.mp3 +0 -0
- psychopy/assets/fonts/NotoSans-Bold.ttf +0 -0
- psychopy/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Italic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Regular.ttf +0 -0
- psychopy/assets/voicekeyThresholdStim.wav +0 -0
- psychopy/clock.py +4 -1
- psychopy/colors.py +2 -0
- psychopy/core.py +1 -1
- psychopy/data/base.py +1 -1
- psychopy/data/experiment.py +151 -46
- psychopy/data/routine.py +27 -1
- psychopy/data/staircase.py +2 -1
- psychopy/data/trial.py +62 -14
- psychopy/data/utils.py +1 -1
- psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +333 -218
- psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +261 -239
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +319 -180
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +204 -116
- psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
- psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/bart.psyexp +779 -866
- psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +242 -180
- psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +419 -406
- psychopy/demos/builder/Experiments/dragAndDrop/README.md +2 -37
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +460 -1204
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/blank_grid.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/make_shapes.psyexp +221 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/readme.md +4 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_1.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_10.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_2.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_3.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_4.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_5.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_6.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_7.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_8.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_9.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
- psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +583 -542
- psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +458 -427
- psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +588 -550
- psychopy/demos/builder/Experiments/stroop/stroop.psyexp +303 -207
- psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +390 -215
- psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +390 -215
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +357 -331
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -2
- psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +287 -277
- psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +370 -320
- psychopy/demos/builder/Feature Demos/noise/noise.psyexp +452 -399
- psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +168 -133
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +4 -3
- psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +420 -392
- psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +917 -871
- psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +200 -0
- psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +25 -9
- psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +372 -361
- psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +25 -9
- psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +320 -235
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +790 -651
- psychopy/demos/builder/Hardware/camera/camera.psyexp +326 -246
- psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +432 -327
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +440 -321
- psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +190 -181
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +323 -312
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy_legacy.psyexp +312 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +329 -273
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy_legacy.psyexp +312 -0
- psychopy/demos/builder/Hardware/microphone/microphone.psyexp +450 -404
- psychopy/demos/builder/Hardware/pump/pump.psyexp +593 -329
- psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +336 -274
- psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +200 -149
- psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -279
- psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +677 -564
- psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +214 -158
- psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +195 -146
- psychopy/demos/coder/experiment control/runtimeInfo.py +1 -1
- psychopy/devices/__init__.py +1 -1
- psychopy/event.py +1 -1
- psychopy/exceptions.py +1 -1
- psychopy/experiment/__init__.py +1 -1
- psychopy/experiment/_experiment.py +30 -9
- psychopy/experiment/components/__init__.py +1 -6
- psychopy/experiment/components/_base.py +44 -19
- psychopy/experiment/components/aperture/__init__.py +1 -1
- psychopy/experiment/components/brush/__init__.py +2 -2
- psychopy/experiment/components/button/__init__.py +24 -28
- psychopy/experiment/components/camera/__init__.py +38 -39
- psychopy/experiment/components/code/__init__.py +1 -1
- psychopy/experiment/components/dots/__init__.py +1 -1
- psychopy/experiment/components/eyetracker_record/__init__.py +7 -3
- psychopy/experiment/components/form/__init__.py +3 -3
- psychopy/experiment/components/grating/__init__.py +1 -1
- psychopy/experiment/components/image/__init__.py +1 -1
- psychopy/experiment/components/joyButtons/__init__.py +2 -2
- psychopy/experiment/components/joyButtons/virtualJoyButtons.py +1 -1
- psychopy/experiment/components/joystick/__init__.py +3 -3
- psychopy/experiment/components/joystick/virtualJoystick.py +1 -1
- psychopy/experiment/components/keyboard/__init__.py +98 -122
- psychopy/experiment/components/microphone/__init__.py +54 -98
- psychopy/experiment/components/mouse/__init__.py +92 -93
- psychopy/experiment/components/movie/__init__.py +28 -50
- psychopy/experiment/components/parallelOut/__init__.py +3 -3
- psychopy/experiment/components/polygon/__init__.py +2 -3
- psychopy/experiment/components/roi/__init__.py +2 -2
- psychopy/experiment/components/routineSettings/__init__.py +2 -0
- psychopy/experiment/components/serialOut/__init__.py +7 -7
- psychopy/experiment/components/settings/__init__.py +317 -313
- psychopy/experiment/components/settings/eyetracking.py +108 -0
- psychopy/experiment/components/slider/__init__.py +5 -5
- psychopy/experiment/components/sound/__init__.py +168 -78
- psychopy/experiment/components/soundsensor/__init__.py +361 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor@2x.png +0 -0
- psychopy/experiment/components/static/__init__.py +59 -33
- psychopy/experiment/components/text/__init__.py +2 -6
- psychopy/experiment/components/textbox/__init__.py +3 -7
- psychopy/experiment/components/unknown/__init__.py +2 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +2 -0
- psychopy/experiment/exports.py +1 -1
- psychopy/experiment/flow.py +2 -2
- psychopy/experiment/localization.py +1 -1
- psychopy/experiment/loops.py +43 -10
- psychopy/experiment/params.py +6 -4
- psychopy/experiment/plugins.py +8 -1
- psychopy/experiment/py2js.py +1 -1
- psychopy/experiment/py2js_transpiler.py +1 -1
- psychopy/experiment/routines/__init__.py +1 -1
- psychopy/experiment/routines/_base.py +23 -24
- psychopy/experiment/routines/audioValidator/__init__.py +343 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/__init__.py +76 -17
- psychopy/experiment/routines/eyetracker_validate/__init__.py +1 -1
- psychopy/experiment/routines/unknown/__init__.py +2 -0
- psychopy/experiment/routines/{photodiodeValidator → visualValidator}/__init__.py +89 -120
- psychopy/experiment/routines/visualValidator/classic/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/classic/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator@2x.png +0 -0
- psychopy/experiment/utils.py +1 -1
- psychopy/gui/__init__.py +1 -1
- psychopy/gui/qtgui.py +15 -6
- psychopy/gui/wxgui.py +1 -1
- psychopy/hardware/__init__.py +0 -1
- psychopy/hardware/base.py +147 -16
- psychopy/hardware/bbtk/__init__.py +10 -16
- psychopy/hardware/brainproducts.py +7 -13
- psychopy/hardware/button.py +21 -2
- psychopy/hardware/buttonbox/__init__.py +1 -1
- psychopy/hardware/camera/__init__.py +16 -3
- psychopy/hardware/cedrus.py +5 -16
- psychopy/hardware/crs/__init__.py +1 -1
- psychopy/hardware/crs/bits.py +36 -33
- psychopy/hardware/crs/colorcal.py +8 -11
- psychopy/hardware/crs/optical.py +7 -10
- psychopy/hardware/crs/shaders.py +18 -5
- psychopy/hardware/emotiv.py +1 -1
- psychopy/hardware/emulator.py +11 -5
- psychopy/hardware/exceptions.py +86 -0
- psychopy/hardware/forp.py +18 -23
- psychopy/hardware/gammasci.py +8 -3
- psychopy/hardware/iolab.py +8 -19
- psychopy/hardware/joystick/__init__.py +865 -266
- psychopy/hardware/joystick/_base.py +251 -0
- psychopy/hardware/joystick/backend_glfw.py +306 -0
- psychopy/hardware/joystick/backend_pyglet.py +309 -0
- psychopy/hardware/joystick/mappings.py +287 -0
- psychopy/hardware/keyboard.py +4 -2
- psychopy/hardware/labhackers.py +1 -1
- psychopy/hardware/labjacks.py +9 -13
- psychopy/hardware/{photodiode.py → lightsensor.py} +146 -203
- psychopy/hardware/listener.py +9 -8
- psychopy/hardware/manager.py +24 -35
- psychopy/hardware/microphone.py +534 -154
- psychopy/hardware/minolta.py +14 -4
- psychopy/hardware/mouse/__init__.py +1 -1
- psychopy/hardware/photometer/__init__.py +2 -2
- psychopy/hardware/pr.py +14 -4
- psychopy/hardware/qmix.py +18 -27
- psychopy/hardware/serialdevice.py +43 -12
- psychopy/hardware/soundsensor.py +473 -0
- psychopy/hardware/spatial/__init__.py +231 -0
- psychopy/hardware/speaker.py +298 -36
- psychopy/hardware/triggerbox/__init__.py +1 -1
- psychopy/hardware/triggerbox/base.py +1 -1
- psychopy/hardware/triggerbox/parallel.py +1 -1
- psychopy/info.py +1 -1
- psychopy/iohub/devices/eyetracker/__init__.py +10 -18
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +15 -33
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +1 -0
- psychopy/iohub/devices/mouse/linux2.py +2 -1
- psychopy/layout.py +1 -1
- psychopy/liaison.py +91 -39
- psychopy/locale_setup.py +11 -1
- psychopy/localization/__init__.py +1 -1
- psychopy/localization/_localization.py +1 -1
- psychopy/localization/messages.pot +2 -2
- psychopy/logging.py +14 -12
- psychopy/microphone.py +4 -3
- psychopy/misc.py +1 -1
- psychopy/monitors/MonitorCenter.py +3 -3
- psychopy/monitors/__init__.py +1 -1
- psychopy/monitors/calibData.py +1 -1
- psychopy/monitors/calibTools.py +3 -2
- psychopy/platform_specific/__init__.py +1 -1
- psychopy/platform_specific/darwin.py +1 -1
- psychopy/platform_specific/linux.py +1 -1
- psychopy/platform_specific/win32.py +1 -1
- psychopy/plugins/__init__.py +26 -17
- psychopy/plugins/util.py +65 -0
- psychopy/preferences/Darwin.spec +11 -3
- psychopy/preferences/FreeBSD.spec +11 -3
- psychopy/preferences/Linux.spec +11 -3
- psychopy/preferences/Windows.spec +11 -3
- psychopy/preferences/__init__.py +1 -1
- psychopy/preferences/baseNoArch.spec +11 -3
- psychopy/preferences/hints.py +78 -61
- psychopy/preferences/preferences.py +82 -13
- psychopy/projects/__init__.py +1 -1
- psychopy/projects/pavlovia.py +29 -13
- psychopy/scripts/psyexpCompile.py +1 -1
- psychopy/session.py +81 -8
- psychopy/sound/__init__.py +25 -10
- psychopy/sound/_base.py +134 -34
- psychopy/sound/audioclip.py +38 -15
- psychopy/sound/audiodevice.py +1 -1
- psychopy/sound/backend_ptb.py +53 -321
- psychopy/sound/backend_pygame.py +7 -3
- psychopy/sound/backend_pyo.py +53 -22
- psychopy/sound/backend_pysound.py +10 -27
- psychopy/sound/backend_sounddevice.py +33 -21
- psychopy/sound/exceptions.py +1 -1
- psychopy/sound/microphone.py +83 -5
- psychopy/sound/transcribe.py +3 -3
- psychopy/tests/data/test_basic_run.py +1 -0
- psychopy/tests/data/test_sounds/default_16000.wav +0 -0
- psychopy/tests/data/test_sounds/default_192000.wav +0 -0
- psychopy/tests/data/test_sounds/default_22050.wav +0 -0
- psychopy/tests/data/test_sounds/default_32000.wav +0 -0
- psychopy/tests/data/test_sounds/default_44100.wav +0 -0
- psychopy/tests/data/test_sounds/default_48000.wav +0 -0
- psychopy/tests/data/test_sounds/default_8000.wav +0 -0
- psychopy/tests/data/test_sounds/default_96000.wav +0 -0
- psychopy/tests/test_alerts/test_alerttools.py +2 -1
- psychopy/tests/test_app/test_command_line.py +65 -0
- psychopy/tests/test_data/test_TrialHandler2.py +18 -7
- psychopy/tests/test_demos/test_builder_demos.py +1 -1
- psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +5238 -4188
- psychopy/tests/test_experiment/needs_wx/test_components.py +1 -1
- psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
- psychopy/tests/test_experiment/test_components/test_all_components.py +1 -1
- psychopy/tests/test_experiment/test_components/test_base_components.py +26 -17
- psychopy/tests/test_experiment/test_loops.py +12 -4
- psychopy/tests/test_experiment/test_params.py +17 -4
- psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +2 -2
- psychopy/tests/test_hardware/test_photodiode.py +66 -0
- psychopy/tests/test_liaison/test_Liaison.py +4 -4
- psychopy/tests/test_misc/test_clock.py +2 -0
- psychopy/tests/test_misc/test_color.py +2 -0
- psychopy/tests/test_misc/test_event.py +1 -0
- psychopy/tests/test_plugins/__init__.py +0 -0
- psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
- psychopy/tests/test_sound/test_sound.py +111 -40
- psychopy/tests/test_tools/test_colorspacetools.py +24 -23
- psychopy/tests/test_tools/test_mathtools.py +9 -9
- psychopy/tests/test_tools/test_viewtools.py +101 -0
- psychopy/tests/test_validators/__init__.py +0 -0
- psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
- psychopy/tests/test_visual/test_all_stimuli.py +2 -2
- psychopy/tests/test_visual/test_basevisual.py +37 -7
- psychopy/tests/test_visual/test_button.py +2 -2
- psychopy/tests/test_visual/test_circle.py +10 -2
- psychopy/tests/test_visual/test_dots.py +1 -1
- psychopy/tests/test_visual/test_form.py +13 -13
- psychopy/tests/test_visual/test_gamma.py +3 -3
- psychopy/tests/test_visual/test_image.py +2 -2
- psychopy/tests/test_visual/test_progress.py +2 -2
- psychopy/tests/test_visual/test_roi.py +8 -2
- psychopy/tests/test_visual/test_shape.py +2 -2
- psychopy/tests/test_visual/test_slider.py +2 -2
- psychopy/tests/test_visual/test_target.py +2 -2
- psychopy/tests/test_visual/test_textbox.py +6 -8
- psychopy/tests/test_visual/test_winScalePos.py +6 -5
- psychopy/tests/test_visual/test_window.py +17 -0
- psychopy/tests/utils.py +51 -1
- psychopy/tools/__init__.py +1 -1
- psychopy/tools/arraytools.py +2 -2
- psychopy/tools/attributetools.py +52 -1
- psychopy/tools/audiotools.py +4 -1
- psychopy/tools/colorspacetools.py +6 -4
- psychopy/tools/coordinatetools.py +1 -1
- psychopy/tools/fileerrortools.py +21 -9
- psychopy/tools/filetools.py +2 -2
- psychopy/tools/fontmanager.py +47 -28
- psychopy/tools/gltools.py +2964 -558
- psychopy/tools/imagetools.py +1 -1
- psychopy/tools/mathtools.py +997 -127
- psychopy/tools/monitorunittools.py +7 -1
- psychopy/tools/movietools.py +1 -2
- psychopy/tools/pkgtools.py +157 -127
- psychopy/tools/plottools.py +1 -1
- psychopy/tools/rifttools.py +1 -1
- psychopy/tools/stereotools.py +1 -1
- psychopy/tools/stimulustools.py +172 -2
- psychopy/tools/stringtools.py +22 -2
- psychopy/tools/systemtools.py +1 -1
- psychopy/tools/typetools.py +1 -1
- psychopy/tools/unittools.py +1 -1
- psychopy/tools/versionchooser.py +3 -1
- psychopy/tools/viewtools.py +54 -70
- psychopy/tools/wizard.py +2 -2
- psychopy/validation/__init__.py +6 -0
- psychopy/validation/audio.py +74 -0
- psychopy/validation/visual.py +115 -0
- psychopy/visual/__init__.py +1 -4
- psychopy/visual/aperture.py +9 -6
- psychopy/visual/backends/__init__.py +1 -1
- psychopy/visual/backends/_base.py +1 -1
- psychopy/visual/backends/gamma.py +1 -1
- psychopy/visual/backends/glfwbackend.py +8 -12
- psychopy/visual/backends/pygamebackend.py +1 -1
- psychopy/visual/backends/pygletbackend.py +32 -11
- psychopy/visual/basevisual.py +93 -13
- psychopy/visual/brush.py +1 -1
- psychopy/visual/bufferimage.py +90 -10
- psychopy/visual/button.py +1 -1
- psychopy/visual/circle.py +12 -20
- psychopy/visual/custommouse.py +1 -1
- psychopy/visual/dot.py +80 -14
- psychopy/visual/elementarray.py +84 -10
- psychopy/visual/filters.py +1 -1
- psychopy/visual/form.py +43 -28
- psychopy/visual/grating.py +105 -25
- psychopy/visual/helpers.py +1 -1
- psychopy/visual/image.py +98 -20
- psychopy/visual/line.py +15 -25
- psychopy/visual/movie.py +1 -1
- psychopy/visual/movie2.py +4 -3
- psychopy/visual/movie3.py +4 -3
- psychopy/visual/movies/__init__.py +1 -1
- psychopy/visual/movies/frame.py +1 -1
- psychopy/visual/movies/metadata.py +1 -1
- psychopy/visual/movies/players/__init__.py +1 -1
- psychopy/visual/movies/players/_base.py +1 -1
- psychopy/visual/movies/players/ffpyplayer_player.py +2 -3
- psychopy/visual/nnlvs.py +9 -6
- psychopy/visual/noise.py +4 -16
- psychopy/visual/patch.py +4 -3
- psychopy/visual/pie.py +3 -14
- psychopy/visual/polygon.py +21 -28
- psychopy/visual/radial.py +4 -18
- psychopy/visual/ratingscale.py +4 -3
- psychopy/visual/rect.py +16 -25
- psychopy/visual/rift.py +8 -2
- psychopy/visual/secondorder.py +4 -16
- psychopy/visual/shaders.py +620 -286
- psychopy/visual/shape.py +281 -90
- psychopy/visual/simpleimage.py +1 -1
- psychopy/visual/slider.py +78 -25
- psychopy/visual/stim3d.py +5 -608
- psychopy/visual/text.py +13 -3
- psychopy/visual/textbox2/textbox2.py +188 -56
- psychopy/visual/vlcmoviestim.py +1 -1
- psychopy/visual/window.py +373 -200
- psychopy/web.py +1 -1
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/METADATA +9 -9
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/RECORD +644 -621
- psychopy/.DS_Store +0 -0
- psychopy/__init__.py.orig +0 -65
- psychopy/app/.DS_Store +0 -0
- psychopy/app/Resources/.DS_Store +0 -0
- psychopy/app/Resources/classic/filecsv16.png +0 -0
- psychopy/app/Resources/classic/fileimage16.png +0 -0
- psychopy/app/Resources/classic/fileunknown16.png +0 -0
- psychopy/app/Resources/dark/filecsv16.png +0 -0
- psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
- psychopy/app/Resources/dark/fileimage16.png +0 -0
- psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
- psychopy/app/Resources/dark/fileunknown16.png +0 -0
- psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
- psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
- psychopy/app/Resources/light/filecsv16.png +0 -0
- psychopy/app/Resources/light/filecsv16@2x.png +0 -0
- psychopy/app/Resources/light/fileimage16.png +0 -0
- psychopy/app/Resources/light/fileimage16@2x.png +0 -0
- psychopy/app/Resources/light/fileunknown16.png +0 -0
- psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
- psychopy/app/Resources/psychopySplash.png +0 -0
- psychopy/app/Resources/psychopySplash@2x.png +0 -0
- psychopy/app/builder/builder.py.orig +0 -3932
- psychopy/app/builder/dialogs/__init__.py.orig +0 -1679
- psychopy/app/builder/dialogs/paramCtrls.py.orig +0 -713
- psychopy/app/colorpicker/__init__.py.orig +0 -411
- psychopy/app/locale/ar_001/.DS_Store +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/.DS_Store +0 -0
- psychopy/core.py.orig +0 -169
- psychopy/demos/builder/.DS_Store +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +0 -330
- psychopy/demos/builder/Experiments/.DS_Store +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +0 -61
- psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +0 -91
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
- psychopy/demos/builder/Tools/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +0 -38
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +0 -3418
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +0 -2
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +0 -15
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +0 -562
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
- psychopy/demos/coder/iohub/.iohpid +0 -1
- psychopy/demos/coder/iohub/eyetracking/.iohpid +0 -1
- psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/.DS_Store +0 -0
- psychopy/experiment/_experiment.py.orig +0 -1032
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/_base.py.orig +0 -823
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py.orig +0 -490
- psychopy/experiment/components/settings/__init__.py.orig +0 -1337
- psychopy/experiment/components/textbox/__init__.py.orig +0 -310
- psychopy/experiment/components/webcam/.DS_Store +0 -0
- psychopy/experiment/components/webcam/light/.DS_Store +0 -0
- psychopy/experiment/loops.py.orig +0 -829
- psychopy/experiment/params.py.orig +0 -408
- psychopy/experiment/routine.py.orig +0 -503
- psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/brainproducts.py.orig +0 -680
- psychopy/hardware/iolab.py.orig +0 -238
- psychopy/iohub/datastore/__init__.py.orig +0 -443
- psychopy/iohub/datastore/util.py.orig +0 -692
- psychopy/iohub/devices/mouse/darwin.py.orig +0 -427
- psychopy/iohub/devices/mouse/linux2.py.orig +0 -198
- psychopy/preferences/.DS_Store +0 -0
- psychopy/projects/pavlovia.py.orig +0 -1295
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestCircle_fill_local.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
- psychopy/tests/data/aperture1_norm_local.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_height_local.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_norm_local.png +0 -0
- psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
- psychopy/tests/data/blend_add_height_local.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
- psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
- psychopy/tests/data/blend_add_norm_local.png +0 -0
- psychopy/tests/data/blend_add_stencil_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
- psychopy/tests/data/circleHex_height_local.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
- psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
- psychopy/tests/data/circleHex_norm_local.png +0 -0
- psychopy/tests/data/circleHex_stencil_local.png +0 -0
- psychopy/tests/data/color_comparison_local.png +0 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/dots_height_local.png +0 -0
- psychopy/tests/data/dots_normAddBlend_local.png +0 -0
- psychopy/tests/data/dots_normHexbackground_local.png +0 -0
- psychopy/tests/data/dots_normNoShade_local.png +0 -0
- psychopy/tests/data/dots_norm_local.png +0 -0
- psychopy/tests/data/dots_stencil_local.png +0 -0
- psychopy/tests/data/elarray1_height_local.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
- psychopy/tests/data/elarray1_norm_local.png +0 -0
- psychopy/tests/data/elarray1_stencil_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
- psychopy/tests/data/gabor1_height_local.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
- psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
- psychopy/tests/data/gabor1_norm_local.png +0 -0
- psychopy/tests/data/gabor1_stencil_local.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_height_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
- psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
- psychopy/tests/data/movFrame1_stencil_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/numpyImage_height_local.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
- psychopy/tests/data/numpyImage_norm_local.png +0 -0
- psychopy/tests/data/numpyImage_stencil_local.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
- psychopy/tests/data/shape2_1_norm_local.png +0 -0
- psychopy/tests/data/shape2_1_stencil_local.png +0 -0
- psychopy/tests/data/text1_height_local.png +0 -0
- psychopy/tests/data/text1_normAddBlend_local.png +0 -0
- psychopy/tests/data/text1_normHexbackground_local.png +0 -0
- psychopy/tests/data/text1_norm_local.png +0 -0
- psychopy/tests/data/text1_stencil_local.png +0 -0
- psychopy/tests/data/wedge1_height_local.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
- psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
- psychopy/tests/data/wedge1_norm_local.png +0 -0
- psychopy/tests/data/wedge1_stencil_local.png +0 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +0 -177
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +0 -168
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
- psychopy/tests/test_data/.DS_Store +0 -0
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py +0 -67
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +0 -68
- psychopy/tests/test_hardware/test_CRS_bitsShaders.py +0 -110
- psychopy/tests/test_visual/test_image.py.orig +0 -219
- psychopy/visual/basevisual.py.orig +0 -1723
- psychopy/visual/form.py.orig +0 -1181
- psychopy/visual/text.py.orig +0 -752
- psychopy/visual/textbox2/textbox2.py.orig +0 -1315
- psychopy/visual/windowwarp.py.orig +0 -463
- /psychopy/{app/cortex.log → alerts/alertsCatalogue/3600.yaml} +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Bold.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-BoldItalic.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Italic.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Regular.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/DejaVuSerif.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/IndieFlower-Regular.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
- /psychopy/demos/builder/Experiments/{GoNoGo → goNoGo}/readme.md +0 -0
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/WHEEL +0 -0
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/licenses/LICENSE +0 -0
psychopy/hardware/speaker.py
CHANGED
|
@@ -1,37 +1,284 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
"""Classes and functions managing physical speaker devices for audio playback.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# Part of the PsychoPy library
|
|
7
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
8
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
|
9
|
+
|
|
10
|
+
import io
|
|
11
|
+
import sys
|
|
12
|
+
import contextlib
|
|
13
|
+
from types import SimpleNamespace
|
|
14
|
+
import psychtoolbox.audio as ptb
|
|
15
|
+
from psychopy.hardware.exceptions import DeviceNotConnectedError
|
|
16
|
+
from psychopy.localization import _translate
|
|
17
|
+
from psychopy.preferences import prefs
|
|
1
18
|
from psychopy.hardware import BaseDevice
|
|
2
|
-
from psychopy.sound import setDevice, getDevices, backend
|
|
3
19
|
from psychopy import logging
|
|
20
|
+
from psychopy.tools import systemtools
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"SpeakerDevice",
|
|
24
|
+
]
|
|
4
25
|
|
|
5
26
|
|
|
6
27
|
class SpeakerDevice(BaseDevice):
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
"""Class for managing a physical speaker device for audio playback.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
index : int, optional
|
|
33
|
+
Numeric index for the physical speaker device, according to psychtoolbox. Leave as None to
|
|
34
|
+
find the speaker by name.
|
|
35
|
+
name : str, optional
|
|
36
|
+
String name for the physical speaker device, according to your operating system. Leave as
|
|
37
|
+
None to find the speaker by numeric index.
|
|
38
|
+
latencyClass : int
|
|
39
|
+
One of:
|
|
40
|
+
|
|
41
|
+
* 0: Don't take exclusive control over the speaker, so other apps can still use it. Send
|
|
42
|
+
sounds via the system mixer so that sample rates are all handled, even though this
|
|
43
|
+
introduces latency.
|
|
44
|
+
|
|
45
|
+
* 1: Don't take exclusive control over the speaker, so other apps can still use it. Send
|
|
46
|
+
sounds directly to reduce latency, so sounds will need to match the sample rate of the
|
|
47
|
+
speaker. **Recommended in most cases; if `resample` is True then sample rates are
|
|
48
|
+
already handled on load!**
|
|
49
|
+
|
|
50
|
+
* 2: Take exclusive control over the speaker, so other apps can't use it. Send sounds
|
|
51
|
+
directly to reduce latency, so sounds will need to be the same sample rate as one
|
|
52
|
+
another, but this can be any sample rate supported by the speaker.
|
|
53
|
+
|
|
54
|
+
* 3: Take exclusive control over the speaker, so other apps can't use it. Send sounds
|
|
55
|
+
directly to reduce latency, so sounds will need to be the same sample rate as one
|
|
56
|
+
another, but this can be any sample rate supported by the speaker. Force the system to
|
|
57
|
+
prioritise resources towards playing sounds on this speaker for absolute minimum
|
|
58
|
+
latency, but fallback to mode 2 if the system rejects this.
|
|
59
|
+
|
|
60
|
+
* 4: Take exclusive control over the speaker, so other apps can't use it. Send sounds
|
|
61
|
+
directly to reduce latency, so sounds will need to be the same sample rate as one
|
|
62
|
+
another, but this can be any sample rate supported by the speaker. Force the system to
|
|
63
|
+
prioritise resources towards playing sounds on this speaker for absolute minimum
|
|
64
|
+
latency, and raise an error if the system rejects this.
|
|
65
|
+
resample : bool, optional
|
|
66
|
+
If the sample rate of an audio clip doesn't match the sample rate of the speaker, should
|
|
67
|
+
PsychoPy resample the sound on load?
|
|
68
|
+
"""
|
|
69
|
+
# dict of extant streams, by numeric index
|
|
70
|
+
streams = {}
|
|
71
|
+
|
|
72
|
+
def __init__(self, index=None, name=None, latencyClass=1, resample=True):
|
|
73
|
+
if index is not None and name is not None:
|
|
74
|
+
logging.warn(
|
|
75
|
+
"Both 'index' and 'name' were provided to SpeakerDevice; ignoring 'index'"
|
|
76
|
+
)
|
|
77
|
+
index = None
|
|
78
|
+
# try simple integerisation of index
|
|
79
|
+
if isinstance(index, str):
|
|
80
|
+
try:
|
|
81
|
+
index = float(index)
|
|
82
|
+
except ValueError:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
# if index is default, get default speaker device
|
|
86
|
+
if index in (-1, None) and name is None:
|
|
87
|
+
index = None # set to none so we can find by name later
|
|
88
|
+
pref = prefs.hardware['audioDevice']
|
|
89
|
+
pref = pref[0] if isinstance(pref, (list, tuple)) else pref
|
|
90
|
+
|
|
91
|
+
if pref in ("default", "None"):
|
|
92
|
+
# if no pref, use first device
|
|
93
|
+
name = self.getAvailableDevices()[0]['deviceName']
|
|
94
|
+
# warn the user, this speaker might be a virtual device with no audio or something
|
|
95
|
+
logging.warn(
|
|
96
|
+
_translate(
|
|
97
|
+
"No default speaker specified in Preferences / Hardware, using first speaker found: {}"
|
|
98
|
+
).format(name)
|
|
99
|
+
)
|
|
100
|
+
else:
|
|
101
|
+
# if pref is a name, use that
|
|
102
|
+
name = pref
|
|
103
|
+
|
|
104
|
+
# store name and index
|
|
105
|
+
self.name = name
|
|
31
106
|
self.index = index
|
|
32
|
-
# set global device (best we can do for now)
|
|
33
|
-
setDevice(index)
|
|
34
107
|
|
|
108
|
+
# store playback prefs
|
|
109
|
+
self.resample = resample
|
|
110
|
+
self.latencyClass = latencyClass
|
|
111
|
+
# create stream
|
|
112
|
+
self.createStream()
|
|
113
|
+
# start off open
|
|
114
|
+
self.open()
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def exclusive(self):
|
|
118
|
+
"""
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
bool
|
|
122
|
+
Does PsychoPy have exclusive control of this speaker? If True then other apps will not be
|
|
123
|
+
able to play sounds on the same speaker.
|
|
124
|
+
"""
|
|
125
|
+
return self.latencyClass >= 2
|
|
126
|
+
|
|
127
|
+
def createStream(self):
|
|
128
|
+
"""
|
|
129
|
+
Create the psychtoolbox audio stream
|
|
130
|
+
|
|
131
|
+
Attributes
|
|
132
|
+
----------
|
|
133
|
+
Calling this method will set the following attributes:
|
|
134
|
+
|
|
135
|
+
profile : dict
|
|
136
|
+
The profile from psychtoolbox, a dict with the following keys: Active, State,
|
|
137
|
+
RequestedStartTime, StartTime, CaptureStartTime, RequestedStopTime, EstimatedStopTime,
|
|
138
|
+
CurrentStreamTime, ElapsedOutSamples, PositionSecs, RecordedSecs, ReadSecs,
|
|
139
|
+
SchedulePosition, XRuns, TotalCalls, TimeFailed, BufferSize, CPULoad, PredictedLatency,
|
|
140
|
+
LatencyBias, SampleRate, OutDeviceIndex, InDeviceIndex
|
|
141
|
+
index : int
|
|
142
|
+
A numeric index referring to the device. This may differ from the value of `index` this
|
|
143
|
+
object was initialised with, as this will be the numeric index of the actual physical
|
|
144
|
+
speaker best matching what was requested.
|
|
145
|
+
name : str
|
|
146
|
+
A string name referring to the device. This may differ from the value of `name` this
|
|
147
|
+
object was initialised with, as this will be the system-reported name of the actual
|
|
148
|
+
physical speaker best matching what was requested.
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
# get the devices from psychtoolbox
|
|
152
|
+
try:
|
|
153
|
+
wasapiPref = prefs.hardware['audioWASAPIOnly']
|
|
154
|
+
except KeyError:
|
|
155
|
+
wasapiPref = False
|
|
156
|
+
|
|
157
|
+
if sys.platform == 'win32' and wasapiPref:
|
|
158
|
+
allFoundDevices = ptb.get_devices(device_type=13)
|
|
159
|
+
else:
|
|
160
|
+
allFoundDevices = ptb.get_devices()
|
|
161
|
+
|
|
162
|
+
if not allFoundDevices:
|
|
163
|
+
raise DeviceNotConnectedError(
|
|
164
|
+
_translate("No audio devices found!"),
|
|
165
|
+
deviceClass=SpeakerDevice
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# find ptb profile for this device
|
|
169
|
+
findByName = self.index is None and self.name is not None
|
|
170
|
+
self.profile = None
|
|
171
|
+
for thisProfile in allFoundDevices:
|
|
172
|
+
# skip input-only devices (microphones)
|
|
173
|
+
if thisProfile['NrOutputChannels'] == 0:
|
|
174
|
+
continue
|
|
175
|
+
|
|
176
|
+
if findByName and self.name == thisProfile['DeviceName']:
|
|
177
|
+
self.profile = thisProfile
|
|
178
|
+
break
|
|
179
|
+
else: # use index instead
|
|
180
|
+
if self.index == thisProfile['DeviceIndex']:
|
|
181
|
+
self.profile = thisProfile
|
|
182
|
+
break
|
|
183
|
+
|
|
184
|
+
# raise error if device not found
|
|
185
|
+
if self.profile is None:
|
|
186
|
+
raise DeviceNotConnectedError(
|
|
187
|
+
_translate(
|
|
188
|
+
"No speaker device found with {key} '{name}'"
|
|
189
|
+
).format(name=self.name, key="name" if findByName else "index"),
|
|
190
|
+
deviceClass=SpeakerDevice
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
logging.debug(
|
|
194
|
+
f"Found speaker device: {self.profile['DeviceName']} ({self.profile['DeviceIndex']})"
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# if physical device already has a stream, use it rather than making a new one
|
|
198
|
+
if self.profile['DeviceIndex'] in SpeakerDevice.streams:
|
|
199
|
+
self.stream = SpeakerDevice.streams['DeviceIndex']
|
|
200
|
+
else:
|
|
201
|
+
self.stream = None
|
|
202
|
+
# try to connect using profile at various sample rates
|
|
203
|
+
for sampleRateHz in (
|
|
204
|
+
# start with the rate from profile (this will usually work)
|
|
205
|
+
int(self.profile['DefaultSampleRate']),
|
|
206
|
+
# if that fails, try some common sample rates
|
|
207
|
+
48000,
|
|
208
|
+
44100,
|
|
209
|
+
22050,
|
|
210
|
+
16000
|
|
211
|
+
):
|
|
212
|
+
# stop trying new options once we have a stream
|
|
213
|
+
if self.stream is not None:
|
|
214
|
+
continue
|
|
215
|
+
# try this sample rate
|
|
216
|
+
try:
|
|
217
|
+
# redirect stderr to a buffer to avoid ptb error spam
|
|
218
|
+
outBuff = io.StringIO()
|
|
219
|
+
errBuff = io.StringIO()
|
|
220
|
+
with contextlib.redirect_stdout(outBuff):
|
|
221
|
+
with contextlib.redirect_stderr(errBuff):
|
|
222
|
+
self.stream = ptb.Stream(
|
|
223
|
+
mode=1+8,
|
|
224
|
+
device_id=self.profile['DeviceIndex'],
|
|
225
|
+
freq=sampleRateHz,
|
|
226
|
+
channels=self.profile['NrOutputChannels'],
|
|
227
|
+
latency_class=[self.latencyClass],
|
|
228
|
+
)
|
|
229
|
+
# if it worked, set own parameters
|
|
230
|
+
self.index = self.profile['DeviceIndex']
|
|
231
|
+
self.name = self.profile['DeviceName']
|
|
232
|
+
self.sampleRateHz = sampleRateHz
|
|
233
|
+
self.channels = self.profile['NrOutputChannels']
|
|
234
|
+
# ...and log/print the stderr from psychtoolbox (only if successful!)
|
|
235
|
+
logs = errBuff.getvalue() + outBuff.getvalue()
|
|
236
|
+
for line in logs.split("\n"):
|
|
237
|
+
if line.startswith("PTB-INFO: "):
|
|
238
|
+
logging.info(line[10:])
|
|
239
|
+
elif line.startswith("PTB-ERROR: "):
|
|
240
|
+
logging.error(line[11:])
|
|
241
|
+
elif line.strip():
|
|
242
|
+
print(line)
|
|
243
|
+
except:
|
|
244
|
+
pass
|
|
245
|
+
# if everything failed, raise an error
|
|
246
|
+
if self.stream is None:
|
|
247
|
+
raise ConnectionError(
|
|
248
|
+
"Failed to setup a PsychToolBox audio stream for device %(DeviceName)s "
|
|
249
|
+
"(%(DeviceIndex)s)." % self.profile
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
logging.info(
|
|
253
|
+
f"Created stream for speaker device: {self.profile['DeviceName']} "
|
|
254
|
+
f"({self.profile['DeviceIndex']})"
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
def open(self):
|
|
258
|
+
"""
|
|
259
|
+
Open the audio stream for this speaker so that sound can be played to it.
|
|
260
|
+
"""
|
|
261
|
+
if not self.isOpen:
|
|
262
|
+
self.stream.start(0, 0, 1)
|
|
263
|
+
|
|
264
|
+
def close(self):
|
|
265
|
+
"""
|
|
266
|
+
Close the audio stream for this speaker.
|
|
267
|
+
"""
|
|
268
|
+
if self.isOpen:
|
|
269
|
+
self.stream.close()
|
|
270
|
+
|
|
271
|
+
@property
|
|
272
|
+
def isOpen(self):
|
|
273
|
+
"""
|
|
274
|
+
Is this speaker "open", i.e. is it active and ready for a Sound to play tracks on it
|
|
275
|
+
"""
|
|
276
|
+
# sometimes a closed stream will have an integer for status
|
|
277
|
+
if not isinstance(self.stream.status, dict):
|
|
278
|
+
return False
|
|
279
|
+
|
|
280
|
+
return bool(self.stream.status['Active'])
|
|
281
|
+
|
|
35
282
|
def isSameDevice(self, other):
|
|
36
283
|
"""
|
|
37
284
|
Determine whether this object represents the same physical speaker as a given other object.
|
|
@@ -47,7 +294,7 @@ class SpeakerDevice(BaseDevice):
|
|
|
47
294
|
bool
|
|
48
295
|
True if the two objects represent the same physical device
|
|
49
296
|
"""
|
|
50
|
-
if isinstance(other,
|
|
297
|
+
if isinstance(other, type(self)):
|
|
51
298
|
# if given another object, get index
|
|
52
299
|
index = other.index
|
|
53
300
|
elif isinstance(other, dict) and "index" in other:
|
|
@@ -57,8 +304,8 @@ class SpeakerDevice(BaseDevice):
|
|
|
57
304
|
# if the other object is the wrong type or doesn't have an index, it's not this
|
|
58
305
|
return False
|
|
59
306
|
|
|
60
|
-
return self.index
|
|
61
|
-
|
|
307
|
+
return index in (self.index, self.name)
|
|
308
|
+
|
|
62
309
|
def testDevice(self):
|
|
63
310
|
"""
|
|
64
311
|
Play a simple sound to check whether this device is working.
|
|
@@ -67,22 +314,37 @@ class SpeakerDevice(BaseDevice):
|
|
|
67
314
|
import time
|
|
68
315
|
# create a basic sound
|
|
69
316
|
snd = Sound(
|
|
70
|
-
speaker=self
|
|
71
|
-
value="A"
|
|
317
|
+
speaker=self,
|
|
318
|
+
value="A",
|
|
319
|
+
stereo=self.channels > 1,
|
|
320
|
+
sampleRate=self.sampleRateHz
|
|
72
321
|
)
|
|
73
322
|
# play the sound for 1s
|
|
74
323
|
snd.play()
|
|
75
324
|
time.sleep(1)
|
|
76
325
|
snd.stop()
|
|
77
|
-
|
|
326
|
+
|
|
78
327
|
@staticmethod
|
|
79
328
|
def getAvailableDevices():
|
|
329
|
+
# skip in vm
|
|
330
|
+
if systemtools.isVM_CI(): # GitHub actions VM does not have a sound device
|
|
331
|
+
return []
|
|
332
|
+
# only show WASAPI drivers for Windows
|
|
333
|
+
if sys.platform == 'win32':
|
|
334
|
+
deviceType = 13
|
|
335
|
+
else:
|
|
336
|
+
deviceType = None
|
|
337
|
+
|
|
80
338
|
devices = []
|
|
81
|
-
|
|
82
|
-
|
|
339
|
+
for profile in ptb.get_devices(device_type=deviceType):
|
|
340
|
+
# skip input-only devices (microphones)
|
|
341
|
+
if profile['NrOutputChannels'] == 0:
|
|
342
|
+
continue
|
|
343
|
+
# construct profile
|
|
83
344
|
device = {
|
|
84
|
-
'deviceName': profile.get('DeviceName', "Unknown
|
|
345
|
+
'deviceName': profile.get('DeviceName', "Unknown Speaker"),
|
|
85
346
|
'index': profile.get('DeviceIndex', None),
|
|
347
|
+
'name': profile.get('DeviceName', None)
|
|
86
348
|
}
|
|
87
349
|
devices.append(device)
|
|
88
350
|
|
|
@@ -18,7 +18,7 @@ file.
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
# Part of the PsychoPy library
|
|
21
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
21
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
22
22
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
23
23
|
|
|
24
24
|
__all__ = [
|
|
@@ -10,7 +10,7 @@ trigger boxes from within PsychoPy.
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
# Part of the PsychoPy library
|
|
13
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
13
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
14
14
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
15
15
|
|
|
16
16
|
__all__ = ['BaseTriggerBox']
|
|
@@ -8,7 +8,7 @@ port.
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Part of the PsychoPy library
|
|
11
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
11
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
12
12
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
13
13
|
|
|
14
14
|
__all__ = [
|
psychopy/info.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Part of the PsychoPy library
|
|
5
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
5
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
6
6
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
7
7
|
|
|
8
8
|
"""This module has tools for fetching data about the system or the current
|
|
@@ -6,6 +6,7 @@ from .. import Device, ioDeviceError
|
|
|
6
6
|
from ...constants import DeviceConstants, EyeTrackerConstants
|
|
7
7
|
from . import hw
|
|
8
8
|
from ...errors import print2err
|
|
9
|
+
from psychopy.tools.stimulustools import serialize, actualize
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class EyeTrackerDevice(Device):
|
|
@@ -268,25 +269,16 @@ class EyeTrackerDevice(Device):
|
|
|
268
269
|
dict
|
|
269
270
|
Dict describing the given Calibration object
|
|
270
271
|
"""
|
|
272
|
+
targetAttributes = serialize(calib.target, includeClass=True)
|
|
273
|
+
# target animation
|
|
274
|
+
targetAttributes['animate'] = {
|
|
275
|
+
'enable': calib.movementAnimation,
|
|
276
|
+
'expansion_ratio': calib.expandScale,
|
|
277
|
+
'contract_only': calib.expandScale == 1,
|
|
278
|
+
}
|
|
279
|
+
|
|
271
280
|
return {
|
|
272
|
-
'target_attributes':
|
|
273
|
-
# target outer circle
|
|
274
|
-
'outer_diameter': calib.target.radius * 2,
|
|
275
|
-
'outer_stroke_width': calib.target.outer.lineWidth,
|
|
276
|
-
'outer_fill_color': getattr(calib.target.outer._fillColor, calib.colorSpace) if calib.target.outer._fillColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
277
|
-
'outer_line_color': getattr(calib.target.outer._borderColor, calib.colorSpace) if calib.target.outer._borderColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
278
|
-
# target inner circle
|
|
279
|
-
'inner_diameter': calib.target.innerRadius * 2,
|
|
280
|
-
'inner_stroke_width': calib.target.inner.lineWidth,
|
|
281
|
-
'inner_fill_color': getattr(calib.target.inner._borderColor, calib.colorSpace) if calib.target.inner._borderColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
282
|
-
'inner_line_color': getattr(calib.target.inner._borderColor, calib.colorSpace) if calib.target.inner._borderColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
283
|
-
# target animation
|
|
284
|
-
'animate':{
|
|
285
|
-
'enable': calib.movementAnimation,
|
|
286
|
-
'expansion_ratio': calib.expandScale,
|
|
287
|
-
'contract_only': calib.expandScale == 1,
|
|
288
|
-
},
|
|
289
|
-
},
|
|
281
|
+
'target_attributes': targetAttributes,
|
|
290
282
|
'type': calib.targetLayout,
|
|
291
283
|
'randomize': calib.randomisePos,
|
|
292
284
|
'auto_pace': calib.progressMode == "time",
|
|
@@ -12,6 +12,7 @@ from psychopy.iohub.constants import EventConstants as EC
|
|
|
12
12
|
from psychopy.iohub.devices.keyboard import KeyboardInputEvent
|
|
13
13
|
from psychopy.iohub.errors import print2err
|
|
14
14
|
from psychopy.constants import PLAYING
|
|
15
|
+
from psychopy.tools.stimulustools import serialize, actualize
|
|
15
16
|
|
|
16
17
|
currentTime = Computer.getTime
|
|
17
18
|
|
|
@@ -46,7 +47,11 @@ class BaseCalibrationProcedure:
|
|
|
46
47
|
self._lastCalibrationOK = False
|
|
47
48
|
self._device_config = self._eyetracker.getConfiguration()
|
|
48
49
|
display = self._eyetracker._display_device
|
|
49
|
-
|
|
50
|
+
# apply calibration args to defaults
|
|
51
|
+
self._device_config['calibration'].update(calibration_args)
|
|
52
|
+
# get target attributes (ignore default keys as args can vary)
|
|
53
|
+
self._device_config['calibration']['target_attributes'] = calibration_args['target_attributes']
|
|
54
|
+
# use modified default config for calibration args
|
|
50
55
|
self._calibration_args = self._device_config.get('calibration')
|
|
51
56
|
unit_type = self.getCalibSetting('unit_type')
|
|
52
57
|
if unit_type is None:
|
|
@@ -154,38 +159,15 @@ class BaseCalibrationProcedure:
|
|
|
154
159
|
color_type = self.getCalibSetting('color_type')
|
|
155
160
|
unit_type = self.getCalibSetting('unit_type')
|
|
156
161
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
self.targetStim = visual.TargetStim(
|
|
167
|
-
self.window, name="CP", style="circles",
|
|
168
|
-
radius=radius,
|
|
169
|
-
fillColor=self.getCalibSetting(['target_attributes', 'outer_fill_color']),
|
|
170
|
-
borderColor=self.getCalibSetting(['target_attributes', 'outer_line_color']),
|
|
171
|
-
lineWidth=self.getCalibSetting(['target_attributes', 'outer_stroke_width']),
|
|
172
|
-
innerRadius=innerRadius,
|
|
173
|
-
innerFillColor=self.getCalibSetting(['target_attributes', 'inner_fill_color']),
|
|
174
|
-
innerBorderColor=self.getCalibSetting(['target_attributes', 'inner_line_color']),
|
|
175
|
-
innerLineWidth=self.getCalibSetting(['target_attributes', 'inner_stroke_width']),
|
|
176
|
-
pos=(0, 0),
|
|
177
|
-
units=unit_type,
|
|
178
|
-
colorSpace=color_type,
|
|
179
|
-
autoLog=False
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
if self._calibration_args.get('target_type') == 'CIRCLE_TARGET':
|
|
183
|
-
setDefaultCalibrationTarget()
|
|
184
|
-
else:
|
|
185
|
-
self.targetStim = createCustomCalibrationStim(self.window, self._calibration_args)
|
|
186
|
-
if self.targetStim is None:
|
|
187
|
-
# Error creating custom stim, so use default target stim type
|
|
188
|
-
setDefaultCalibrationTarget()
|
|
162
|
+
# get attributes to create target
|
|
163
|
+
targetAttrs = self._calibration_args.get('target_attributes').copy()
|
|
164
|
+
# sanitize for creating
|
|
165
|
+
if "animate" in targetAttrs:
|
|
166
|
+
targetAttrs.pop("animate")
|
|
167
|
+
if "win" in targetAttrs:
|
|
168
|
+
targetAttrs['win'] = self.window
|
|
169
|
+
|
|
170
|
+
self.targetStim = actualize(targetAttrs)
|
|
189
171
|
|
|
190
172
|
self.originalTargetSize = self.targetStim.size
|
|
191
173
|
self.targetClassHasPlayPause = hasattr(self.targetStim, 'play') and hasattr(self.targetStim, 'pause')
|
|
@@ -14,6 +14,7 @@ try:
|
|
|
14
14
|
import psychopy_eyetracker_pupil_labs.pupil_labs.pupil_core as __plugin__
|
|
15
15
|
from psychopy_eyetracker_pupil_labs.pupil_labs.neon import (
|
|
16
16
|
__file__,
|
|
17
|
+
MonocularEyeSampleEvent,
|
|
17
18
|
BinocularEyeSampleEvent,
|
|
18
19
|
EyeTracker)
|
|
19
20
|
except (ModuleNotFoundError, ImportError, NameError):
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
from ctypes import cdll
|
|
7
7
|
|
|
8
8
|
from . import MouseDevice
|
|
9
|
-
from .. import
|
|
9
|
+
from .. import Computer, Device, xlib
|
|
10
|
+
from ..keyboard import Keyboard
|
|
10
11
|
from ...constants import MouseConstants
|
|
11
12
|
from ...errors import print2err, printExceptionDetailsToStdErr
|
|
12
13
|
|
psychopy/layout.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Part of the PsychoPy library
|
|
5
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
5
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
6
6
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
7
7
|
|
|
8
8
|
"""Classes and functions for working with coordinates systems."""
|