psychopy 2025.2.4__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.
- psychopy/CHANGELOG.txt +3981 -0
- psychopy/GIT_SHA +1 -0
- psychopy/LICENSE.txt +11 -0
- psychopy/LICENSES.txt +55 -0
- psychopy/VERSION +1 -0
- psychopy/__init__.py +148 -0
- psychopy/alerts/__init__.py +65 -0
- psychopy/alerts/_alerts.py +224 -0
- psychopy/alerts/_errorHandler.py +50 -0
- psychopy/alerts/alertsCatalogue/1000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/1100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/1500.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2110.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2115.yaml +21 -0
- psychopy/alerts/alertsCatalogue/2120.yaml +22 -0
- psychopy/alerts/alertsCatalogue/2150.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2155.yaml +21 -0
- psychopy/alerts/alertsCatalogue/2300.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2500.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3110.yaml +25 -0
- psychopy/alerts/alertsCatalogue/3115.yaml +24 -0
- psychopy/alerts/alertsCatalogue/3200.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
- psychopy/alerts/alertsCatalogue/3400.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3600.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/4051.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4052.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/4105.yaml +18 -0
- psychopy/alerts/alertsCatalogue/4115.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4120.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4125.yaml +23 -0
- psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4160.yaml +25 -0
- psychopy/alerts/alertsCatalogue/4200.yaml +0 -0
- psychopy/alerts/alertsCatalogue/4205.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4210.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4305.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4310.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4315.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4320.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4325.yaml +23 -0
- psychopy/alerts/alertsCatalogue/4330.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4335.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4340.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4405.yaml +24 -0
- psychopy/alerts/alertsCatalogue/4505.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4510.yaml +25 -0
- psychopy/alerts/alertsCatalogue/4520.yaml +26 -0
- psychopy/alerts/alertsCatalogue/4530.yaml +23 -0
- psychopy/alerts/alertsCatalogue/4540.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4545.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4550.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4605.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4610.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4615.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4705.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4710.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4810.yaml +19 -0
- psychopy/alerts/alertsCatalogue/5000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/5055.yaml +25 -0
- psychopy/alerts/alertsCatalogue/6000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/6105.yaml +18 -0
- psychopy/alerts/alertsCatalogue/7105.yaml +19 -0
- psychopy/alerts/alertsCatalogue/8105.yaml +21 -0
- psychopy/alerts/alertsCatalogue/8110.yaml +21 -0
- psychopy/alerts/alertsCatalogue/9998.yaml +19 -0
- psychopy/alerts/alertsCatalogue/9999.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +123 -0
- psychopy/alerts/alertsCatalogue/alertTemplate.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertmsg.py +173 -0
- psychopy/alerts/alertsCatalogue/generateAlertmsg.py +34 -0
- psychopy/alerts/alerttools.py +322 -0
- psychopy/app/Resources/README.md +12 -0
- psychopy/app/Resources/__init__.py +0 -0
- psychopy/app/Resources/betasplash.png +0 -0
- psychopy/app/Resources/betasplash@2x.png +0 -0
- psychopy/app/Resources/builder.ico +0 -0
- psychopy/app/Resources/classic/FlowBottom_CompLeft.png +0 -0
- psychopy/app/Resources/classic/FlowBottom_CompRight.png +0 -0
- psychopy/app/Resources/classic/FlowTop_CompLeft.png +0 -0
- psychopy/app/Resources/classic/FlowTop_CompRight.png +0 -0
- psychopy/app/Resources/classic/README.txt +9 -0
- psychopy/app/Resources/classic/__init__.py +0 -0
- psychopy/app/Resources/classic/_layouts.ai +1138 -1
- psychopy/app/Resources/classic/add.png +0 -0
- psychopy/app/Resources/classic/add@2x.png +0 -0
- psychopy/app/Resources/classic/addExp32.png +0 -0
- psychopy/app/Resources/classic/add_many.png +0 -0
- psychopy/app/Resources/classic/add_many@2x.png +0 -0
- psychopy/app/Resources/classic/alerts.png +0 -0
- psychopy/app/Resources/classic/beta.png +0 -0
- psychopy/app/Resources/classic/browser.png +0 -0
- psychopy/app/Resources/classic/browser@2x.png +0 -0
- psychopy/app/Resources/classic/bug16.png +0 -0
- psychopy/app/Resources/classic/case.png +0 -0
- psychopy/app/Resources/classic/case@2x.png +0 -0
- psychopy/app/Resources/classic/circle_mask.png +0 -0
- psychopy/app/Resources/classic/circle_mask@2x.png +0 -0
- psychopy/app/Resources/classic/clear.png +0 -0
- psychopy/app/Resources/classic/clear@2x.png +0 -0
- psychopy/app/Resources/classic/coderclass16.png +0 -0
- psychopy/app/Resources/classic/coderfunc16.png +0 -0
- psychopy/app/Resources/classic/coderimport16.png +0 -0
- psychopy/app/Resources/classic/coderjs16.png +0 -0
- psychopy/app/Resources/classic/coderpython16.png +0 -0
- psychopy/app/Resources/classic/codervar16.png +0 -0
- psychopy/app/Resources/classic/cogwindow32.png +0 -0
- psychopy/app/Resources/classic/color32.png +0 -0
- psychopy/app/Resources/classic/compile32.png +0 -0
- psychopy/app/Resources/classic/compile_js.png +0 -0
- psychopy/app/Resources/classic/compile_js@2x.png +0 -0
- psychopy/app/Resources/classic/compile_py.png +0 -0
- psychopy/app/Resources/classic/compile_py@2x.png +0 -0
- psychopy/app/Resources/classic/copy16.png +0 -0
- psychopy/app/Resources/classic/currentFile.png +0 -0
- psychopy/app/Resources/classic/currentFile@2x.png +0 -0
- psychopy/app/Resources/classic/delete16.png +0 -0
- psychopy/app/Resources/classic/desktop.png +0 -0
- psychopy/app/Resources/classic/desktop@2x.png +0 -0
- psychopy/app/Resources/classic/devices.png +0 -0
- psychopy/app/Resources/classic/devices@2x.png +0 -0
- psychopy/app/Resources/classic/dirup16.png +0 -0
- psychopy/app/Resources/classic/docclose16.png +0 -0
- psychopy/app/Resources/classic/download.png +0 -0
- psychopy/app/Resources/classic/edit.png +0 -0
- psychopy/app/Resources/classic/edit@2x.png +0 -0
- psychopy/app/Resources/classic/editbtn.png +0 -0
- psychopy/app/Resources/classic/editbtn16.png +0 -0
- psychopy/app/Resources/classic/editbtn16@2x.png +0 -0
- psychopy/app/Resources/classic/editbtn@2x.png +0 -0
- psychopy/app/Resources/classic/email.png +0 -0
- psychopy/app/Resources/classic/email@2x.png +0 -0
- psychopy/app/Resources/classic/experiment.png +0 -0
- psychopy/app/Resources/classic/experiment@2x.png +0 -0
- psychopy/app/Resources/classic/expsettings.png +0 -0
- psychopy/app/Resources/classic/expsettings@2x.png +0 -0
- psychopy/app/Resources/classic/file.png +0 -0
- psychopy/app/Resources/classic/file@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/filenew.png +0 -0
- psychopy/app/Resources/classic/filenew32.png +0 -0
- psychopy/app/Resources/classic/filenew@2x.png +0 -0
- psychopy/app/Resources/classic/fileopen.png +0 -0
- psychopy/app/Resources/classic/fileopen32.png +0 -0
- psychopy/app/Resources/classic/fileopen@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/filesave.png +0 -0
- psychopy/app/Resources/classic/filesave32.png +0 -0
- psychopy/app/Resources/classic/filesave@2x.png +0 -0
- psychopy/app/Resources/classic/filesaveas.png +0 -0
- psychopy/app/Resources/classic/filesaveas32.png +0 -0
- psychopy/app/Resources/classic/filesaveas@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/filter.png +0 -0
- psychopy/app/Resources/classic/filter@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/folder-open16.png +0 -0
- psychopy/app/Resources/classic/folder16.png +0 -0
- psychopy/app/Resources/classic/foldernew16.png +0 -0
- psychopy/app/Resources/classic/fork.png +0 -0
- psychopy/app/Resources/classic/fork@2x.png +0 -0
- psychopy/app/Resources/classic/github.png +0 -0
- psychopy/app/Resources/classic/github@2x.png +0 -0
- psychopy/app/Resources/classic/globe.png +0 -0
- psychopy/app/Resources/classic/globe@2x.png +0 -0
- psychopy/app/Resources/classic/globe_bug.png +0 -0
- psychopy/app/Resources/classic/globe_bug@2x.png +0 -0
- psychopy/app/Resources/classic/globe_greensync.png +0 -0
- psychopy/app/Resources/classic/globe_greensync@2x.png +0 -0
- psychopy/app/Resources/classic/globe_info.png +0 -0
- psychopy/app/Resources/classic/globe_info@2x.png +0 -0
- psychopy/app/Resources/classic/globe_magnifier.png +0 -0
- psychopy/app/Resources/classic/globe_magnifier@2x.png +0 -0
- psychopy/app/Resources/classic/globe_run.png +0 -0
- psychopy/app/Resources/classic/globe_run@2x.png +0 -0
- psychopy/app/Resources/classic/globe_user.png +0 -0
- psychopy/app/Resources/classic/globe_user@2x.png +0 -0
- psychopy/app/Resources/classic/goto16.png +0 -0
- psychopy/app/Resources/classic/greendot.png +0 -0
- psychopy/app/Resources/classic/greendot@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe.png +0 -0
- psychopy/app/Resources/classic/greenglobe@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_bug.png +0 -0
- psychopy/app/Resources/classic/greenglobe_bug@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_greensync.png +0 -0
- psychopy/app/Resources/classic/greenglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_info.png +0 -0
- psychopy/app/Resources/classic/greenglobe_info@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_magnifier.png +0 -0
- psychopy/app/Resources/classic/greenglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_run.png +0 -0
- psychopy/app/Resources/classic/greenglobe_run@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_user.png +0 -0
- psychopy/app/Resources/classic/greenglobe_user@2x.png +0 -0
- psychopy/app/Resources/classic/greydot.png +0 -0
- psychopy/app/Resources/classic/greydot@2x.png +0 -0
- psychopy/app/Resources/classic/greytick.png +0 -0
- psychopy/app/Resources/classic/greytick@2x.png +0 -0
- psychopy/app/Resources/classic/invalid_img.png +0 -0
- psychopy/app/Resources/classic/jsPilot.png +0 -0
- psychopy/app/Resources/classic/jsPilot@2x.png +0 -0
- psychopy/app/Resources/classic/jsRun.png +0 -0
- psychopy/app/Resources/classic/jsRun@2x.png +0 -0
- psychopy/app/Resources/classic/libroot.png +0 -0
- psychopy/app/Resources/classic/libroot@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/monitor16.png +0 -0
- psychopy/app/Resources/classic/monitors.png +0 -0
- psychopy/app/Resources/classic/monitors16.png +0 -0
- psychopy/app/Resources/classic/monitors32.png +0 -0
- psychopy/app/Resources/classic/monitors@2x.png +0 -0
- psychopy/app/Resources/classic/orangedot.png +0 -0
- psychopy/app/Resources/classic/orangedot@2x.png +0 -0
- psychopy/app/Resources/classic/pavlovia.png +0 -0
- psychopy/app/Resources/classic/pavlovia16.png +0 -0
- psychopy/app/Resources/classic/pavlovia16@2x.png +0 -0
- psychopy/app/Resources/classic/pavlovia@2x.png +0 -0
- psychopy/app/Resources/classic/pavsync.png +0 -0
- psychopy/app/Resources/classic/pavsync@2x.png +0 -0
- psychopy/app/Resources/classic/person_off.png +0 -0
- psychopy/app/Resources/classic/person_off@2x.png +0 -0
- psychopy/app/Resources/classic/person_on.png +0 -0
- psychopy/app/Resources/classic/person_on@2x.png +0 -0
- psychopy/app/Resources/classic/photometer.png +0 -0
- psychopy/app/Resources/classic/photometer@2x.png +0 -0
- psychopy/app/Resources/classic/plugin16.png +0 -0
- psychopy/app/Resources/classic/plugin16@2x.png +0 -0
- psychopy/app/Resources/classic/plugins32.png +0 -0
- psychopy/app/Resources/classic/plus.png +0 -0
- psychopy/app/Resources/classic/plus@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-app.png +0 -0
- psychopy/app/Resources/classic/preferences-app48.png +0 -0
- psychopy/app/Resources/classic/preferences-app@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-conn.png +0 -0
- psychopy/app/Resources/classic/preferences-conn48.png +0 -0
- psychopy/app/Resources/classic/preferences-conn@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-debug.png +0 -0
- psychopy/app/Resources/classic/preferences-debug@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-general.png +0 -0
- psychopy/app/Resources/classic/preferences-general48.png +0 -0
- psychopy/app/Resources/classic/preferences-general@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-hardware.png +0 -0
- psychopy/app/Resources/classic/preferences-hardware48.png +0 -0
- psychopy/app/Resources/classic/preferences-hardware@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-keyboard.png +0 -0
- psychopy/app/Resources/classic/preferences-keyboard48.png +0 -0
- psychopy/app/Resources/classic/preferences-keyboard@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-pilot.png +0 -0
- psychopy/app/Resources/classic/preferences-pilot@2x.png +0 -0
- psychopy/app/Resources/classic/preferences32.png +0 -0
- psychopy/app/Resources/classic/pyPilot.png +0 -0
- psychopy/app/Resources/classic/pyPilot@2x.png +0 -0
- psychopy/app/Resources/classic/pyRun.png +0 -0
- psychopy/app/Resources/classic/pyRun@2x.png +0 -0
- psychopy/app/Resources/classic/reddot.png +0 -0
- psychopy/app/Resources/classic/reddot@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe.png +0 -0
- psychopy/app/Resources/classic/redglobe@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_bug.png +0 -0
- psychopy/app/Resources/classic/redglobe_bug@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_greensync.png +0 -0
- psychopy/app/Resources/classic/redglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_info.png +0 -0
- psychopy/app/Resources/classic/redglobe_info@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_magnifier.png +0 -0
- psychopy/app/Resources/classic/redglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_run.png +0 -0
- psychopy/app/Resources/classic/redglobe_run@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_user.png +0 -0
- psychopy/app/Resources/classic/redglobe_user@2x.png +0 -0
- psychopy/app/Resources/classic/redo.png +0 -0
- psychopy/app/Resources/classic/redo32.png +0 -0
- psychopy/app/Resources/classic/redo@2x.png +0 -0
- psychopy/app/Resources/classic/regex.png +0 -0
- psychopy/app/Resources/classic/regex@2x.png +0 -0
- psychopy/app/Resources/classic/removeExp32.png +0 -0
- psychopy/app/Resources/classic/rename16.png +0 -0
- psychopy/app/Resources/classic/restart.png +0 -0
- psychopy/app/Resources/classic/restart@2x.png +0 -0
- psychopy/app/Resources/classic/run.png +0 -0
- psychopy/app/Resources/classic/run@2x.png +0 -0
- psychopy/app/Resources/classic/runner.png +0 -0
- psychopy/app/Resources/classic/runner@2x.png +0 -0
- psychopy/app/Resources/classic/runnerPilot.png +0 -0
- psychopy/app/Resources/classic/runnerPilot@2x.png +0 -0
- psychopy/app/Resources/classic/savebtn.png +0 -0
- psychopy/app/Resources/classic/savebtn16.png +0 -0
- psychopy/app/Resources/classic/savebtn16@2x.png +0 -0
- psychopy/app/Resources/classic/savebtn@2x.png +0 -0
- psychopy/app/Resources/classic/search.png +0 -0
- psychopy/app/Resources/classic/search@2x.png +0 -0
- psychopy/app/Resources/classic/showBuilder.png +0 -0
- psychopy/app/Resources/classic/showBuilder@2x.png +0 -0
- psychopy/app/Resources/classic/showCoder.png +0 -0
- psychopy/app/Resources/classic/showCoder@2x.png +0 -0
- psychopy/app/Resources/classic/showRunner.png +0 -0
- psychopy/app/Resources/classic/showRunner@2x.png +0 -0
- psychopy/app/Resources/classic/starred.png +0 -0
- psychopy/app/Resources/classic/starred@2x.png +0 -0
- psychopy/app/Resources/classic/start.png +0 -0
- psychopy/app/Resources/classic/start@2x.png +0 -0
- psychopy/app/Resources/classic/stdout.png +0 -0
- psychopy/app/Resources/classic/stop.png +0 -0
- psychopy/app/Resources/classic/stop32.png +0 -0
- psychopy/app/Resources/classic/stop@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlBot.png +0 -0
- psychopy/app/Resources/classic/switchCtrlBot@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlLeft.png +0 -0
- psychopy/app/Resources/classic/switchCtrlLeft@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlRight.png +0 -0
- psychopy/app/Resources/classic/switchCtrlRight@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlTop.png +0 -0
- psychopy/app/Resources/classic/switchCtrlTop@2x.png +0 -0
- psychopy/app/Resources/classic/tick.png +0 -0
- psychopy/app/Resources/classic/tick@2x.png +0 -0
- psychopy/app/Resources/classic/undo.png +0 -0
- psychopy/app/Resources/classic/undo32.png +0 -0
- psychopy/app/Resources/classic/undo@2x.png +0 -0
- psychopy/app/Resources/classic/unstarred.png +0 -0
- psychopy/app/Resources/classic/unstarred@2x.png +0 -0
- psychopy/app/Resources/classic/user_none.png +0 -0
- psychopy/app/Resources/classic/view-refresh16.png +0 -0
- psychopy/app/Resources/classic/viewbtn.png +0 -0
- psychopy/app/Resources/classic/viewbtn16.png +0 -0
- psychopy/app/Resources/classic/viewbtn16@2x.png +0 -0
- psychopy/app/Resources/classic/viewbtn@2x.png +0 -0
- psychopy/app/Resources/classic/windows16.png +0 -0
- psychopy/app/Resources/classic/windows16@2x.png +0 -0
- psychopy/app/Resources/coder.ico +0 -0
- psychopy/app/Resources/dark/FlowBottom_CompLeft.png +0 -0
- psychopy/app/Resources/dark/FlowBottom_CompRight.png +0 -0
- psychopy/app/Resources/dark/FlowTop_CompLeft.png +0 -0
- psychopy/app/Resources/dark/FlowTop_CompRight.png +0 -0
- psychopy/app/Resources/dark/README.txt +3 -0
- psychopy/app/Resources/dark/__init__.py +0 -0
- psychopy/app/Resources/dark/add.png +0 -0
- psychopy/app/Resources/dark/add@2x.png +0 -0
- psychopy/app/Resources/dark/addExp32.png +0 -0
- psychopy/app/Resources/dark/addExp32@2x.png +0 -0
- psychopy/app/Resources/dark/add_many.png +0 -0
- psychopy/app/Resources/dark/add_many@2x.png +0 -0
- psychopy/app/Resources/dark/alerts.png +0 -0
- psychopy/app/Resources/dark/alerts@2x.png +0 -0
- psychopy/app/Resources/dark/beta.png +0 -0
- psychopy/app/Resources/dark/beta@2x.png +0 -0
- psychopy/app/Resources/dark/browser.png +0 -0
- psychopy/app/Resources/dark/browser@2x.png +0 -0
- psychopy/app/Resources/dark/bug16.png +0 -0
- psychopy/app/Resources/dark/bug16@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/circle_mask.png +0 -0
- psychopy/app/Resources/dark/circle_mask@2x.png +0 -0
- psychopy/app/Resources/dark/clear.png +0 -0
- psychopy/app/Resources/dark/clear@2x.png +0 -0
- psychopy/app/Resources/dark/coderclass16.png +0 -0
- psychopy/app/Resources/dark/coderclass16@2x.png +0 -0
- psychopy/app/Resources/dark/coderfunc16.png +0 -0
- psychopy/app/Resources/dark/coderfunc16@2x.png +0 -0
- psychopy/app/Resources/dark/coderimport16.png +0 -0
- psychopy/app/Resources/dark/coderimport16@2x.png +0 -0
- psychopy/app/Resources/dark/coderjs.png +0 -0
- psychopy/app/Resources/dark/coderjs@2x.png +0 -0
- psychopy/app/Resources/dark/coderpython.png +0 -0
- psychopy/app/Resources/dark/coderpython@2x.png +0 -0
- psychopy/app/Resources/dark/codervar16.png +0 -0
- psychopy/app/Resources/dark/codervar16@2x.png +0 -0
- psychopy/app/Resources/dark/cogwindow32.png +0 -0
- psychopy/app/Resources/dark/cogwindow32@2x.png +0 -0
- psychopy/app/Resources/dark/color32.png +0 -0
- psychopy/app/Resources/dark/color32@2x.png +0 -0
- psychopy/app/Resources/dark/compile_js.png +0 -0
- psychopy/app/Resources/dark/compile_js@2x.png +0 -0
- psychopy/app/Resources/dark/compile_py.png +0 -0
- psychopy/app/Resources/dark/compile_py@2x.png +0 -0
- psychopy/app/Resources/dark/copy16.png +0 -0
- psychopy/app/Resources/dark/copy16@2x.png +0 -0
- psychopy/app/Resources/dark/currentFile16.png +0 -0
- psychopy/app/Resources/dark/currentFile16@2x.png +0 -0
- psychopy/app/Resources/dark/delete16.png +0 -0
- psychopy/app/Resources/dark/delete16@2x.png +0 -0
- psychopy/app/Resources/dark/desktop.png +0 -0
- psychopy/app/Resources/dark/desktop@2x.png +0 -0
- psychopy/app/Resources/dark/devices.png +0 -0
- psychopy/app/Resources/dark/devices@2x.png +0 -0
- psychopy/app/Resources/dark/dirup16.png +0 -0
- psychopy/app/Resources/dark/dirup16@2x.png +0 -0
- psychopy/app/Resources/dark/docclose16.png +0 -0
- psychopy/app/Resources/dark/docclose16@2x.png +0 -0
- psychopy/app/Resources/dark/download.png +0 -0
- psychopy/app/Resources/dark/download@2x.png +0 -0
- psychopy/app/Resources/dark/edit.png +0 -0
- psychopy/app/Resources/dark/edit@2x.png +0 -0
- psychopy/app/Resources/dark/editbtn16.png +0 -0
- psychopy/app/Resources/dark/editbtn16@2x.png +0 -0
- psychopy/app/Resources/dark/email.png +0 -0
- psychopy/app/Resources/dark/email@2x.png +0 -0
- psychopy/app/Resources/dark/experiment.png +0 -0
- psychopy/app/Resources/dark/experiment@2x.png +0 -0
- psychopy/app/Resources/dark/expsettings.png +0 -0
- psychopy/app/Resources/dark/expsettings@2x.png +0 -0
- psychopy/app/Resources/dark/file.png +0 -0
- psychopy/app/Resources/dark/file@16w.png +0 -0
- psychopy/app/Resources/dark/file@16w@2x.png +0 -0
- psychopy/app/Resources/dark/file@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/filenew.png +0 -0
- psychopy/app/Resources/dark/filenew32.png +0 -0
- psychopy/app/Resources/dark/filenew32@2x.png +0 -0
- psychopy/app/Resources/dark/filenew@2x.png +0 -0
- psychopy/app/Resources/dark/fileopen.png +0 -0
- psychopy/app/Resources/dark/fileopen32.png +0 -0
- psychopy/app/Resources/dark/fileopen32@2x.png +0 -0
- psychopy/app/Resources/dark/fileopen@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/filesave.png +0 -0
- psychopy/app/Resources/dark/filesave32.png +0 -0
- psychopy/app/Resources/dark/filesave32@2x.png +0 -0
- psychopy/app/Resources/dark/filesave@2x.png +0 -0
- psychopy/app/Resources/dark/filesaveas.png +0 -0
- psychopy/app/Resources/dark/filesaveas32.png +0 -0
- psychopy/app/Resources/dark/filesaveas32@2x.png +0 -0
- psychopy/app/Resources/dark/filesaveas@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/filter.png +0 -0
- psychopy/app/Resources/dark/filter@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/folder-open16.png +0 -0
- psychopy/app/Resources/dark/folder-open16@2x.png +0 -0
- psychopy/app/Resources/dark/folder16.png +0 -0
- psychopy/app/Resources/dark/folder16@2x.png +0 -0
- psychopy/app/Resources/dark/foldernew16.png +0 -0
- psychopy/app/Resources/dark/foldernew16@2x.png +0 -0
- psychopy/app/Resources/dark/fork.png +0 -0
- psychopy/app/Resources/dark/fork@2x.png +0 -0
- psychopy/app/Resources/dark/github.png +0 -0
- psychopy/app/Resources/dark/github@2x.png +0 -0
- psychopy/app/Resources/dark/globe.png +0 -0
- psychopy/app/Resources/dark/globe@2x.png +0 -0
- psychopy/app/Resources/dark/globe_bug.png +0 -0
- psychopy/app/Resources/dark/globe_bug@2x.png +0 -0
- psychopy/app/Resources/dark/globe_greensync.png +0 -0
- psychopy/app/Resources/dark/globe_greensync@2x.png +0 -0
- psychopy/app/Resources/dark/globe_info.png +0 -0
- psychopy/app/Resources/dark/globe_info@2x.png +0 -0
- psychopy/app/Resources/dark/globe_magnifier.png +0 -0
- psychopy/app/Resources/dark/globe_magnifier@2x.png +0 -0
- psychopy/app/Resources/dark/globe_run.png +0 -0
- psychopy/app/Resources/dark/globe_run@2x.png +0 -0
- psychopy/app/Resources/dark/globe_user.png +0 -0
- psychopy/app/Resources/dark/globe_user@2x.png +0 -0
- psychopy/app/Resources/dark/goto.png +0 -0
- psychopy/app/Resources/dark/goto@2x.png +0 -0
- psychopy/app/Resources/dark/greendot.png +0 -0
- psychopy/app/Resources/dark/greendot@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe.png +0 -0
- psychopy/app/Resources/dark/greenglobe@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_bug.png +0 -0
- psychopy/app/Resources/dark/greenglobe_bug@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_greensync.png +0 -0
- psychopy/app/Resources/dark/greenglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_info.png +0 -0
- psychopy/app/Resources/dark/greenglobe_info@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_magnifier.png +0 -0
- psychopy/app/Resources/dark/greenglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_run.png +0 -0
- psychopy/app/Resources/dark/greenglobe_run@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_user.png +0 -0
- psychopy/app/Resources/dark/greenglobe_user@2x.png +0 -0
- psychopy/app/Resources/dark/greydot.png +0 -0
- psychopy/app/Resources/dark/greydot@2x.png +0 -0
- psychopy/app/Resources/dark/greytick.png +0 -0
- psychopy/app/Resources/dark/greytick@2x.png +0 -0
- psychopy/app/Resources/dark/invalid_img.png +0 -0
- psychopy/app/Resources/dark/jsPilot.png +0 -0
- psychopy/app/Resources/dark/jsPilot@2x.png +0 -0
- psychopy/app/Resources/dark/jsRun.png +0 -0
- psychopy/app/Resources/dark/jsRun@2x.png +0 -0
- psychopy/app/Resources/dark/libroot16.png +0 -0
- psychopy/app/Resources/dark/libroot16@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/monitor16.png +0 -0
- psychopy/app/Resources/dark/monitor16@2x.png +0 -0
- psychopy/app/Resources/dark/monitors.png +0 -0
- psychopy/app/Resources/dark/monitors32.png +0 -0
- psychopy/app/Resources/dark/monitors32@2x.png +0 -0
- psychopy/app/Resources/dark/monitors@2x.png +0 -0
- psychopy/app/Resources/dark/orangedot.png +0 -0
- psychopy/app/Resources/dark/orangedot@2x.png +0 -0
- psychopy/app/Resources/dark/pavlovia.png +0 -0
- psychopy/app/Resources/dark/pavlovia16.png +0 -0
- psychopy/app/Resources/dark/pavlovia16@2x.png +0 -0
- psychopy/app/Resources/dark/pavlovia@2x.png +0 -0
- psychopy/app/Resources/dark/pavsync.png +0 -0
- psychopy/app/Resources/dark/pavsync@2x.png +0 -0
- psychopy/app/Resources/dark/person_off.png +0 -0
- psychopy/app/Resources/dark/person_off@2x.png +0 -0
- psychopy/app/Resources/dark/person_on.png +0 -0
- psychopy/app/Resources/dark/person_on@2x.png +0 -0
- psychopy/app/Resources/dark/photometer.png +0 -0
- psychopy/app/Resources/dark/photometer@2x.png +0 -0
- psychopy/app/Resources/dark/plugin16.png +0 -0
- psychopy/app/Resources/dark/plugin16@2x.png +0 -0
- psychopy/app/Resources/dark/plugins32.png +0 -0
- psychopy/app/Resources/dark/plugins32@2x.png +0 -0
- psychopy/app/Resources/dark/plus.png +0 -0
- psychopy/app/Resources/dark/plus@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-app.png +0 -0
- psychopy/app/Resources/dark/preferences-app48.png +0 -0
- psychopy/app/Resources/dark/preferences-app48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-app@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-conn.png +0 -0
- psychopy/app/Resources/dark/preferences-conn48.png +0 -0
- psychopy/app/Resources/dark/preferences-conn48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-conn@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-debug.png +0 -0
- psychopy/app/Resources/dark/preferences-debug@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-general.png +0 -0
- psychopy/app/Resources/dark/preferences-general48.png +0 -0
- psychopy/app/Resources/dark/preferences-general48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-general@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware48.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard48.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-pilot.png +0 -0
- psychopy/app/Resources/dark/preferences-pilot@2x.png +0 -0
- psychopy/app/Resources/dark/preferences32.png +0 -0
- psychopy/app/Resources/dark/preferences32@2x.png +0 -0
- psychopy/app/Resources/dark/pyPilot.png +0 -0
- psychopy/app/Resources/dark/pyPilot@2x.png +0 -0
- psychopy/app/Resources/dark/pyRun.png +0 -0
- psychopy/app/Resources/dark/pyRun@2x.png +0 -0
- psychopy/app/Resources/dark/reddot.png +0 -0
- psychopy/app/Resources/dark/reddot@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe.png +0 -0
- psychopy/app/Resources/dark/redglobe@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_bug.png +0 -0
- psychopy/app/Resources/dark/redglobe_bug@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_greensync.png +0 -0
- psychopy/app/Resources/dark/redglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_info.png +0 -0
- psychopy/app/Resources/dark/redglobe_info@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_magnifier.png +0 -0
- psychopy/app/Resources/dark/redglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_run.png +0 -0
- psychopy/app/Resources/dark/redglobe_run@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_user.png +0 -0
- psychopy/app/Resources/dark/redglobe_user@2x.png +0 -0
- psychopy/app/Resources/dark/redo.png +0 -0
- psychopy/app/Resources/dark/redo32.png +0 -0
- psychopy/app/Resources/dark/redo32@2x.png +0 -0
- psychopy/app/Resources/dark/redo@2x.png +0 -0
- psychopy/app/Resources/dark/regex.png +0 -0
- psychopy/app/Resources/dark/regex@2x.png +0 -0
- psychopy/app/Resources/dark/removeExp32.png +0 -0
- psychopy/app/Resources/dark/removeExp32@2x.png +0 -0
- psychopy/app/Resources/dark/rename16.png +0 -0
- psychopy/app/Resources/dark/rename16@2x.png +0 -0
- psychopy/app/Resources/dark/restart.png +0 -0
- psychopy/app/Resources/dark/restart@2x.png +0 -0
- psychopy/app/Resources/dark/runner.png +0 -0
- psychopy/app/Resources/dark/runner@2x.png +0 -0
- psychopy/app/Resources/dark/runnerPilot.png +0 -0
- psychopy/app/Resources/dark/runnerPilot@2x.png +0 -0
- psychopy/app/Resources/dark/savebtn16.png +0 -0
- psychopy/app/Resources/dark/savebtn16@2x.png +0 -0
- psychopy/app/Resources/dark/search.png +0 -0
- psychopy/app/Resources/dark/search@2x.png +0 -0
- psychopy/app/Resources/dark/showBuilder.png +0 -0
- psychopy/app/Resources/dark/showBuilder@2x.png +0 -0
- psychopy/app/Resources/dark/showCoder.png +0 -0
- psychopy/app/Resources/dark/showCoder@2x.png +0 -0
- psychopy/app/Resources/dark/showRunner.png +0 -0
- psychopy/app/Resources/dark/showRunner@2x.png +0 -0
- psychopy/app/Resources/dark/starred.png +0 -0
- psychopy/app/Resources/dark/starred@2x.png +0 -0
- psychopy/app/Resources/dark/start.png +0 -0
- psychopy/app/Resources/dark/start@2x.png +0 -0
- psychopy/app/Resources/dark/stdout.png +0 -0
- psychopy/app/Resources/dark/stdout@2x.png +0 -0
- psychopy/app/Resources/dark/stop.png +0 -0
- psychopy/app/Resources/dark/stop32.png +0 -0
- psychopy/app/Resources/dark/stop32@2x.png +0 -0
- psychopy/app/Resources/dark/stop@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlBot.png +0 -0
- psychopy/app/Resources/dark/switchCtrlBot@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlLeft.png +0 -0
- psychopy/app/Resources/dark/switchCtrlLeft@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlRight.png +0 -0
- psychopy/app/Resources/dark/switchCtrlRight@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlTop.png +0 -0
- psychopy/app/Resources/dark/switchCtrlTop@2x.png +0 -0
- psychopy/app/Resources/dark/tick.png +0 -0
- psychopy/app/Resources/dark/tick@2x.png +0 -0
- psychopy/app/Resources/dark/undo.png +0 -0
- psychopy/app/Resources/dark/undo32.png +0 -0
- psychopy/app/Resources/dark/undo32@2x.png +0 -0
- psychopy/app/Resources/dark/undo@2x.png +0 -0
- psychopy/app/Resources/dark/unstarred.png +0 -0
- psychopy/app/Resources/dark/unstarred@2x.png +0 -0
- psychopy/app/Resources/dark/user_none.png +0 -0
- psychopy/app/Resources/dark/view-refresh16.png +0 -0
- psychopy/app/Resources/dark/view-refresh16@2x.png +0 -0
- psychopy/app/Resources/dark/viewbtn16.png +0 -0
- psychopy/app/Resources/dark/viewbtn16@2x.png +0 -0
- psychopy/app/Resources/dark/windows16.png +0 -0
- psychopy/app/Resources/dark/windows16@2x.png +0 -0
- psychopy/app/Resources/light/FlowBottom_CompLeft.png +0 -0
- psychopy/app/Resources/light/FlowBottom_CompRight.png +0 -0
- psychopy/app/Resources/light/FlowTop_CompLeft.png +0 -0
- psychopy/app/Resources/light/FlowTop_CompRight.png +0 -0
- psychopy/app/Resources/light/README.txt +3 -0
- psychopy/app/Resources/light/__init__.py +0 -0
- psychopy/app/Resources/light/add.png +0 -0
- psychopy/app/Resources/light/add@2x.png +0 -0
- psychopy/app/Resources/light/addExp32.png +0 -0
- psychopy/app/Resources/light/addExp32@2x.png +0 -0
- psychopy/app/Resources/light/add_many.png +0 -0
- psychopy/app/Resources/light/add_many@2x.png +0 -0
- psychopy/app/Resources/light/alerts.png +0 -0
- psychopy/app/Resources/light/alerts@2x.png +0 -0
- psychopy/app/Resources/light/beta.png +0 -0
- psychopy/app/Resources/light/beta@2x.png +0 -0
- psychopy/app/Resources/light/browser.png +0 -0
- psychopy/app/Resources/light/browser@2x.png +0 -0
- psychopy/app/Resources/light/bug16.png +0 -0
- psychopy/app/Resources/light/bug16@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/circle_mask.png +0 -0
- psychopy/app/Resources/light/circle_mask@2x.png +0 -0
- psychopy/app/Resources/light/clear.png +0 -0
- psychopy/app/Resources/light/clear@2x.png +0 -0
- psychopy/app/Resources/light/coderclass16.png +0 -0
- psychopy/app/Resources/light/coderclass16@2x.png +0 -0
- psychopy/app/Resources/light/coderfunc16.png +0 -0
- psychopy/app/Resources/light/coderfunc16@2x.png +0 -0
- psychopy/app/Resources/light/coderimport16.png +0 -0
- psychopy/app/Resources/light/coderimport16@2x.png +0 -0
- psychopy/app/Resources/light/coderjs.png +0 -0
- psychopy/app/Resources/light/coderjs@2x.png +0 -0
- psychopy/app/Resources/light/coderpython.png +0 -0
- psychopy/app/Resources/light/coderpython@2x.png +0 -0
- psychopy/app/Resources/light/codervar16.png +0 -0
- psychopy/app/Resources/light/codervar16@2x.png +0 -0
- psychopy/app/Resources/light/cogwindow32.png +0 -0
- psychopy/app/Resources/light/cogwindow32@2x.png +0 -0
- psychopy/app/Resources/light/color16.png +0 -0
- psychopy/app/Resources/light/color16@2x.png +0 -0
- psychopy/app/Resources/light/color32.png +0 -0
- psychopy/app/Resources/light/color32@2x.png +0 -0
- psychopy/app/Resources/light/compile_js.png +0 -0
- psychopy/app/Resources/light/compile_js@2x.png +0 -0
- psychopy/app/Resources/light/compile_py.png +0 -0
- psychopy/app/Resources/light/compile_py@2x.png +0 -0
- psychopy/app/Resources/light/copy16.png +0 -0
- psychopy/app/Resources/light/copy16@2x.png +0 -0
- psychopy/app/Resources/light/currentFile16.png +0 -0
- psychopy/app/Resources/light/currentFile16@2x.png +0 -0
- psychopy/app/Resources/light/delete16.png +0 -0
- psychopy/app/Resources/light/delete16@2x.png +0 -0
- psychopy/app/Resources/light/delete8.png +0 -0
- psychopy/app/Resources/light/desktop.png +0 -0
- psychopy/app/Resources/light/desktop@2x.png +0 -0
- psychopy/app/Resources/light/devices.png +0 -0
- psychopy/app/Resources/light/devices@2x.png +0 -0
- psychopy/app/Resources/light/dirup16.png +0 -0
- psychopy/app/Resources/light/dirup16@2x.png +0 -0
- psychopy/app/Resources/light/docclose16.png +0 -0
- psychopy/app/Resources/light/docclose16@2x.png +0 -0
- psychopy/app/Resources/light/download.png +0 -0
- psychopy/app/Resources/light/download@2x.png +0 -0
- psychopy/app/Resources/light/edit.png +0 -0
- psychopy/app/Resources/light/edit@2x.png +0 -0
- psychopy/app/Resources/light/editbtn16.png +0 -0
- psychopy/app/Resources/light/editbtn16@2x.png +0 -0
- psychopy/app/Resources/light/email.png +0 -0
- psychopy/app/Resources/light/email@2x.png +0 -0
- psychopy/app/Resources/light/experiment.png +0 -0
- psychopy/app/Resources/light/experiment@2x.png +0 -0
- psychopy/app/Resources/light/expsettings.png +0 -0
- psychopy/app/Resources/light/expsettings@2x.png +0 -0
- psychopy/app/Resources/light/file.png +0 -0
- psychopy/app/Resources/light/file@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/filenew.png +0 -0
- psychopy/app/Resources/light/filenew32.png +0 -0
- psychopy/app/Resources/light/filenew32@2x.png +0 -0
- psychopy/app/Resources/light/filenew@2x.png +0 -0
- psychopy/app/Resources/light/fileopen.png +0 -0
- psychopy/app/Resources/light/fileopen32.png +0 -0
- psychopy/app/Resources/light/fileopen32@2x.png +0 -0
- psychopy/app/Resources/light/fileopen@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/filesave.png +0 -0
- psychopy/app/Resources/light/filesave32.png +0 -0
- psychopy/app/Resources/light/filesave32@2x.png +0 -0
- psychopy/app/Resources/light/filesave@2x.png +0 -0
- psychopy/app/Resources/light/filesaveas.png +0 -0
- psychopy/app/Resources/light/filesaveas32.png +0 -0
- psychopy/app/Resources/light/filesaveas32@2x.png +0 -0
- psychopy/app/Resources/light/filesaveas@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/filter.png +0 -0
- psychopy/app/Resources/light/filter@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/folder-open16.png +0 -0
- psychopy/app/Resources/light/folder-open16@2x.png +0 -0
- psychopy/app/Resources/light/folder16.png +0 -0
- psychopy/app/Resources/light/folder16@2x.png +0 -0
- psychopy/app/Resources/light/foldernew16.png +0 -0
- psychopy/app/Resources/light/foldernew16@2x.png +0 -0
- psychopy/app/Resources/light/fork.png +0 -0
- psychopy/app/Resources/light/fork@2x.png +0 -0
- psychopy/app/Resources/light/github.png +0 -0
- psychopy/app/Resources/light/github@2x.png +0 -0
- psychopy/app/Resources/light/globe.png +0 -0
- psychopy/app/Resources/light/globe@2x.png +0 -0
- psychopy/app/Resources/light/globe_bug.png +0 -0
- psychopy/app/Resources/light/globe_bug@2x.png +0 -0
- psychopy/app/Resources/light/globe_greensync.png +0 -0
- psychopy/app/Resources/light/globe_greensync@2x.png +0 -0
- psychopy/app/Resources/light/globe_info.png +0 -0
- psychopy/app/Resources/light/globe_info@2x.png +0 -0
- psychopy/app/Resources/light/globe_magnifier.png +0 -0
- psychopy/app/Resources/light/globe_magnifier@2x.png +0 -0
- psychopy/app/Resources/light/globe_run.png +0 -0
- psychopy/app/Resources/light/globe_run@2x.png +0 -0
- psychopy/app/Resources/light/globe_user.png +0 -0
- psychopy/app/Resources/light/globe_user@2x.png +0 -0
- psychopy/app/Resources/light/goto16.png +0 -0
- psychopy/app/Resources/light/goto16@2x.png +0 -0
- psychopy/app/Resources/light/greendot.png +0 -0
- psychopy/app/Resources/light/greendot@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe.png +0 -0
- psychopy/app/Resources/light/greenglobe@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_bug.png +0 -0
- psychopy/app/Resources/light/greenglobe_bug@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_greensync.png +0 -0
- psychopy/app/Resources/light/greenglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_info.png +0 -0
- psychopy/app/Resources/light/greenglobe_info@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_magnifier.png +0 -0
- psychopy/app/Resources/light/greenglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_run.png +0 -0
- psychopy/app/Resources/light/greenglobe_run@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_user.png +0 -0
- psychopy/app/Resources/light/greenglobe_user@2x.png +0 -0
- psychopy/app/Resources/light/greydot.png +0 -0
- psychopy/app/Resources/light/greydot@2x.png +0 -0
- psychopy/app/Resources/light/greytick.png +0 -0
- psychopy/app/Resources/light/greytick@2x.png +0 -0
- psychopy/app/Resources/light/invalid_img.png +0 -0
- psychopy/app/Resources/light/jsPilot.png +0 -0
- psychopy/app/Resources/light/jsPilot@2x.png +0 -0
- psychopy/app/Resources/light/jsRun.png +0 -0
- psychopy/app/Resources/light/jsRun@2x.png +0 -0
- psychopy/app/Resources/light/libroot16.png +0 -0
- psychopy/app/Resources/light/libroot16@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/monitor16.png +0 -0
- psychopy/app/Resources/light/monitor16@2x.png +0 -0
- psychopy/app/Resources/light/monitors.png +0 -0
- psychopy/app/Resources/light/monitors32.png +0 -0
- psychopy/app/Resources/light/monitors32@2x.png +0 -0
- psychopy/app/Resources/light/monitors@2x.png +0 -0
- psychopy/app/Resources/light/orangedot.png +0 -0
- psychopy/app/Resources/light/orangedot@2x.png +0 -0
- psychopy/app/Resources/light/pavlovia.png +0 -0
- psychopy/app/Resources/light/pavlovia16.png +0 -0
- psychopy/app/Resources/light/pavlovia16@2x.png +0 -0
- psychopy/app/Resources/light/pavlovia@2x.png +0 -0
- psychopy/app/Resources/light/pavsync.png +0 -0
- psychopy/app/Resources/light/pavsync@2x.png +0 -0
- psychopy/app/Resources/light/person_off.png +0 -0
- psychopy/app/Resources/light/person_off@2x.png +0 -0
- psychopy/app/Resources/light/person_on.png +0 -0
- psychopy/app/Resources/light/person_on@2x.png +0 -0
- psychopy/app/Resources/light/photometer.png +0 -0
- psychopy/app/Resources/light/photometer@2x.png +0 -0
- psychopy/app/Resources/light/plugin16.png +0 -0
- psychopy/app/Resources/light/plugin16@2x.png +0 -0
- psychopy/app/Resources/light/plugins32.png +0 -0
- psychopy/app/Resources/light/plugins32@2x.png +0 -0
- psychopy/app/Resources/light/plus.png +0 -0
- psychopy/app/Resources/light/plus@2x.png +0 -0
- psychopy/app/Resources/light/preferences-app.png +0 -0
- psychopy/app/Resources/light/preferences-app48.png +0 -0
- psychopy/app/Resources/light/preferences-app48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-app@2x.png +0 -0
- psychopy/app/Resources/light/preferences-conn.png +0 -0
- psychopy/app/Resources/light/preferences-conn48.png +0 -0
- psychopy/app/Resources/light/preferences-conn48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-conn@2x.png +0 -0
- psychopy/app/Resources/light/preferences-general.png +0 -0
- psychopy/app/Resources/light/preferences-general48.png +0 -0
- psychopy/app/Resources/light/preferences-general48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-general@2x.png +0 -0
- psychopy/app/Resources/light/preferences-hardware.png +0 -0
- psychopy/app/Resources/light/preferences-hardware48.png +0 -0
- psychopy/app/Resources/light/preferences-hardware48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-hardware@2x.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard48.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard@2x.png +0 -0
- psychopy/app/Resources/light/preferences-pilot.png +0 -0
- psychopy/app/Resources/light/preferences-pilot@2x.png +0 -0
- psychopy/app/Resources/light/preferences32.png +0 -0
- psychopy/app/Resources/light/preferences32@2x.png +0 -0
- psychopy/app/Resources/light/pyPilot.png +0 -0
- psychopy/app/Resources/light/pyPilot@2x.png +0 -0
- psychopy/app/Resources/light/pyRun.png +0 -0
- psychopy/app/Resources/light/pyRun@2x.png +0 -0
- psychopy/app/Resources/light/reddot.png +0 -0
- psychopy/app/Resources/light/reddot@2x.png +0 -0
- psychopy/app/Resources/light/redglobe.png +0 -0
- psychopy/app/Resources/light/redglobe@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_bug.png +0 -0
- psychopy/app/Resources/light/redglobe_bug@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_greensync.png +0 -0
- psychopy/app/Resources/light/redglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_info.png +0 -0
- psychopy/app/Resources/light/redglobe_info@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_magnifier.png +0 -0
- psychopy/app/Resources/light/redglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_run.png +0 -0
- psychopy/app/Resources/light/redglobe_run@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_user.png +0 -0
- psychopy/app/Resources/light/redglobe_user@2x.png +0 -0
- psychopy/app/Resources/light/redo.png +0 -0
- psychopy/app/Resources/light/redo32.png +0 -0
- psychopy/app/Resources/light/redo32@2x.png +0 -0
- psychopy/app/Resources/light/redo@2x.png +0 -0
- psychopy/app/Resources/light/regex.png +0 -0
- psychopy/app/Resources/light/regex@2x.png +0 -0
- psychopy/app/Resources/light/removeExp32.png +0 -0
- psychopy/app/Resources/light/removeExp32@2x.png +0 -0
- psychopy/app/Resources/light/rename16.png +0 -0
- psychopy/app/Resources/light/rename16@2x.png +0 -0
- psychopy/app/Resources/light/restart.png +0 -0
- psychopy/app/Resources/light/restart@2x.png +0 -0
- psychopy/app/Resources/light/runner.png +0 -0
- psychopy/app/Resources/light/runner@2x.png +0 -0
- psychopy/app/Resources/light/runnerPilot.png +0 -0
- psychopy/app/Resources/light/runnerPilot@2x.png +0 -0
- psychopy/app/Resources/light/savebtn16.png +0 -0
- psychopy/app/Resources/light/savebtn16@2x.png +0 -0
- psychopy/app/Resources/light/search.png +0 -0
- psychopy/app/Resources/light/search@2x.png +0 -0
- psychopy/app/Resources/light/showBuilder.png +0 -0
- psychopy/app/Resources/light/showBuilder@2x.png +0 -0
- psychopy/app/Resources/light/showCoder.png +0 -0
- psychopy/app/Resources/light/showCoder@2x.png +0 -0
- psychopy/app/Resources/light/showRunner.png +0 -0
- psychopy/app/Resources/light/showRunner@2x.png +0 -0
- psychopy/app/Resources/light/starred.png +0 -0
- psychopy/app/Resources/light/starred@2x.png +0 -0
- psychopy/app/Resources/light/start.png +0 -0
- psychopy/app/Resources/light/start@2x.png +0 -0
- psychopy/app/Resources/light/stdout.png +0 -0
- psychopy/app/Resources/light/stdout@2x.png +0 -0
- psychopy/app/Resources/light/stop.png +0 -0
- psychopy/app/Resources/light/stop32.png +0 -0
- psychopy/app/Resources/light/stop32@2x.png +0 -0
- psychopy/app/Resources/light/stop@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlBot.png +0 -0
- psychopy/app/Resources/light/switchCtrlBot@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlLeft.png +0 -0
- psychopy/app/Resources/light/switchCtrlLeft@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlRight.png +0 -0
- psychopy/app/Resources/light/switchCtrlRight@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlTop.png +0 -0
- psychopy/app/Resources/light/switchCtrlTop@2x.png +0 -0
- psychopy/app/Resources/light/tick.png +0 -0
- psychopy/app/Resources/light/tick@2x.png +0 -0
- psychopy/app/Resources/light/undo.png +0 -0
- psychopy/app/Resources/light/undo32.png +0 -0
- psychopy/app/Resources/light/undo32@2x.png +0 -0
- psychopy/app/Resources/light/undo@2x.png +0 -0
- psychopy/app/Resources/light/unstarred.png +0 -0
- psychopy/app/Resources/light/unstarred@2x.png +0 -0
- psychopy/app/Resources/light/user_none.png +0 -0
- psychopy/app/Resources/light/view-refresh16.png +0 -0
- psychopy/app/Resources/light/view-refresh16@2x.png +0 -0
- psychopy/app/Resources/light/viewbtn16.png +0 -0
- psychopy/app/Resources/light/viewbtn16@2x.png +0 -0
- psychopy/app/Resources/light/windows16.png +0 -0
- psychopy/app/Resources/light/windows16@2x.png +0 -0
- psychopy/app/Resources/moveComponentIcons.py +50 -0
- psychopy/app/Resources/psychopy.desktop +13 -0
- psychopy/app/Resources/psychopy.icns +0 -0
- psychopy/app/Resources/psychopy.ico +0 -0
- psychopy/app/Resources/psychopy.png +0 -0
- psychopy/app/Resources/psychopy.xml +9 -0
- psychopy/app/Resources/psychopy@2x.png +0 -0
- psychopy/app/Resources/routine_templates/Basic.psyexp +344 -0
- psychopy/app/Resources/routine_templates/Misc.psyexp +228 -0
- psychopy/app/Resources/routine_templates/Online.psyexp +200 -0
- psychopy/app/Resources/routine_templates/Trials.psyexp +735 -0
- psychopy/app/Resources/routine_templates/readme.md +14 -0
- psychopy/app/Resources/runner.ico +0 -0
- psychopy/app/Resources/splash.png +0 -0
- psychopy/app/Resources/splash@2x.png +0 -0
- psychopy/app/Resources/tips.txt +45 -0
- psychopy/app/Resources/tips_ar_001.txt +45 -0
- psychopy/app/Resources/tips_fr_FR.txt +45 -0
- psychopy/app/Resources/tips_ja_JP.txt +42 -0
- psychopy/app/Resources/tips_zh_CN.txt +45 -0
- psychopy/app/Resources/window.ico +0 -0
- psychopy/app/__init__.py +339 -0
- psychopy/app/__main__.py +3 -0
- psychopy/app/_psychopyApp.py +1298 -0
- psychopy/app/appData.spec +58 -0
- psychopy/app/builder/__init__.py +5 -0
- psychopy/app/builder/builder.py +4738 -0
- psychopy/app/builder/dialogs/__init__.py +1910 -0
- psychopy/app/builder/dialogs/dlgsCode.py +631 -0
- psychopy/app/builder/dialogs/dlgsConditions.py +669 -0
- psychopy/app/builder/dialogs/findDlg.py +275 -0
- psychopy/app/builder/dialogs/paramCtrls.py +1802 -0
- psychopy/app/builder/validators.py +589 -0
- psychopy/app/coder/__init__.py +8 -0
- psychopy/app/coder/codeEditorBase.py +460 -0
- psychopy/app/coder/coder.py +3100 -0
- psychopy/app/coder/fileBrowser.py +714 -0
- psychopy/app/coder/folding.py +128 -0
- psychopy/app/coder/psychoParser.py +139 -0
- psychopy/app/coder/repl.py +496 -0
- psychopy/app/coder/sourceTree.py +302 -0
- psychopy/app/colorpicker/__init__.py +594 -0
- psychopy/app/colorpicker/ui.py +336 -0
- psychopy/app/connections/__init__.py +10 -0
- psychopy/app/connections/news.py +104 -0
- psychopy/app/connections/sendusage.py +61 -0
- psychopy/app/connections/updates.py +642 -0
- psychopy/app/console.py +164 -0
- psychopy/app/deviceManager/__init__.py +1 -0
- psychopy/app/deviceManager/addDialog.py +218 -0
- psychopy/app/deviceManager/dialog.py +185 -0
- psychopy/app/deviceManager/panel.py +191 -0
- psychopy/app/deviceManager/utils.py +60 -0
- psychopy/app/dialogs.py +664 -0
- psychopy/app/errorDlg.py +238 -0
- psychopy/app/frametracker.py +8 -0
- psychopy/app/idle.py +181 -0
- psychopy/app/jobs.py +676 -0
- psychopy/app/linuxconfig/__init__.py +153 -0
- psychopy/app/linuxconfig/ui.py +88 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +12695 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +11221 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.po +10195 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +11917 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +11924 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +11917 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +11084 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +11590 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +11091 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +11072 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +11071 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +11072 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +11268 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +11463 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +11288 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +11441 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +11069 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +12085 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +11929 -0
- psychopy/app/localizedStrings.py +386 -0
- psychopy/app/pavlovia_ui/__init__.py +22 -0
- psychopy/app/pavlovia_ui/_base.py +268 -0
- psychopy/app/pavlovia_ui/functions.py +176 -0
- psychopy/app/pavlovia_ui/menu.py +140 -0
- psychopy/app/pavlovia_ui/project.py +943 -0
- psychopy/app/pavlovia_ui/search.py +444 -0
- psychopy/app/pavlovia_ui/sync.py +137 -0
- psychopy/app/pavlovia_ui/user.py +264 -0
- psychopy/app/plugin_manager/__init__.py +5 -0
- psychopy/app/plugin_manager/dialog.py +402 -0
- psychopy/app/plugin_manager/output.py +132 -0
- psychopy/app/plugin_manager/packageIndex.py +303 -0
- psychopy/app/plugin_manager/packages.py +643 -0
- psychopy/app/plugin_manager/plugins.py +1363 -0
- psychopy/app/plugin_manager/utils.py +115 -0
- psychopy/app/preferencesDlg.py +771 -0
- psychopy/app/psychopyApp.py +207 -0
- psychopy/app/ribbon.py +1019 -0
- psychopy/app/runner/__init__.py +1 -0
- psychopy/app/runner/runner.py +1299 -0
- psychopy/app/runner/scriptProcess.py +363 -0
- psychopy/app/stdout/__init__.py +1 -0
- psychopy/app/stdout/stdOutRich.py +410 -0
- psychopy/app/sysInfoDlg.py +242 -0
- psychopy/app/themes/__init__.py +78 -0
- psychopy/app/themes/colors.py +201 -0
- psychopy/app/themes/css/contrast_black.css +112 -0
- psychopy/app/themes/css/contrast_white.css +115 -0
- psychopy/app/themes/css/dark.css +112 -0
- psychopy/app/themes/css/light.css +115 -0
- psychopy/app/themes/fonts.py +629 -0
- psychopy/app/themes/handlers.py +321 -0
- psychopy/app/themes/icons.py +267 -0
- psychopy/app/themes/spec/Classic.json +154 -0
- psychopy/app/themes/spec/ClassicDark.json +154 -0
- psychopy/app/themes/spec/GitHub.json +154 -0
- psychopy/app/themes/spec/HiVisDark.json +153 -0
- psychopy/app/themes/spec/HiVisLight.json +154 -0
- psychopy/app/themes/spec/MinimalDark.json +154 -0
- psychopy/app/themes/spec/MinimalLight.json +153 -0
- psychopy/app/themes/spec/PsychopyDark.json +231 -0
- psychopy/app/themes/spec/PsychopyLight.json +236 -0
- psychopy/app/themes/ui.py +74 -0
- psychopy/app/ui/__init__.py +184 -0
- psychopy/app/urls.py +31 -0
- psychopy/app/utils.py +1741 -0
- psychopy/app/viewer/__init__.py +0 -0
- psychopy/assets/Psychopy Window Favicon@16w.png +0 -0
- psychopy/assets/Psychopy Window Favicon@32w.png +0 -0
- psychopy/assets/USB-C.png +0 -0
- psychopy/assets/USB.png +0 -0
- psychopy/assets/__init__.py +0 -0
- psychopy/assets/click.png +0 -0
- psychopy/assets/clicknext.png +0 -0
- psychopy/assets/creditCard.png +0 -0
- psychopy/assets/default.mp3 +0 -0
- psychopy/assets/default.mp4 +0 -0
- psychopy/assets/default.png +0 -0
- psychopy/assets/fonts/Arvo-Bold.ttf +0 -0
- psychopy/assets/fonts/Arvo-BoldItalic.ttf +0 -0
- psychopy/assets/fonts/Arvo-Italic.ttf +0 -0
- psychopy/assets/fonts/Arvo-Regular.ttf +0 -0
- psychopy/assets/fonts/DejaVuSerif.ttf +0 -0
- psychopy/assets/fonts/IndieFlower-Regular.ttf +0 -0
- psychopy/assets/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- psychopy/assets/fonts/JetBrainsMono-VariableFont_wght.ttf +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/next.png +0 -0
- psychopy/assets/psychopy.ico +0 -0
- psychopy/assets/psychopy.png +0 -0
- psychopy/assets/templates/__init__.py +0 -0
- psychopy/assets/templates/instruct1.png +0 -0
- psychopy/assets/templates/instruct2.png +0 -0
- psychopy/assets/touch.png +0 -0
- psychopy/assets/touchnext.png +0 -0
- psychopy/assets/voicekeyThresholdStim.wav +0 -0
- psychopy/assets/window.ico +0 -0
- psychopy/changes/2023.1.0.md +9 -0
- psychopy/changes/2024.1.0.md +16 -0
- psychopy/changes/__init__.py +0 -0
- psychopy/clock.py +619 -0
- psychopy/colors.py +1058 -0
- psychopy/compatibility.py +147 -0
- psychopy/constants.py +87 -0
- psychopy/contrib/__init__.py +0 -0
- psychopy/contrib/configobj/LICENSE +39 -0
- psychopy/contrib/configobj/__init__.py +2455 -0
- psychopy/contrib/configobj/_version.py +2 -0
- psychopy/contrib/configobj/validate.py +1458 -0
- psychopy/contrib/lazy_import.py +402 -0
- psychopy/contrib/mseq.py +273 -0
- psychopy/contrib/mseqSearch.py +183 -0
- psychopy/contrib/psi.py +100 -0
- psychopy/contrib/quest.py +484 -0
- psychopy/contrib/tesselate.py +188 -0
- psychopy/core.py +167 -0
- psychopy/data/__init__.py +45 -0
- psychopy/data/base.py +566 -0
- psychopy/data/counterbalance.py +210 -0
- psychopy/data/experiment.py +1049 -0
- psychopy/data/fit.py +248 -0
- psychopy/data/routine.py +94 -0
- psychopy/data/shelf.py +237 -0
- psychopy/data/staircase.py +2270 -0
- psychopy/data/trial.py +2505 -0
- psychopy/data/utils.py +858 -0
- psychopy/demos/__init__.py +0 -0
- psychopy/demos/builder/Design Templates/branchedExperiment/README.md +5 -0
- psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +354 -0
- psychopy/demos/builder/Design Templates/branchedExperiment/trialTypes.xlsx +0 -0
- psychopy/demos/builder/Design Templates/psychophysicsStaircase/README.md +20 -0
- psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +286 -0
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/README.md +14 -0
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +340 -0
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/stairDefinitions.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/README.md +18 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/chooseBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/facesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/housesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +219 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house03.jpg +0 -0
- psychopy/demos/builder/Experiments/BART/README.md +30 -0
- psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
- psychopy/demos/builder/Experiments/BART/assets/background.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/bang.mp3 +0 -0
- psychopy/demos/builder/Experiments/BART/assets/bang.wav +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 +844 -0
- psychopy/demos/builder/Experiments/BART/spreadsheets/conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +255 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/README.md +23 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/TIPI.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/bigFiveItems.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/demographics.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/mini_IPIP.xlsx +0 -0
- psychopy/demos/builder/Experiments/GoNoGo/conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +462 -0
- psychopy/demos/builder/Experiments/GoNoGo/go.png +0 -0
- psychopy/demos/builder/Experiments/GoNoGo/nogo.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/README.md +5 -0
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +494 -0
- 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/goNoGo/readme.md +14 -0
- psychopy/demos/builder/Experiments/mentalRotation/F.png +0 -0
- psychopy/demos/builder/Experiments/mentalRotation/FR.png +0 -0
- psychopy/demos/builder/Experiments/mentalRotation/MentalRot.csv +33 -0
- psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +646 -0
- psychopy/demos/builder/Experiments/mentalRotation/README.md +23 -0
- psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +509 -0
- psychopy/demos/builder/Experiments/navon/README.md +26 -0
- psychopy/demos/builder/Experiments/navon/bigHsmallH.png +0 -0
- psychopy/demos/builder/Experiments/navon/bigHsmallS.png +0 -0
- psychopy/demos/builder/Experiments/navon/bigSsmallH.png +0 -0
- psychopy/demos/builder/Experiments/navon/bigSsmallS.png +0 -0
- psychopy/demos/builder/Experiments/navon/mask.png +0 -0
- psychopy/demos/builder/Experiments/navon/stimuli.pptx +0 -0
- psychopy/demos/builder/Experiments/navon/trialTypes.xlsx +0 -0
- psychopy/demos/builder/Experiments/sternberg/README.md +14 -0
- psychopy/demos/builder/Experiments/sternberg/mainTrials.xlsx +0 -0
- psychopy/demos/builder/Experiments/sternberg/pracTrials.xlsx +0 -0
- psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +649 -0
- psychopy/demos/builder/Experiments/stroop/README.md +15 -0
- psychopy/demos/builder/Experiments/stroop/stroop.psyexp +321 -0
- psychopy/demos/builder/Experiments/stroop/trialTypes.csv +7 -0
- psychopy/demos/builder/Experiments/stroopExtended/README.md +14 -0
- psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +418 -0
- psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +418 -0
- psychopy/demos/builder/Experiments/stroopExtended/trialTypes.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopExtended/trialTypesReverse.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopVoice/README.md +27 -0
- psychopy/demos/builder/Experiments/stroopVoice/conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +382 -0
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +371 -0
- psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
- psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +308 -0
- psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +391 -0
- psychopy/demos/builder/Feature Demos/gratings/readme.md +8 -0
- psychopy/demos/builder/Feature Demos/movies/movie.psyexp +220 -0
- psychopy/demos/builder/Feature Demos/movies/readme.md +3 -0
- psychopy/demos/builder/Feature Demos/noise/face.jpg +0 -0
- psychopy/demos/builder/Feature Demos/noise/noise.psyexp +477 -0
- psychopy/demos/builder/Feature Demos/noise/readme.md +3 -0
- psychopy/demos/builder/Feature Demos/panorama/panImg.jpg +0 -0
- psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +177 -0
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +434 -0
- psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
- psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +451 -0
- psychopy/demos/builder/Feature Demos/progress/readme.md +1 -0
- psychopy/demos/builder/Feature Demos/sliders/README.md +8 -0
- psychopy/demos/builder/Feature Demos/sliders/fruitConditions.xlsx +0 -0
- psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +984 -0
- psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +199 -0
- psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +639 -0
- psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +415 -0
- psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +659 -0
- psychopy/demos/builder/Hardware/EGI_netstation/README.md +17 -0
- psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +339 -0
- psychopy/demos/builder/Hardware/EGI_netstation/trialTypesEEG.csv +7 -0
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/readme.md +19 -0
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/trials_params.xlsx +0 -0
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +830 -0
- psychopy/demos/builder/Hardware/camera/camera.psyexp +330 -0
- psychopy/demos/builder/Hardware/camera/readme.md +6 -0
- psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +459 -0
- psychopy/demos/builder/Hardware/eyetracking/readme.md +7 -0
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/Bullseye_grey.mov +0 -0
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +468 -0
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/readme.md +7 -0
- psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +211 -0
- psychopy/demos/builder/Hardware/fMRI/readme.md +7 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +360 -0
- 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 +360 -0
- 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 +484 -0
- psychopy/demos/builder/Hardware/microphone/phrases.xlsx +0 -0
- psychopy/demos/builder/Hardware/microphone/readme.md +9 -0
- psychopy/demos/builder/Hardware/pump/README.md +19 -0
- psychopy/demos/builder/Hardware/pump/pump.psyexp +646 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +350 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/readme.md +5 -0
- psychopy/demos/builder/Helper Tools/clockFace/README.md +3 -0
- psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +211 -0
- psychopy/demos/builder/Helper Tools/colors/README.md +5 -0
- psychopy/demos/builder/Helper Tools/colors/colors.psyexp +321 -0
- psychopy/demos/builder/Helper Tools/drawPolygon/README.md +5 -0
- psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +704 -0
- psychopy/demos/builder/Helper Tools/keyNameFinder/README.md +14 -0
- psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +225 -0
- psychopy/demos/builder/Helper Tools/spatialUnits/README.md +6 -0
- psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +206 -0
- psychopy/demos/builder/README.txt +43 -0
- psychopy/demos/builder/__init__.py +0 -0
- psychopy/demos/coder/__init__.py +0 -0
- psychopy/demos/coder/basic/hello_world.py +37 -0
- psychopy/demos/coder/csvFromPsydat.py +29 -0
- psychopy/demos/coder/experiment control/JND_staircase_analysis.py +85 -0
- psychopy/demos/coder/experiment control/JND_staircase_exp.py +110 -0
- psychopy/demos/coder/experiment control/TrialHandler.py +64 -0
- psychopy/demos/coder/experiment control/TrialHandler2.py +42 -0
- psychopy/demos/coder/experiment control/__init__.py +0 -0
- psychopy/demos/coder/experiment control/autoDraw_autoLog.py +50 -0
- psychopy/demos/coder/experiment control/experimentHandler.py +57 -0
- psychopy/demos/coder/experiment control/fMRI_launchScan.py +74 -0
- psychopy/demos/coder/experiment control/gammaMotionAnalysis.py +68 -0
- psychopy/demos/coder/experiment control/gammaMotionNull.py +169 -0
- psychopy/demos/coder/experiment control/logFiles.py +55 -0
- psychopy/demos/coder/experiment control/piloting.py +65 -0
- psychopy/demos/coder/experiment control/runtimeInfo.py +79 -0
- psychopy/demos/coder/hardware/CRS_BitsBox.py +75 -0
- psychopy/demos/coder/hardware/CRS_BitsPlusPlus.py +73 -0
- psychopy/demos/coder/hardware/RiftHeadTrackingExample.py +95 -0
- psychopy/demos/coder/hardware/RiftMinimal.py +44 -0
- psychopy/demos/coder/hardware/VSHD_Distortion.py +49 -0
- psychopy/demos/coder/hardware/__init__.py +0 -0
- psychopy/demos/coder/hardware/camera.py +90 -0
- psychopy/demos/coder/hardware/cedrusRB730.py +38 -0
- psychopy/demos/coder/hardware/crsBitsAdvancedDemo.py +780 -0
- psychopy/demos/coder/hardware/egi_netstation.py +45 -0
- psychopy/demos/coder/hardware/hdf5_extract.py +133 -0
- psychopy/demos/coder/hardware/ioLab_bbox.py +62 -0
- psychopy/demos/coder/hardware/labjack_u3.py +61 -0
- psychopy/demos/coder/hardware/monitorDemo.py +28 -0
- psychopy/demos/coder/hardware/parallelPortOutput.py +49 -0
- psychopy/demos/coder/hardware/qmixPump.py +79 -0
- psychopy/demos/coder/hardware/testSoundLatency.py +127 -0
- psychopy/demos/coder/input/GUI.py +52 -0
- psychopy/demos/coder/input/__init__.py +0 -0
- psychopy/demos/coder/input/customMouse.py +51 -0
- psychopy/demos/coder/input/joystick_universal.py +84 -0
- psychopy/demos/coder/input/keyNameFinder.py +39 -0
- psychopy/demos/coder/input/mic.png +0 -0
- psychopy/demos/coder/input/mouse.py +66 -0
- psychopy/demos/coder/iohub/delaytest.py +231 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/canal.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/fall.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/lake.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/party.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/swimming.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByConditionVariables.py +67 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByMessages.py +34 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/run.py +323 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/trial_conditions.xlsx +0 -0
- psychopy/demos/coder/iohub/eyetracking/simple.py +147 -0
- psychopy/demos/coder/iohub/eyetracking/validation.py +251 -0
- psychopy/demos/coder/iohub/iodatastore/saveEventReport.py +56 -0
- psychopy/demos/coder/iohub/keyboard.py +189 -0
- psychopy/demos/coder/iohub/keyboardreactiontime.py +88 -0
- psychopy/demos/coder/iohub/launchHub.py +160 -0
- psychopy/demos/coder/iohub/mouse.py +112 -0
- psychopy/demos/coder/iohub/mouse_multi_window.py +124 -0
- psychopy/demos/coder/iohub/serial/_parseserial.py +53 -0
- psychopy/demos/coder/iohub/serial/customparser.py +84 -0
- psychopy/demos/coder/iohub/serial/pstbox.py +166 -0
- psychopy/demos/coder/iohub/wintab/_wintabgraphics.py +281 -0
- psychopy/demos/coder/iohub/wintab/pen_demo.py +260 -0
- psychopy/demos/coder/misc/encrypt_data.py +48 -0
- psychopy/demos/coder/misc/hdf5_2_csv +33 -0
- psychopy/demos/coder/misc/makeMovie.py +28 -0
- psychopy/demos/coder/misc/rigidBodyTransform.py +76 -0
- psychopy/demos/coder/stimuli/Campaign.ttf +0 -0
- psychopy/demos/coder/stimuli/MovieStim.py +65 -0
- psychopy/demos/coder/stimuli/__init__.py +0 -0
- psychopy/demos/coder/stimuli/aperture.py +37 -0
- psychopy/demos/coder/stimuli/beach.jpg +0 -0
- psychopy/demos/coder/stimuli/bufferImageStim.py +78 -0
- psychopy/demos/coder/stimuli/clockface.py +43 -0
- psychopy/demos/coder/stimuli/colorPalette.py +134 -0
- psychopy/demos/coder/stimuli/compare_text_timing.py +193 -0
- psychopy/demos/coder/stimuli/counterphase.py +43 -0
- psychopy/demos/coder/stimuli/customTextures.py +57 -0
- psychopy/demos/coder/stimuli/dot_gabors.py +35 -0
- psychopy/demos/coder/stimuli/dots.py +35 -0
- psychopy/demos/coder/stimuli/elementArrays.py +92 -0
- psychopy/demos/coder/stimuli/embeddedOpenGL.py +35 -0
- psychopy/demos/coder/stimuli/face.jpg +0 -0
- psychopy/demos/coder/stimuli/face_jpg.py +48 -0
- psychopy/demos/coder/stimuli/gabor.py +30 -0
- psychopy/demos/coder/stimuli/imagesAndPatches.py +51 -0
- psychopy/demos/coder/stimuli/jwpIntro.mp4 +0 -0
- psychopy/demos/coder/stimuli/kanizsa.py +41 -0
- psychopy/demos/coder/stimuli/maskReveal.py +63 -0
- psychopy/demos/coder/stimuli/plaid.py +43 -0
- psychopy/demos/coder/stimuli/ratingScale.py +183 -0
- psychopy/demos/coder/stimuli/rotatingFlashingWedge.py +37 -0
- psychopy/demos/coder/stimuli/screensAndWindows.py +58 -0
- psychopy/demos/coder/stimuli/secondOrderGratings.py +66 -0
- psychopy/demos/coder/stimuli/shapeContains.py +50 -0
- psychopy/demos/coder/stimuli/shapes.py +63 -0
- psychopy/demos/coder/stimuli/soundStimuli.py +49 -0
- psychopy/demos/coder/stimuli/starField.py +48 -0
- psychopy/demos/coder/stimuli/stim3d.py +107 -0
- psychopy/demos/coder/stimuli/textBoxStim/textbox_glyph_placement.py +93 -0
- psychopy/demos/coder/stimuli/textBoxStim/textbox_simple.py +71 -0
- psychopy/demos/coder/stimuli/textStimuli.py +106 -0
- psychopy/demos/coder/stimuli/textbox_editable.py +64 -0
- psychopy/demos/coder/stimuli/variousVisualStims.py +47 -0
- psychopy/demos/coder/stimuli/visual_noise.py +31 -0
- psychopy/demos/coder/sysInfo.py +56 -0
- psychopy/demos/coder/timing/__init__.py +0 -0
- psychopy/demos/coder/timing/callOnFlip.py +39 -0
- psychopy/demos/coder/timing/clocksAndTimers.py +46 -0
- psychopy/demos/coder/timing/millikeyKeyboardTimingTest.py +323 -0
- psychopy/demos/coder/timing/timeByFrames.py +80 -0
- psychopy/demos/coder/timing/timeByFramesEx.py +107 -0
- psychopy/demos/coder/understanding psychopy/colors.py +70 -0
- psychopy/demos/coder/understanding psychopy/fontLayout.py +69 -0
- psychopy/demos/demo_migration.py +214 -0
- psychopy/demos/modernizeDemos.py +16 -0
- psychopy/demos/test_demo_migration.py +155 -0
- psychopy/devices/__init__.py +8 -0
- psychopy/event.py +1339 -0
- psychopy/exceptions.py +59 -0
- psychopy/experiment/__init__.py +51 -0
- psychopy/experiment/_experiment.py +1514 -0
- psychopy/experiment/blankTemplate.xltx +0 -0
- psychopy/experiment/components/__init__.py +402 -0
- psychopy/experiment/components/_base.py +1689 -0
- psychopy/experiment/components/aperture/__init__.py +153 -0
- psychopy/experiment/components/aperture/classic/aperture.png +0 -0
- psychopy/experiment/components/aperture/classic/aperture@2x.png +0 -0
- psychopy/experiment/components/aperture/dark/aperture.png +0 -0
- psychopy/experiment/components/aperture/dark/aperture@2x.png +0 -0
- psychopy/experiment/components/aperture/light/aperture.png +0 -0
- psychopy/experiment/components/aperture/light/aperture@2x.png +0 -0
- psychopy/experiment/components/brush/__init__.py +165 -0
- psychopy/experiment/components/brush/classic/brush.png +0 -0
- psychopy/experiment/components/brush/classic/brush@2x.png +0 -0
- psychopy/experiment/components/brush/dark/brush.png +0 -0
- psychopy/experiment/components/brush/dark/brush@2x.png +0 -0
- psychopy/experiment/components/brush/light/brush.png +0 -0
- psychopy/experiment/components/brush/light/brush@2x.png +0 -0
- psychopy/experiment/components/button/__init__.py +493 -0
- psychopy/experiment/components/button/classic/button.png +0 -0
- psychopy/experiment/components/button/classic/button@2x.png +0 -0
- psychopy/experiment/components/button/dark/button.png +0 -0
- psychopy/experiment/components/button/dark/button@2x.png +0 -0
- psychopy/experiment/components/button/light/button.png +0 -0
- psychopy/experiment/components/button/light/button@2x.png +0 -0
- psychopy/experiment/components/buttonBox/__init__.py +322 -0
- psychopy/experiment/components/buttonBox/classic/buttonBox.png +0 -0
- psychopy/experiment/components/buttonBox/classic/buttonBox@2x.png +0 -0
- psychopy/experiment/components/buttonBox/dark/buttonBox.png +0 -0
- psychopy/experiment/components/buttonBox/dark/buttonBox@2x.png +0 -0
- psychopy/experiment/components/buttonBox/light/buttonBox.png +0 -0
- psychopy/experiment/components/buttonBox/light/buttonBox@2x.png +0 -0
- psychopy/experiment/components/camera/__init__.py +381 -0
- psychopy/experiment/components/camera/classic/webcam.png +0 -0
- psychopy/experiment/components/camera/classic/webcam@2x.png +0 -0
- psychopy/experiment/components/camera/dark/webcam.png +0 -0
- psychopy/experiment/components/camera/dark/webcam@2x.png +0 -0
- psychopy/experiment/components/camera/light/webcam.png +0 -0
- psychopy/experiment/components/camera/light/webcam@2x.png +0 -0
- psychopy/experiment/components/code/__init__.py +299 -0
- psychopy/experiment/components/code/classic/code.png +0 -0
- psychopy/experiment/components/code/classic/code@2x.png +0 -0
- psychopy/experiment/components/code/dark/code.png +0 -0
- psychopy/experiment/components/code/dark/code@2x.png +0 -0
- psychopy/experiment/components/code/light/code.png +0 -0
- psychopy/experiment/components/code/light/code@2x.png +0 -0
- psychopy/experiment/components/dots/__init__.py +199 -0
- psychopy/experiment/components/dots/classic/dots.png +0 -0
- psychopy/experiment/components/dots/classic/dots@2x.png +0 -0
- psychopy/experiment/components/dots/dark/dots.png +0 -0
- psychopy/experiment/components/dots/dark/dots@2x.png +0 -0
- psychopy/experiment/components/dots/dots.xcf +0 -0
- psychopy/experiment/components/dots/light/dots.png +0 -0
- psychopy/experiment/components/dots/light/dots@2x.png +0 -0
- psychopy/experiment/components/eyetracker_record/__init__.py +194 -0
- psychopy/experiment/components/eyetracker_record/classic/eyetracker_record.png +0 -0
- psychopy/experiment/components/eyetracker_record/classic/eyetracker_record@2x.png +0 -0
- psychopy/experiment/components/eyetracker_record/dark/eyetracker_record.png +0 -0
- psychopy/experiment/components/eyetracker_record/dark/eyetracker_record@2x.png +0 -0
- psychopy/experiment/components/eyetracker_record/light/eyetracker_record.png +0 -0
- psychopy/experiment/components/eyetracker_record/light/eyetracker_record@2x.png +0 -0
- psychopy/experiment/components/form/__init__.py +227 -0
- psychopy/experiment/components/form/classic/form.png +0 -0
- psychopy/experiment/components/form/classic/form@2x.png +0 -0
- psychopy/experiment/components/form/dark/form.png +0 -0
- psychopy/experiment/components/form/dark/form@2x.png +0 -0
- psychopy/experiment/components/form/formItems.xltx +0 -0
- psychopy/experiment/components/form/light/form.png +0 -0
- psychopy/experiment/components/form/light/form@2x.png +0 -0
- psychopy/experiment/components/grating/__init__.py +203 -0
- psychopy/experiment/components/grating/classic/grating.png +0 -0
- psychopy/experiment/components/grating/classic/grating@2x.png +0 -0
- psychopy/experiment/components/grating/dark/grating.png +0 -0
- psychopy/experiment/components/grating/dark/grating@2x.png +0 -0
- psychopy/experiment/components/grating/light/grating.png +0 -0
- psychopy/experiment/components/grating/light/grating@2x.png +0 -0
- psychopy/experiment/components/image/__init__.py +195 -0
- psychopy/experiment/components/image/classic/image.png +0 -0
- psychopy/experiment/components/image/classic/image@2x.png +0 -0
- psychopy/experiment/components/image/dark/image.png +0 -0
- psychopy/experiment/components/image/dark/image@2x.png +0 -0
- psychopy/experiment/components/image/light/image.png +0 -0
- psychopy/experiment/components/image/light/image@2x.png +0 -0
- psychopy/experiment/components/joyButtons/__init__.py +453 -0
- psychopy/experiment/components/joyButtons/classic/joyButtons.png +0 -0
- psychopy/experiment/components/joyButtons/classic/joybuttons@2x.png +0 -0
- psychopy/experiment/components/joyButtons/dark/joyButtons.png +0 -0
- psychopy/experiment/components/joyButtons/dark/joyButtons@2x.png +0 -0
- psychopy/experiment/components/joyButtons/light/joyButtons.png +0 -0
- psychopy/experiment/components/joyButtons/light/joyButtons@2x.png +0 -0
- psychopy/experiment/components/joyButtons/virtualJoyButtons.py +34 -0
- psychopy/experiment/components/joystick/__init__.py +572 -0
- psychopy/experiment/components/joystick/classic/joystick.png +0 -0
- psychopy/experiment/components/joystick/classic/joystick@2x.png +0 -0
- psychopy/experiment/components/joystick/dark/joystick.png +0 -0
- psychopy/experiment/components/joystick/dark/joystick@2x.png +0 -0
- psychopy/experiment/components/joystick/light/joystick.png +0 -0
- psychopy/experiment/components/joystick/light/joystick@2x.png +0 -0
- psychopy/experiment/components/joystick/virtualJoystick.py +40 -0
- psychopy/experiment/components/keyboard/__init__.py +568 -0
- psychopy/experiment/components/keyboard/classic/keyboard.png +0 -0
- psychopy/experiment/components/keyboard/classic/keyboard@2x.png +0 -0
- psychopy/experiment/components/keyboard/dark/keyboard.png +0 -0
- psychopy/experiment/components/keyboard/dark/keyboard@2x.png +0 -0
- psychopy/experiment/components/keyboard/light/keyboard.png +0 -0
- psychopy/experiment/components/keyboard/light/keyboard@2x.png +0 -0
- psychopy/experiment/components/keyboard.xcf +0 -0
- psychopy/experiment/components/microphone/__init__.py +600 -0
- psychopy/experiment/components/microphone/classic/microphone.png +0 -0
- psychopy/experiment/components/microphone/classic/microphone@2x.png +0 -0
- psychopy/experiment/components/microphone/dark/microphone.png +0 -0
- psychopy/experiment/components/microphone/dark/microphone@2x.png +0 -0
- psychopy/experiment/components/microphone/light/microphone.png +0 -0
- psychopy/experiment/components/microphone/light/microphone@2x.png +0 -0
- psychopy/experiment/components/mouse/__init__.py +773 -0
- psychopy/experiment/components/mouse/classic/mouse.png +0 -0
- psychopy/experiment/components/mouse/classic/mouse@2x.png +0 -0
- psychopy/experiment/components/mouse/dark/mouse.png +0 -0
- psychopy/experiment/components/mouse/dark/mouse@2x.png +0 -0
- psychopy/experiment/components/mouse/light/mouse.png +0 -0
- psychopy/experiment/components/mouse/light/mouse@2x.png +0 -0
- psychopy/experiment/components/movie/__init__.py +348 -0
- psychopy/experiment/components/movie/classic/movie.png +0 -0
- psychopy/experiment/components/movie/classic/movie@2x.png +0 -0
- psychopy/experiment/components/movie/dark/movie.png +0 -0
- psychopy/experiment/components/movie/dark/movie@2x.png +0 -0
- psychopy/experiment/components/movie/light/movie.png +0 -0
- psychopy/experiment/components/movie/light/movie@2x.png +0 -0
- psychopy/experiment/components/panorama/__init__.py +456 -0
- psychopy/experiment/components/panorama/classic/panorama.png +0 -0
- psychopy/experiment/components/panorama/classic/panorama@2x.png +0 -0
- psychopy/experiment/components/panorama/dark/panorama.png +0 -0
- psychopy/experiment/components/panorama/dark/panorama@2x.png +0 -0
- psychopy/experiment/components/panorama/light/panorama.png +0 -0
- psychopy/experiment/components/panorama/light/panorama@2x.png +0 -0
- psychopy/experiment/components/parallelOut/__init__.py +178 -0
- psychopy/experiment/components/parallelOut/classic/parallel.png +0 -0
- psychopy/experiment/components/parallelOut/classic/parallel@2x.png +0 -0
- psychopy/experiment/components/parallelOut/dark/parallel.png +0 -0
- psychopy/experiment/components/parallelOut/dark/parallel@2x.png +0 -0
- psychopy/experiment/components/parallelOut/light/parallel.png +0 -0
- psychopy/experiment/components/parallelOut/light/parallel@2x.png +0 -0
- psychopy/experiment/components/polygon/__init__.py +332 -0
- psychopy/experiment/components/polygon/classic/polygon.png +0 -0
- psychopy/experiment/components/polygon/classic/polygon@2x.png +0 -0
- psychopy/experiment/components/polygon/dark/polygon.png +0 -0
- psychopy/experiment/components/polygon/dark/polygon@2x.png +0 -0
- psychopy/experiment/components/polygon/light/polygon.png +0 -0
- psychopy/experiment/components/polygon/light/polygon@2x.png +0 -0
- psychopy/experiment/components/progress/__init__.py +130 -0
- psychopy/experiment/components/progress/classic/progress.png +0 -0
- psychopy/experiment/components/progress/classic/progress@2x.png +0 -0
- psychopy/experiment/components/progress/dark/progress.png +0 -0
- psychopy/experiment/components/progress/dark/progress@2x.png +0 -0
- psychopy/experiment/components/progress/light/progress.png +0 -0
- psychopy/experiment/components/progress/light/progress@2x.png +0 -0
- psychopy/experiment/components/resourceManager/__init__.py +176 -0
- psychopy/experiment/components/resourceManager/classic/resource_manager.png +0 -0
- psychopy/experiment/components/resourceManager/classic/resource_manager@2x.png +0 -0
- psychopy/experiment/components/resourceManager/dark/resource_manager.png +0 -0
- psychopy/experiment/components/resourceManager/dark/resource_manager@2x.png +0 -0
- psychopy/experiment/components/resourceManager/light/resource_manager.png +0 -0
- psychopy/experiment/components/resourceManager/light/resource_manager@2x.png +0 -0
- psychopy/experiment/components/roi/__init__.py +316 -0
- psychopy/experiment/components/roi/classic/eyetracker_roi.png +0 -0
- psychopy/experiment/components/roi/classic/eyetracker_roi@2x.png +0 -0
- psychopy/experiment/components/roi/dark/eyetracker_roi.png +0 -0
- psychopy/experiment/components/roi/dark/eyetracker_roi@2X.png +0 -0
- psychopy/experiment/components/roi/light/eyetracker_roi.png +0 -0
- psychopy/experiment/components/roi/light/eyetracker_roi@2X.png +0 -0
- psychopy/experiment/components/routineSettings/__init__.py +387 -0
- psychopy/experiment/components/routineSettings/classic/routineSettings.png +0 -0
- psychopy/experiment/components/routineSettings/classic/routineSettings@2x.png +0 -0
- psychopy/experiment/components/routineSettings/dark/routineSettings.png +0 -0
- psychopy/experiment/components/routineSettings/dark/routineSettings@2x.png +0 -0
- psychopy/experiment/components/routineSettings/light/routineSettings.png +0 -0
- psychopy/experiment/components/routineSettings/light/routineSettings@2x.png +0 -0
- psychopy/experiment/components/serialOut/__init__.py +304 -0
- psychopy/experiment/components/serialOut/classic/serial.png +0 -0
- psychopy/experiment/components/serialOut/classic/serial@2x.png +0 -0
- psychopy/experiment/components/serialOut/dark/serial.png +0 -0
- psychopy/experiment/components/serialOut/dark/serial@2x.png +0 -0
- psychopy/experiment/components/serialOut/light/serial.png +0 -0
- psychopy/experiment/components/serialOut/light/serial@2x.png +0 -0
- psychopy/experiment/components/settings/JS_htmlHeader.tmpl +23 -0
- psychopy/experiment/components/settings/JS_setupExp.tmpl +28 -0
- psychopy/experiment/components/settings/__init__.py +2254 -0
- psychopy/experiment/components/settings/classic/settings.png +0 -0
- psychopy/experiment/components/settings/classic/settings@2x.png +0 -0
- psychopy/experiment/components/settings/dark/settings.png +0 -0
- psychopy/experiment/components/settings/dark/settings@2x.png +0 -0
- psychopy/experiment/components/settings/eyetracking.py +108 -0
- psychopy/experiment/components/settings/light/settings.png +0 -0
- psychopy/experiment/components/settings/light/settings@2x.png +0 -0
- psychopy/experiment/components/slider/__init__.py +410 -0
- psychopy/experiment/components/slider/classic/slider.png +0 -0
- psychopy/experiment/components/slider/classic/slider@2x.png +0 -0
- psychopy/experiment/components/slider/dark/slider.png +0 -0
- psychopy/experiment/components/slider/dark/slider@2x.png +0 -0
- psychopy/experiment/components/slider/light/slider.png +0 -0
- psychopy/experiment/components/slider/light/slider@2x.png +0 -0
- psychopy/experiment/components/sound/__init__.py +441 -0
- psychopy/experiment/components/sound/classic/sound.png +0 -0
- psychopy/experiment/components/sound/classic/sound@2x.png +0 -0
- psychopy/experiment/components/sound/dark/sound.png +0 -0
- psychopy/experiment/components/sound/dark/sound@2x.png +0 -0
- psychopy/experiment/components/sound/light/sound.png +0 -0
- psychopy/experiment/components/sound/light/sound@2x.png +0 -0
- psychopy/experiment/components/soundsensor/__init__.py +324 -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 +293 -0
- psychopy/experiment/components/static/classic/static.png +0 -0
- psychopy/experiment/components/static/classic/static@2x.png +0 -0
- psychopy/experiment/components/static/dark/static.png +0 -0
- psychopy/experiment/components/static/dark/static@2x.png +0 -0
- psychopy/experiment/components/static/light/static.png +0 -0
- psychopy/experiment/components/static/light/static@2x.png +0 -0
- psychopy/experiment/components/text/__init__.py +190 -0
- psychopy/experiment/components/text/classic/text.png +0 -0
- psychopy/experiment/components/text/classic/text@2x.png +0 -0
- psychopy/experiment/components/text/dark/text.png +0 -0
- psychopy/experiment/components/text/dark/text@2x.png +0 -0
- psychopy/experiment/components/text/light/text.png +0 -0
- psychopy/experiment/components/text/light/text@2x.png +0 -0
- psychopy/experiment/components/textbox/__init__.py +336 -0
- psychopy/experiment/components/textbox/classic/textbox.png +0 -0
- psychopy/experiment/components/textbox/classic/textbox@2x.png +0 -0
- psychopy/experiment/components/textbox/dark/textbox.png +0 -0
- psychopy/experiment/components/textbox/dark/textbox@2x.png +0 -0
- psychopy/experiment/components/textbox/light/textbox.png +0 -0
- psychopy/experiment/components/textbox/light/textbox@2x.png +0 -0
- psychopy/experiment/components/unknown/__init__.py +87 -0
- psychopy/experiment/components/unknown/classic/unknown.png +0 -0
- psychopy/experiment/components/unknown/classic/unknown@2x.png +0 -0
- psychopy/experiment/components/unknown/dark/unknown.png +0 -0
- psychopy/experiment/components/unknown/dark/unknown@2x.png +0 -0
- psychopy/experiment/components/unknown/light/unknown.png +0 -0
- psychopy/experiment/components/unknown/light/unknown@2x.png +0 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +86 -0
- psychopy/experiment/components/unknownPlugin/classic/unknownPlugin.png +0 -0
- psychopy/experiment/components/unknownPlugin/classic/unknownPlugin@2x.png +0 -0
- psychopy/experiment/components/unknownPlugin/dark/unknownPlugin.png +0 -0
- psychopy/experiment/components/unknownPlugin/dark/unknownPlugin@2x.png +0 -0
- psychopy/experiment/components/unknownPlugin/light/unknownPlugin.png +0 -0
- psychopy/experiment/components/unknownPlugin/light/unknownPlugin@2x.png +0 -0
- psychopy/experiment/components/utils.py +0 -0
- psychopy/experiment/components/variable/__init__.py +184 -0
- psychopy/experiment/components/variable/classic/variable.png +0 -0
- psychopy/experiment/components/variable/classic/variable@2x.png +0 -0
- psychopy/experiment/components/variable/dark/variable.png +0 -0
- psychopy/experiment/components/variable/dark/variable@2x.png +0 -0
- psychopy/experiment/components/variable/light/variable.png +0 -0
- psychopy/experiment/components/variable/light/variable@2x.png +0 -0
- psychopy/experiment/devices.py +303 -0
- psychopy/experiment/experiment.xsd +223 -0
- psychopy/experiment/exports.py +390 -0
- psychopy/experiment/flow.py +547 -0
- psychopy/experiment/localization.py +11 -0
- psychopy/experiment/loopTemplate.xltx +0 -0
- psychopy/experiment/loops.py +1051 -0
- psychopy/experiment/monitor.py +74 -0
- psychopy/experiment/params.py +541 -0
- psychopy/experiment/plugins.py +42 -0
- psychopy/experiment/py2js.py +183 -0
- psychopy/experiment/py2js_transpiler.py +613 -0
- psychopy/experiment/questPlusTemplate.xltx +0 -0
- psychopy/experiment/questTemplate.xltx +0 -0
- psychopy/experiment/routines/__init__.py +108 -0
- psychopy/experiment/routines/_base.py +1172 -0
- psychopy/experiment/routines/audioValidator/__init__.py +229 -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/counterbalance/__init__.py +320 -0
- psychopy/experiment/routines/counterbalance/classic/counterbalance.png +0 -0
- psychopy/experiment/routines/counterbalance/classic/counterbalance@2x.png +0 -0
- psychopy/experiment/routines/counterbalance/counterbalanceItems.xltx +0 -0
- psychopy/experiment/routines/counterbalance/dark/counterbalance.png +0 -0
- psychopy/experiment/routines/counterbalance/dark/counterbalance@2x.png +0 -0
- psychopy/experiment/routines/counterbalance/light/counterbalance.png +0 -0
- psychopy/experiment/routines/counterbalance/light/counterbalance@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/__init__.py +334 -0
- psychopy/experiment/routines/eyetracker_calibrate/classic/eyetracker_calib.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/__init__.py +354 -0
- psychopy/experiment/routines/eyetracker_validate/classic/eyetracker_valid.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid@2x.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/__init__.py +236 -0
- psychopy/experiment/routines/pavlovia_survey/classic/survey.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/classic/survey@2x.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/dark/survey.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/dark/survey@2x.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/light/survey.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/light/survey@2x.png +0 -0
- psychopy/experiment/routines/unknown/__init__.py +30 -0
- psychopy/experiment/routines/unknown/classic/eyetracker_record.png +0 -0
- psychopy/experiment/routines/unknown/classic/unknown.png +0 -0
- psychopy/experiment/routines/unknown/dark/eyetracker_record.png +0 -0
- psychopy/experiment/routines/unknown/dark/eyetracker_record@2x.png +0 -0
- psychopy/experiment/routines/unknown/dark/unknown.png +0 -0
- psychopy/experiment/routines/unknown/dark/unknown@2x.png +0 -0
- psychopy/experiment/routines/unknown/light/eyetracker_record.png +0 -0
- psychopy/experiment/routines/unknown/light/eyetracker_record@2x.png +0 -0
- psychopy/experiment/routines/unknown/light/unknown.png +0 -0
- psychopy/experiment/routines/unknown/light/unknown@2x.png +0 -0
- psychopy/experiment/routines/utils.py +0 -0
- psychopy/experiment/routines/visualValidator/__init__.py +395 -0
- 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/staircaseTemplate.xltx +0 -0
- psychopy/experiment/utils.py +44 -0
- psychopy/filters.py +11 -0
- psychopy/gamma.py +9 -0
- psychopy/gui/__init__.py +47 -0
- psychopy/gui/qtgui.py +882 -0
- psychopy/gui/util.py +74 -0
- psychopy/gui/wxgui.py +420 -0
- psychopy/hardware/__init__.py +178 -0
- psychopy/hardware/base.py +466 -0
- psychopy/hardware/bbtk/__init__.py +24 -0
- psychopy/hardware/brainproducts.py +25 -0
- psychopy/hardware/button.py +238 -0
- psychopy/hardware/buttonbox/__init__.py +122 -0
- psychopy/hardware/camera/__init__.py +3657 -0
- psychopy/hardware/cedrus.py +24 -0
- psychopy/hardware/crs/__init__.py +46 -0
- psychopy/hardware/crs/bits.py +37 -0
- psychopy/hardware/crs/colorcal.py +18 -0
- psychopy/hardware/crs/optical.py +33 -0
- psychopy/hardware/crs/shaders.py +34 -0
- psychopy/hardware/emotiv.py +33 -0
- psychopy/hardware/emulator.py +46 -0
- psychopy/hardware/exceptions.py +86 -0
- psychopy/hardware/eyetracker.py +132 -0
- psychopy/hardware/forp.py +37 -0
- psychopy/hardware/gammasci.py +26 -0
- psychopy/hardware/iolab.py +24 -0
- psychopy/hardware/joystick/__init__.py +1196 -0
- 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 +975 -0
- psychopy/hardware/knownDevices.json +52 -0
- psychopy/hardware/labhackers.py +27 -0
- psychopy/hardware/labjacks.py +26 -0
- psychopy/hardware/lightsensor.py +789 -0
- psychopy/hardware/listener.py +330 -0
- psychopy/hardware/manager.py +992 -0
- psychopy/hardware/microphone.py +1630 -0
- psychopy/hardware/minolta.py +33 -0
- psychopy/hardware/monitor.py +144 -0
- psychopy/hardware/mouse/__init__.py +885 -0
- psychopy/hardware/photometer/__init__.py +207 -0
- psychopy/hardware/pr.py +33 -0
- psychopy/hardware/qmix.py +32 -0
- psychopy/hardware/serialdevice.py +387 -0
- psychopy/hardware/soundsensor.py +476 -0
- psychopy/hardware/spatial/__init__.py +231 -0
- psychopy/hardware/speaker.py +351 -0
- psychopy/hardware/triggerbox/__init__.py +56 -0
- psychopy/hardware/triggerbox/base.py +170 -0
- psychopy/hardware/triggerbox/parallel.py +362 -0
- psychopy/info.py +719 -0
- psychopy/iohub/__init__.py +50 -0
- psychopy/iohub/client/__init__.py +1481 -0
- psychopy/iohub/client/connect.py +260 -0
- psychopy/iohub/client/eyetracker/__init__.py +4 -0
- psychopy/iohub/client/eyetracker/validation/__init__.py +8 -0
- psychopy/iohub/client/eyetracker/validation/posgrid.py +274 -0
- psychopy/iohub/client/eyetracker/validation/procedure.py +1292 -0
- psychopy/iohub/client/eyetracker/validation/trigger.py +240 -0
- psychopy/iohub/client/keyboard.py +513 -0
- psychopy/iohub/client/wintab.py +378 -0
- psychopy/iohub/constants.py +1176 -0
- psychopy/iohub/datastore/__init__.py +439 -0
- psychopy/iohub/datastore/default_datastore.yaml +8 -0
- psychopy/iohub/datastore/util.py +868 -0
- psychopy/iohub/default_config.yaml +17 -0
- psychopy/iohub/devices/__init__.py +1047 -0
- psychopy/iohub/devices/computer.py +607 -0
- psychopy/iohub/devices/default_device.yaml +15 -0
- psychopy/iohub/devices/deviceConfigValidation.py +519 -0
- psychopy/iohub/devices/display/__init__.py +755 -0
- psychopy/iohub/devices/display/default_display.yaml +118 -0
- psychopy/iohub/devices/display/supported_config_settings.yaml +69 -0
- psychopy/iohub/devices/eventfilters.py +3572 -0
- psychopy/iohub/devices/experiment/__init__.py +316 -0
- psychopy/iohub/devices/experiment/default_experiment.yaml +74 -0
- psychopy/iohub/devices/experiment/supported_config_settings.yaml +26 -0
- psychopy/iohub/devices/eyetracker/__init__.py +474 -0
- psychopy/iohub/devices/eyetracker/calibration/__init__.py +1 -0
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +391 -0
- psychopy/iohub/devices/eyetracker/default_eyetracker.yaml +18 -0
- psychopy/iohub/devices/eyetracker/eye_events.py +1751 -0
- psychopy/iohub/devices/eyetracker/filters/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/filters/parser.py +913 -0
- psychopy/iohub/devices/eyetracker/hw/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/calibration.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +31 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/__init__.py +8 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/calibration.py +10 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/default_eyetracker.yaml +102 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +443 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/supported_config_settings.yaml +110 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +27 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/eyetracker.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/bisector.py +20 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/constants.py +19 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/data_parse.py +22 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/eyetracker.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/pupil_remote.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/__init__.py +28 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/calibration.py +22 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/eyetracker.py +38 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/calibration.py +19 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/eyetracker.py +17 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/tobiiwrapper.py +19 -0
- psychopy/iohub/devices/eyetracker/supported_config_settings.yaml +44 -0
- psychopy/iohub/devices/keyboard/__init__.py +309 -0
- psychopy/iohub/devices/keyboard/darwin.py +431 -0
- psychopy/iohub/devices/keyboard/darwinkey.py +94 -0
- psychopy/iohub/devices/keyboard/default_keyboard.yaml +94 -0
- psychopy/iohub/devices/keyboard/linux2.py +102 -0
- psychopy/iohub/devices/keyboard/supported_config_settings.yaml +39 -0
- psychopy/iohub/devices/keyboard/win32.py +356 -0
- psychopy/iohub/devices/mouse/__init__.py +709 -0
- psychopy/iohub/devices/mouse/darwin.py +414 -0
- psychopy/iohub/devices/mouse/default_mouse.yaml +92 -0
- psychopy/iohub/devices/mouse/linux2.py +172 -0
- psychopy/iohub/devices/mouse/supported_config_settings.yaml +39 -0
- psychopy/iohub/devices/mouse/win32.py +284 -0
- psychopy/iohub/devices/pyXHook.py +619 -0
- psychopy/iohub/devices/serial/__init__.py +779 -0
- psychopy/iohub/devices/serial/default_pstbox.yaml +108 -0
- psychopy/iohub/devices/serial/default_serial.yaml +108 -0
- psychopy/iohub/devices/serial/supported_config_settings.yaml +85 -0
- psychopy/iohub/devices/serial/supported_config_settings_pstbox.yaml +85 -0
- psychopy/iohub/devices/supported_config_settings.yaml +36 -0
- psychopy/iohub/devices/wintab/__init__.py +580 -0
- psychopy/iohub/devices/wintab/default_wintab.yaml +89 -0
- psychopy/iohub/devices/wintab/supported_config_settings.yaml +42 -0
- psychopy/iohub/devices/wintab/win32.py +722 -0
- psychopy/iohub/devices/xlib.py +6795 -0
- psychopy/iohub/errors.py +61 -0
- psychopy/iohub/lazy_import.py +582 -0
- psychopy/iohub/net.py +349 -0
- psychopy/iohub/server.py +1075 -0
- psychopy/iohub/start_iohub_process.py +121 -0
- psychopy/iohub/util/__init__.py +832 -0
- psychopy/iohub/util/visualangle.py +126 -0
- psychopy/layout.py +916 -0
- psychopy/liaison.py +471 -0
- psychopy/locale_setup.py +41 -0
- psychopy/localization/__init__.py +22 -0
- psychopy/localization/_localization.py +155 -0
- psychopy/localization/generateTranslationTemplate.py +257 -0
- psychopy/localization/mappings.txt +170 -0
- psychopy/localization/messages.pot +9950 -0
- psychopy/localization/readme.txt +68 -0
- psychopy/logging.py +415 -0
- psychopy/microphone.py +28 -0
- psychopy/misc.py +40 -0
- psychopy/monitors/MonitorCenter.py +1354 -0
- psychopy/monitors/__init__.py +30 -0
- psychopy/monitors/calibData.py +78 -0
- psychopy/monitors/calibTools.py +1301 -0
- psychopy/monitors/getLumSeries.py +50 -0
- psychopy/monitors/psychopy-icon.svg +395 -0
- psychopy/monitors/psychopy.ico +0 -0
- psychopy/parallel/__init__.py +206 -0
- psychopy/parallel/_dlportio.py +150 -0
- psychopy/parallel/_inpout.py +120 -0
- psychopy/parallel/_linux.py +105 -0
- psychopy/piloting.py +61 -0
- psychopy/platform_specific/__init__.py +46 -0
- psychopy/platform_specific/darwin.py +326 -0
- psychopy/platform_specific/linux.py +77 -0
- psychopy/platform_specific/win32.py +124 -0
- psychopy/plugins/__init__.py +1397 -0
- psychopy/plugins/util.py +104 -0
- psychopy/preferences/Darwin.spec +294 -0
- psychopy/preferences/FreeBSD.spec +294 -0
- psychopy/preferences/Linux.spec +294 -0
- psychopy/preferences/Windows.spec +294 -0
- psychopy/preferences/__init__.py +20 -0
- psychopy/preferences/baseNoArch.spec +290 -0
- psychopy/preferences/devices.py +80 -0
- psychopy/preferences/generateHints.py +93 -0
- psychopy/preferences/generateSpec.py +80 -0
- psychopy/preferences/hints.py +367 -0
- psychopy/preferences/preferences.py +448 -0
- psychopy/projects/__init__.py +11 -0
- psychopy/projects/gitignore.py +45 -0
- psychopy/projects/pavlovia.py +1674 -0
- psychopy/projects/sshkeys.py +107 -0
- psychopy/psychojs.zip +0 -0
- psychopy/pylintrc +69 -0
- psychopy/scripts/__init__.py +0 -0
- psychopy/scripts/psychopy-pkgutil.py +969 -0
- psychopy/scripts/psyexpCompile.py +229 -0
- psychopy/session.py +1651 -0
- psychopy/sound/__init__.py +50 -0
- psychopy/sound/_base.py +399 -0
- psychopy/sound/audioclip.py +1325 -0
- psychopy/sound/audiodevice.py +857 -0
- psychopy/sound/backend_ptb.py +406 -0
- psychopy/sound/backend_pygame.py +323 -0
- psychopy/sound/backend_pyo.py +64 -0
- psychopy/sound/backend_pysound.py +324 -0
- psychopy/sound/backend_sounddevice.py +44 -0
- psychopy/sound/backends/__init__.py +0 -0
- psychopy/sound/exceptions.py +115 -0
- psychopy/sound/microphone.py +357 -0
- psychopy/sound/sound.py +58 -0
- psychopy/sound/transcribe.py +1321 -0
- psychopy/tests/README.md +344 -0
- psychopy/tests/__init__.py +47 -0
- psychopy/tests/data/Electronic_Chime-KevanGC-495939803.wav +0 -0
- psychopy/tests/data/TestCircle_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq10_s0.5.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq10_s0.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq10_s1.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq1_s0.5.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq1_s0.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq1_s1.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq3_s0.5.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq3_s0.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq3_s1.png +0 -0
- psychopy/tests/data/TestImage_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestImage_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestImage_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestImage_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestImage_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestImage_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestImage_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestImage_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestImage_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestImage_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestImage_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestImage_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_minmax_0.png +0 -0
- psychopy/tests/data/TestProgress_testValue_minmax_1.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_center center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_center center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_top center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_top center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestROI_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestROI_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestROI_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestROI_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestROI_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestROI_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestROI_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestROI_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestROI_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestROI_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestROI_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestROI_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestSession_exp1.png +0 -0
- psychopy/tests/data/TestSession_exp2.png +0 -0
- psychopy/tests/data/TestShape_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestShape_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestShape_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestShape_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestShape_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestShape_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestShape_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestShape_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestShape_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestShape_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestShape_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestShape_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_0p6.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_0p8.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p2.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p4.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p6.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p8.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_2p0.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_None.png +0 -0
- psychopy/tests/data/TestUnknownPluginComponent_load_resave.psyexp +135 -0
- psychopy/tests/data/Test_textbox/test_ori_0_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_top left.png +0 -0
- psychopy/tests/data/Test_textbox_testSpeechpoint_-3ovr8_0ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_-3ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_3ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_testSpeechpoint_3ovr8_0ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_top_right.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_top_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_top_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_top_right.png +0 -0
- psychopy/tests/data/TextComponent_disabled.psyexp +63 -0
- psychopy/tests/data/TextComponent_not_disabled.psyexp +63 -0
- psychopy/tests/data/aperture1_deg.png +0 -0
- psychopy/tests/data/aperture1_degFlat.png +0 -0
- psychopy/tests/data/aperture1_degFlatPos.png +0 -0
- psychopy/tests/data/aperture1_norm.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground.png +0 -0
- psychopy/tests/data/aperture1_normNoShade.png +0 -0
- psychopy/tests/data/aperture1_pix.png +0 -0
- psychopy/tests/data/aperture1_stencil.png +0 -0
- psychopy/tests/data/aperture2_deg.png +0 -0
- psychopy/tests/data/aperture2_degFlat.png +0 -0
- psychopy/tests/data/aperture2_degFlatPos.png +0 -0
- psychopy/tests/data/aperture2_norm.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground.png +0 -0
- psychopy/tests/data/aperture2_normNoShade.png +0 -0
- psychopy/tests/data/aperture2_pix.png +0 -0
- psychopy/tests/data/aperture2_stencil.png +0 -0
- psychopy/tests/data/beatandrcos_cm.png +0 -0
- psychopy/tests/data/beatandrcos_deg.png +0 -0
- psychopy/tests/data/beatandrcos_degFlat.png +0 -0
- psychopy/tests/data/beatandrcos_degFlatPos.png +0 -0
- psychopy/tests/data/beatandrcos_height.png +0 -0
- psychopy/tests/data/beatandrcos_norm.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground.png +0 -0
- psychopy/tests/data/beatandrcos_pix.png +0 -0
- psychopy/tests/data/beatandrcos_stencil.png +0 -0
- psychopy/tests/data/blend_add_cm.png +0 -0
- psychopy/tests/data/blend_add_deg.png +0 -0
- psychopy/tests/data/blend_add_degFlat.png +0 -0
- psychopy/tests/data/blend_add_degFlatPos.png +0 -0
- psychopy/tests/data/blend_add_height.png +0 -0
- psychopy/tests/data/blend_add_norm.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground.png +0 -0
- psychopy/tests/data/blend_add_normNoShade.png +0 -0
- psychopy/tests/data/blend_add_pix.png +0 -0
- psychopy/tests/data/blend_add_stencil.png +0 -0
- psychopy/tests/data/broken2020_2_5_resources/broken_resources.psyexp +84 -0
- psychopy/tests/data/broken2020_2_5_resources/psychopy72.png +0 -0
- psychopy/tests/data/bufferimg_gabor_cm.png +0 -0
- psychopy/tests/data/bufferimg_gabor_deg.png +0 -0
- psychopy/tests/data/bufferimg_gabor_degFlat.png +0 -0
- psychopy/tests/data/bufferimg_gabor_degFlatPos.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade.png +0 -0
- psychopy/tests/data/bufferimg_gabor_pix.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil.png +0 -0
- psychopy/tests/data/circleHex_cm.png +0 -0
- psychopy/tests/data/circleHex_deg.png +0 -0
- psychopy/tests/data/circleHex_degFlat.png +0 -0
- psychopy/tests/data/circleHex_degFlatPos.png +0 -0
- psychopy/tests/data/circleHex_height.png +0 -0
- psychopy/tests/data/circleHex_norm.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground.png +0 -0
- psychopy/tests/data/circleHex_normNoShade.png +0 -0
- psychopy/tests/data/circleHex_pix.png +0 -0
- psychopy/tests/data/circleHex_stencil.png +0 -0
- psychopy/tests/data/corrFullRandom.csv +16 -0
- psychopy/tests/data/corrFullRandom.tsv +6 -0
- psychopy/tests/data/corrFullRandomTH2.csv +16 -0
- psychopy/tests/data/corrMultiKeyExpWide.csv +3 -0
- psychopy/tests/data/corrMultiKeyTrials.csv +8 -0
- psychopy/tests/data/corrMultiKeyTrials.xlsx +0 -0
- psychopy/tests/data/corrRandom.csv +16 -0
- psychopy/tests/data/corrRandom.tsv +6 -0
- psychopy/tests/data/corrRandomTH2.csv +16 -0
- psychopy/tests/data/corrXlsx.xlsx +0 -0
- psychopy/tests/data/correctScript/js/correctCodeComponent.js +181 -0
- psychopy/tests/data/correctScript/js/correctImageComponent.js +204 -0
- psychopy/tests/data/correctScript/js/correctKeyboardComponent.js +225 -0
- psychopy/tests/data/correctScript/js/correctMouseComponent.js +221 -0
- psychopy/tests/data/correctScript/js/correctMovieComponent.js +210 -0
- psychopy/tests/data/correctScript/js/correctPolygonComponent.js +205 -0
- psychopy/tests/data/correctScript/js/correctSliderComponent.js +209 -0
- psychopy/tests/data/correctScript/js/correctSoundComponent.js +205 -0
- psychopy/tests/data/correctScript/js/correctTextComponent.js +207 -0
- psychopy/tests/data/correctScript/python/correctApertureComponent.py +157 -0
- psychopy/tests/data/correctScript/python/correctCodeComponent.py +135 -0
- psychopy/tests/data/correctScript/python/correctDotsComponent.py +161 -0
- psychopy/tests/data/correctScript/python/correctEnvGratingComponent.py +167 -0
- psychopy/tests/data/correctScript/python/correctFormComponent.py +150 -0
- psychopy/tests/data/correctScript/python/correctGratingComponent.py +158 -0
- psychopy/tests/data/correctScript/python/correctImageComponent.py +160 -0
- psychopy/tests/data/correctScript/python/correctJoyButtonsComponent.py +204 -0
- psychopy/tests/data/correctScript/python/correctJoystickComponent.py +214 -0
- psychopy/tests/data/correctScript/python/correctKeyboardComponent.py +169 -0
- psychopy/tests/data/correctScript/python/correctMicrophoneComponent.py +163 -0
- psychopy/tests/data/correctScript/python/correctMouseComponent.py +174 -0
- psychopy/tests/data/correctScript/python/correctMovieComponent.py +160 -0
- psychopy/tests/data/correctScript/python/correctNoiseStimComponent.py +169 -0
- psychopy/tests/data/correctScript/python/correctParallelOutComponent.py +156 -0
- psychopy/tests/data/correctScript/python/correctPatchComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctPolygonComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctQmixPumpComponent.py +174 -0
- psychopy/tests/data/correctScript/python/correctRatingScaleComponent.py +152 -0
- psychopy/tests/data/correctScript/python/correctSliderComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctSoundComponent.py +157 -0
- psychopy/tests/data/correctScript/python/correctStaticComponent.py +176 -0
- psychopy/tests/data/correctScript/python/correctTextComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctVariableComponent.py +139 -0
- psychopy/tests/data/correctScript/python/correctcedrusButtonBoxComponent.py +199 -0
- psychopy/tests/data/correctScript/python/correctioLabsButtonBoxComponent.py +187 -0
- psychopy/tests/data/dataTest.xlsx +0 -0
- psychopy/tests/data/dots_cm.png +0 -0
- psychopy/tests/data/dots_deg.png +0 -0
- psychopy/tests/data/dots_degFlat.png +0 -0
- psychopy/tests/data/dots_degFlatPos.png +0 -0
- psychopy/tests/data/dots_height.png +0 -0
- psychopy/tests/data/dots_norm.png +0 -0
- psychopy/tests/data/dots_normAddBlend.png +0 -0
- psychopy/tests/data/dots_normHexbackground.png +0 -0
- psychopy/tests/data/dots_normNoShade.png +0 -0
- psychopy/tests/data/dots_pix.png +0 -0
- psychopy/tests/data/dots_stencil.png +0 -0
- psychopy/tests/data/duplicateHeaders.csv +2 -0
- psychopy/tests/data/elarray1_cm.png +0 -0
- psychopy/tests/data/elarray1_deg.png +0 -0
- psychopy/tests/data/elarray1_degFlat.png +0 -0
- psychopy/tests/data/elarray1_degFlatPos.png +0 -0
- psychopy/tests/data/elarray1_height.png +0 -0
- psychopy/tests/data/elarray1_norm.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground.png +0 -0
- psychopy/tests/data/elarray1_pix.png +0 -0
- psychopy/tests/data/elarray1_stencil.png +0 -0
- psychopy/tests/data/envelopeandrcos_cm.png +0 -0
- psychopy/tests/data/envelopeandrcos_deg.png +0 -0
- psychopy/tests/data/envelopeandrcos_degFlat.png +0 -0
- psychopy/tests/data/envelopeandrcos_degFlatPos.png +0 -0
- psychopy/tests/data/envelopeandrcos_height.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground.png +0 -0
- psychopy/tests/data/envelopeandrcos_pix.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_cm.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_deg.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_degFlat.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_degFlatPos.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_pix.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil.png +0 -0
- psychopy/tests/data/filltext.png +0 -0
- psychopy/tests/data/form_font_demographics.png +0 -0
- psychopy/tests/data/form_font_demographics.xlsx +0 -0
- psychopy/tests/data/form_font_languages.png +0 -0
- psychopy/tests/data/form_font_languages.xlsx +0 -0
- psychopy/tests/data/form_font_nonstandard.png +0 -0
- psychopy/tests/data/futureParams.psyexp +150 -0
- psychopy/tests/data/gabor1_cm.png +0 -0
- psychopy/tests/data/gabor1_deg.png +0 -0
- psychopy/tests/data/gabor1_degFlat.png +0 -0
- psychopy/tests/data/gabor1_degFlatPos.png +0 -0
- psychopy/tests/data/gabor1_height.png +0 -0
- psychopy/tests/data/gabor1_norm.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground.png +0 -0
- psychopy/tests/data/gabor1_normNoShade.png +0 -0
- psychopy/tests/data/gabor1_pix.png +0 -0
- psychopy/tests/data/gabor1_stencil.png +0 -0
- psychopy/tests/data/gabor2_cm.png +0 -0
- psychopy/tests/data/gabor2_deg.png +0 -0
- psychopy/tests/data/gabor2_degFlat.png +0 -0
- psychopy/tests/data/gabor2_degFlatPos.png +0 -0
- psychopy/tests/data/gabor2_height.png +0 -0
- psychopy/tests/data/gabor2_norm.png +0 -0
- psychopy/tests/data/gabor2_normAddBlend.png +0 -0
- psychopy/tests/data/gabor2_normHexbackground.png +0 -0
- psychopy/tests/data/gabor2_normNoShade.png +0 -0
- psychopy/tests/data/gabor2_pix.png +0 -0
- psychopy/tests/data/gabor2_stencil.png +0 -0
- psychopy/tests/data/ghost_stroop.psyexp +131 -0
- psychopy/tests/data/ghost_trialTypes.xlsx +0 -0
- psychopy/tests/data/green_48000.flac.dist +0 -0
- psychopy/tests/data/greyscale.jpg +0 -0
- psychopy/tests/data/greyscale2.png +0 -0
- psychopy/tests/data/greyscale2_cm.png +0 -0
- psychopy/tests/data/greyscale2_deg.png +0 -0
- psychopy/tests/data/greyscale2_degFlat.png +0 -0
- psychopy/tests/data/greyscale2_degFlatPos.png +0 -0
- psychopy/tests/data/greyscale2_height.png +0 -0
- psychopy/tests/data/greyscale2_norm.png +0 -0
- psychopy/tests/data/greyscale2_normAddBlend.png +0 -0
- psychopy/tests/data/greyscale2_normHexbackground.png +0 -0
- psychopy/tests/data/greyscale2_normNoShade.png +0 -0
- psychopy/tests/data/greyscale2_pix.png +0 -0
- psychopy/tests/data/greyscale2_stencil.png +0 -0
- psychopy/tests/data/greyscaleLowContr_cm.png +0 -0
- psychopy/tests/data/greyscaleLowContr_deg.png +0 -0
- psychopy/tests/data/greyscaleLowContr_degFlat.png +0 -0
- psychopy/tests/data/greyscaleLowContr_degFlatPos.png +0 -0
- psychopy/tests/data/greyscaleLowContr_height.png +0 -0
- psychopy/tests/data/greyscaleLowContr_norm.png +0 -0
- psychopy/tests/data/greyscaleLowContr_normAddBlend.png +0 -0
- psychopy/tests/data/greyscaleLowContr_normHexbackground.png +0 -0
- psychopy/tests/data/greyscaleLowContr_normNoShade.png +0 -0
- psychopy/tests/data/greyscaleLowContr_pix.png +0 -0
- psychopy/tests/data/greyscaleLowContr_stencil.png +0 -0
- psychopy/tests/data/greyscale_cm.png +0 -0
- psychopy/tests/data/greyscale_deg.png +0 -0
- psychopy/tests/data/greyscale_degFlat.png +0 -0
- psychopy/tests/data/greyscale_degFlatPos.png +0 -0
- psychopy/tests/data/greyscale_height.png +0 -0
- psychopy/tests/data/greyscale_norm.png +0 -0
- psychopy/tests/data/greyscale_normAddBlend.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground.png +0 -0
- psychopy/tests/data/greyscale_normNoShade.png +0 -0
- psychopy/tests/data/greyscale_pix.png +0 -0
- psychopy/tests/data/greyscale_stencil.png +0 -0
- psychopy/tests/data/imageAndGauss_cm.png +0 -0
- psychopy/tests/data/imageAndGauss_deg.png +0 -0
- psychopy/tests/data/imageAndGauss_degFlat.png +0 -0
- psychopy/tests/data/imageAndGauss_degFlatPos.png +0 -0
- psychopy/tests/data/imageAndGauss_height.png +0 -0
- psychopy/tests/data/imageAndGauss_norm.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade.png +0 -0
- psychopy/tests/data/imageAndGauss_pix.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil.png +0 -0
- psychopy/tests/data/movFrame1_cm.png +0 -0
- psychopy/tests/data/movFrame1_deg.png +0 -0
- psychopy/tests/data/movFrame1_degFlat.png +0 -0
- psychopy/tests/data/movFrame1_degFlatPos.png +0 -0
- psychopy/tests/data/movFrame1_height.png +0 -0
- psychopy/tests/data/movFrame1_norm.png +0 -0
- psychopy/tests/data/movFrame1_normAddBlend.png +0 -0
- psychopy/tests/data/movFrame1_normHexbackground.png +0 -0
- psychopy/tests/data/movFrame1_normNoShade.png +0 -0
- psychopy/tests/data/movFrame1_pix.png +0 -0
- psychopy/tests/data/movFrame1_stencil.png +0 -0
- psychopy/tests/data/multiKeypressExperiment.psydat +357 -0
- psychopy/tests/data/multiKeypressTrialhandler.psydat +252 -0
- psychopy/tests/data/multiStairConds.xlsx +0 -0
- psychopy/tests/data/multiStairQuestPlus.xlsx +0 -0
- psychopy/tests/data/newstyle.psydat +6155 -0
- psychopy/tests/data/noiseAndRcos_cm.png +0 -0
- psychopy/tests/data/noiseAndRcos_deg.png +0 -0
- psychopy/tests/data/noiseAndRcos_degFlat.png +0 -0
- psychopy/tests/data/noiseAndRcos_degFlatPos.png +0 -0
- psychopy/tests/data/noiseAndRcos_height.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade.png +0 -0
- psychopy/tests/data/noiseAndRcos_pix.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_cm.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_deg.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_degFlat.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_degFlatPos.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_pix.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil.png +0 -0
- psychopy/tests/data/numpyImage_cm.png +0 -0
- psychopy/tests/data/numpyImage_deg.png +0 -0
- psychopy/tests/data/numpyImage_degFlat.png +0 -0
- psychopy/tests/data/numpyImage_degFlatPos.png +0 -0
- psychopy/tests/data/numpyImage_height.png +0 -0
- psychopy/tests/data/numpyImage_norm.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade.png +0 -0
- psychopy/tests/data/numpyImage_pix.png +0 -0
- psychopy/tests/data/numpyImage_stencil.png +0 -0
- psychopy/tests/data/numpyLowContr_cm.png +0 -0
- psychopy/tests/data/numpyLowContr_deg.png +0 -0
- psychopy/tests/data/numpyLowContr_degFlat.png +0 -0
- psychopy/tests/data/numpyLowContr_degFlatPos.png +0 -0
- psychopy/tests/data/numpyLowContr_height.png +0 -0
- psychopy/tests/data/numpyLowContr_norm.png +0 -0
- psychopy/tests/data/numpyLowContr_normAddBlend.png +0 -0
- psychopy/tests/data/numpyLowContr_normHexbackground.png +0 -0
- psychopy/tests/data/numpyLowContr_normNoShade.png +0 -0
- psychopy/tests/data/numpyLowContr_pix.png +0 -0
- psychopy/tests/data/numpyLowContr_stencil.png +0 -0
- psychopy/tests/data/oldstyle.psydat +1534 -0
- psychopy/tests/data/oldstyle_stair.psydat +263 -0
- psychopy/tests/data/ratingscale1_cm.png +0 -0
- psychopy/tests/data/ratingscale1_deg.png +0 -0
- psychopy/tests/data/ratingscale1_degFlat.png +0 -0
- psychopy/tests/data/ratingscale1_degFlatPos.png +0 -0
- psychopy/tests/data/ratingscale1_height.png +0 -0
- psychopy/tests/data/ratingscale1_norm.png +0 -0
- psychopy/tests/data/ratingscale1_normAddBlend.png +0 -0
- psychopy/tests/data/ratingscale1_normHexbackground.png +0 -0
- psychopy/tests/data/ratingscale1_normNoShade.png +0 -0
- psychopy/tests/data/ratingscale1_pix.png +0 -0
- psychopy/tests/data/ratingscale1_stencil.png +0 -0
- psychopy/tests/data/red_16000.flac.dist +0 -0
- psychopy/tests/data/retroListParam.psyexp +82 -0
- psychopy/tests/data/right_to_left_unidcode.xlsx +0 -0
- psychopy/tests/data/sample.meshwarp.data +11522 -0
- psychopy/tests/data/shape2_1_cm.png +0 -0
- psychopy/tests/data/shape2_1_deg.png +0 -0
- psychopy/tests/data/shape2_1_degFlat.png +0 -0
- psychopy/tests/data/shape2_1_degFlatPos.png +0 -0
- psychopy/tests/data/shape2_1_height.png +0 -0
- psychopy/tests/data/shape2_1_norm.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade.png +0 -0
- psychopy/tests/data/shape2_1_pix.png +0 -0
- psychopy/tests/data/shape2_1_stencil.png +0 -0
- psychopy/tests/data/shape2_2_cm.png +0 -0
- psychopy/tests/data/shape2_2_deg.png +0 -0
- psychopy/tests/data/shape2_2_degFlat.png +0 -0
- psychopy/tests/data/shape2_2_degFlatPos.png +0 -0
- psychopy/tests/data/shape2_2_height.png +0 -0
- psychopy/tests/data/shape2_2_norm.png +0 -0
- psychopy/tests/data/shape2_2_normAddBlend.png +0 -0
- psychopy/tests/data/shape2_2_normHexbackground.png +0 -0
- psychopy/tests/data/shape2_2_normNoShade.png +0 -0
- psychopy/tests/data/shape2_2_pix.png +0 -0
- psychopy/tests/data/shape2_2_stencil.png +0 -0
- psychopy/tests/data/simpleimage1_cm.png +0 -0
- psychopy/tests/data/simpleimage1_deg.png +0 -0
- psychopy/tests/data/simpleimage1_degFlat.png +0 -0
- psychopy/tests/data/simpleimage1_degFlatPos.png +0 -0
- psychopy/tests/data/simpleimage1_height.png +0 -0
- psychopy/tests/data/simpleimage1_norm.png +0 -0
- psychopy/tests/data/simpleimage1_normAddBlend.png +0 -0
- psychopy/tests/data/simpleimage1_normHexbackground.png +0 -0
- psychopy/tests/data/simpleimage1_normNoShade.png +0 -0
- psychopy/tests/data/simpleimage1_pix.png +0 -0
- psychopy/tests/data/simpleimage1_stencil.png +0 -0
- psychopy/tests/data/test001EntryImporting.psyexp +66 -0
- psychopy/tests/data/testMovie.mp4 +0 -0
- psychopy/tests/data/test_basic_run.py +1 -0
- psychopy/tests/data/test_circle_radius_.1height.png +0 -0
- psychopy/tests/data/test_circle_radius_.2height.png +0 -0
- psychopy/tests/data/test_circle_radius_10pix.png +0 -0
- psychopy/tests/data/test_circle_radius_20pix.png +0 -0
- psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
- psychopy/tests/data/test_form_combinations_choice_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_choice_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_choice_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_choice_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_get_resources/blue.png +0 -0
- psychopy/tests/data/test_get_resources/groupA.csv +3 -0
- psychopy/tests/data/test_get_resources/groupB.csv +3 -0
- psychopy/tests/data/test_get_resources/groups.csv +3 -0
- psychopy/tests/data/test_get_resources/handledbyrm_constrloop.psyexp +143 -0
- psychopy/tests/data/test_get_resources/handledbyrm_noloop.psyexp +114 -0
- psychopy/tests/data/test_get_resources/handledbyrm_recurloop.psyexp +138 -0
- psychopy/tests/data/test_get_resources/handledbyrm_strloop.psyexp +126 -0
- psychopy/tests/data/test_get_resources/handledbystatic_constrloop.psyexp +141 -0
- psychopy/tests/data/test_get_resources/handledbystatic_noloop.psyexp +112 -0
- psychopy/tests/data/test_get_resources/handledbystatic_recurloop.psyexp +136 -0
- psychopy/tests/data/test_get_resources/handledbystatic_strloop.psyexp +124 -0
- psychopy/tests/data/test_get_resources/unhandled_constrloop.psyexp +128 -0
- psychopy/tests/data/test_get_resources/unhandled_noloop.psyexp +99 -0
- psychopy/tests/data/test_get_resources/unhandled_recurloop.psyexp +123 -0
- psychopy/tests/data/test_get_resources/unhandled_strloop.psyexp +111 -0
- psychopy/tests/data/test_get_resources/white.png +0 -0
- psychopy/tests/data/test_get_resources/yellow.png +0 -0
- psychopy/tests/data/test_image_aspect_default_None.png +0 -0
- psychopy/tests/data/test_image_aspect_default_xFull_yNone.png +0 -0
- psychopy/tests/data/test_image_aspect_default_xNone_yFull.png +0 -0
- psychopy/tests/data/test_image_aspect_default_xNone_yNone.png +0 -0
- psychopy/tests/data/test_image_flip_anchor_horiz.png +0 -0
- psychopy/tests/data/test_image_flip_anchor_vert.png +0 -0
- psychopy/tests/data/test_loaded_namespace/test_counterbalance.psyexp +142 -0
- psychopy/tests/data/test_loaded_namespace/test_custom_missing.psyexp +129 -0
- psychopy/tests/data/test_loaded_namespace/test_missing_counterbalance.psyexp +116 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_exp.psyexp +181 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_missing.psyexp +140 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_name_calibration.psyexp +164 -0
- psychopy/tests/data/test_loops/testLoopsBlocks.psyexp +161 -0
- psychopy/tests/data/test_loops/testStaircase.psyexp +105 -0
- psychopy/tests/data/test_loops/test_current_loop_attr.psyexp +185 -0
- psychopy/tests/data/test_panorama/panoramaTestImage.png +0 -0
- psychopy/tests/data/test_panorama/panoramaTestImage.svg +1 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_-0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_-0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_-1.0.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_1.0.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_-0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_0.3.png +0 -0
- psychopy/tests/data/test_resources.psyexp +491 -0
- psychopy/tests/data/test_session/outside_root/externalExp.psyexp +116 -0
- psychopy/tests/data/test_session/root/annotation/annotation.psyexp +161 -0
- psychopy/tests/data/test_session/root/error/error.psyexp +93 -0
- psychopy/tests/data/test_session/root/exp1/exp1.psyexp +133 -0
- psychopy/tests/data/test_session/root/exp2/exp2.psyexp +133 -0
- psychopy/tests/data/test_session/root/frameRate/frameRate.psyexp +114 -0
- psychopy/tests/data/test_session/root/invUseVersion/invUseVersion.psyexp +133 -0
- psychopy/tests/data/test_session/root/testClockFormat/testClockFormat.psyexp +122 -0
- psychopy/tests/data/test_session/root/testCtrls/testCtrls.psyexp +115 -0
- psychopy/tests/data/test_session/root/testEditExpInfo/testEditExpInfo.psyexp +135 -0
- psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
- psychopy/tests/data/test_session/root/testNamedButtonBox/testNamedButtonBox.psyexp +145 -0
- psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
- psychopy/tests/data/test_slider_horiz_accute_horiz.png +0 -0
- psychopy/tests/data/test_slider_horiz_accute_vert.png +0 -0
- psychopy/tests/data/test_slider_horiz_horiz.png +0 -0
- psychopy/tests/data/test_slider_horiz_obtuse_horiz.png +0 -0
- psychopy/tests/data/test_slider_horiz_obtuse_vert.png +0 -0
- psychopy/tests/data/test_slider_horiz_vert.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_blanks.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_clustered.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_morelabels.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_morelabelsclustered.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_moreticks.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_moreticksclustered.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_nolabels.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_noticks.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_simple.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_False_flip_False.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_False_flip_True.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_True_flip_False.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_True_flip_True.png +0 -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/data/test_static_component_script.psyexp +76 -0
- psychopy/tests/data/test_win_bg_large_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_large_500_default.png +0 -0
- psychopy/tests/data/test_win_bg_small_200_default.png +0 -0
- psychopy/tests/data/test_win_bg_small_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_200_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_500_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_fill_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_200_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_500_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_fill_default.png +0 -0
- psychopy/tests/data/test_win_bgcolor_blue.png +0 -0
- psychopy/tests/data/test_win_bgcolor_green.png +0 -0
- psychopy/tests/data/test_win_bgcolor_red.png +0 -0
- psychopy/tests/data/testimage.jpg +0 -0
- psychopy/tests/data/testimagegray.jpg +0 -0
- psychopy/tests/data/testpixels.png +0 -0
- psychopy/tests/data/testwedges.png +0 -0
- psychopy/tests/data/text1_cm.png +0 -0
- psychopy/tests/data/text1_deg.png +0 -0
- psychopy/tests/data/text1_degFlat.png +0 -0
- psychopy/tests/data/text1_degFlatPos.png +0 -0
- psychopy/tests/data/text1_height.png +0 -0
- psychopy/tests/data/text1_norm.png +0 -0
- psychopy/tests/data/text1_normAddBlend.png +0 -0
- psychopy/tests/data/text1_normHexbackground.png +0 -0
- psychopy/tests/data/text1_normNoShade.png +0 -0
- psychopy/tests/data/text1_pix.png +0 -0
- psychopy/tests/data/text1_stencil.png +0 -0
- psychopy/tests/data/text2_cm.png +0 -0
- psychopy/tests/data/text2_deg.png +0 -0
- psychopy/tests/data/text2_degFlat.png +0 -0
- psychopy/tests/data/text2_degFlatPos.png +0 -0
- psychopy/tests/data/text2_norm.png +0 -0
- psychopy/tests/data/text2_normNoShade.png +0 -0
- psychopy/tests/data/text2_pix.png +0 -0
- psychopy/tests/data/textbox_charcolors_default_roygbiv.png +0 -0
- psychopy/tests/data/textbox_charcolors_default_white_hello_black_there.png +0 -0
- psychopy/tests/data/textbox_default_align_bottom_center.png +0 -0
- psychopy/tests/data/textbox_default_align_bottom_left.png +0 -0
- psychopy/tests/data/textbox_default_align_bottom_right.png +0 -0
- psychopy/tests/data/textbox_default_align_center.png +0 -0
- psychopy/tests/data/textbox_default_align_center_center.png +0 -0
- psychopy/tests/data/textbox_default_align_center_left.png +0 -0
- psychopy/tests/data/textbox_default_align_center_right.png +0 -0
- psychopy/tests/data/textbox_default_align_centre.png +0 -0
- psychopy/tests/data/textbox_default_align_centre_centre.png +0 -0
- psychopy/tests/data/textbox_default_align_more_than_two_words.png +0 -0
- psychopy/tests/data/textbox_default_align_someword.png +0 -0
- psychopy/tests/data/textbox_default_align_top_center.png +0 -0
- psychopy/tests/data/textbox_default_align_top_left.png +0 -0
- psychopy/tests/data/textbox_default_align_top_right.png +0 -0
- psychopy/tests/data/textbox_default_colors_WOB.png +0 -0
- psychopy/tests/data/textbox_default_colors_exemplar1.png +0 -0
- psychopy/tests/data/textbox_default_colors_exemplar2.png +0 -0
- psychopy/tests/data/textbox_default_colors_exemplar3.png +0 -0
- psychopy/tests/data/textbox_default_colors_tyke1.png +0 -0
- psychopy/tests/data/textbox_default_colors_tyke2.png +0 -0
- psychopy/tests/data/textbox_default_colors_tyke3.png +0 -0
- psychopy/tests/data/textbox_default_cutoff_top.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_1.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_2.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_3.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_4.png +0 -0
- psychopy/tests/data/textbox_default_tyke_1.png +0 -0
- psychopy/tests/data/textbox_default_tyke_2.png +0 -0
- psychopy/tests/data/textbox_typing_blank.png +0 -0
- psychopy/tests/data/textbox_typing_longKoeran.png +0 -0
- psychopy/tests/data/textbox_typing_longWord.png +0 -0
- psychopy/tests/data/textbox_typing_navDel.png +0 -0
- psychopy/tests/data/textbox_typing_navLR.png +0 -0
- psychopy/tests/data/textbox_typing_newline.png +0 -0
- psychopy/tests/data/textbox_typing_pangram.png +0 -0
- psychopy/tests/data/textbox_uax14_align_bottom_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_bottom_left.png +0 -0
- psychopy/tests/data/textbox_uax14_align_bottom_right.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center_left.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center_right.png +0 -0
- psychopy/tests/data/textbox_uax14_align_centre.png +0 -0
- psychopy/tests/data/textbox_uax14_align_centre_centre.png +0 -0
- psychopy/tests/data/textbox_uax14_align_more_than_two_words.png +0 -0
- psychopy/tests/data/textbox_uax14_align_someword.png +0 -0
- psychopy/tests/data/textbox_uax14_align_top_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_top_left.png +0 -0
- psychopy/tests/data/textbox_uax14_align_top_right.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_WOB.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_exemplar1.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_exemplar2.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_exemplar3.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_tyke1.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_tyke2.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_tyke3.png +0 -0
- psychopy/tests/data/textbox_uax14_cutoff_top.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_1.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_2.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_3.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_4.png +0 -0
- psychopy/tests/data/textbox_uax14_tyke_1.png +0 -0
- psychopy/tests/data/textbox_uax14_tyke_2.png +0 -0
- psychopy/tests/data/trialTypes.csv +1 -0
- psychopy/tests/data/trialTypes.docx +0 -0
- psychopy/tests/data/trialTypes.pkl +0 -0
- psychopy/tests/data/trialTypes.tsv +7 -0
- psychopy/tests/data/trialTypes.xls +0 -0
- psychopy/tests/data/trialTypes.xlsx +0 -0
- psychopy/tests/data/trialTypes_eu.csv +7 -0
- psychopy/tests/data/trialsBlankCols.xlsx +0 -0
- psychopy/tests/data/wedge1_cm.png +0 -0
- psychopy/tests/data/wedge1_deg.png +0 -0
- psychopy/tests/data/wedge1_degFlat.png +0 -0
- psychopy/tests/data/wedge1_degFlatPos.png +0 -0
- psychopy/tests/data/wedge1_height.png +0 -0
- psychopy/tests/data/wedge1_norm.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground.png +0 -0
- psychopy/tests/data/wedge1_normNoShade.png +0 -0
- psychopy/tests/data/wedge1_pix.png +0 -0
- psychopy/tests/data/wedge1_stencil.png +0 -0
- psychopy/tests/data/wedge2_cm.png +0 -0
- psychopy/tests/data/wedge2_deg.png +0 -0
- psychopy/tests/data/wedge2_degFlat.png +0 -0
- psychopy/tests/data/wedge2_degFlatPos.png +0 -0
- psychopy/tests/data/wedge2_height.png +0 -0
- psychopy/tests/data/wedge2_norm.png +0 -0
- psychopy/tests/data/wedge2_normAddBlend.png +0 -0
- psychopy/tests/data/wedge2_normHexbackground.png +0 -0
- psychopy/tests/data/wedge2_normNoShade.png +0 -0
- psychopy/tests/data/wedge2_pix.png +0 -0
- psychopy/tests/data/wedge2_stencil.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_-1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_-2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-2_2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale2_2_pos0_0.png +0 -0
- psychopy/tests/doc/run_btn.png +0 -0
- psychopy/tests/doc/test-suite-bugs.jpg +0 -0
- psychopy/tests/doc/user-bugs.jpg +0 -0
- psychopy/tests/dummy_xorg.conf +21 -0
- psychopy/tests/run.py +50 -0
- psychopy/tests/test_Installation.py +38 -0
- psychopy/tests/test_alerts/test_alerts.py +37 -0
- psychopy/tests/test_alerts/test_alerttools.py +132 -0
- psychopy/tests/test_app/__init__.py +0 -0
- psychopy/tests/test_app/conftest.py +40 -0
- psychopy/tests/test_app/test_builder/__init__.py +0 -0
- psychopy/tests/test_app/test_builder/test_BuilderFrame.py +166 -0
- psychopy/tests/test_app/test_builder/test_CompileFromBuilder.py +133 -0
- psychopy/tests/test_app/test_builder/test_ComponentDialogs.py +98 -0
- psychopy/tests/test_app/test_command_line.py +65 -0
- psychopy/tests/test_app/test_runner/__init__.py +0 -0
- psychopy/tests/test_app/test_runner/test_RunnerFrame.py +166 -0
- psychopy/tests/test_app/test_speed.py +147 -0
- psychopy/tests/test_app/test_themes/test_icons.py +79 -0
- psychopy/tests/test_codecov.py +29 -0
- psychopy/tests/test_colors/test_Color.py +41 -0
- psychopy/tests/test_data/dataPrev.xlsx +0 -0
- psychopy/tests/test_data/test_ExperimentHandler.py +171 -0
- psychopy/tests/test_data/test_MultiStairHandler.py +174 -0
- psychopy/tests/test_data/test_StairHandlers.py +1241 -0
- psychopy/tests/test_data/test_TrialHandler.py +335 -0
- psychopy/tests/test_data/test_TrialHandler2.py +584 -0
- psychopy/tests/test_data/test_TrialHandlerExt.py +359 -0
- psychopy/tests/test_data/test_fitFunctions.py +101 -0
- psychopy/tests/test_data/test_utils.py +173 -0
- psychopy/tests/test_data/test_xlsx.py +92 -0
- psychopy/tests/test_demos/test_builder_demos.py +52 -0
- psychopy/tests/test_experiment/__init__.py +0 -0
- psychopy/tests/test_experiment/known_py_diffs.txt +47 -0
- psychopy/tests/test_experiment/needs_wx/__init__.py +0 -0
- psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +14780 -0
- psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +130 -0
- psychopy/tests/test_experiment/needs_wx/test_Experiment.py +406 -0
- psychopy/tests/test_experiment/needs_wx/test_components.py +170 -0
- psychopy/tests/test_experiment/test_component_compile_js.py +59 -0
- psychopy/tests/test_experiment/test_component_compile_python.py +165 -0
- psychopy/tests/test_experiment/test_components/__init__.py +1 -0
- psychopy/tests/test_experiment/test_components/test_ButtonBoxComponent.py +218 -0
- psychopy/tests/test_experiment/test_components/test_CodeComponent.py +70 -0
- psychopy/tests/test_experiment/test_components/test_GratingComponent.py +7 -0
- psychopy/tests/test_experiment/test_components/test_ImageComponent.py +8 -0
- psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
- psychopy/tests/test_experiment/test_components/test_MouseComponent.py +136 -0
- psychopy/tests/test_experiment/test_components/test_PolygonComponent.py +65 -0
- psychopy/tests/test_experiment/test_components/test_ResourceManagerComponent.py +50 -0
- psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
- psychopy/tests/test_experiment/test_components/test_SettingsComponent.py +80 -0
- psychopy/tests/test_experiment/test_components/test_StaticComponent.py +51 -0
- psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
- psychopy/tests/test_experiment/test_components/test_all_components.py +104 -0
- psychopy/tests/test_experiment/test_components/test_base_components.py +477 -0
- psychopy/tests/test_experiment/test_experiment.py +199 -0
- psychopy/tests/test_experiment/test_loops.py +103 -0
- psychopy/tests/test_experiment/test_params.py +363 -0
- psychopy/tests/test_experiment/test_py2js.py +230 -0
- psychopy/tests/test_experiment/test_routines/__init__.py +1 -0
- psychopy/tests/test_experiment/test_routines/test_EyetrackerCalibrationRoutine.py +9 -0
- psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +9 -0
- psychopy/tests/test_experiment/test_routines/test_all_routines.py +23 -0
- psychopy/tests/test_experiment/test_routines/test_base_routine.py +154 -0
- psychopy/tests/test_experiment/test_routines/test_standalone_routines.py +36 -0
- psychopy/tests/test_gui/test_DlgFromDictQt.py +82 -0
- psychopy/tests/test_gui/test_DlgFromDictWx.py +82 -0
- psychopy/tests/test_hardware/__init__.py +0 -0
- psychopy/tests/test_hardware/test_device_manager.py +36 -0
- psychopy/tests/test_hardware/test_emulator.py +106 -0
- psychopy/tests/test_hardware/test_gammasci.py +35 -0
- psychopy/tests/test_hardware/test_keyboard.py +241 -0
- psychopy/tests/test_hardware/test_keyboard_events.py +362 -0
- psychopy/tests/test_hardware/test_photodiode.py +66 -0
- psychopy/tests/test_hardware/test_ports.py +129 -0
- psychopy/tests/test_iohub/__init__.py +1 -0
- psychopy/tests/test_iohub/test_computer.py +124 -0
- psychopy/tests/test_iohub/test_event_get_and_clear.py +94 -0
- psychopy/tests/test_iohub/test_keyboard.py +91 -0
- psychopy/tests/test_iohub/test_launch.py +19 -0
- psychopy/tests/test_iohub/testutil.py +54 -0
- psychopy/tests/test_liaison/test_Liaison.py +275 -0
- psychopy/tests/test_misc/__init__.py +0 -0
- psychopy/tests/test_misc/memory_usage.py +164 -0
- psychopy/tests/test_misc/test_GammaFun.py +15 -0
- psychopy/tests/test_misc/test_clock.py +63 -0
- psychopy/tests/test_misc/test_color.py +205 -0
- psychopy/tests/test_misc/test_core.py +451 -0
- psychopy/tests/test_misc/test_event.py +308 -0
- psychopy/tests/test_misc/test_info.py +18 -0
- psychopy/tests/test_misc/test_layout.py +49 -0
- psychopy/tests/test_misc/test_locale.py +38 -0
- psychopy/tests/test_misc/test_web.py +22 -0
- psychopy/tests/test_monitors/test_monitors.py +91 -0
- psychopy/tests/test_plugins/__init__.py +0 -0
- psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
- psychopy/tests/test_preferences/__init__.py +0 -0
- psychopy/tests/test_preferences/test_prefs.py +28 -0
- psychopy/tests/test_session/test_Session.py +257 -0
- psychopy/tests/test_sound/__init__.py +0 -0
- psychopy/tests/test_sound/test_audioclip.py +331 -0
- psychopy/tests/test_sound/test_hamming.py +45 -0
- psychopy/tests/test_sound/test_sound.py +138 -0
- psychopy/tests/test_sound/test_sound_pygame.py +67 -0
- psychopy/tests/test_tools/test_animationtools.py +51 -0
- psychopy/tests/test_tools/test_arraytools.py +242 -0
- psychopy/tests/test_tools/test_attributetools.py +257 -0
- psychopy/tests/test_tools/test_colorspacetools.py +150 -0
- psychopy/tests/test_tools/test_environmenttools.py +52 -0
- psychopy/tests/test_tools/test_fileerrortools.py +97 -0
- psychopy/tests/test_tools/test_filetools.py +104 -0
- psychopy/tests/test_tools/test_imagetools.py +57 -0
- psychopy/tests/test_tools/test_mathtools.py +688 -0
- psychopy/tests/test_tools/test_stringtools.py +143 -0
- psychopy/tests/test_tools/test_versionchooser.py +209 -0
- psychopy/tests/test_tools/test_viewtools.py +168 -0
- psychopy/tests/test_validators/__init__.py +0 -0
- psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
- psychopy/tests/test_visual/__init__.py +0 -0
- psychopy/tests/test_visual/measure_parity.py +243 -0
- psychopy/tests/test_visual/test_all_stimuli.py +655 -0
- psychopy/tests/test_visual/test_basevisual.py +564 -0
- psychopy/tests/test_visual/test_brush.py +68 -0
- psychopy/tests/test_visual/test_button.py +15 -0
- psychopy/tests/test_visual/test_circle.py +74 -0
- psychopy/tests/test_visual/test_contains_overlaps.py +242 -0
- psychopy/tests/test_visual/test_custommouse.py +47 -0
- psychopy/tests/test_visual/test_dots.py +155 -0
- psychopy/tests/test_visual/test_form.py +414 -0
- psychopy/tests/test_visual/test_framepacking.py +41 -0
- psychopy/tests/test_visual/test_gamma.py +152 -0
- psychopy/tests/test_visual/test_glfw_backend.py +14 -0
- psychopy/tests/test_visual/test_image.py +219 -0
- psychopy/tests/test_visual/test_panorama.py +41 -0
- psychopy/tests/test_visual/test_progress.py +96 -0
- psychopy/tests/test_visual/test_projections.py +215 -0
- psychopy/tests/test_visual/test_projections_interactive.py +163 -0
- psychopy/tests/test_visual/test_roi.py +105 -0
- psychopy/tests/test_visual/test_shape.py +23 -0
- psychopy/tests/test_visual/test_slider.py +328 -0
- psychopy/tests/test_visual/test_target.py +35 -0
- psychopy/tests/test_visual/test_textbox.py +508 -0
- psychopy/tests/test_visual/test_winFlipTiming.py +95 -0
- psychopy/tests/test_visual/test_winScalePos.py +78 -0
- psychopy/tests/test_visual/test_window.py +124 -0
- psychopy/tests/utils.py +372 -0
- psychopy/tools/LineBreak.txt +3597 -0
- psychopy/tools/__init__.py +9 -0
- psychopy/tools/animationtools.py +49 -0
- psychopy/tools/apptools.py +32 -0
- psychopy/tools/arraytools.py +561 -0
- psychopy/tools/attributetools.py +263 -0
- psychopy/tools/audiotools.py +361 -0
- psychopy/tools/colorspacetools.py +717 -0
- psychopy/tools/coordinatetools.py +104 -0
- psychopy/tools/environmenttools.py +62 -0
- psychopy/tools/fileerrortools.py +66 -0
- psychopy/tools/filetools.py +406 -0
- psychopy/tools/fontmanager.py +1065 -0
- psychopy/tools/gltools.py +7367 -0
- psychopy/tools/imagetools.py +65 -0
- psychopy/tools/linebreak.py +322 -0
- psychopy/tools/mathtools.py +4910 -0
- psychopy/tools/monitorunittools.py +276 -0
- psychopy/tools/movietools.py +1111 -0
- psychopy/tools/pkgtools.py +654 -0
- psychopy/tools/plottools.py +25 -0
- psychopy/tools/rifttools.py +76 -0
- psychopy/tools/stereotools.py +9 -0
- psychopy/tools/stimulustools.py +198 -0
- psychopy/tools/stringtools.py +466 -0
- psychopy/tools/systemtools.py +1331 -0
- psychopy/tools/typetools.py +52 -0
- psychopy/tools/unittools.py +16 -0
- psychopy/tools/versionchooser.py +604 -0
- psychopy/tools/viewtools.py +1068 -0
- psychopy/tools/wizard.py +804 -0
- psychopy/validation/__init__.py +6 -0
- psychopy/validation/audio.py +78 -0
- psychopy/validation/visual.py +119 -0
- psychopy/visual/__init__.py +121 -0
- psychopy/visual/aperture.py +333 -0
- psychopy/visual/backends/__init__.py +77 -0
- psychopy/visual/backends/_base.py +481 -0
- psychopy/visual/backends/gamma.py +349 -0
- psychopy/visual/backends/glfwbackend.py +24 -0
- psychopy/visual/backends/pygamebackend.py +343 -0
- psychopy/visual/backends/pygletbackend.py +970 -0
- psychopy/visual/basevisual.py +2027 -0
- psychopy/visual/brush.py +204 -0
- psychopy/visual/bufferimage.py +311 -0
- psychopy/visual/button.py +194 -0
- psychopy/visual/circle.py +165 -0
- psychopy/visual/custommouse.py +263 -0
- psychopy/visual/dot.py +734 -0
- psychopy/visual/dropdown.py +165 -0
- psychopy/visual/elementarray.py +802 -0
- psychopy/visual/filters.py +419 -0
- psychopy/visual/form.py +1195 -0
- psychopy/visual/globalVars.py +24 -0
- psychopy/visual/grating.py +581 -0
- psychopy/visual/helpers.py +336 -0
- psychopy/visual/image.py +438 -0
- psychopy/visual/line.py +227 -0
- psychopy/visual/movie.py +12 -0
- psychopy/visual/movie2.py +21 -0
- psychopy/visual/movie3.py +18 -0
- psychopy/visual/movies/__init__.py +2334 -0
- psychopy/visual/movies/frame.py +258 -0
- psychopy/visual/movies/metadata.py +242 -0
- psychopy/visual/movies/players/_base.py +364 -0
- psychopy/visual/nnlvs.py +830 -0
- psychopy/visual/noise.py +32 -0
- psychopy/visual/panorama.py +313 -0
- psychopy/visual/patch.py +21 -0
- psychopy/visual/pie.py +237 -0
- psychopy/visual/polygon.py +226 -0
- psychopy/visual/progress.py +313 -0
- psychopy/visual/radial.py +29 -0
- psychopy/visual/ratingscale.py +18 -0
- psychopy/visual/rect.py +195 -0
- psychopy/visual/rift.py +2660 -0
- psychopy/visual/roi.py +141 -0
- psychopy/visual/secondorder.py +27 -0
- psychopy/visual/shaders.py +787 -0
- psychopy/visual/shape.py +897 -0
- psychopy/visual/simpleimage.py +303 -0
- psychopy/visual/slider.py +1222 -0
- psychopy/visual/stim3d.py +2109 -0
- psychopy/visual/target.py +278 -0
- psychopy/visual/text.py +769 -0
- psychopy/visual/textbox/__init__.py +1280 -0
- psychopy/visual/textbox/fontmanager.py +574 -0
- psychopy/visual/textbox/parsedtext.py +317 -0
- psychopy/visual/textbox/textgrid.py +278 -0
- psychopy/visual/textbox/textureatlas.py +248 -0
- psychopy/visual/textbox2/__init__.py +4 -0
- psychopy/visual/textbox2/textbox2.py +1970 -0
- psychopy/visual/vlcmoviestim.py +1294 -0
- psychopy/visual/window.py +3910 -0
- psychopy/visual/windowframepack.py +86 -0
- psychopy/visual/windowwarp.py +457 -0
- psychopy/voicekey/__init__.py +56 -0
- psychopy/voicekey/labjack_vks.py +9 -0
- psychopy/voicekey/parallel_vks.py +9 -0
- psychopy/voicekey/vk_tools.py +131 -0
- psychopy/web.py +289 -0
- psychopy-2025.2.4.dist-info/METADATA +160 -0
- psychopy-2025.2.4.dist-info/RECORD +3127 -0
- psychopy-2025.2.4.dist-info/WHEEL +4 -0
- psychopy-2025.2.4.dist-info/entry_points.txt +5 -0
- psychopy-2025.2.4.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,2334 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""A stimulus class for playing movies (mpeg, avi, etc...) in PsychoPy.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Part of the PsychoPy library
|
|
8
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
9
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
|
10
|
+
|
|
11
|
+
__all__ = ['MovieStim']
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import ctypes
|
|
15
|
+
import os.path
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
import tempfile
|
|
19
|
+
import time
|
|
20
|
+
|
|
21
|
+
from psychopy import layout, prefs
|
|
22
|
+
from psychopy.tools.filetools import pathToString, defaultStim
|
|
23
|
+
from psychopy.visual.basevisual import (
|
|
24
|
+
BaseVisualStim, DraggingMixin, ContainerMixin, ColorMixin
|
|
25
|
+
)
|
|
26
|
+
from psychopy.constants import (
|
|
27
|
+
FINISHED, NOT_STARTED, PAUSED, PLAYING, STOPPED, SEEKING)
|
|
28
|
+
from psychopy import core
|
|
29
|
+
|
|
30
|
+
from .metadata import MovieMetadata, NULL_MOVIE_METADATA
|
|
31
|
+
from .frame import MovieFrame, NULL_MOVIE_FRAME_INFO
|
|
32
|
+
|
|
33
|
+
from psychopy import logging
|
|
34
|
+
import numpy as np
|
|
35
|
+
import pyglet
|
|
36
|
+
pyglet.options['debug_gl'] = False
|
|
37
|
+
GL = pyglet.gl
|
|
38
|
+
|
|
39
|
+
# threshold to stop reporting dropped frames
|
|
40
|
+
reportNDroppedFrames = 10
|
|
41
|
+
defaultTimeout = 5.0 # seconds
|
|
42
|
+
|
|
43
|
+
# constants for use with ffpyplayer
|
|
44
|
+
FFPYPLAYER_STATUS_EOF = 'eof'
|
|
45
|
+
FFPYPLAYER_STATUS_PAUSED = 'paused'
|
|
46
|
+
|
|
47
|
+
PREFERRED_VIDEO_LIB = 'ffpyplayer'
|
|
48
|
+
|
|
49
|
+
# Keep track of movie readers here. This is used to close all movie readers
|
|
50
|
+
# when the main thread exits. We identify movie readers by hashing the filename
|
|
51
|
+
# they are presently reading from.
|
|
52
|
+
|
|
53
|
+
_openMovieReaders = set()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# ------------------------------------------------------------------------------
|
|
57
|
+
# Classes
|
|
58
|
+
#
|
|
59
|
+
|
|
60
|
+
class MoviePlaybackError(Exception):
|
|
61
|
+
"""Exception raised when there is an error during movie playback."""
|
|
62
|
+
def __init__(self, message):
|
|
63
|
+
super().__init__(message)
|
|
64
|
+
self.message = message
|
|
65
|
+
|
|
66
|
+
def __str__(self):
|
|
67
|
+
return f"MoviePlaybackError: {self.message}"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class MovieFileNotFoundError(MoviePlaybackError):
|
|
71
|
+
"""Exception raised when a movie file is not found."""
|
|
72
|
+
def __init__(self, filename):
|
|
73
|
+
super().__init__(f"Movie file not found: {filename}")
|
|
74
|
+
self.filename = filename
|
|
75
|
+
|
|
76
|
+
def __str__(self):
|
|
77
|
+
return f"MovieFileNotFoundError: {self.filename} does not exist."
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class MovieFileFormatError(MoviePlaybackError):
|
|
81
|
+
"""Exception raised when a movie file format is not supported."""
|
|
82
|
+
def __init__(self, filename):
|
|
83
|
+
super().__init__(f"Movie file format not supported: {filename}")
|
|
84
|
+
self.filename = filename
|
|
85
|
+
|
|
86
|
+
def __str__(self):
|
|
87
|
+
return f"MovieFileFormatError: {self.filename} is not a supported movie format."
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class MovieAudioError(MoviePlaybackError):
|
|
91
|
+
"""Exception raised when there is an error with movie audio playback."""
|
|
92
|
+
def __init__(self, message):
|
|
93
|
+
super().__init__(message)
|
|
94
|
+
self.message = message
|
|
95
|
+
|
|
96
|
+
def __str__(self):
|
|
97
|
+
return f"MovieAudioError: {self.message}"
|
|
98
|
+
|
|
99
|
+
# ------------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
class MovieMetadata:
|
|
102
|
+
"""Class for storing metadata about a movie file.
|
|
103
|
+
|
|
104
|
+
This class is used to store metadata about a movie file. This includes
|
|
105
|
+
information about the video and audio tracks in the movie. Metadata is
|
|
106
|
+
extracted from the movie file when the movie reader is opened.
|
|
107
|
+
|
|
108
|
+
This class is not intended to be used directly by users. It is used
|
|
109
|
+
internally by the `MovieFileReader` class to store metadata about the movie
|
|
110
|
+
file being read.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
filename : str
|
|
115
|
+
The name (or path) of the movie file to extract metadata from.
|
|
116
|
+
size : tuple
|
|
117
|
+
The size of the movie in pixels (width, height).
|
|
118
|
+
frameRate : float
|
|
119
|
+
The frame rate of the movie in frames per second.
|
|
120
|
+
duration : float
|
|
121
|
+
The duration of the movie in seconds.
|
|
122
|
+
colorFormat : str
|
|
123
|
+
The color format of the movie (e.g. 'rgb24', etc.).
|
|
124
|
+
audioTrack : AudioMetadata or None
|
|
125
|
+
The audio track metadata.
|
|
126
|
+
|
|
127
|
+
"""
|
|
128
|
+
__slots__ = (
|
|
129
|
+
'_filename', '_size', '_frameRate', '_duration', '_frameInterval',
|
|
130
|
+
'_colorFormat', '_audioTrack')
|
|
131
|
+
|
|
132
|
+
def __init__(self, filename, size, frameRate, duration, colorFormat,
|
|
133
|
+
audioTrack=None):
|
|
134
|
+
self._filename = filename
|
|
135
|
+
self._size = size
|
|
136
|
+
self._frameRate = frameRate
|
|
137
|
+
self._duration = duration
|
|
138
|
+
self._frameInterval = 1.0 / self._frameRate
|
|
139
|
+
|
|
140
|
+
if isinstance(colorFormat, bytes):
|
|
141
|
+
colorFormat = colorFormat.decode('utf-8')
|
|
142
|
+
self._colorFormat = colorFormat
|
|
143
|
+
|
|
144
|
+
# audio track metadata
|
|
145
|
+
self._audioTrack = audioTrack
|
|
146
|
+
|
|
147
|
+
def __repr__(self):
|
|
148
|
+
return (
|
|
149
|
+
f"MovieMetadata(filename={self.filename}, "
|
|
150
|
+
f"size={self.size}, "
|
|
151
|
+
f"frameRate={self.frameRate}, "
|
|
152
|
+
f"duration={self.duration})")
|
|
153
|
+
|
|
154
|
+
def __str__(self):
|
|
155
|
+
return (
|
|
156
|
+
f"MovieMetadata(filename={self.filename}, "
|
|
157
|
+
f"size={self.size}, "
|
|
158
|
+
f"frameRate={self.frameRate}, "
|
|
159
|
+
f"duration={self.duration})")
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
def filename(self):
|
|
163
|
+
"""The name (path) of the movie file (`str`).
|
|
164
|
+
|
|
165
|
+
"""
|
|
166
|
+
return self._filename
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def size(self):
|
|
170
|
+
"""The size of the movie in pixels (`tuple`).
|
|
171
|
+
|
|
172
|
+
"""
|
|
173
|
+
return self._size
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def frameRate(self):
|
|
177
|
+
"""The frame rate of the movie in frames per second (`float`).
|
|
178
|
+
|
|
179
|
+
"""
|
|
180
|
+
return self._frameRate
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def frameInterval(self):
|
|
184
|
+
"""The interval between frames in the movie in seconds (`float`).
|
|
185
|
+
|
|
186
|
+
"""
|
|
187
|
+
return self._frameInterval
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def duration(self):
|
|
191
|
+
"""The duration of the movie in seconds (`float`).
|
|
192
|
+
|
|
193
|
+
"""
|
|
194
|
+
return self._duration
|
|
195
|
+
|
|
196
|
+
@property
|
|
197
|
+
def colorFormat(self):
|
|
198
|
+
"""The color format of the movie (`str`).
|
|
199
|
+
|
|
200
|
+
"""
|
|
201
|
+
return self._colorFormat
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def audioTrack(self):
|
|
205
|
+
"""The audio track metadata (`AudioMetadata` or `None`).
|
|
206
|
+
|
|
207
|
+
"""
|
|
208
|
+
return self._audioTrack
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class MovieFileReader:
|
|
212
|
+
"""Read movie frames from file.
|
|
213
|
+
|
|
214
|
+
This class manages reading movie frames from a file or stream. The method
|
|
215
|
+
used to read the movie frames is determined by the `decoderLib` parameter.
|
|
216
|
+
|
|
217
|
+
Parameters
|
|
218
|
+
----------
|
|
219
|
+
filename : str
|
|
220
|
+
The name (or path) of the file to read the movie from.
|
|
221
|
+
decoderLib : str
|
|
222
|
+
The library to use to handle decoding the movie. The default is
|
|
223
|
+
'ffpyplayer'.
|
|
224
|
+
decoderOpts : dict or None
|
|
225
|
+
A dictionary of options to pass to the decoder. These option can be used
|
|
226
|
+
to control the quality of the movie, for example. The options depend on
|
|
227
|
+
the `decoderLib` in use. If `None`, the reader will use the default
|
|
228
|
+
options for the backend.
|
|
229
|
+
|
|
230
|
+
Notes
|
|
231
|
+
-----
|
|
232
|
+
* If `decoderLib='ffpyplayer'`, audio playback is handled externally by
|
|
233
|
+
SDL2. This means that audio playback is not synchronized with frame
|
|
234
|
+
presentation in PsychoPy. However, playback will not begin until the audio
|
|
235
|
+
track starts playing.
|
|
236
|
+
* Do not access private attributes or methods of this class directly since
|
|
237
|
+
doing so is not thread-safe. Use the public methods provided by this class
|
|
238
|
+
to interact with the movie reader.
|
|
239
|
+
|
|
240
|
+
"""
|
|
241
|
+
def __init__(self,
|
|
242
|
+
filename,
|
|
243
|
+
decoderLib='ffpyplayer',
|
|
244
|
+
decoderOpts=None):
|
|
245
|
+
|
|
246
|
+
self._filename = filename
|
|
247
|
+
self._decoderLib = decoderLib
|
|
248
|
+
self._decoderOpts = {} if decoderOpts is None else decoderOpts
|
|
249
|
+
|
|
250
|
+
# thread for the reader
|
|
251
|
+
self._player = None # player interface object
|
|
252
|
+
|
|
253
|
+
# movie information
|
|
254
|
+
self._metadata = None # metadata object
|
|
255
|
+
|
|
256
|
+
# store decoded video segmenets in memory
|
|
257
|
+
self._frameStore = []
|
|
258
|
+
|
|
259
|
+
# callbacks for video events
|
|
260
|
+
self._streamEOFCallback = None
|
|
261
|
+
|
|
262
|
+
# video segment format
|
|
263
|
+
# [{'video': videoFrame, 'audio': audioFrame, 'pts': pts}, ...]
|
|
264
|
+
|
|
265
|
+
def __hash__(self):
|
|
266
|
+
"""Use the absolute file path as the hash value since we only allow one
|
|
267
|
+
instance per file.
|
|
268
|
+
"""
|
|
269
|
+
return hash(os.path.abspath(self._filename))
|
|
270
|
+
|
|
271
|
+
def _clearFrameQueue(self):
|
|
272
|
+
"""Clear the frame queue in a thread-safe way.
|
|
273
|
+
"""
|
|
274
|
+
with self._frameQueue.mutex:
|
|
275
|
+
self._frameQueue.queue.clear()
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
def decoderLib(self):
|
|
279
|
+
"""The library used to decode the movie (`str`).
|
|
280
|
+
|
|
281
|
+
"""
|
|
282
|
+
return self._decoderLib
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def frameSize(self):
|
|
286
|
+
"""The frame size of the movie in pixels (`tuple`).
|
|
287
|
+
|
|
288
|
+
This is only valid after calling `open()`. If not, the value is
|
|
289
|
+
`(-1, -1)`.
|
|
290
|
+
|
|
291
|
+
"""
|
|
292
|
+
return self._srcFrameSize
|
|
293
|
+
|
|
294
|
+
@property
|
|
295
|
+
def frameInterval(self):
|
|
296
|
+
"""The interval between frames in the movie in seconds (`float`).
|
|
297
|
+
|
|
298
|
+
This is only valid after calling `open()`. If not, the value is `-1`.
|
|
299
|
+
|
|
300
|
+
"""
|
|
301
|
+
return self._frameInterval
|
|
302
|
+
|
|
303
|
+
@property
|
|
304
|
+
def frameRate(self):
|
|
305
|
+
"""The frame rate of the movie in frames per second (`float`).
|
|
306
|
+
|
|
307
|
+
This is only valid after calling `open()`. If not, the value is `-1`.
|
|
308
|
+
|
|
309
|
+
"""
|
|
310
|
+
return self._frameRate
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
def duration(self):
|
|
314
|
+
"""The duration of the movie in seconds (`float`).
|
|
315
|
+
|
|
316
|
+
This is only valid after calling `open()`. If not, the value is `-1`.
|
|
317
|
+
|
|
318
|
+
"""
|
|
319
|
+
return self._duration
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def volume(self):
|
|
323
|
+
"""The volume level of the movie player (`float`).
|
|
324
|
+
|
|
325
|
+
This is only valid after calling `open()`. If not, the value is `0.0`.
|
|
326
|
+
|
|
327
|
+
"""
|
|
328
|
+
if self._decoderLib == 'ffpyplayer':
|
|
329
|
+
return self._getVolumeFFPyPlayer()
|
|
330
|
+
else:
|
|
331
|
+
raise NotImplementedError(
|
|
332
|
+
'Volume control is not implemented for this decoder library.')
|
|
333
|
+
|
|
334
|
+
@volume.setter
|
|
335
|
+
def volume(self, value):
|
|
336
|
+
"""Set the volume level of the movie player (`float`).
|
|
337
|
+
|
|
338
|
+
This is only valid after calling `open()`. If not, the value is `0.0`.
|
|
339
|
+
|
|
340
|
+
"""
|
|
341
|
+
if self._decoderLib == 'ffpyplayer':
|
|
342
|
+
self._setVolumeFFPyPlayer(value)
|
|
343
|
+
else:
|
|
344
|
+
raise NotImplementedError(
|
|
345
|
+
'Volume control is not implemented for this decoder library.')
|
|
346
|
+
|
|
347
|
+
@property
|
|
348
|
+
def filename(self):
|
|
349
|
+
"""The name (path) of the movie file (`str`).
|
|
350
|
+
|
|
351
|
+
This cannot be changed after the reader has been opened.
|
|
352
|
+
|
|
353
|
+
"""
|
|
354
|
+
return self._filename
|
|
355
|
+
|
|
356
|
+
def load(self, filename):
|
|
357
|
+
"""Load a movie file.
|
|
358
|
+
|
|
359
|
+
This is an alias for `setMovie()` to synchronize naming with other video
|
|
360
|
+
classes around PsychoPy.
|
|
361
|
+
|
|
362
|
+
Parameters
|
|
363
|
+
----------
|
|
364
|
+
filename : str
|
|
365
|
+
The name (path) of the file to read the movie from.
|
|
366
|
+
|
|
367
|
+
"""
|
|
368
|
+
self.setMovie(filename)
|
|
369
|
+
|
|
370
|
+
def setMovie(self, filename):
|
|
371
|
+
"""Set the movie file to read from and open it.
|
|
372
|
+
|
|
373
|
+
If there is a movie file currently open, it will be closed before
|
|
374
|
+
opening the new movie file. Playback will be reset to the beginning of
|
|
375
|
+
the movie.
|
|
376
|
+
|
|
377
|
+
Parameters
|
|
378
|
+
----------
|
|
379
|
+
filename : str
|
|
380
|
+
The name (path) of the file to read the movie from.
|
|
381
|
+
|
|
382
|
+
"""
|
|
383
|
+
if self.isOpen:
|
|
384
|
+
self.close()
|
|
385
|
+
|
|
386
|
+
# check if the file exists and is readable
|
|
387
|
+
if not os.path.isfile(filename):
|
|
388
|
+
raise IOError('Movie file does not exist: {}'.format(filename))
|
|
389
|
+
|
|
390
|
+
self._filename = filename
|
|
391
|
+
|
|
392
|
+
self.open()
|
|
393
|
+
|
|
394
|
+
def getMetadata(self):
|
|
395
|
+
"""Get metadata about the movie file.
|
|
396
|
+
|
|
397
|
+
This function returns a `MovieMetadata` object containing metadata
|
|
398
|
+
about the movie file. This includes information about the video and audio
|
|
399
|
+
tracks in the movie. Metadata is extracted from the movie file when the
|
|
400
|
+
movie reader is opened.
|
|
401
|
+
|
|
402
|
+
Returns
|
|
403
|
+
-------
|
|
404
|
+
MovieMetadata
|
|
405
|
+
Movie metadata object. If no movie is loaded, return a
|
|
406
|
+
`NULL_MOVIE_METADATA` object instead of `None`. At a minimum,
|
|
407
|
+
ensure that fields `duration`, `size`, and `frameRate` are
|
|
408
|
+
populated if a valid movie is loaded.
|
|
409
|
+
|
|
410
|
+
"""
|
|
411
|
+
if self._metadata is None:
|
|
412
|
+
return NULL_MOVIE_METADATA
|
|
413
|
+
# raise ValueError('Movie metadata not available. Movie not open.')
|
|
414
|
+
|
|
415
|
+
return self._metadata
|
|
416
|
+
|
|
417
|
+
# --------------------------------------------------------------------------
|
|
418
|
+
# Backend-specific reader interface methods
|
|
419
|
+
#
|
|
420
|
+
# These methods are used to interface with the backend specified by the
|
|
421
|
+
# `decoderLib` parameter. The methods are not intended to be used directly
|
|
422
|
+
# by users. In the future, these will likely be moved into separate classes
|
|
423
|
+
# for each backend. Methods are suffixed with the backend name and are
|
|
424
|
+
# selected based on the `decoderLib` parameter inside public methods which
|
|
425
|
+
# relate to them (e.g. `open()` will call `_openFFPyPlayer()` if the backend
|
|
426
|
+
# is `ffpyplayer`).
|
|
427
|
+
#
|
|
428
|
+
|
|
429
|
+
# --------------------------------------------------------------------------
|
|
430
|
+
# FFPyPlayer specific methods
|
|
431
|
+
#
|
|
432
|
+
|
|
433
|
+
def _openFFPyPlayer(self):
|
|
434
|
+
"""Open a movie reader using FFPyPlayer.
|
|
435
|
+
|
|
436
|
+
This function opens the movie file and extracts metadata about the movie
|
|
437
|
+
file. Metadata will be accessible via the `getMetadata()` method.
|
|
438
|
+
|
|
439
|
+
"""
|
|
440
|
+
# import in the class too avoid hard dependency on ffpyplayer
|
|
441
|
+
try:
|
|
442
|
+
from ffpyplayer.player import MediaPlayer
|
|
443
|
+
except ImportError:
|
|
444
|
+
raise ImportError(
|
|
445
|
+
'The `ffpyplayer` library is required to read movie files with '
|
|
446
|
+
'`decoderLib=ffpyplayer`.')
|
|
447
|
+
|
|
448
|
+
logging.info("Opening movie file: {}".format(self._filename))
|
|
449
|
+
|
|
450
|
+
# Using sync to audio since it allows us to poll the player for frames
|
|
451
|
+
# any number of frames and allows the audio to be played at the correct
|
|
452
|
+
# rate if using the SDL2 interface
|
|
453
|
+
syncMode = 'audio'
|
|
454
|
+
|
|
455
|
+
# default options
|
|
456
|
+
defaultFFOpts = {
|
|
457
|
+
'paused': True,
|
|
458
|
+
'sync': syncMode, # always use audio sync
|
|
459
|
+
'an': False,
|
|
460
|
+
'volume': 0.0, # mute
|
|
461
|
+
'loop': 1, # number of replays (0=infinite, 1=once, 2=twice, etc.)
|
|
462
|
+
'infbuf': True
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
# merge user settings with defaults, user settings take precedence
|
|
466
|
+
defaultFFOpts.update(self._decoderOpts)
|
|
467
|
+
self._decoderOpts = defaultFFOpts
|
|
468
|
+
|
|
469
|
+
# create media player interface
|
|
470
|
+
self._player = MediaPlayer(
|
|
471
|
+
self._filename,
|
|
472
|
+
ff_opts=self._decoderOpts)
|
|
473
|
+
|
|
474
|
+
self._player.set_mute(True) # mute the player first
|
|
475
|
+
self._player.set_pause(False)
|
|
476
|
+
|
|
477
|
+
# Get metadata and 'warm-up' the player to ensure it is responsive
|
|
478
|
+
# before we start decoding frames.
|
|
479
|
+
|
|
480
|
+
# wait for valid metadata to be available
|
|
481
|
+
logging.debug("Waiting for movie metadata...")
|
|
482
|
+
startTime = time.time()
|
|
483
|
+
while time.time() - startTime < defaultTimeout: # 5 second timeout
|
|
484
|
+
movieMetadata = self._player.get_metadata()
|
|
485
|
+
# keep calling until we get a valid frame size
|
|
486
|
+
if movieMetadata['src_vid_size'] != (0, 0):
|
|
487
|
+
break
|
|
488
|
+
else:
|
|
489
|
+
raise RuntimeError(
|
|
490
|
+
'FFPyPlayer failed to extract metadata from the movie. Check '
|
|
491
|
+
'the movie file and decoder options.')
|
|
492
|
+
|
|
493
|
+
# warmup, takes a while before the video starts playing
|
|
494
|
+
startTime = time.time()
|
|
495
|
+
while time.time() - startTime < defaultTimeout: # 5 second timeout
|
|
496
|
+
frame, _ = self._player.get_frame()
|
|
497
|
+
if frame != None:
|
|
498
|
+
break
|
|
499
|
+
else:
|
|
500
|
+
raise RuntimeError(
|
|
501
|
+
'FFPyPlayer failed to start decoding the movie. Check the '
|
|
502
|
+
'movie file and decoder options.')
|
|
503
|
+
|
|
504
|
+
# go back to first frame
|
|
505
|
+
self._player.set_pause(True) # pause the player again
|
|
506
|
+
self._player.set_mute(False) # unmute the player
|
|
507
|
+
|
|
508
|
+
# seek to the beginning of the movie
|
|
509
|
+
self._player.seek(0.0, relative=False)
|
|
510
|
+
|
|
511
|
+
# compute frame rate and interval
|
|
512
|
+
numer, denom = movieMetadata['frame_rate']
|
|
513
|
+
frameRate = numer / denom
|
|
514
|
+
self._frameInterval = 1.0 / frameRate
|
|
515
|
+
|
|
516
|
+
# populate the metadata object with the movie metadata we got
|
|
517
|
+
self._metadata = MovieMetadata(
|
|
518
|
+
self._filename,
|
|
519
|
+
movieMetadata['src_vid_size'],
|
|
520
|
+
frameRate,
|
|
521
|
+
movieMetadata['duration'],
|
|
522
|
+
movieMetadata['src_pix_fmt'])
|
|
523
|
+
|
|
524
|
+
logging.debug("Movie metadata: {}".format(movieMetadata))
|
|
525
|
+
|
|
526
|
+
def _seekFFPyPlayer(self, reqPTS):
|
|
527
|
+
"""FFPyPlayer specific seek routine.
|
|
528
|
+
|
|
529
|
+
This is called by `seek()` when the `ffpyplayer` backend is in use.
|
|
530
|
+
Video decoding will be paused after calling this function.
|
|
531
|
+
|
|
532
|
+
Parameters
|
|
533
|
+
----------
|
|
534
|
+
reqPTS : float
|
|
535
|
+
The presentation timestamp (PTS) to seek to in seconds.
|
|
536
|
+
|
|
537
|
+
Returns
|
|
538
|
+
-------
|
|
539
|
+
float
|
|
540
|
+
The presentation timestamp (PTS) of the frame we landed on in
|
|
541
|
+
seconds.
|
|
542
|
+
|
|
543
|
+
"""
|
|
544
|
+
reqPTS = min(max(0.0, reqPTS), self._metadata.duration)
|
|
545
|
+
|
|
546
|
+
if self._player is None:
|
|
547
|
+
return
|
|
548
|
+
|
|
549
|
+
# clear the frame store
|
|
550
|
+
self._cleanUpFrameStore()
|
|
551
|
+
|
|
552
|
+
# seek to the desired PTS
|
|
553
|
+
self._player.seek(
|
|
554
|
+
reqPTS,
|
|
555
|
+
relative=False,
|
|
556
|
+
seek_by_bytes=False,
|
|
557
|
+
accurate=True)
|
|
558
|
+
|
|
559
|
+
return self._player.get_pts()
|
|
560
|
+
|
|
561
|
+
def _convertFrameToRGBFFPyPlayer(self, frame):
|
|
562
|
+
"""Convert a frame to RGB format.
|
|
563
|
+
|
|
564
|
+
This function converts a frame to RGB format. The frame is returned as
|
|
565
|
+
a Numpy array. The resulting array will be in the correct format to
|
|
566
|
+
upload to OpenGL as a texture.
|
|
567
|
+
|
|
568
|
+
Parameters
|
|
569
|
+
----------
|
|
570
|
+
frame : FFPyPlayer frame
|
|
571
|
+
The frame to convert.
|
|
572
|
+
|
|
573
|
+
Returns
|
|
574
|
+
-------
|
|
575
|
+
numpy.ndarray
|
|
576
|
+
The converted frame in RGB format.
|
|
577
|
+
|
|
578
|
+
"""
|
|
579
|
+
from ffpyplayer.pic import SWScale
|
|
580
|
+
|
|
581
|
+
if frame.get_pixel_format() == 'rgb24': # already converted
|
|
582
|
+
return frame
|
|
583
|
+
|
|
584
|
+
rgbImg = SWScale(
|
|
585
|
+
self._metadata.size[0], self._metadata.size[1], # width, height
|
|
586
|
+
frame.get_pixel_format(),
|
|
587
|
+
ofmt='rgb24').scale(frame)
|
|
588
|
+
|
|
589
|
+
return rgbImg
|
|
590
|
+
|
|
591
|
+
def _bufferFramesFFPyPlayer(self, start=0.0, end=None, units='seconds'):
|
|
592
|
+
"""Buffer frames from the movie file using FFPyPlayer.
|
|
593
|
+
|
|
594
|
+
Parameters
|
|
595
|
+
----------
|
|
596
|
+
start : float
|
|
597
|
+
The start time in seconds to buffer frames from.
|
|
598
|
+
end : float or int
|
|
599
|
+
The end time in seconds to buffer frames to. If `None`, the end
|
|
600
|
+
time is set to the duration of the movie. If `int`, the end time is
|
|
601
|
+
interpreted as a frame index.
|
|
602
|
+
units : str
|
|
603
|
+
The units to use for the start and end times. This can be 'seconds'
|
|
604
|
+
or 'frames'. If 'frames', the start and end times are interpreted as
|
|
605
|
+
frame indices.
|
|
606
|
+
|
|
607
|
+
"""
|
|
608
|
+
if self._player is None:
|
|
609
|
+
return
|
|
610
|
+
|
|
611
|
+
# check if we have a valid start time
|
|
612
|
+
if start < 0.0:
|
|
613
|
+
raise ValueError('Start time must be greater than or equal to 0.0.')
|
|
614
|
+
|
|
615
|
+
# check if we have a valid end time
|
|
616
|
+
if end is None:
|
|
617
|
+
end = self._metadata.duration
|
|
618
|
+
elif end < 0.0:
|
|
619
|
+
raise ValueError('End time must be greater than or equal to 0.0.')
|
|
620
|
+
|
|
621
|
+
# convert the start and end times to frame indices
|
|
622
|
+
if units == 'frames':
|
|
623
|
+
start = self._frameIndexToTimestamp(start)
|
|
624
|
+
end = self._frameIndexToTimestamp(end)
|
|
625
|
+
|
|
626
|
+
# seek to the start time
|
|
627
|
+
self._seekFFPyPlayer(start)
|
|
628
|
+
|
|
629
|
+
# buffer frames from the movie file
|
|
630
|
+
while True:
|
|
631
|
+
frame, status = self._player.get_frame()
|
|
632
|
+
|
|
633
|
+
if status == 'eof':
|
|
634
|
+
break
|
|
635
|
+
|
|
636
|
+
if frame is None:
|
|
637
|
+
break
|
|
638
|
+
|
|
639
|
+
img, curPts = frame
|
|
640
|
+
if curPts >= end:
|
|
641
|
+
break
|
|
642
|
+
if curPts >= start:
|
|
643
|
+
# convert the frame to RGB format
|
|
644
|
+
rgbImg = self._convertFrameToRGB(img)
|
|
645
|
+
self._frameStore.append((rgbImg, curPts, status))
|
|
646
|
+
|
|
647
|
+
def _getFrameFFPyPlayer(self, reqPTS=0.0):
|
|
648
|
+
"""Get a frame from the movie file using FFPyPlayer.
|
|
649
|
+
|
|
650
|
+
This method gets the desired frame from the movie file. If it has not
|
|
651
|
+
been decoded yet, this function will ensure the frame is decoded and
|
|
652
|
+
made available.
|
|
653
|
+
|
|
654
|
+
Parameters
|
|
655
|
+
----------
|
|
656
|
+
reqPTS : float
|
|
657
|
+
The presentation timestamp (PTS) of the frame to get in seconds.
|
|
658
|
+
This hints the reader to which frame to decode and return.
|
|
659
|
+
|
|
660
|
+
Returns
|
|
661
|
+
-------
|
|
662
|
+
tuple
|
|
663
|
+
Video data (`ndarray`), presentation timestamp (PTS), and status.
|
|
664
|
+
The status value may be backend specific.
|
|
665
|
+
|
|
666
|
+
"""
|
|
667
|
+
# check if we have a player object, return None if not
|
|
668
|
+
if self._player is None:
|
|
669
|
+
return None
|
|
670
|
+
# raise ValueError('Movie reader is not open. Cannot grab frame.')
|
|
671
|
+
|
|
672
|
+
# normalzie the PTS to be between 0 and the duration of the movie
|
|
673
|
+
reqPTS = min(max(0.0, reqPTS),
|
|
674
|
+
self._metadata.duration + self._metadata.frameInterval)
|
|
675
|
+
|
|
676
|
+
# check if we have the frame in the store
|
|
677
|
+
frame = self._getFrameFromStore(reqPTS)
|
|
678
|
+
if frame is not None:
|
|
679
|
+
return frame
|
|
680
|
+
|
|
681
|
+
while 1: # keep getting frames until we reach the desired PTS
|
|
682
|
+
frame, status = self._player.get_frame()
|
|
683
|
+
|
|
684
|
+
if status == 'eof':
|
|
685
|
+
if self._streamEOFCallback is not None:
|
|
686
|
+
self._streamEOFCallback()
|
|
687
|
+
self._cleanUpFrameStore()
|
|
688
|
+
break
|
|
689
|
+
elif status == 'paused':
|
|
690
|
+
break
|
|
691
|
+
|
|
692
|
+
if frame is None:
|
|
693
|
+
break
|
|
694
|
+
|
|
695
|
+
img, curPts = frame # extract frame information
|
|
696
|
+
|
|
697
|
+
# if we have gotten the frame we are looking for, return it
|
|
698
|
+
if curPts + self._metadata.frameInterval >= reqPTS:
|
|
699
|
+
self._frameStore.append(
|
|
700
|
+
(self._convertFrameToRGBFFPyPlayer(img), curPts, status))
|
|
701
|
+
break
|
|
702
|
+
|
|
703
|
+
toReturn = self._getFrameFromStore(reqPTS)
|
|
704
|
+
|
|
705
|
+
self._cleanUpFrameStore(reqPTS) # clean up the frame store
|
|
706
|
+
|
|
707
|
+
return toReturn
|
|
708
|
+
|
|
709
|
+
# --------------------------------------------------------------------------
|
|
710
|
+
# File I/O methods
|
|
711
|
+
#
|
|
712
|
+
|
|
713
|
+
def open(self):
|
|
714
|
+
"""Open the movie file for reading.
|
|
715
|
+
|
|
716
|
+
Calling this will open the movie file and extract metadata to determine
|
|
717
|
+
the frame rate, size, and duration of the movie.
|
|
718
|
+
|
|
719
|
+
"""
|
|
720
|
+
logging.debug("Using decoder library: {}".format(self._decoderLib))
|
|
721
|
+
if self._decoderLib == 'ffpyplayer':
|
|
722
|
+
self._openFFPyPlayer()
|
|
723
|
+
elif self._decoderLib == 'opencv':
|
|
724
|
+
self._openOpenCV()
|
|
725
|
+
else:
|
|
726
|
+
raise ValueError(
|
|
727
|
+
'Unknown decoder library: {}'.format(self._decoderLib))
|
|
728
|
+
|
|
729
|
+
# register the reader with the global list of open movie readers
|
|
730
|
+
if self in _openMovieReaders:
|
|
731
|
+
raise RuntimeError(
|
|
732
|
+
'Movie reader already open for file: {}'.format(self._filename))
|
|
733
|
+
|
|
734
|
+
self._playbackStatus = NOT_STARTED # reset playback status
|
|
735
|
+
|
|
736
|
+
_openMovieReaders.add(self)
|
|
737
|
+
|
|
738
|
+
@property
|
|
739
|
+
def isOpen(self):
|
|
740
|
+
"""Whether the movie file is open (`bool`).
|
|
741
|
+
|
|
742
|
+
If `True`, the movie file is open and frames can be read from it. If
|
|
743
|
+
`False`, the movie file is closed and no more frames can be read from
|
|
744
|
+
it.
|
|
745
|
+
|
|
746
|
+
"""
|
|
747
|
+
return self in _openMovieReaders
|
|
748
|
+
|
|
749
|
+
def close(self):
|
|
750
|
+
"""Close the movie file or stream.
|
|
751
|
+
|
|
752
|
+
This will unload the movie file and free any resources associated with
|
|
753
|
+
it.
|
|
754
|
+
|
|
755
|
+
"""
|
|
756
|
+
self._freePlayer() # free the player
|
|
757
|
+
|
|
758
|
+
# clear frames from store
|
|
759
|
+
self._cleanUpFrameStore()
|
|
760
|
+
|
|
761
|
+
self._metadata = None # clear metadata
|
|
762
|
+
|
|
763
|
+
# remove the reader from the global list of open movie readers
|
|
764
|
+
if self in _openMovieReaders:
|
|
765
|
+
_openMovieReaders.remove(self)
|
|
766
|
+
|
|
767
|
+
def _freePlayer(self):
|
|
768
|
+
"""Clean up the player.
|
|
769
|
+
|
|
770
|
+
This function closes the player and clears the player object. Do not
|
|
771
|
+
call this method directly while the player is still in use.
|
|
772
|
+
|
|
773
|
+
"""
|
|
774
|
+
if self._player is None:
|
|
775
|
+
return
|
|
776
|
+
|
|
777
|
+
if self._decoderLib == 'ffpyplayer':
|
|
778
|
+
self._player.set_mute(True) # mute the player
|
|
779
|
+
self._player.set_pause(True) # pause the player
|
|
780
|
+
self._player.close_player()
|
|
781
|
+
|
|
782
|
+
self._player = None
|
|
783
|
+
|
|
784
|
+
def _cleanUpFrameStore(self, keepAfterPTS=None):
|
|
785
|
+
"""Clean up the frame store.
|
|
786
|
+
|
|
787
|
+
This function is called when the movie reader is closed. It clears the
|
|
788
|
+
frame queue and the video segment buffer.
|
|
789
|
+
|
|
790
|
+
Parameters
|
|
791
|
+
----------
|
|
792
|
+
keepAfterPTS : float
|
|
793
|
+
The presentation timestamp (PTS) to keep in the frame store. All
|
|
794
|
+
frames before this PTS will be removed from the frame store. If
|
|
795
|
+
`None`, all frames will be removed from the frame store.
|
|
796
|
+
|
|
797
|
+
"""
|
|
798
|
+
if keepAfterPTS is None:
|
|
799
|
+
self._frameStore.clear()
|
|
800
|
+
return
|
|
801
|
+
|
|
802
|
+
for i, frame in enumerate(self._frameStore):
|
|
803
|
+
if frame[1] >= keepAfterPTS - self._metadata.frameInterval:
|
|
804
|
+
self._frameStore = self._frameStore[i:]
|
|
805
|
+
break
|
|
806
|
+
|
|
807
|
+
def _getFrameFromStore(self, reqPTS):
|
|
808
|
+
"""Get a frame from the store.
|
|
809
|
+
|
|
810
|
+
This function gets a frame from the store. The frame is returned as
|
|
811
|
+
a Numpy array. The resulting array will be in the correct format to
|
|
812
|
+
upload to OpenGL as a texture.
|
|
813
|
+
|
|
814
|
+
Parameters
|
|
815
|
+
----------
|
|
816
|
+
reqPTS : float
|
|
817
|
+
The presentation timestamp (PTS) of the frame to get in seconds.
|
|
818
|
+
|
|
819
|
+
Returns
|
|
820
|
+
-------
|
|
821
|
+
numpy.ndarray
|
|
822
|
+
The converted frame in RGB format.
|
|
823
|
+
|
|
824
|
+
"""
|
|
825
|
+
if self._frameStore is None:
|
|
826
|
+
return None
|
|
827
|
+
|
|
828
|
+
for img, pts, status in self._frameStore:
|
|
829
|
+
if pts <= reqPTS < pts + self._metadata.frameInterval:
|
|
830
|
+
return (img, pts, status)
|
|
831
|
+
|
|
832
|
+
return None # no frame found
|
|
833
|
+
|
|
834
|
+
def setStreamEOFCallback(self, callback):
|
|
835
|
+
"""Set a callback function to be called when the end of the movie is
|
|
836
|
+
reached.
|
|
837
|
+
|
|
838
|
+
Parameters
|
|
839
|
+
----------
|
|
840
|
+
callback : callable or None
|
|
841
|
+
The callback function to call when the end of the movie is reached.
|
|
842
|
+
The function should take no arguments. If `None`, no callback
|
|
843
|
+
function will be called.
|
|
844
|
+
|
|
845
|
+
"""
|
|
846
|
+
if callback is None:
|
|
847
|
+
self._streamEOFCallback = None
|
|
848
|
+
return
|
|
849
|
+
|
|
850
|
+
if not callable(callback):
|
|
851
|
+
raise ValueError('Callback must be a callable function.')
|
|
852
|
+
|
|
853
|
+
self._streamEOFCallback = callback
|
|
854
|
+
|
|
855
|
+
def _frameIndexToTimestamp(self, frameIndex):
|
|
856
|
+
"""Convert a frame index to a presentation timestamp (PTS).
|
|
857
|
+
|
|
858
|
+
This function converts a frame index to a presentation timestamp (PTS)
|
|
859
|
+
in seconds. The frame index is the index of the frame in the movie file.
|
|
860
|
+
|
|
861
|
+
Parameters
|
|
862
|
+
----------
|
|
863
|
+
frameIndex : int
|
|
864
|
+
The index of the frame in the movie file.
|
|
865
|
+
|
|
866
|
+
Returns
|
|
867
|
+
-------
|
|
868
|
+
float
|
|
869
|
+
The presentation timestamp (PTS) of the frame in seconds.
|
|
870
|
+
|
|
871
|
+
"""
|
|
872
|
+
return frameIndex * self._metadata.frameInterval
|
|
873
|
+
|
|
874
|
+
def _timestampToFrameIndex(self, pts):
|
|
875
|
+
"""Convert a presentation timestamp (PTS) to a frame index.
|
|
876
|
+
|
|
877
|
+
This function converts a presentation timestamp (PTS) in seconds to a
|
|
878
|
+
frame index. The frame index is the index of the frame in the movie
|
|
879
|
+
file.
|
|
880
|
+
|
|
881
|
+
Parameters
|
|
882
|
+
----------
|
|
883
|
+
pts : float
|
|
884
|
+
The presentation timestamp (PTS) of the frame in seconds.
|
|
885
|
+
|
|
886
|
+
Returns
|
|
887
|
+
-------
|
|
888
|
+
int
|
|
889
|
+
The index of the frame in the movie file.
|
|
890
|
+
|
|
891
|
+
"""
|
|
892
|
+
return int(pts / self._metadata.frameInterval)
|
|
893
|
+
|
|
894
|
+
def _restartFFPyPlayer(self):
|
|
895
|
+
"""Restart the FFPyPlayer decoder.
|
|
896
|
+
|
|
897
|
+
This function restarts the FFPyPlayer decoder. This is useful if the
|
|
898
|
+
decoder has stopped working or if the movie file has changed.
|
|
899
|
+
|
|
900
|
+
"""
|
|
901
|
+
self._seekFFPyPlayer(0.0) # seek to the beginning of the movie
|
|
902
|
+
|
|
903
|
+
def pause(self, state=True):
|
|
904
|
+
"""Pause the movie reader.
|
|
905
|
+
|
|
906
|
+
This function pauses the movie reader. If the movie reader is already
|
|
907
|
+
paused, this function does nothing. If the movie reader is not open,
|
|
908
|
+
this function raises a `ValueError`.
|
|
909
|
+
|
|
910
|
+
Parameters
|
|
911
|
+
----------
|
|
912
|
+
state : bool
|
|
913
|
+
If `True`, the movie reader is paused. If `False`, the movie reader
|
|
914
|
+
is not paused. The default is `True`.
|
|
915
|
+
|
|
916
|
+
"""
|
|
917
|
+
if self._player is None:
|
|
918
|
+
return
|
|
919
|
+
|
|
920
|
+
self._player.set_pause(bool(state))
|
|
921
|
+
|
|
922
|
+
def seek(self, pts):
|
|
923
|
+
"""Seek to a specific presentation timestamp (PTS) in the movie.
|
|
924
|
+
|
|
925
|
+
This function seeks to a specific presentation timestamp (PTS) in the
|
|
926
|
+
movie file. The decoder will begin decoding frames from the specified
|
|
927
|
+
PTS. If the PTS is outside the range of the movie, the decoder will seek
|
|
928
|
+
to the end of the movie.
|
|
929
|
+
|
|
930
|
+
Seeking blocks the main thread until the desired frame is found.
|
|
931
|
+
|
|
932
|
+
Parameters
|
|
933
|
+
----------
|
|
934
|
+
pts : float
|
|
935
|
+
The presentation timestamp (PTS) to seek to in seconds.
|
|
936
|
+
|
|
937
|
+
"""
|
|
938
|
+
if self._decoderLib == 'ffpyplayer':
|
|
939
|
+
self._seekFFPyPlayer(pts)
|
|
940
|
+
elif self._decoderLib == 'opencv': # rough in support for opencv
|
|
941
|
+
raise NotImplementedError(
|
|
942
|
+
'The `opencv` library is not supported for movie reading.')
|
|
943
|
+
else:
|
|
944
|
+
raise ValueError(
|
|
945
|
+
'Unknown decoder library: {}'.format(self._decoderLib))
|
|
946
|
+
|
|
947
|
+
def mute(self, state=True):
|
|
948
|
+
"""Mute the movie reader.
|
|
949
|
+
|
|
950
|
+
This function mutes the movie reader. If the movie reader is already
|
|
951
|
+
muted, this function does nothing. If the movie reader is not open,
|
|
952
|
+
this function raises a `ValueError`.
|
|
953
|
+
|
|
954
|
+
Parameters
|
|
955
|
+
----------
|
|
956
|
+
state : bool
|
|
957
|
+
If `True`, the movie reader is muted. If `False`, the movie reader
|
|
958
|
+
is not muted. The default is `True`.
|
|
959
|
+
|
|
960
|
+
"""
|
|
961
|
+
if self._player is None:
|
|
962
|
+
return
|
|
963
|
+
|
|
964
|
+
self._player.set_mute(bool(state))
|
|
965
|
+
|
|
966
|
+
@property
|
|
967
|
+
def memoryUsed(self):
|
|
968
|
+
"""Get the amount of memory used for cache.
|
|
969
|
+
|
|
970
|
+
Returns
|
|
971
|
+
-------
|
|
972
|
+
int
|
|
973
|
+
The amount of memory used by the movie reader in bytes.
|
|
974
|
+
|
|
975
|
+
"""
|
|
976
|
+
# sum of bytes used by video segments
|
|
977
|
+
totalFramesDecoded = len(self._frameStore)
|
|
978
|
+
pixelSize = 3 if 'rgb' in self._srcPixelFormat else 4
|
|
979
|
+
pixelCount = self._srcFrameSize[0] * self._srcFrameSize[1]
|
|
980
|
+
|
|
981
|
+
return totalFramesDecoded * pixelCount * pixelSize
|
|
982
|
+
|
|
983
|
+
def getFrame(self, pts=0.0):
|
|
984
|
+
"""Get a frame from the movie file at the specified presentation
|
|
985
|
+
timestamp.
|
|
986
|
+
|
|
987
|
+
Parameters
|
|
988
|
+
----------
|
|
989
|
+
pts : float or None
|
|
990
|
+
The presentation timestamp (PTS) of the frame to get in seconds.
|
|
991
|
+
Timestamps can be as precise as six decimal places.
|
|
992
|
+
dropFrame : bool
|
|
993
|
+
If `True`, the frame is dropped if it is not available, and the
|
|
994
|
+
most recent frame will be returned immediately. If `False`, the
|
|
995
|
+
function will block until the desired frame is returned.
|
|
996
|
+
|
|
997
|
+
Returns
|
|
998
|
+
-------
|
|
999
|
+
tuple
|
|
1000
|
+
Video data.
|
|
1001
|
+
|
|
1002
|
+
"""
|
|
1003
|
+
if self._decoderLib == 'ffpyplayer':
|
|
1004
|
+
return self._getFrameFFPyPlayer(pts)
|
|
1005
|
+
|
|
1006
|
+
def getSubtitle(self):
|
|
1007
|
+
"""Get the subtitle from the movie file.
|
|
1008
|
+
|
|
1009
|
+
This function returns the subtitle from the movie file. The subtitle is
|
|
1010
|
+
returned as a string. If no subtitle is available, this function returns
|
|
1011
|
+
`None`.
|
|
1012
|
+
|
|
1013
|
+
Returns
|
|
1014
|
+
-------
|
|
1015
|
+
str or None
|
|
1016
|
+
The subtitle from the movie file. If no subtitle is available, this
|
|
1017
|
+
function returns `None`.
|
|
1018
|
+
|
|
1019
|
+
"""
|
|
1020
|
+
if self._player is None:
|
|
1021
|
+
return ''
|
|
1022
|
+
#raise ValueError('Movie reader is not open. Cannot get subtitle.')
|
|
1023
|
+
|
|
1024
|
+
return ''
|
|
1025
|
+
|
|
1026
|
+
def _getVolumeFFPyPlayer(self):
|
|
1027
|
+
"""Get the volume of the movie player using the ffpyplayer library.
|
|
1028
|
+
|
|
1029
|
+
Returns
|
|
1030
|
+
-------
|
|
1031
|
+
float
|
|
1032
|
+
The volume level of the movie player, between 0.0 (mute) and 1.0 (full volume).
|
|
1033
|
+
"""
|
|
1034
|
+
if self._player is None:
|
|
1035
|
+
return 0.0
|
|
1036
|
+
|
|
1037
|
+
return self._player.get_volume()
|
|
1038
|
+
|
|
1039
|
+
def _setVolumeFFPyPlayer(self, volume):
|
|
1040
|
+
"""Set the volume of the movie player using the ffpyplayer library.
|
|
1041
|
+
|
|
1042
|
+
Parameters
|
|
1043
|
+
----------
|
|
1044
|
+
volume : float
|
|
1045
|
+
The volume level to set, between 0.0 (mute) and 1.0 (full volume).
|
|
1046
|
+
|
|
1047
|
+
"""
|
|
1048
|
+
if self._player is None:
|
|
1049
|
+
return
|
|
1050
|
+
|
|
1051
|
+
self._player.set_volume(volume)
|
|
1052
|
+
|
|
1053
|
+
def setVolume(self, volume):
|
|
1054
|
+
"""Set the volume of the movie player.
|
|
1055
|
+
|
|
1056
|
+
Parameters
|
|
1057
|
+
----------
|
|
1058
|
+
volume : float
|
|
1059
|
+
The volume level to set, between 0.0 (mute) and 1.0 (full volume).
|
|
1060
|
+
|
|
1061
|
+
"""
|
|
1062
|
+
if self._player is None:
|
|
1063
|
+
return
|
|
1064
|
+
|
|
1065
|
+
volume = min(1.0, max(0.0, float(volume)))
|
|
1066
|
+
|
|
1067
|
+
logging.debug("Setting movie volume to: {}".format(volume))
|
|
1068
|
+
|
|
1069
|
+
if self._decoderLib == 'ffpyplayer':
|
|
1070
|
+
self._setVolumeFFPyPlayer(volume)
|
|
1071
|
+
else:
|
|
1072
|
+
raise NotImplementedError(
|
|
1073
|
+
'Volume control is not implemented for this decoder library.')
|
|
1074
|
+
|
|
1075
|
+
def __del__(self):
|
|
1076
|
+
"""Close the movie file when the object is deleted.
|
|
1077
|
+
"""
|
|
1078
|
+
self.close()
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
class MovieStim(BaseVisualStim, DraggingMixin, ColorMixin, ContainerMixin):
|
|
1082
|
+
"""Class for presenting movie clips as stimuli.
|
|
1083
|
+
|
|
1084
|
+
This class is used to present movie clips loaded from file as stimuli in
|
|
1085
|
+
PsychoPy. Movies will play at the their native frame rate regardless of the
|
|
1086
|
+
refresh rate of the display.
|
|
1087
|
+
|
|
1088
|
+
Parameters
|
|
1089
|
+
----------
|
|
1090
|
+
win : :class:`~psychopy.visual.Window`
|
|
1091
|
+
Window the video is being drawn to.
|
|
1092
|
+
filename : str
|
|
1093
|
+
Name of the file or stream URL to play. If an empty string, no file will
|
|
1094
|
+
be loaded on initialization but can be set later.
|
|
1095
|
+
movieLib : str or None
|
|
1096
|
+
Library to use for video decoding. By default, the 'preferred' library
|
|
1097
|
+
by PsychoPy developers is used. Default is `'ffpyplayer'`. An alert is
|
|
1098
|
+
raised if you are not using the preferred player.
|
|
1099
|
+
audioLib : str or None
|
|
1100
|
+
Library to use for audio decoding. If `movieLib` is `'ffpyplayer'`
|
|
1101
|
+
then this must be `'sdl2'` for audio playback. If `None`, the
|
|
1102
|
+
default audio library for the `movieLib` will be used (this will be
|
|
1103
|
+
`'sdl2'` for `movieLib='ffpyplayer'`).
|
|
1104
|
+
units : str
|
|
1105
|
+
Units to use when sizing the video frame on the window, affects how
|
|
1106
|
+
`size` is interpreted.
|
|
1107
|
+
size : ArrayLike or None
|
|
1108
|
+
Size of the video frame on the window in `units`. If `None`, the native
|
|
1109
|
+
size of the video will be used.
|
|
1110
|
+
draggable : bool
|
|
1111
|
+
Can this stimulus be dragged by a mouse click?
|
|
1112
|
+
flipVert : bool
|
|
1113
|
+
If `True` then the movie will be top-bottom flipped.
|
|
1114
|
+
flipHoriz : bool
|
|
1115
|
+
If `True` then the movie will be right-left flipped.
|
|
1116
|
+
volume : int or float
|
|
1117
|
+
If specifying an `int` the nominal level is 100, and 0 is silence. If a
|
|
1118
|
+
`float`, values between 0 and 1 may be used.
|
|
1119
|
+
loop : bool
|
|
1120
|
+
Whether to start the movie over from the beginning if draw is called and
|
|
1121
|
+
the movie is done. Default is `False`.
|
|
1122
|
+
autoStart : bool
|
|
1123
|
+
Automatically begin playback of the video when `flip()` is called.
|
|
1124
|
+
|
|
1125
|
+
Notes
|
|
1126
|
+
-----
|
|
1127
|
+
* Precise audio and visual syncronization is not guaranteed when using
|
|
1128
|
+
the `ffpyplayer` library for video playback. If you require precise
|
|
1129
|
+
synchronization, consider extracting the audio from the movie file and
|
|
1130
|
+
playing it separately using the `sound.Sound` class instead.
|
|
1131
|
+
|
|
1132
|
+
"""
|
|
1133
|
+
def __init__(self,
|
|
1134
|
+
win,
|
|
1135
|
+
filename="",
|
|
1136
|
+
movieLib=u'ffpyplayer',
|
|
1137
|
+
audioLib=None,
|
|
1138
|
+
units='pix',
|
|
1139
|
+
size=None,
|
|
1140
|
+
pos=(0.0, 0.0),
|
|
1141
|
+
ori=0.0,
|
|
1142
|
+
anchor="center",
|
|
1143
|
+
draggable=False,
|
|
1144
|
+
flipVert=False,
|
|
1145
|
+
flipHoriz=False,
|
|
1146
|
+
color=(1.0, 1.0, 1.0), # remove?
|
|
1147
|
+
colorSpace='rgb',
|
|
1148
|
+
opacity=1.0,
|
|
1149
|
+
contrast=1,
|
|
1150
|
+
volume=1.0,
|
|
1151
|
+
name='',
|
|
1152
|
+
loop=False,
|
|
1153
|
+
autoLog=True,
|
|
1154
|
+
depth=0.0,
|
|
1155
|
+
noAudio=False,
|
|
1156
|
+
interpolate=True,
|
|
1157
|
+
autoStart=True):
|
|
1158
|
+
|
|
1159
|
+
# what local vars are defined (these are the init params) for use
|
|
1160
|
+
self._initParams = dir()
|
|
1161
|
+
self._initParams.remove('self')
|
|
1162
|
+
|
|
1163
|
+
super(MovieStim, self).__init__(
|
|
1164
|
+
win, units=units, name=name, autoLog=False)
|
|
1165
|
+
|
|
1166
|
+
# drawing stuff
|
|
1167
|
+
self.draggable = draggable
|
|
1168
|
+
self.flipVert = flipVert
|
|
1169
|
+
self.flipHoriz = flipHoriz
|
|
1170
|
+
self.pos = pos
|
|
1171
|
+
self.ori = ori
|
|
1172
|
+
self.size = size
|
|
1173
|
+
self.depth = depth
|
|
1174
|
+
self.anchor = anchor
|
|
1175
|
+
self.colorSpace = colorSpace
|
|
1176
|
+
self.color = color
|
|
1177
|
+
self.opacity = opacity
|
|
1178
|
+
|
|
1179
|
+
# playback stuff
|
|
1180
|
+
self._movieLib = movieLib
|
|
1181
|
+
self._decoderOpts = {}
|
|
1182
|
+
self._player = None # player interface object
|
|
1183
|
+
self._filename = pathToString(filename)
|
|
1184
|
+
self._volume = volume
|
|
1185
|
+
self._noAudio = noAudio # cannot be changed
|
|
1186
|
+
self._loop = loop
|
|
1187
|
+
self._loopCount = 0 # number of times the movie has looped
|
|
1188
|
+
self._recentFrame = None
|
|
1189
|
+
self._autoStart = autoStart
|
|
1190
|
+
self._isLoaded = False
|
|
1191
|
+
self._pts = 0.0
|
|
1192
|
+
self._movieTime = 0.0 # current movie position in seconds
|
|
1193
|
+
self._lastFrameAbsTime = -1.0 # absolute time of the last frame
|
|
1194
|
+
|
|
1195
|
+
# internal status flags for keeping track of the playback state
|
|
1196
|
+
self._playbackStatus = NOT_STARTED
|
|
1197
|
+
self._wasPaused = False # was the movie paused?
|
|
1198
|
+
|
|
1199
|
+
# audio stuff
|
|
1200
|
+
if audioLib is None and self._movieLib == 'ffpyplayer':
|
|
1201
|
+
self._audioLib = 'sdl2'
|
|
1202
|
+
self._noAudio = False # use SDL2 for audio playback
|
|
1203
|
+
else:
|
|
1204
|
+
self._audioLib = audioLib
|
|
1205
|
+
self._noAudio = True # no audio if using a different library
|
|
1206
|
+
|
|
1207
|
+
# warn the user if they are using the SDL2 audio library that precise
|
|
1208
|
+
# A/V sync is not supported
|
|
1209
|
+
if self._audioLib == 'sdl2':
|
|
1210
|
+
logging.warning(
|
|
1211
|
+
'Using `sdl2` for audio playback via `ffpyplayer`. This is not '
|
|
1212
|
+
'recommended for applications requiring precise audio-visual '
|
|
1213
|
+
'synchronization.')
|
|
1214
|
+
else:
|
|
1215
|
+
raise MovieAudioError(
|
|
1216
|
+
"Movie audio playback is only supported with the 'sdl2' library "
|
|
1217
|
+
"at this time.")
|
|
1218
|
+
|
|
1219
|
+
# audio playback configuration
|
|
1220
|
+
self._audioConfig = {}
|
|
1221
|
+
self._audioTempFile = None # audio extracted from the movie
|
|
1222
|
+
self._audioSamples = [] # audio samples from the movie
|
|
1223
|
+
self._audioReader = None # audio reader object
|
|
1224
|
+
self._audioSampleRate = 44100 # audio sample rate
|
|
1225
|
+
self._audioChannels = 2 # number of audio channels
|
|
1226
|
+
|
|
1227
|
+
# OpenGL data
|
|
1228
|
+
self.interpolate = interpolate
|
|
1229
|
+
self._texFilterNeedsUpdate = True
|
|
1230
|
+
self._metadata = NULL_MOVIE_METADATA
|
|
1231
|
+
self._pixbuffId = GL.GLuint(0)
|
|
1232
|
+
self._textureId = GL.GLuint(0)
|
|
1233
|
+
|
|
1234
|
+
# load a file if provided, otherwise the user must call `setMovie()`
|
|
1235
|
+
self._filename = pathToString(filename)
|
|
1236
|
+
if self._filename: # load a movie if provided
|
|
1237
|
+
self.loadMovie(self._filename)
|
|
1238
|
+
|
|
1239
|
+
self.autoLog = autoLog
|
|
1240
|
+
|
|
1241
|
+
@property
|
|
1242
|
+
def size(self):
|
|
1243
|
+
return BaseVisualStim.size.fget(self)
|
|
1244
|
+
|
|
1245
|
+
@size.setter
|
|
1246
|
+
def size(self, value):
|
|
1247
|
+
# store requested size
|
|
1248
|
+
self._requestedSize = value
|
|
1249
|
+
# if player isn't initialsied yet, do no more
|
|
1250
|
+
if not self._hasPlayer:
|
|
1251
|
+
return
|
|
1252
|
+
# duplicate if necessary
|
|
1253
|
+
if isinstance(value, (float, int)):
|
|
1254
|
+
value = [value, value]
|
|
1255
|
+
# make sure value is a list so we can assign indices
|
|
1256
|
+
if isinstance(value, tuple):
|
|
1257
|
+
value = [val for val in value]
|
|
1258
|
+
# handle aspect ratio
|
|
1259
|
+
if value[0] is None and value[1] is None:
|
|
1260
|
+
# if both values are none, use original size
|
|
1261
|
+
value = layout.Size(self.frameSize, units="pix", win=self.win)
|
|
1262
|
+
elif value[0] is None:
|
|
1263
|
+
# if width is None, use height and maintain aspect ratio
|
|
1264
|
+
value[0] = (self.frameSize[0] / self.frameSize[1]) * value[1]
|
|
1265
|
+
elif value[1] is None:
|
|
1266
|
+
# if height is None, use width and maintain aspect ratio
|
|
1267
|
+
value[1] = (self.frameSize[1] / self.frameSize[0]) * value[0]
|
|
1268
|
+
# set as normal
|
|
1269
|
+
BaseVisualStim.size.fset(self, value)
|
|
1270
|
+
|
|
1271
|
+
@property
|
|
1272
|
+
def filename(self):
|
|
1273
|
+
"""File name for the loaded video (`str`)."""
|
|
1274
|
+
return self._filename
|
|
1275
|
+
|
|
1276
|
+
@filename.setter
|
|
1277
|
+
def filename(self, value):
|
|
1278
|
+
self.loadMovie(value)
|
|
1279
|
+
|
|
1280
|
+
def setMovie(self, value):
|
|
1281
|
+
if self._isLoaded:
|
|
1282
|
+
self.unload()
|
|
1283
|
+
self.loadMovie(value)
|
|
1284
|
+
|
|
1285
|
+
@property
|
|
1286
|
+
def autoStart(self):
|
|
1287
|
+
"""Start playback when `.draw()` is called (`bool`)."""
|
|
1288
|
+
return self._autoStart
|
|
1289
|
+
|
|
1290
|
+
@autoStart.setter
|
|
1291
|
+
def autoStart(self, value):
|
|
1292
|
+
self._autoStart = bool(value)
|
|
1293
|
+
|
|
1294
|
+
@property
|
|
1295
|
+
def frameRate(self):
|
|
1296
|
+
"""Frame rate of the movie in Hertz (`float`).
|
|
1297
|
+
"""
|
|
1298
|
+
return self._player.metadata.frameRate
|
|
1299
|
+
|
|
1300
|
+
@property
|
|
1301
|
+
def loop(self):
|
|
1302
|
+
"""Whether the movie will loop when it reaches the end (`bool`).
|
|
1303
|
+
|
|
1304
|
+
If `True`, the movie will start over from the beginning when it reaches
|
|
1305
|
+
the end. If `False`, the movie will stop at the end.
|
|
1306
|
+
|
|
1307
|
+
"""
|
|
1308
|
+
return self._loop
|
|
1309
|
+
|
|
1310
|
+
@loop.setter
|
|
1311
|
+
def loop(self, value):
|
|
1312
|
+
"""Set whether the movie will loop when it reaches the end.
|
|
1313
|
+
|
|
1314
|
+
Parameters
|
|
1315
|
+
----------
|
|
1316
|
+
value : bool
|
|
1317
|
+
If `True`, the movie will loop when it reaches the end. If `False`,
|
|
1318
|
+
the movie will stop at the end.
|
|
1319
|
+
|
|
1320
|
+
"""
|
|
1321
|
+
self._loop = bool(value)
|
|
1322
|
+
|
|
1323
|
+
@property
|
|
1324
|
+
def loopCount(self):
|
|
1325
|
+
"""Number of times the movie has looped (`int`).
|
|
1326
|
+
|
|
1327
|
+
"""
|
|
1328
|
+
return self._player.loopCount if self._hasPlayer else 0
|
|
1329
|
+
|
|
1330
|
+
@property
|
|
1331
|
+
def _hasPlayer(self):
|
|
1332
|
+
"""`True` if a media player instance is started.
|
|
1333
|
+
"""
|
|
1334
|
+
# use this property to check if the player instance is started in
|
|
1335
|
+
# methods which require it
|
|
1336
|
+
return hasattr(self, "_player") and self._player is not None
|
|
1337
|
+
|
|
1338
|
+
# --------------------------------------------------------------------------
|
|
1339
|
+
# Movie file handlers
|
|
1340
|
+
#
|
|
1341
|
+
|
|
1342
|
+
def _setFileName(self, filename):
|
|
1343
|
+
"""Set the file name of the movie.
|
|
1344
|
+
|
|
1345
|
+
This function sets the file name of the movie. The file name is used
|
|
1346
|
+
to load the movie from disk. If the file name is not set, the movie
|
|
1347
|
+
will not be loaded.
|
|
1348
|
+
|
|
1349
|
+
Parameters
|
|
1350
|
+
----------
|
|
1351
|
+
filename : str
|
|
1352
|
+
The file name of the movie.
|
|
1353
|
+
|
|
1354
|
+
"""
|
|
1355
|
+
# If given `default.mp4`, sub in full path
|
|
1356
|
+
if isinstance(filename, str):
|
|
1357
|
+
# alias default names (so it always points to default.png)
|
|
1358
|
+
if filename in defaultStim:
|
|
1359
|
+
filename = Path(prefs.paths['assets']) / defaultStim[filename]
|
|
1360
|
+
|
|
1361
|
+
# check if the file has can be loaded
|
|
1362
|
+
if not os.path.isfile(filename):
|
|
1363
|
+
raise MovieFileNotFoundError(
|
|
1364
|
+
"Cannot open movie file `{}`".format(filename))
|
|
1365
|
+
else:
|
|
1366
|
+
# If given a recording component, use its last clip
|
|
1367
|
+
if hasattr(filename, "lastClip"):
|
|
1368
|
+
filename = filename.lastClip
|
|
1369
|
+
|
|
1370
|
+
self._filename = os.path.abspath(str(filename))
|
|
1371
|
+
|
|
1372
|
+
def loadMovie(self, filename):
|
|
1373
|
+
"""Load a movie file from disk.
|
|
1374
|
+
|
|
1375
|
+
Parameters
|
|
1376
|
+
----------
|
|
1377
|
+
filename : str
|
|
1378
|
+
Path to movie file. Must be a format that FFMPEG supports.
|
|
1379
|
+
|
|
1380
|
+
"""
|
|
1381
|
+
# Set the movie file name, this handles normalizing the path and
|
|
1382
|
+
# checking if the file exists.
|
|
1383
|
+
|
|
1384
|
+
self._setFileName(filename)
|
|
1385
|
+
|
|
1386
|
+
# Time opening the movie file
|
|
1387
|
+
|
|
1388
|
+
t0 = time.time() # time it
|
|
1389
|
+
logging.debug(
|
|
1390
|
+
"Opening movie file: {}".format(self._filename))
|
|
1391
|
+
|
|
1392
|
+
# Extact the audio track so we can read samples from it. This needs to
|
|
1393
|
+
# be done before the movie is opened by the player to avoid file access
|
|
1394
|
+
# issues. The audio track is extracted to a temporary file which is
|
|
1395
|
+
# deleted when the movie is closed.
|
|
1396
|
+
|
|
1397
|
+
disableAudio = False
|
|
1398
|
+
if not self._noAudio and self._audioLib not in ('sdl', 'sdl2'):
|
|
1399
|
+
# if using SDL, playback is handled by the ffpyplayer library so we
|
|
1400
|
+
# don't need to extract the audio track or setup the audio stream
|
|
1401
|
+
self._extractAudioTrack()
|
|
1402
|
+
disableAudio = True
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
self._decoderOpts['an'] = disableAudio
|
|
1406
|
+
|
|
1407
|
+
# Setup looping if the user has requested it. This is done by setting the
|
|
1408
|
+
# `loop` option in the decoder options so FFMPEG will loop the movie
|
|
1409
|
+
# automatically when it reaches the end. The loop count is reset to 0.
|
|
1410
|
+
|
|
1411
|
+
self._decoderOpts['loop'] = 0 if self._loop else 1
|
|
1412
|
+
self._loopCount = 0 # reset loop count
|
|
1413
|
+
|
|
1414
|
+
# Create the movie player interface, this is what decodes movie frames
|
|
1415
|
+
# in the background. We disable audio playback since we are using the
|
|
1416
|
+
# our own audio library for playback.
|
|
1417
|
+
|
|
1418
|
+
self._player = MovieFileReader(
|
|
1419
|
+
filename=self._filename,
|
|
1420
|
+
decoderLib=self._movieLib,
|
|
1421
|
+
decoderOpts=self._decoderOpts)
|
|
1422
|
+
|
|
1423
|
+
# Open the player, this will get metadata about the movie and start
|
|
1424
|
+
# decoding frames in the background.
|
|
1425
|
+
|
|
1426
|
+
self._player.open()
|
|
1427
|
+
|
|
1428
|
+
logging.debug(
|
|
1429
|
+
"Movie file opened in {:.2f} seconds".format(
|
|
1430
|
+
time.time() - t0))
|
|
1431
|
+
|
|
1432
|
+
# Setup the OpenGL buffers for the movie frames. The sizes of the
|
|
1433
|
+
# buffers are determined by the size of the movie frames obtained from
|
|
1434
|
+
# the player.
|
|
1435
|
+
|
|
1436
|
+
self._freeTextureBuffers() # free buffers (if any) before creating a new one
|
|
1437
|
+
self._setupTextureBuffers()
|
|
1438
|
+
|
|
1439
|
+
# update size in case frame size has changed
|
|
1440
|
+
self.size = self._requestedSize
|
|
1441
|
+
|
|
1442
|
+
# reset movie state and timekeeping variables
|
|
1443
|
+
self._playbackStatus = NOT_STARTED # reset playback status
|
|
1444
|
+
self._pts = 0.0 # reset presentation timestamp
|
|
1445
|
+
self._movieTime = 0.0 # reset movie time
|
|
1446
|
+
self._isLoaded = True
|
|
1447
|
+
|
|
1448
|
+
# set the volume to previous
|
|
1449
|
+
self.volume = self._volume
|
|
1450
|
+
|
|
1451
|
+
def _setupAudioStream(self):
|
|
1452
|
+
"""Setup the audio stream for the movie.
|
|
1453
|
+
"""
|
|
1454
|
+
# todo - handle setting up the audio library stream
|
|
1455
|
+
if self._noAudio or self._audioLib in ('sdl', 'sdl2'):
|
|
1456
|
+
return
|
|
1457
|
+
|
|
1458
|
+
def _pushAudioSamples(self):
|
|
1459
|
+
"""Push audio samples to the audio buffer.
|
|
1460
|
+
"""
|
|
1461
|
+
# todo - implement this
|
|
1462
|
+
if self._noAudio or self._audioLib in ('sdl', 'sdl2'):
|
|
1463
|
+
return
|
|
1464
|
+
|
|
1465
|
+
def _extractAudioTrack(self):
|
|
1466
|
+
"""Extract the audio track from the movie file.
|
|
1467
|
+
|
|
1468
|
+
This function extracts the audio track from the movie file and writes
|
|
1469
|
+
it to a temporary file. The temporary file is used to play the audio
|
|
1470
|
+
track in sync with the video frames.
|
|
1471
|
+
|
|
1472
|
+
"""
|
|
1473
|
+
t0 = time.time()
|
|
1474
|
+
logging.debug("Extracting audio track from movie file: {}".format(
|
|
1475
|
+
self._filename))
|
|
1476
|
+
|
|
1477
|
+
# Create a temporary file where the audio track will be written to. The
|
|
1478
|
+
# file will be deleted when the movie is closed.
|
|
1479
|
+
self._audioTempFile = tempfile.NamedTemporaryFile(
|
|
1480
|
+
suffix='.wav',
|
|
1481
|
+
delete=False)
|
|
1482
|
+
|
|
1483
|
+
# use moviepy to extract the audio track
|
|
1484
|
+
import moviepy as mp
|
|
1485
|
+
|
|
1486
|
+
videoClip = mp.VideoFileClip(
|
|
1487
|
+
self._filename)
|
|
1488
|
+
audioTrackData = videoClip.audio
|
|
1489
|
+
|
|
1490
|
+
audioTrackData.write_audiofile(
|
|
1491
|
+
self._audioTempFile.name,
|
|
1492
|
+
codec='pcm_s16le',
|
|
1493
|
+
fps=44100,
|
|
1494
|
+
nbytes=2,
|
|
1495
|
+
logger=None)
|
|
1496
|
+
|
|
1497
|
+
videoClip.close()
|
|
1498
|
+
self._audioTempFile.close()
|
|
1499
|
+
|
|
1500
|
+
logging.warning(
|
|
1501
|
+
"Audio track written to temporary file: {} ({} bytes)".format(
|
|
1502
|
+
self._audioTempFile.name,
|
|
1503
|
+
os.path.getsize(self._audioTempFile.name)))
|
|
1504
|
+
|
|
1505
|
+
logging.warning(
|
|
1506
|
+
"Audio track extraction completed in {:.2f} seconds".format(
|
|
1507
|
+
time.time() - t0))
|
|
1508
|
+
|
|
1509
|
+
# use soundfile to read the audio samples from the temporary file
|
|
1510
|
+
import soundfile as sf
|
|
1511
|
+
samples, sr = sf.read(
|
|
1512
|
+
self._audioTempFile.name,
|
|
1513
|
+
dtype='float32',
|
|
1514
|
+
always_2d=True)
|
|
1515
|
+
self._audioSampleRate = sr
|
|
1516
|
+
self._audioSamples = samples
|
|
1517
|
+
|
|
1518
|
+
# compute the size of the audio samples in bytes
|
|
1519
|
+
audioSize = self._audioSamples.nbytes
|
|
1520
|
+
|
|
1521
|
+
logging.debug(
|
|
1522
|
+
"Audio track size: {} bytes".format(audioSize))
|
|
1523
|
+
|
|
1524
|
+
def load(self, filename):
|
|
1525
|
+
"""Load a movie file from disk (alias of `setMovie`).
|
|
1526
|
+
|
|
1527
|
+
Parameters
|
|
1528
|
+
----------
|
|
1529
|
+
filename : str
|
|
1530
|
+
Path to movie file. Must be a format that FFMPEG supports.
|
|
1531
|
+
|
|
1532
|
+
"""
|
|
1533
|
+
self.setMovie(filename=filename)
|
|
1534
|
+
|
|
1535
|
+
def unload(self, log=True):
|
|
1536
|
+
"""Stop and unload the movie.
|
|
1537
|
+
|
|
1538
|
+
Parameters
|
|
1539
|
+
----------
|
|
1540
|
+
log : bool
|
|
1541
|
+
Log this event.
|
|
1542
|
+
|
|
1543
|
+
"""
|
|
1544
|
+
if self._isLoaded:
|
|
1545
|
+
self._player.close()
|
|
1546
|
+
self._freeTextureBuffers() # free buffer before creating a new one
|
|
1547
|
+
self._isLoaded = False
|
|
1548
|
+
|
|
1549
|
+
# --------------------------------------------------------------------------
|
|
1550
|
+
# Time and frame management
|
|
1551
|
+
#
|
|
1552
|
+
|
|
1553
|
+
def _updateMoviePos(self):
|
|
1554
|
+
"""Update the movie position.
|
|
1555
|
+
|
|
1556
|
+
This function updates the movie position. The movie position is the
|
|
1557
|
+
presentation timestamp (PTS) of the current frame. The PTS is updated
|
|
1558
|
+
when the movie is played or paused.
|
|
1559
|
+
|
|
1560
|
+
"""
|
|
1561
|
+
# todo - use 'geFutureFlipTime' to get the time of the next flip to align
|
|
1562
|
+
|
|
1563
|
+
# the movie with the flip time
|
|
1564
|
+
now = core.getTime()
|
|
1565
|
+
# if self._playbackStatus == SEEKING:
|
|
1566
|
+
# self._lastFrameAbsTime = now
|
|
1567
|
+
# # if we are seeking, the movie time is not updated until done
|
|
1568
|
+
# return
|
|
1569
|
+
|
|
1570
|
+
if self._playbackStatus == PLAYING:
|
|
1571
|
+
# check if were at the end of the movie
|
|
1572
|
+
if self._movieTime < self.duration:
|
|
1573
|
+
# determine the current movie time
|
|
1574
|
+
self._movieTime = min(
|
|
1575
|
+
self._movieTime + (now - self._lastFrameAbsTime),
|
|
1576
|
+
self.duration)
|
|
1577
|
+
else:
|
|
1578
|
+
if self._loop:
|
|
1579
|
+
# if looping, reset the movie time to 0
|
|
1580
|
+
self._loopCount += 1 # increment loop count
|
|
1581
|
+
self._movieTime = 0.0
|
|
1582
|
+
else:
|
|
1583
|
+
# if not looping, stop playback
|
|
1584
|
+
self._player.pause(True)
|
|
1585
|
+
self._movieTime = self.duration # set to end of movie
|
|
1586
|
+
self._playbackStatus = FINISHED # indicate movie is done
|
|
1587
|
+
|
|
1588
|
+
elif self._playbackStatus == NOT_STARTED:
|
|
1589
|
+
self._movieTime = 0.0 # reset movie time to 0
|
|
1590
|
+
|
|
1591
|
+
# if paused, the movie time does not advance but we still need to
|
|
1592
|
+
# update the last frame time
|
|
1593
|
+
self._lastFrameAbsTime = now # always updates
|
|
1594
|
+
|
|
1595
|
+
# --------------------------------------------------------------------------
|
|
1596
|
+
# Drawing and rendering
|
|
1597
|
+
#
|
|
1598
|
+
|
|
1599
|
+
@property
|
|
1600
|
+
def frameTexture(self):
|
|
1601
|
+
"""Texture ID for the current video frame (`GLuint`). You can use this
|
|
1602
|
+
as a video texture. However, you must periodically call
|
|
1603
|
+
`updateVideoFrame` to keep this up to date.
|
|
1604
|
+
|
|
1605
|
+
"""
|
|
1606
|
+
return self._textureId
|
|
1607
|
+
|
|
1608
|
+
def updateVideoFrame(self):
|
|
1609
|
+
"""Update the present video frame. The next call to `draw()` will make
|
|
1610
|
+
the retrieved frame appear.
|
|
1611
|
+
|
|
1612
|
+
Returns
|
|
1613
|
+
-------
|
|
1614
|
+
bool
|
|
1615
|
+
If `True`, the video texture has been updated and the frame index is
|
|
1616
|
+
advanced by one. If `False`, the last frame should be kept
|
|
1617
|
+
on-screen.
|
|
1618
|
+
|
|
1619
|
+
"""
|
|
1620
|
+
# get the current movie frame for the video time
|
|
1621
|
+
self._updateMoviePos() # update the movie position
|
|
1622
|
+
|
|
1623
|
+
frameData = self._player.getFrame(self._movieTime)
|
|
1624
|
+
|
|
1625
|
+
if frameData is None: # handle frame not available by showing last frame
|
|
1626
|
+
# if self._playbackStatus == PLAYING: # something went wrong
|
|
1627
|
+
# self._playbackStatus = SEEKING
|
|
1628
|
+
|
|
1629
|
+
return False
|
|
1630
|
+
|
|
1631
|
+
frameImage, pts, _ = frameData
|
|
1632
|
+
|
|
1633
|
+
# check if we are seeking
|
|
1634
|
+
# if self._playbackStatus == SEEKING:
|
|
1635
|
+
# if self._wasPaused:
|
|
1636
|
+
# self._playbackStatus = PAUSED
|
|
1637
|
+
# else:
|
|
1638
|
+
# self._playbackStatus = PLAYING
|
|
1639
|
+
|
|
1640
|
+
if frameImage is not None:
|
|
1641
|
+
# suggested by Alex Forrence (aforren1) originally in PR #6439 to use memoryview
|
|
1642
|
+
videoBuffer = frameImage.to_memoryview()[0].memview
|
|
1643
|
+
videoFrameArray = np.frombuffer(videoBuffer, dtype=np.uint8)
|
|
1644
|
+
self._recentFrame = videoFrameArray # most recent frame
|
|
1645
|
+
else:
|
|
1646
|
+
self._recentFrame = None
|
|
1647
|
+
|
|
1648
|
+
self._pts = pts # store the current PTS of the frame we got
|
|
1649
|
+
|
|
1650
|
+
return True
|
|
1651
|
+
|
|
1652
|
+
def _freeTextureBuffers(self):
|
|
1653
|
+
"""Free texture and pixel buffers. Call this when tearing down this
|
|
1654
|
+
class or if a movie is stopped.
|
|
1655
|
+
|
|
1656
|
+
"""
|
|
1657
|
+
try:
|
|
1658
|
+
# delete buffers and textures if previously created
|
|
1659
|
+
if self._pixbuffId.value > 0:
|
|
1660
|
+
GL.glDeleteBuffers(1, self._pixbuffId)
|
|
1661
|
+
self._pixbuffId = GL.GLuint()
|
|
1662
|
+
|
|
1663
|
+
# delete the old texture if present
|
|
1664
|
+
if self._textureId.value > 0:
|
|
1665
|
+
GL.glDeleteTextures(1, self._textureId)
|
|
1666
|
+
self._textureId = GL.GLuint()
|
|
1667
|
+
|
|
1668
|
+
except Exception: # can happen when unloading or shutting down
|
|
1669
|
+
pass
|
|
1670
|
+
|
|
1671
|
+
def _setupTextureBuffers(self):
|
|
1672
|
+
"""Setup texture buffers which hold frame data. This creates a 2D
|
|
1673
|
+
RGB texture and pixel buffer. The pixel buffer serves as the store for
|
|
1674
|
+
texture color data. Each frame, the pixel buffer memory is mapped and
|
|
1675
|
+
frame data is copied over to the GPU from the decoder.
|
|
1676
|
+
|
|
1677
|
+
This is called every time a video file is loaded. The
|
|
1678
|
+
`_freeTextureBuffers` method is called in this routine prior to creating
|
|
1679
|
+
new buffers, so it's safe to call this right after loading a new movie
|
|
1680
|
+
without having to `_freeTextureBuffers` first.
|
|
1681
|
+
|
|
1682
|
+
"""
|
|
1683
|
+
# get the size of the movie frame and compute the buffer size
|
|
1684
|
+
vidWidth, vidHeight = self._player.getMetadata().size
|
|
1685
|
+
nBufferBytes = vidWidth * vidHeight * 3
|
|
1686
|
+
|
|
1687
|
+
# Create the pixel buffer object which will serve as the texture memory
|
|
1688
|
+
# store. Pixel data will be copied to this buffer each frame.
|
|
1689
|
+
GL.glGenBuffers(1, ctypes.byref(self._pixbuffId))
|
|
1690
|
+
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, self._pixbuffId)
|
|
1691
|
+
GL.glBufferData(
|
|
1692
|
+
GL.GL_PIXEL_UNPACK_BUFFER,
|
|
1693
|
+
nBufferBytes * ctypes.sizeof(GL.GLubyte),
|
|
1694
|
+
None,
|
|
1695
|
+
GL.GL_STREAM_DRAW) # one-way app -> GL
|
|
1696
|
+
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, 0)
|
|
1697
|
+
|
|
1698
|
+
# Create a texture which will hold the data streamed to the pixel
|
|
1699
|
+
# buffer. Only one texture needs to be allocated.
|
|
1700
|
+
GL.glEnable(GL.GL_TEXTURE_2D)
|
|
1701
|
+
GL.glGenTextures(1, ctypes.byref(self._textureId))
|
|
1702
|
+
GL.glBindTexture(GL.GL_TEXTURE_2D, self._textureId)
|
|
1703
|
+
GL.glTexImage2D(
|
|
1704
|
+
GL.GL_TEXTURE_2D,
|
|
1705
|
+
0,
|
|
1706
|
+
GL.GL_RGB8,
|
|
1707
|
+
vidWidth, vidHeight, # frame dims in pixels
|
|
1708
|
+
0,
|
|
1709
|
+
GL.GL_RGB,
|
|
1710
|
+
GL.GL_UNSIGNED_BYTE,
|
|
1711
|
+
None)
|
|
1712
|
+
|
|
1713
|
+
# setup texture filtering
|
|
1714
|
+
if self.interpolate:
|
|
1715
|
+
texFilter = GL.GL_LINEAR
|
|
1716
|
+
else:
|
|
1717
|
+
texFilter = GL.GL_NEAREST
|
|
1718
|
+
|
|
1719
|
+
GL.glTexParameteri(
|
|
1720
|
+
GL.GL_TEXTURE_2D,
|
|
1721
|
+
GL.GL_TEXTURE_MAG_FILTER,
|
|
1722
|
+
texFilter)
|
|
1723
|
+
GL.glTexParameteri(
|
|
1724
|
+
GL.GL_TEXTURE_2D,
|
|
1725
|
+
GL.GL_TEXTURE_MIN_FILTER,
|
|
1726
|
+
texFilter)
|
|
1727
|
+
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP)
|
|
1728
|
+
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP)
|
|
1729
|
+
GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
|
|
1730
|
+
GL.glDisable(GL.GL_TEXTURE_2D)
|
|
1731
|
+
|
|
1732
|
+
GL.glFlush() # make sure all buffers are ready
|
|
1733
|
+
|
|
1734
|
+
def _pixelTransfer(self):
|
|
1735
|
+
"""Copy pixel data from video frame to texture.
|
|
1736
|
+
|
|
1737
|
+
This is called when a new frame is available. The pixel data is copied
|
|
1738
|
+
from the video frame to the texture store on the GPU.
|
|
1739
|
+
|
|
1740
|
+
"""
|
|
1741
|
+
# get the size of the movie frame and compute the buffer size
|
|
1742
|
+
vidWidth, vidHeight = self._player.getMetadata().size
|
|
1743
|
+
|
|
1744
|
+
nBufferBytes = vidWidth * vidHeight * 3
|
|
1745
|
+
|
|
1746
|
+
# bind pixel unpack buffer
|
|
1747
|
+
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, self._pixbuffId)
|
|
1748
|
+
|
|
1749
|
+
# Free last storage buffer before mapping and writing new frame
|
|
1750
|
+
# data. This allows the GPU to process the extant buffer in VRAM
|
|
1751
|
+
# uploaded last cycle without being stalled by the CPU accessing it.
|
|
1752
|
+
GL.glBufferData(
|
|
1753
|
+
GL.GL_PIXEL_UNPACK_BUFFER,
|
|
1754
|
+
nBufferBytes * ctypes.sizeof(GL.GLubyte),
|
|
1755
|
+
None,
|
|
1756
|
+
GL.GL_STREAM_DRAW)
|
|
1757
|
+
|
|
1758
|
+
# Map the buffer to client memory, `GL_WRITE_ONLY` to tell the
|
|
1759
|
+
# driver to optimize for a one-way write operation if it can.
|
|
1760
|
+
bufferPtr = GL.glMapBuffer(
|
|
1761
|
+
GL.GL_PIXEL_UNPACK_BUFFER,
|
|
1762
|
+
GL.GL_WRITE_ONLY)
|
|
1763
|
+
|
|
1764
|
+
# copy the frame data to the buffer
|
|
1765
|
+
ctypes.memmove(bufferPtr,
|
|
1766
|
+
self._recentFrame.ctypes.data,
|
|
1767
|
+
nBufferBytes)
|
|
1768
|
+
|
|
1769
|
+
# Very important that we unmap the buffer data after copying, but
|
|
1770
|
+
# keep the buffer bound for setting the texture.
|
|
1771
|
+
GL.glUnmapBuffer(GL.GL_PIXEL_UNPACK_BUFFER)
|
|
1772
|
+
|
|
1773
|
+
# bind the texture in OpenGL
|
|
1774
|
+
GL.glEnable(GL.GL_TEXTURE_2D)
|
|
1775
|
+
GL.glActiveTexture(GL.GL_TEXTURE0)
|
|
1776
|
+
GL.glBindTexture(GL.GL_TEXTURE_2D, self._textureId)
|
|
1777
|
+
|
|
1778
|
+
# copy the PBO to the texture
|
|
1779
|
+
GL.glTexSubImage2D(
|
|
1780
|
+
GL.GL_TEXTURE_2D, 0, 0, 0,
|
|
1781
|
+
vidWidth, vidHeight,
|
|
1782
|
+
GL.GL_RGB,
|
|
1783
|
+
GL.GL_UNSIGNED_BYTE,
|
|
1784
|
+
0) # point to the presently bound buffer
|
|
1785
|
+
|
|
1786
|
+
# update texture filtering only if needed
|
|
1787
|
+
if self._texFilterNeedsUpdate:
|
|
1788
|
+
if self.interpolate:
|
|
1789
|
+
texFilter = GL.GL_LINEAR
|
|
1790
|
+
else:
|
|
1791
|
+
texFilter = GL.GL_NEAREST
|
|
1792
|
+
|
|
1793
|
+
GL.glTexParameteri(
|
|
1794
|
+
GL.GL_TEXTURE_2D,
|
|
1795
|
+
GL.GL_TEXTURE_MAG_FILTER,
|
|
1796
|
+
texFilter)
|
|
1797
|
+
GL.glTexParameteri(
|
|
1798
|
+
GL.GL_TEXTURE_2D,
|
|
1799
|
+
GL.GL_TEXTURE_MIN_FILTER,
|
|
1800
|
+
texFilter)
|
|
1801
|
+
|
|
1802
|
+
self._texFilterNeedsUpdate = False
|
|
1803
|
+
|
|
1804
|
+
# important to unbind the PBO
|
|
1805
|
+
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, 0)
|
|
1806
|
+
GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
|
|
1807
|
+
GL.glDisable(GL.GL_TEXTURE_2D)
|
|
1808
|
+
|
|
1809
|
+
def _drawRectangle(self):
|
|
1810
|
+
"""Draw the video frame to the window.
|
|
1811
|
+
|
|
1812
|
+
This is called by the `draw()` method to blit the video to the display
|
|
1813
|
+
window. The dimensions of the video are set by the `size` parameter.
|
|
1814
|
+
|
|
1815
|
+
"""
|
|
1816
|
+
# make sure that textures are on and GL_TEXTURE0 is active
|
|
1817
|
+
GL.glEnable(GL.GL_TEXTURE_2D)
|
|
1818
|
+
GL.glActiveTexture(GL.GL_TEXTURE0)
|
|
1819
|
+
|
|
1820
|
+
# sets opacity (1, 1, 1 = RGB placeholder)
|
|
1821
|
+
GL.glColor4f(1, 1, 1, self.opacity)
|
|
1822
|
+
GL.glPushMatrix()
|
|
1823
|
+
self.win.setScale('pix')
|
|
1824
|
+
|
|
1825
|
+
# move to centre of stimulus and rotate
|
|
1826
|
+
vertsPix = self.verticesPix
|
|
1827
|
+
|
|
1828
|
+
array = (GL.GLfloat * 32)(
|
|
1829
|
+
1, 1, # texture coords
|
|
1830
|
+
vertsPix[0, 0], vertsPix[0, 1], 0., # vertex
|
|
1831
|
+
0, 1,
|
|
1832
|
+
vertsPix[1, 0], vertsPix[1, 1], 0.,
|
|
1833
|
+
0, 0,
|
|
1834
|
+
vertsPix[2, 0], vertsPix[2, 1], 0.,
|
|
1835
|
+
1, 0,
|
|
1836
|
+
vertsPix[3, 0], vertsPix[3, 1], 0.,
|
|
1837
|
+
)
|
|
1838
|
+
GL.glPushAttrib(GL.GL_ENABLE_BIT)
|
|
1839
|
+
|
|
1840
|
+
GL.glActiveTexture(GL.GL_TEXTURE0)
|
|
1841
|
+
GL.glBindTexture(GL.GL_TEXTURE_2D, self._textureId)
|
|
1842
|
+
GL.glPushClientAttrib(GL.GL_CLIENT_VERTEX_ARRAY_BIT)
|
|
1843
|
+
|
|
1844
|
+
# 2D texture array, 3D vertex array
|
|
1845
|
+
GL.glInterleavedArrays(GL.GL_T2F_V3F, 0, array)
|
|
1846
|
+
GL.glDrawArrays(GL.GL_QUADS, 0, 4)
|
|
1847
|
+
GL.glPopClientAttrib()
|
|
1848
|
+
GL.glPopAttrib()
|
|
1849
|
+
GL.glPopMatrix()
|
|
1850
|
+
|
|
1851
|
+
GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
|
|
1852
|
+
GL.glDisable(GL.GL_TEXTURE_2D)
|
|
1853
|
+
|
|
1854
|
+
def _drawThrobber(self):
|
|
1855
|
+
"""Draw a throbber to indicate that the movie is loading or seeking.
|
|
1856
|
+
"""
|
|
1857
|
+
# todo - implement this
|
|
1858
|
+
pass
|
|
1859
|
+
|
|
1860
|
+
def draw(self, win=None):
|
|
1861
|
+
"""Draw the current frame to a particular window.
|
|
1862
|
+
|
|
1863
|
+
The current position in the movie will be determined automatically. This
|
|
1864
|
+
method should be called on every frame that the movie is meant to
|
|
1865
|
+
appear. If `.autoStart==True` the video will begin playing when this is
|
|
1866
|
+
called.
|
|
1867
|
+
|
|
1868
|
+
Parameters
|
|
1869
|
+
----------
|
|
1870
|
+
win : :class:`~psychopy.visual.Window` or `None`
|
|
1871
|
+
Window the video is being drawn to. If `None`, the window specified
|
|
1872
|
+
at initialization will be used instead.
|
|
1873
|
+
|
|
1874
|
+
Returns
|
|
1875
|
+
-------
|
|
1876
|
+
bool
|
|
1877
|
+
`True` if the frame was updated this draw call.
|
|
1878
|
+
|
|
1879
|
+
"""
|
|
1880
|
+
self._selectWindow(self.win if win is None else win)
|
|
1881
|
+
|
|
1882
|
+
# handle autoplay
|
|
1883
|
+
if self._autoStart and self.isNotStarted:
|
|
1884
|
+
self.play()
|
|
1885
|
+
|
|
1886
|
+
# update the video frame and draw it to a quad
|
|
1887
|
+
if self.updateVideoFrame():
|
|
1888
|
+
self._pixelTransfer()
|
|
1889
|
+
|
|
1890
|
+
self._drawRectangle() # draw the texture to the target window
|
|
1891
|
+
|
|
1892
|
+
# if self._playbackStatus == SEEKING:
|
|
1893
|
+
# self._drawThrobber()
|
|
1894
|
+
|
|
1895
|
+
return True
|
|
1896
|
+
|
|
1897
|
+
# --------------------------------------------------------------------------
|
|
1898
|
+
# Video playback controls and status
|
|
1899
|
+
#
|
|
1900
|
+
|
|
1901
|
+
@property
|
|
1902
|
+
def isPlaying(self):
|
|
1903
|
+
"""`True` if the video is presently playing (`bool`).
|
|
1904
|
+
"""
|
|
1905
|
+
return self._playbackStatus == PLAYING
|
|
1906
|
+
|
|
1907
|
+
@property
|
|
1908
|
+
def isNotStarted(self):
|
|
1909
|
+
"""`True` if the video may not have started yet (`bool`). This status is
|
|
1910
|
+
given after a video is loaded and play has yet to be called.
|
|
1911
|
+
"""
|
|
1912
|
+
return self._playbackStatus == NOT_STARTED
|
|
1913
|
+
|
|
1914
|
+
@property
|
|
1915
|
+
def isStopped(self):
|
|
1916
|
+
"""`True` if the video is stopped (`bool`). It will resume from the
|
|
1917
|
+
beginning if `play()` is called.
|
|
1918
|
+
"""
|
|
1919
|
+
return self._playbackStatus == STOPPED
|
|
1920
|
+
|
|
1921
|
+
@property
|
|
1922
|
+
def isPaused(self):
|
|
1923
|
+
"""`True` if the video is presently paused (`bool`).
|
|
1924
|
+
"""
|
|
1925
|
+
return self._playbackStatus == PAUSED
|
|
1926
|
+
|
|
1927
|
+
@property
|
|
1928
|
+
def isFinished(self):
|
|
1929
|
+
"""`True` if the video is finished (`bool`). Reports the same status as
|
|
1930
|
+
`isStopped` if the video is stopped.
|
|
1931
|
+
"""
|
|
1932
|
+
return self._playbackStatus == FINISHED
|
|
1933
|
+
|
|
1934
|
+
@property
|
|
1935
|
+
def movieTime(self):
|
|
1936
|
+
"""Current movie time in seconds (`float`). This is the time since the
|
|
1937
|
+
movie started playing. If the movie is paused, this time will not
|
|
1938
|
+
advance.
|
|
1939
|
+
"""
|
|
1940
|
+
return self._movieTime
|
|
1941
|
+
|
|
1942
|
+
def play(self, log=True):
|
|
1943
|
+
"""Start or continue a paused movie from current position.
|
|
1944
|
+
|
|
1945
|
+
Parameters
|
|
1946
|
+
----------
|
|
1947
|
+
log : bool
|
|
1948
|
+
Log the play event.
|
|
1949
|
+
|
|
1950
|
+
"""
|
|
1951
|
+
if self._player is None:
|
|
1952
|
+
return
|
|
1953
|
+
|
|
1954
|
+
if self._playbackStatus == PLAYING:
|
|
1955
|
+
return # nop
|
|
1956
|
+
|
|
1957
|
+
if not self._noAudio:
|
|
1958
|
+
if self._audioLib == 'sdl2':
|
|
1959
|
+
self._player.mute(False)
|
|
1960
|
+
self._player.setVolume(self._volume)
|
|
1961
|
+
|
|
1962
|
+
self._player.pause(False) # start the player
|
|
1963
|
+
self._playbackStatus = PLAYING
|
|
1964
|
+
self._wasPaused = False # reset the paused flag
|
|
1965
|
+
self._lastFrameAbsTime = core.getTime() # get the current time
|
|
1966
|
+
|
|
1967
|
+
if log:
|
|
1968
|
+
logging.info(
|
|
1969
|
+
"Movie playback {} started at {:.2f} seconds".format(
|
|
1970
|
+
self._filename, self._movieTime))
|
|
1971
|
+
|
|
1972
|
+
def pause(self, log=True):
|
|
1973
|
+
"""Pause the current point in the movie. The image of the last frame
|
|
1974
|
+
will persist on-screen until `play()` or `stop()` are called.
|
|
1975
|
+
|
|
1976
|
+
Parameters
|
|
1977
|
+
----------
|
|
1978
|
+
log : bool
|
|
1979
|
+
Log this event.
|
|
1980
|
+
|
|
1981
|
+
"""
|
|
1982
|
+
if not self._noAudio:
|
|
1983
|
+
if self._audioLib == 'sdl2':
|
|
1984
|
+
self._player.mute(True)
|
|
1985
|
+
|
|
1986
|
+
self._player.pause()
|
|
1987
|
+
self._wasPaused = True # set the paused flag
|
|
1988
|
+
self._playbackStatus = PAUSED
|
|
1989
|
+
|
|
1990
|
+
if log:
|
|
1991
|
+
logging.info("Movie {} paused at position {:.2f} seconds".format(
|
|
1992
|
+
self._filename, self._movieTime))
|
|
1993
|
+
|
|
1994
|
+
def toggle(self, log=True):
|
|
1995
|
+
"""Switch between playing and pausing the movie. If the movie is playing,
|
|
1996
|
+
this function will pause it. If the movie is paused, this function will
|
|
1997
|
+
begin playback from the current position.
|
|
1998
|
+
|
|
1999
|
+
Parameters
|
|
2000
|
+
----------
|
|
2001
|
+
log : bool
|
|
2002
|
+
Log this event.
|
|
2003
|
+
|
|
2004
|
+
"""
|
|
2005
|
+
if self.isPlaying:
|
|
2006
|
+
self.pause()
|
|
2007
|
+
else:
|
|
2008
|
+
self.play()
|
|
2009
|
+
|
|
2010
|
+
def stop(self, log=True):
|
|
2011
|
+
"""Stop the current point in the movie (sound will stop, current frame
|
|
2012
|
+
will not advance and remain on-screen). Once stopped the movie can be
|
|
2013
|
+
restarted from the beginning by calling `play()`.
|
|
2014
|
+
|
|
2015
|
+
Note that this method will fully unload the movie and reset the
|
|
2016
|
+
player instance. If you want to reset the movie without unloading it,
|
|
2017
|
+
use `seek(0.0)` instead.
|
|
2018
|
+
|
|
2019
|
+
Parameters
|
|
2020
|
+
----------
|
|
2021
|
+
log : bool
|
|
2022
|
+
Log this event.
|
|
2023
|
+
|
|
2024
|
+
"""
|
|
2025
|
+
# stop should reset the video to the start and pause
|
|
2026
|
+
if self._player is None:
|
|
2027
|
+
return # nothing to stop
|
|
2028
|
+
|
|
2029
|
+
if log:
|
|
2030
|
+
logging.debug("Stopping movie: {}".format(self._filename))
|
|
2031
|
+
|
|
2032
|
+
self._player.close() # close the player
|
|
2033
|
+
|
|
2034
|
+
self.loadMovie(self._filename) # reload the movie
|
|
2035
|
+
|
|
2036
|
+
self._playbackStatus = NOT_STARTED
|
|
2037
|
+
|
|
2038
|
+
if log:
|
|
2039
|
+
logging.info("Movie stopped: {}".format(self._filename))
|
|
2040
|
+
|
|
2041
|
+
def seek(self, timestamp, log=True):
|
|
2042
|
+
"""Seek to a particular timestamp in the movie.
|
|
2043
|
+
|
|
2044
|
+
Parameters
|
|
2045
|
+
----------
|
|
2046
|
+
timestamp : float
|
|
2047
|
+
Time in seconds.
|
|
2048
|
+
log : bool
|
|
2049
|
+
Log this event.
|
|
2050
|
+
|
|
2051
|
+
"""
|
|
2052
|
+
if self._playbackStatus == PLAYING:
|
|
2053
|
+
self._wasPaused = False
|
|
2054
|
+
elif self._playbackStatus == PAUSED:
|
|
2055
|
+
self._wasPaused = True
|
|
2056
|
+
|
|
2057
|
+
# self._playbackStatus = SEEKING
|
|
2058
|
+
self._movieTime = timestamp
|
|
2059
|
+
# self._player.pause(True) # pause the player
|
|
2060
|
+
self._player.seek(self._movieTime)
|
|
2061
|
+
|
|
2062
|
+
# self._pts = self._movieTime # store the current PTS
|
|
2063
|
+
_ = self.updateVideoFrame()
|
|
2064
|
+
|
|
2065
|
+
def rewind(self, seconds=1, log=True):
|
|
2066
|
+
"""Rewind the video.
|
|
2067
|
+
|
|
2068
|
+
Parameters
|
|
2069
|
+
----------
|
|
2070
|
+
seconds : float
|
|
2071
|
+
Time in seconds to rewind from the current position. Default is 5
|
|
2072
|
+
seconds.
|
|
2073
|
+
log : bool
|
|
2074
|
+
Log this event.
|
|
2075
|
+
|
|
2076
|
+
"""
|
|
2077
|
+
newPts = self._movieTime - seconds
|
|
2078
|
+
self._movieTime = min(max(0.0, newPts), self.duration)
|
|
2079
|
+
self.seek(self._movieTime) # seek to the new position
|
|
2080
|
+
|
|
2081
|
+
def fastForward(self, seconds=1, log=True):
|
|
2082
|
+
"""Fast-forward the video.
|
|
2083
|
+
|
|
2084
|
+
Parameters
|
|
2085
|
+
----------
|
|
2086
|
+
seconds : float
|
|
2087
|
+
Time in seconds to fast forward from the current position. Default
|
|
2088
|
+
is 5 seconds.
|
|
2089
|
+
log : bool
|
|
2090
|
+
Log this event.
|
|
2091
|
+
|
|
2092
|
+
"""
|
|
2093
|
+
newPts = self._movieTime + seconds
|
|
2094
|
+
self._movieTime = min(max(0.0, newPts), self.duration)
|
|
2095
|
+
self.seek(self._movieTime) # seek to the new position
|
|
2096
|
+
|
|
2097
|
+
def replay(self, log=True):
|
|
2098
|
+
"""Replay the movie from the beginning.
|
|
2099
|
+
|
|
2100
|
+
Parameters
|
|
2101
|
+
----------
|
|
2102
|
+
log : bool
|
|
2103
|
+
Log this event.
|
|
2104
|
+
|
|
2105
|
+
Notes
|
|
2106
|
+
-----
|
|
2107
|
+
* This tears down the current media player instance and creates a new
|
|
2108
|
+
one. Similar to calling `stop()` and `loadMovie()`. Use `seek(0.0)` if
|
|
2109
|
+
you would like to restart the movie without reloading.
|
|
2110
|
+
|
|
2111
|
+
"""
|
|
2112
|
+
self._movieTime = 0.0 # reset movie time
|
|
2113
|
+
self.seek(self._movieTime)
|
|
2114
|
+
self.play()
|
|
2115
|
+
|
|
2116
|
+
def reset(self):
|
|
2117
|
+
"""Reset the movie to its initial state.
|
|
2118
|
+
"""
|
|
2119
|
+
# self.seek(0.0) # reset movie time to 0
|
|
2120
|
+
self._playbackStatus = NOT_STARTED # reset playback status
|
|
2121
|
+
|
|
2122
|
+
# --------------------------------------------------------------------------
|
|
2123
|
+
# Audio stream control methods
|
|
2124
|
+
#
|
|
2125
|
+
|
|
2126
|
+
@property
|
|
2127
|
+
def muted(self):
|
|
2128
|
+
"""`True` if the stream audio is muted (`bool`).
|
|
2129
|
+
"""
|
|
2130
|
+
if self._audioLib == 'sdl2':
|
|
2131
|
+
return self._player.mute
|
|
2132
|
+
else:
|
|
2133
|
+
return False # for now
|
|
2134
|
+
|
|
2135
|
+
@muted.setter
|
|
2136
|
+
def muted(self, value):
|
|
2137
|
+
self._player.mute = value
|
|
2138
|
+
|
|
2139
|
+
def volumeUp(self, amount=0.05):
|
|
2140
|
+
"""Increase the volume by a fixed amount.
|
|
2141
|
+
|
|
2142
|
+
Parameters
|
|
2143
|
+
----------
|
|
2144
|
+
amount : float or int
|
|
2145
|
+
Amount to increase the volume relative to the current volume.
|
|
2146
|
+
|
|
2147
|
+
"""
|
|
2148
|
+
if self._audioLib == 'sdl2':
|
|
2149
|
+
currentVolume = self._player.volume
|
|
2150
|
+
self._player.setVolume(currentVolume + amount)
|
|
2151
|
+
|
|
2152
|
+
def volumeDown(self, amount=0.05):
|
|
2153
|
+
"""Decrease the volume by a fixed amount.
|
|
2154
|
+
|
|
2155
|
+
Parameters
|
|
2156
|
+
----------
|
|
2157
|
+
amount : float or int
|
|
2158
|
+
Amount to decrease the volume relative to the current volume.
|
|
2159
|
+
|
|
2160
|
+
"""
|
|
2161
|
+
if self._audioLib == 'sdl2':
|
|
2162
|
+
currentVolume = self._player.volume
|
|
2163
|
+
self._player.setVolume(currentVolume - amount)
|
|
2164
|
+
|
|
2165
|
+
@property
|
|
2166
|
+
def volume(self):
|
|
2167
|
+
"""Volume for the audio track for this movie (`int` or `float`).
|
|
2168
|
+
"""
|
|
2169
|
+
if self._audioLib == 'sdl2':
|
|
2170
|
+
return self._player.volume
|
|
2171
|
+
|
|
2172
|
+
@volume.setter
|
|
2173
|
+
def volume(self, value):
|
|
2174
|
+
if self._audioLib == 'sdl2':
|
|
2175
|
+
self._player.volume = value
|
|
2176
|
+
|
|
2177
|
+
# --------------------------------------------------------------------------
|
|
2178
|
+
# Video and playback information
|
|
2179
|
+
#
|
|
2180
|
+
|
|
2181
|
+
@property
|
|
2182
|
+
def frameIndex(self):
|
|
2183
|
+
"""Current frame index being displayed (`int`)."""
|
|
2184
|
+
return 0
|
|
2185
|
+
|
|
2186
|
+
def getCurrentFrameNumber(self):
|
|
2187
|
+
"""Get the current movie frame number (`int`), same as `frameIndex`.
|
|
2188
|
+
"""
|
|
2189
|
+
return self.frameIndex
|
|
2190
|
+
|
|
2191
|
+
@property
|
|
2192
|
+
def duration(self):
|
|
2193
|
+
"""Duration of the loaded video in seconds (`float`). Not valid unless
|
|
2194
|
+
the video has been started.
|
|
2195
|
+
"""
|
|
2196
|
+
if not self._player:
|
|
2197
|
+
return -1.0
|
|
2198
|
+
|
|
2199
|
+
return self._player.getMetadata().duration
|
|
2200
|
+
|
|
2201
|
+
@property
|
|
2202
|
+
def loopCount(self):
|
|
2203
|
+
"""Number of loops completed since playback started (`int`). Incremented
|
|
2204
|
+
each time the movie begins another loop.
|
|
2205
|
+
|
|
2206
|
+
Examples
|
|
2207
|
+
--------
|
|
2208
|
+
Compute how long a looping video has been playing until now::
|
|
2209
|
+
|
|
2210
|
+
totalMovieTime = (mov.loopCount + 1) * mov.pts
|
|
2211
|
+
|
|
2212
|
+
"""
|
|
2213
|
+
if not self._player:
|
|
2214
|
+
return -1
|
|
2215
|
+
|
|
2216
|
+
return self._loopCount
|
|
2217
|
+
|
|
2218
|
+
@property
|
|
2219
|
+
def fps(self):
|
|
2220
|
+
"""Movie frames per second (`float`)."""
|
|
2221
|
+
return self.getFPS()
|
|
2222
|
+
|
|
2223
|
+
def getFPS(self):
|
|
2224
|
+
"""Movie frames per second.
|
|
2225
|
+
|
|
2226
|
+
Returns
|
|
2227
|
+
-------
|
|
2228
|
+
float
|
|
2229
|
+
Nominal number of frames to be displayed per second.
|
|
2230
|
+
|
|
2231
|
+
"""
|
|
2232
|
+
if not self._player:
|
|
2233
|
+
return 1.0
|
|
2234
|
+
|
|
2235
|
+
return self._player.getFrameRate()
|
|
2236
|
+
|
|
2237
|
+
@property
|
|
2238
|
+
def videoSize(self):
|
|
2239
|
+
"""Size of the video `(w, h)` in pixels (`tuple`). Returns `(0, 0)` if
|
|
2240
|
+
no video is loaded.
|
|
2241
|
+
"""
|
|
2242
|
+
return self.frameSize
|
|
2243
|
+
|
|
2244
|
+
@property
|
|
2245
|
+
def origSize(self):
|
|
2246
|
+
"""Alias of `videoSize`
|
|
2247
|
+
"""
|
|
2248
|
+
return self.videoSize
|
|
2249
|
+
|
|
2250
|
+
@property
|
|
2251
|
+
def frameSize(self):
|
|
2252
|
+
"""Size of the video `(w, h)` in pixels (`tuple`). Alias of `videoSize`.
|
|
2253
|
+
"""
|
|
2254
|
+
if not self._player:
|
|
2255
|
+
return 0, 0
|
|
2256
|
+
|
|
2257
|
+
return self._player.getMetadata().size
|
|
2258
|
+
|
|
2259
|
+
@property
|
|
2260
|
+
def pts(self):
|
|
2261
|
+
"""Presentation timestamp of the most recent frame (`float`).
|
|
2262
|
+
|
|
2263
|
+
This value corresponds to the time in movie/stream time the frame is
|
|
2264
|
+
scheduled to be presented.
|
|
2265
|
+
|
|
2266
|
+
"""
|
|
2267
|
+
if not self._player:
|
|
2268
|
+
return -1.0
|
|
2269
|
+
|
|
2270
|
+
return self._pts
|
|
2271
|
+
|
|
2272
|
+
def getPercentageComplete(self):
|
|
2273
|
+
"""Provides a value between 0.0 and 100.0, indicating the amount of the
|
|
2274
|
+
movie that has been already played (`float`).
|
|
2275
|
+
"""
|
|
2276
|
+
return (self._movieTime / self.duration) * 100.0
|
|
2277
|
+
|
|
2278
|
+
# --------------------------------------------------------------------------
|
|
2279
|
+
# Miscellaneous methods
|
|
2280
|
+
#
|
|
2281
|
+
|
|
2282
|
+
def getSubtitleText(self):
|
|
2283
|
+
"""Get the subtitle for the current frame.
|
|
2284
|
+
|
|
2285
|
+
Returns
|
|
2286
|
+
-------
|
|
2287
|
+
str
|
|
2288
|
+
Subtitle for the current frame.
|
|
2289
|
+
|
|
2290
|
+
"""
|
|
2291
|
+
if not self._player:
|
|
2292
|
+
return ""
|
|
2293
|
+
|
|
2294
|
+
return self._player.getSubtitle()
|
|
2295
|
+
|
|
2296
|
+
def __del__(self):
|
|
2297
|
+
"""Destructor for the MovieStim class.
|
|
2298
|
+
|
|
2299
|
+
This function is called when the object is deleted. It closes the movie
|
|
2300
|
+
player and frees any resources used by the object.
|
|
2301
|
+
|
|
2302
|
+
"""
|
|
2303
|
+
self.unload()
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
def _closeAllMovieReaders():
|
|
2307
|
+
"""Close all movie readers.
|
|
2308
|
+
|
|
2309
|
+
This function explicitly closes movie reader interfaces that are presently
|
|
2310
|
+
open, to free resources when the interpreter exits to reduce the chances of
|
|
2311
|
+
any subprocesses spawned by the interface being orphaned.
|
|
2312
|
+
|
|
2313
|
+
Do not call this directly, it is called automatically when the interpreter
|
|
2314
|
+
exits (via `atexit`). If you do, all sorts of bad things will happen if
|
|
2315
|
+
there are any open movie readers still in use.
|
|
2316
|
+
|
|
2317
|
+
"""
|
|
2318
|
+
global _openMovieReaders
|
|
2319
|
+
|
|
2320
|
+
for movieReader in _openMovieReaders:
|
|
2321
|
+
logging.debug(
|
|
2322
|
+
"Closing movie reader interface for file: {}".format(
|
|
2323
|
+
movieReader.filename))
|
|
2324
|
+
if hasattr(movieReader, '_player'):
|
|
2325
|
+
movieReader._freePlayer()
|
|
2326
|
+
|
|
2327
|
+
|
|
2328
|
+
# try an close any players on exit
|
|
2329
|
+
import atexit
|
|
2330
|
+
atexit.register(_closeAllMovieReaders) # call this when the program exits
|
|
2331
|
+
|
|
2332
|
+
|
|
2333
|
+
if __name__ == "__main__":
|
|
2334
|
+
pass
|