psychopy 2024.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of psychopy might be problematic. Click here for more details.

Files changed (2950) hide show
  1. psychopy/CHANGELOG.txt +3571 -0
  2. psychopy/LICENSE.txt +11 -0
  3. psychopy/LICENSES.txt +55 -0
  4. psychopy/__init__.py +74 -0
  5. psychopy/alerts/__init__.py +65 -0
  6. psychopy/alerts/_alerts.py +184 -0
  7. psychopy/alerts/_errorHandler.py +51 -0
  8. psychopy/alerts/alertsCatalogue/1000.yaml +0 -0
  9. psychopy/alerts/alertsCatalogue/1100.yaml +0 -0
  10. psychopy/alerts/alertsCatalogue/1500.yaml +0 -0
  11. psychopy/alerts/alertsCatalogue/2000.yaml +0 -0
  12. psychopy/alerts/alertsCatalogue/2100.yaml +0 -0
  13. psychopy/alerts/alertsCatalogue/2110.yaml +0 -0
  14. psychopy/alerts/alertsCatalogue/2115.yaml +21 -0
  15. psychopy/alerts/alertsCatalogue/2120.yaml +22 -0
  16. psychopy/alerts/alertsCatalogue/2150.yaml +0 -0
  17. psychopy/alerts/alertsCatalogue/2155.yaml +21 -0
  18. psychopy/alerts/alertsCatalogue/2300.yaml +0 -0
  19. psychopy/alerts/alertsCatalogue/2500.yaml +0 -0
  20. psychopy/alerts/alertsCatalogue/3000.yaml +0 -0
  21. psychopy/alerts/alertsCatalogue/3100.yaml +0 -0
  22. psychopy/alerts/alertsCatalogue/3110.yaml +25 -0
  23. psychopy/alerts/alertsCatalogue/3115.yaml +24 -0
  24. psychopy/alerts/alertsCatalogue/3200.yaml +0 -0
  25. psychopy/alerts/alertsCatalogue/3400.yaml +0 -0
  26. psychopy/alerts/alertsCatalogue/4000.yaml +0 -0
  27. psychopy/alerts/alertsCatalogue/4051.yaml +19 -0
  28. psychopy/alerts/alertsCatalogue/4052.yaml +19 -0
  29. psychopy/alerts/alertsCatalogue/4100.yaml +0 -0
  30. psychopy/alerts/alertsCatalogue/4105.yaml +18 -0
  31. psychopy/alerts/alertsCatalogue/4115.yaml +21 -0
  32. psychopy/alerts/alertsCatalogue/4120.yaml +19 -0
  33. psychopy/alerts/alertsCatalogue/4125.yaml +23 -0
  34. psychopy/alerts/alertsCatalogue/4200.yaml +0 -0
  35. psychopy/alerts/alertsCatalogue/4205.yaml +19 -0
  36. psychopy/alerts/alertsCatalogue/4210.yaml +19 -0
  37. psychopy/alerts/alertsCatalogue/4305.yaml +21 -0
  38. psychopy/alerts/alertsCatalogue/4310.yaml +21 -0
  39. psychopy/alerts/alertsCatalogue/4315.yaml +21 -0
  40. psychopy/alerts/alertsCatalogue/4320.yaml +19 -0
  41. psychopy/alerts/alertsCatalogue/4325.yaml +23 -0
  42. psychopy/alerts/alertsCatalogue/4330.yaml +19 -0
  43. psychopy/alerts/alertsCatalogue/4335.yaml +19 -0
  44. psychopy/alerts/alertsCatalogue/4340.yaml +19 -0
  45. psychopy/alerts/alertsCatalogue/4405.yaml +24 -0
  46. psychopy/alerts/alertsCatalogue/4505.yaml +22 -0
  47. psychopy/alerts/alertsCatalogue/4510.yaml +25 -0
  48. psychopy/alerts/alertsCatalogue/4520.yaml +26 -0
  49. psychopy/alerts/alertsCatalogue/4530.yaml +23 -0
  50. psychopy/alerts/alertsCatalogue/4540.yaml +19 -0
  51. psychopy/alerts/alertsCatalogue/4545.yaml +22 -0
  52. psychopy/alerts/alertsCatalogue/4550.yaml +19 -0
  53. psychopy/alerts/alertsCatalogue/4605.yaml +22 -0
  54. psychopy/alerts/alertsCatalogue/4610.yaml +22 -0
  55. psychopy/alerts/alertsCatalogue/4615.yaml +19 -0
  56. psychopy/alerts/alertsCatalogue/4705.yaml +19 -0
  57. psychopy/alerts/alertsCatalogue/4710.yaml +19 -0
  58. psychopy/alerts/alertsCatalogue/5000.yaml +0 -0
  59. psychopy/alerts/alertsCatalogue/5055.yaml +25 -0
  60. psychopy/alerts/alertsCatalogue/6000.yaml +0 -0
  61. psychopy/alerts/alertsCatalogue/6105.yaml +18 -0
  62. psychopy/alerts/alertsCatalogue/7105.yaml +19 -0
  63. psychopy/alerts/alertsCatalogue/8105.yaml +21 -0
  64. psychopy/alerts/alertsCatalogue/8110.yaml +21 -0
  65. psychopy/alerts/alertsCatalogue/9998.yaml +19 -0
  66. psychopy/alerts/alertsCatalogue/9999.yaml +19 -0
  67. psychopy/alerts/alertsCatalogue/alertCategories.yaml +109 -0
  68. psychopy/alerts/alertsCatalogue/alertTemplate.yaml +19 -0
  69. psychopy/alerts/alertsCatalogue/alertmsg.py +144 -0
  70. psychopy/alerts/alertsCatalogue/generateAlertmsg.py +34 -0
  71. psychopy/alerts/alerttools.py +338 -0
  72. psychopy/app/Resources/Psychopy Window Favicon@16w.png +0 -0
  73. psychopy/app/Resources/Psychopy Window Favicon@32w.png +0 -0
  74. psychopy/app/Resources/README.md +12 -0
  75. psychopy/app/Resources/USB-C.png +0 -0
  76. psychopy/app/Resources/USB.png +0 -0
  77. psychopy/app/Resources/__init__.py +0 -0
  78. psychopy/app/Resources/builder.ico +0 -0
  79. psychopy/app/Resources/classic/FlowBottom_CompLeft.png +0 -0
  80. psychopy/app/Resources/classic/FlowBottom_CompRight.png +0 -0
  81. psychopy/app/Resources/classic/FlowTop_CompLeft.png +0 -0
  82. psychopy/app/Resources/classic/FlowTop_CompRight.png +0 -0
  83. psychopy/app/Resources/classic/README.txt +9 -0
  84. psychopy/app/Resources/classic/__init__.py +0 -0
  85. psychopy/app/Resources/classic/_layouts.ai +1138 -1
  86. psychopy/app/Resources/classic/add.png +0 -0
  87. psychopy/app/Resources/classic/add@2x.png +0 -0
  88. psychopy/app/Resources/classic/addExp32.png +0 -0
  89. psychopy/app/Resources/classic/alerts.png +0 -0
  90. psychopy/app/Resources/classic/beta.png +0 -0
  91. psychopy/app/Resources/classic/browser.png +0 -0
  92. psychopy/app/Resources/classic/browser@2x.png +0 -0
  93. psychopy/app/Resources/classic/bug16.png +0 -0
  94. psychopy/app/Resources/classic/circle_mask.png +0 -0
  95. psychopy/app/Resources/classic/circle_mask@2x.png +0 -0
  96. psychopy/app/Resources/classic/clear.png +0 -0
  97. psychopy/app/Resources/classic/clear@2x.png +0 -0
  98. psychopy/app/Resources/classic/coderclass16.png +0 -0
  99. psychopy/app/Resources/classic/coderfunc16.png +0 -0
  100. psychopy/app/Resources/classic/coderimport16.png +0 -0
  101. psychopy/app/Resources/classic/coderjs16.png +0 -0
  102. psychopy/app/Resources/classic/coderpython16.png +0 -0
  103. psychopy/app/Resources/classic/codervar16.png +0 -0
  104. psychopy/app/Resources/classic/cogwindow32.png +0 -0
  105. psychopy/app/Resources/classic/color32.png +0 -0
  106. psychopy/app/Resources/classic/compile32.png +0 -0
  107. psychopy/app/Resources/classic/compile_js.png +0 -0
  108. psychopy/app/Resources/classic/compile_js@2x.png +0 -0
  109. psychopy/app/Resources/classic/compile_py.png +0 -0
  110. psychopy/app/Resources/classic/compile_py@2x.png +0 -0
  111. psychopy/app/Resources/classic/copy16.png +0 -0
  112. psychopy/app/Resources/classic/currentFile.png +0 -0
  113. psychopy/app/Resources/classic/currentFile@2x.png +0 -0
  114. psychopy/app/Resources/classic/delete16.png +0 -0
  115. psychopy/app/Resources/classic/desktop.png +0 -0
  116. psychopy/app/Resources/classic/desktop@2x.png +0 -0
  117. psychopy/app/Resources/classic/dirup16.png +0 -0
  118. psychopy/app/Resources/classic/docclose16.png +0 -0
  119. psychopy/app/Resources/classic/download.png +0 -0
  120. psychopy/app/Resources/classic/edit.png +0 -0
  121. psychopy/app/Resources/classic/edit@2x.png +0 -0
  122. psychopy/app/Resources/classic/editbtn.png +0 -0
  123. psychopy/app/Resources/classic/editbtn16.png +0 -0
  124. psychopy/app/Resources/classic/editbtn16@2x.png +0 -0
  125. psychopy/app/Resources/classic/editbtn@2x.png +0 -0
  126. psychopy/app/Resources/classic/email.png +0 -0
  127. psychopy/app/Resources/classic/email@2x.png +0 -0
  128. psychopy/app/Resources/classic/experiment.png +0 -0
  129. psychopy/app/Resources/classic/experiment@2x.png +0 -0
  130. psychopy/app/Resources/classic/expsettings.png +0 -0
  131. psychopy/app/Resources/classic/expsettings@2x.png +0 -0
  132. psychopy/app/Resources/classic/file.png +0 -0
  133. psychopy/app/Resources/classic/file@2x.png +0 -0
  134. psychopy/app/Resources/classic/filecsv16.png +0 -0
  135. psychopy/app/Resources/classic/fileimage16.png +0 -0
  136. psychopy/app/Resources/classic/filenew.png +0 -0
  137. psychopy/app/Resources/classic/filenew32.png +0 -0
  138. psychopy/app/Resources/classic/filenew@2x.png +0 -0
  139. psychopy/app/Resources/classic/fileopen.png +0 -0
  140. psychopy/app/Resources/classic/fileopen32.png +0 -0
  141. psychopy/app/Resources/classic/fileopen@2x.png +0 -0
  142. psychopy/app/Resources/classic/filesave.png +0 -0
  143. psychopy/app/Resources/classic/filesave32.png +0 -0
  144. psychopy/app/Resources/classic/filesave@2x.png +0 -0
  145. psychopy/app/Resources/classic/filesaveas.png +0 -0
  146. psychopy/app/Resources/classic/filesaveas32.png +0 -0
  147. psychopy/app/Resources/classic/filesaveas@2x.png +0 -0
  148. psychopy/app/Resources/classic/fileunknown16.png +0 -0
  149. psychopy/app/Resources/classic/filter.png +0 -0
  150. psychopy/app/Resources/classic/filter@2x.png +0 -0
  151. psychopy/app/Resources/classic/folder-open16.png +0 -0
  152. psychopy/app/Resources/classic/folder16.png +0 -0
  153. psychopy/app/Resources/classic/foldernew16.png +0 -0
  154. psychopy/app/Resources/classic/fork.png +0 -0
  155. psychopy/app/Resources/classic/fork@2x.png +0 -0
  156. psychopy/app/Resources/classic/github.png +0 -0
  157. psychopy/app/Resources/classic/github@2x.png +0 -0
  158. psychopy/app/Resources/classic/globe.png +0 -0
  159. psychopy/app/Resources/classic/globe@2x.png +0 -0
  160. psychopy/app/Resources/classic/globe_bug.png +0 -0
  161. psychopy/app/Resources/classic/globe_bug@2x.png +0 -0
  162. psychopy/app/Resources/classic/globe_greensync.png +0 -0
  163. psychopy/app/Resources/classic/globe_greensync@2x.png +0 -0
  164. psychopy/app/Resources/classic/globe_info.png +0 -0
  165. psychopy/app/Resources/classic/globe_info@2x.png +0 -0
  166. psychopy/app/Resources/classic/globe_magnifier.png +0 -0
  167. psychopy/app/Resources/classic/globe_magnifier@2x.png +0 -0
  168. psychopy/app/Resources/classic/globe_run.png +0 -0
  169. psychopy/app/Resources/classic/globe_run@2x.png +0 -0
  170. psychopy/app/Resources/classic/globe_user.png +0 -0
  171. psychopy/app/Resources/classic/globe_user@2x.png +0 -0
  172. psychopy/app/Resources/classic/goto16.png +0 -0
  173. psychopy/app/Resources/classic/greendot.png +0 -0
  174. psychopy/app/Resources/classic/greendot@2x.png +0 -0
  175. psychopy/app/Resources/classic/greenglobe.png +0 -0
  176. psychopy/app/Resources/classic/greenglobe@2x.png +0 -0
  177. psychopy/app/Resources/classic/greenglobe_bug.png +0 -0
  178. psychopy/app/Resources/classic/greenglobe_bug@2x.png +0 -0
  179. psychopy/app/Resources/classic/greenglobe_greensync.png +0 -0
  180. psychopy/app/Resources/classic/greenglobe_greensync@2x.png +0 -0
  181. psychopy/app/Resources/classic/greenglobe_info.png +0 -0
  182. psychopy/app/Resources/classic/greenglobe_info@2x.png +0 -0
  183. psychopy/app/Resources/classic/greenglobe_magnifier.png +0 -0
  184. psychopy/app/Resources/classic/greenglobe_magnifier@2x.png +0 -0
  185. psychopy/app/Resources/classic/greenglobe_run.png +0 -0
  186. psychopy/app/Resources/classic/greenglobe_run@2x.png +0 -0
  187. psychopy/app/Resources/classic/greenglobe_user.png +0 -0
  188. psychopy/app/Resources/classic/greenglobe_user@2x.png +0 -0
  189. psychopy/app/Resources/classic/greydot.png +0 -0
  190. psychopy/app/Resources/classic/greydot@2x.png +0 -0
  191. psychopy/app/Resources/classic/greytick.png +0 -0
  192. psychopy/app/Resources/classic/greytick@2x.png +0 -0
  193. psychopy/app/Resources/classic/invalid_img.png +0 -0
  194. psychopy/app/Resources/classic/jsPilot.png +0 -0
  195. psychopy/app/Resources/classic/jsPilot@2x.png +0 -0
  196. psychopy/app/Resources/classic/jsRun.png +0 -0
  197. psychopy/app/Resources/classic/jsRun@2x.png +0 -0
  198. psychopy/app/Resources/classic/libroot.png +0 -0
  199. psychopy/app/Resources/classic/libroot@2x.png +0 -0
  200. psychopy/app/Resources/classic/monitor16.png +0 -0
  201. psychopy/app/Resources/classic/monitors.png +0 -0
  202. psychopy/app/Resources/classic/monitors16.png +0 -0
  203. psychopy/app/Resources/classic/monitors32.png +0 -0
  204. psychopy/app/Resources/classic/monitors@2x.png +0 -0
  205. psychopy/app/Resources/classic/orangedot.png +0 -0
  206. psychopy/app/Resources/classic/orangedot@2x.png +0 -0
  207. psychopy/app/Resources/classic/pavlovia.png +0 -0
  208. psychopy/app/Resources/classic/pavlovia16.png +0 -0
  209. psychopy/app/Resources/classic/pavlovia16@2x.png +0 -0
  210. psychopy/app/Resources/classic/pavlovia@2x.png +0 -0
  211. psychopy/app/Resources/classic/pavsync.png +0 -0
  212. psychopy/app/Resources/classic/pavsync@2x.png +0 -0
  213. psychopy/app/Resources/classic/person_off.png +0 -0
  214. psychopy/app/Resources/classic/person_off@2x.png +0 -0
  215. psychopy/app/Resources/classic/person_on.png +0 -0
  216. psychopy/app/Resources/classic/person_on@2x.png +0 -0
  217. psychopy/app/Resources/classic/plugins32.png +0 -0
  218. psychopy/app/Resources/classic/plus.png +0 -0
  219. psychopy/app/Resources/classic/plus@2x.png +0 -0
  220. psychopy/app/Resources/classic/preferences-app.png +0 -0
  221. psychopy/app/Resources/classic/preferences-app48.png +0 -0
  222. psychopy/app/Resources/classic/preferences-app@2x.png +0 -0
  223. psychopy/app/Resources/classic/preferences-conn.png +0 -0
  224. psychopy/app/Resources/classic/preferences-conn48.png +0 -0
  225. psychopy/app/Resources/classic/preferences-conn@2x.png +0 -0
  226. psychopy/app/Resources/classic/preferences-debug.png +0 -0
  227. psychopy/app/Resources/classic/preferences-debug@2x.png +0 -0
  228. psychopy/app/Resources/classic/preferences-general.png +0 -0
  229. psychopy/app/Resources/classic/preferences-general48.png +0 -0
  230. psychopy/app/Resources/classic/preferences-general@2x.png +0 -0
  231. psychopy/app/Resources/classic/preferences-hardware.png +0 -0
  232. psychopy/app/Resources/classic/preferences-hardware48.png +0 -0
  233. psychopy/app/Resources/classic/preferences-hardware@2x.png +0 -0
  234. psychopy/app/Resources/classic/preferences-keyboard.png +0 -0
  235. psychopy/app/Resources/classic/preferences-keyboard48.png +0 -0
  236. psychopy/app/Resources/classic/preferences-keyboard@2x.png +0 -0
  237. psychopy/app/Resources/classic/preferences-pilot.png +0 -0
  238. psychopy/app/Resources/classic/preferences-pilot@2x.png +0 -0
  239. psychopy/app/Resources/classic/preferences32.png +0 -0
  240. psychopy/app/Resources/classic/pyPilot.png +0 -0
  241. psychopy/app/Resources/classic/pyPilot@2x.png +0 -0
  242. psychopy/app/Resources/classic/pyRun.png +0 -0
  243. psychopy/app/Resources/classic/pyRun@2x.png +0 -0
  244. psychopy/app/Resources/classic/reddot.png +0 -0
  245. psychopy/app/Resources/classic/reddot@2x.png +0 -0
  246. psychopy/app/Resources/classic/redglobe.png +0 -0
  247. psychopy/app/Resources/classic/redglobe@2x.png +0 -0
  248. psychopy/app/Resources/classic/redglobe_bug.png +0 -0
  249. psychopy/app/Resources/classic/redglobe_bug@2x.png +0 -0
  250. psychopy/app/Resources/classic/redglobe_greensync.png +0 -0
  251. psychopy/app/Resources/classic/redglobe_greensync@2x.png +0 -0
  252. psychopy/app/Resources/classic/redglobe_info.png +0 -0
  253. psychopy/app/Resources/classic/redglobe_info@2x.png +0 -0
  254. psychopy/app/Resources/classic/redglobe_magnifier.png +0 -0
  255. psychopy/app/Resources/classic/redglobe_magnifier@2x.png +0 -0
  256. psychopy/app/Resources/classic/redglobe_run.png +0 -0
  257. psychopy/app/Resources/classic/redglobe_run@2x.png +0 -0
  258. psychopy/app/Resources/classic/redglobe_user.png +0 -0
  259. psychopy/app/Resources/classic/redglobe_user@2x.png +0 -0
  260. psychopy/app/Resources/classic/redo.png +0 -0
  261. psychopy/app/Resources/classic/redo32.png +0 -0
  262. psychopy/app/Resources/classic/redo@2x.png +0 -0
  263. psychopy/app/Resources/classic/removeExp32.png +0 -0
  264. psychopy/app/Resources/classic/rename16.png +0 -0
  265. psychopy/app/Resources/classic/restart.png +0 -0
  266. psychopy/app/Resources/classic/restart@2x.png +0 -0
  267. psychopy/app/Resources/classic/run.png +0 -0
  268. psychopy/app/Resources/classic/run@2x.png +0 -0
  269. psychopy/app/Resources/classic/runner.png +0 -0
  270. psychopy/app/Resources/classic/runner@2x.png +0 -0
  271. psychopy/app/Resources/classic/runnerPilot.png +0 -0
  272. psychopy/app/Resources/classic/runnerPilot@2x.png +0 -0
  273. psychopy/app/Resources/classic/savebtn.png +0 -0
  274. psychopy/app/Resources/classic/savebtn16.png +0 -0
  275. psychopy/app/Resources/classic/savebtn16@2x.png +0 -0
  276. psychopy/app/Resources/classic/savebtn@2x.png +0 -0
  277. psychopy/app/Resources/classic/search.png +0 -0
  278. psychopy/app/Resources/classic/search@2x.png +0 -0
  279. psychopy/app/Resources/classic/showBuilder.png +0 -0
  280. psychopy/app/Resources/classic/showBuilder@2x.png +0 -0
  281. psychopy/app/Resources/classic/showCoder.png +0 -0
  282. psychopy/app/Resources/classic/showCoder@2x.png +0 -0
  283. psychopy/app/Resources/classic/showRunner.png +0 -0
  284. psychopy/app/Resources/classic/showRunner@2x.png +0 -0
  285. psychopy/app/Resources/classic/starred.png +0 -0
  286. psychopy/app/Resources/classic/starred@2x.png +0 -0
  287. psychopy/app/Resources/classic/start.png +0 -0
  288. psychopy/app/Resources/classic/start@2x.png +0 -0
  289. psychopy/app/Resources/classic/stdout.png +0 -0
  290. psychopy/app/Resources/classic/stop.png +0 -0
  291. psychopy/app/Resources/classic/stop32.png +0 -0
  292. psychopy/app/Resources/classic/stop@2x.png +0 -0
  293. psychopy/app/Resources/classic/switchCtrlBot.png +0 -0
  294. psychopy/app/Resources/classic/switchCtrlBot@2x.png +0 -0
  295. psychopy/app/Resources/classic/switchCtrlLeft.png +0 -0
  296. psychopy/app/Resources/classic/switchCtrlLeft@2x.png +0 -0
  297. psychopy/app/Resources/classic/switchCtrlRight.png +0 -0
  298. psychopy/app/Resources/classic/switchCtrlRight@2x.png +0 -0
  299. psychopy/app/Resources/classic/switchCtrlTop.png +0 -0
  300. psychopy/app/Resources/classic/switchCtrlTop@2x.png +0 -0
  301. psychopy/app/Resources/classic/tick.png +0 -0
  302. psychopy/app/Resources/classic/tick@2x.png +0 -0
  303. psychopy/app/Resources/classic/undo.png +0 -0
  304. psychopy/app/Resources/classic/undo32.png +0 -0
  305. psychopy/app/Resources/classic/undo@2x.png +0 -0
  306. psychopy/app/Resources/classic/unstarred.png +0 -0
  307. psychopy/app/Resources/classic/unstarred@2x.png +0 -0
  308. psychopy/app/Resources/classic/user_none.png +0 -0
  309. psychopy/app/Resources/classic/view-refresh16.png +0 -0
  310. psychopy/app/Resources/classic/viewbtn.png +0 -0
  311. psychopy/app/Resources/classic/viewbtn16.png +0 -0
  312. psychopy/app/Resources/classic/viewbtn16@2x.png +0 -0
  313. psychopy/app/Resources/classic/viewbtn@2x.png +0 -0
  314. psychopy/app/Resources/classic/windows16.png +0 -0
  315. psychopy/app/Resources/classic/windows16@2x.png +0 -0
  316. psychopy/app/Resources/click.png +0 -0
  317. psychopy/app/Resources/coder.ico +0 -0
  318. psychopy/app/Resources/creditCard.png +0 -0
  319. psychopy/app/Resources/dark/FlowBottom_CompLeft.png +0 -0
  320. psychopy/app/Resources/dark/FlowBottom_CompRight.png +0 -0
  321. psychopy/app/Resources/dark/FlowTop_CompLeft.png +0 -0
  322. psychopy/app/Resources/dark/FlowTop_CompRight.png +0 -0
  323. psychopy/app/Resources/dark/README.txt +3 -0
  324. psychopy/app/Resources/dark/__init__.py +0 -0
  325. psychopy/app/Resources/dark/add.png +0 -0
  326. psychopy/app/Resources/dark/add@2x.png +0 -0
  327. psychopy/app/Resources/dark/addExp32.png +0 -0
  328. psychopy/app/Resources/dark/addExp32@2x.png +0 -0
  329. psychopy/app/Resources/dark/alerts.png +0 -0
  330. psychopy/app/Resources/dark/alerts@2x.png +0 -0
  331. psychopy/app/Resources/dark/beta.png +0 -0
  332. psychopy/app/Resources/dark/beta@2x.png +0 -0
  333. psychopy/app/Resources/dark/browser.png +0 -0
  334. psychopy/app/Resources/dark/browser@2x.png +0 -0
  335. psychopy/app/Resources/dark/bug16.png +0 -0
  336. psychopy/app/Resources/dark/bug16@2x.png +0 -0
  337. psychopy/app/Resources/dark/circle_mask.png +0 -0
  338. psychopy/app/Resources/dark/circle_mask@2x.png +0 -0
  339. psychopy/app/Resources/dark/clear.png +0 -0
  340. psychopy/app/Resources/dark/clear@2x.png +0 -0
  341. psychopy/app/Resources/dark/coderclass16.png +0 -0
  342. psychopy/app/Resources/dark/coderclass16@2x.png +0 -0
  343. psychopy/app/Resources/dark/coderfunc16.png +0 -0
  344. psychopy/app/Resources/dark/coderfunc16@2x.png +0 -0
  345. psychopy/app/Resources/dark/coderimport16.png +0 -0
  346. psychopy/app/Resources/dark/coderimport16@2x.png +0 -0
  347. psychopy/app/Resources/dark/coderjs.png +0 -0
  348. psychopy/app/Resources/dark/coderjs@2x.png +0 -0
  349. psychopy/app/Resources/dark/coderpython.png +0 -0
  350. psychopy/app/Resources/dark/coderpython@2x.png +0 -0
  351. psychopy/app/Resources/dark/codervar16.png +0 -0
  352. psychopy/app/Resources/dark/codervar16@2x.png +0 -0
  353. psychopy/app/Resources/dark/cogwindow32.png +0 -0
  354. psychopy/app/Resources/dark/cogwindow32@2x.png +0 -0
  355. psychopy/app/Resources/dark/color32.png +0 -0
  356. psychopy/app/Resources/dark/color32@2x.png +0 -0
  357. psychopy/app/Resources/dark/compile_js.png +0 -0
  358. psychopy/app/Resources/dark/compile_js@2x.png +0 -0
  359. psychopy/app/Resources/dark/compile_py.png +0 -0
  360. psychopy/app/Resources/dark/compile_py@2x.png +0 -0
  361. psychopy/app/Resources/dark/copy16.png +0 -0
  362. psychopy/app/Resources/dark/copy16@2x.png +0 -0
  363. psychopy/app/Resources/dark/currentFile16.png +0 -0
  364. psychopy/app/Resources/dark/currentFile16@2x.png +0 -0
  365. psychopy/app/Resources/dark/delete16.png +0 -0
  366. psychopy/app/Resources/dark/delete16@2x.png +0 -0
  367. psychopy/app/Resources/dark/desktop.png +0 -0
  368. psychopy/app/Resources/dark/desktop@2x.png +0 -0
  369. psychopy/app/Resources/dark/dirup16.png +0 -0
  370. psychopy/app/Resources/dark/dirup16@2x.png +0 -0
  371. psychopy/app/Resources/dark/docclose16.png +0 -0
  372. psychopy/app/Resources/dark/docclose16@2x.png +0 -0
  373. psychopy/app/Resources/dark/download.png +0 -0
  374. psychopy/app/Resources/dark/download@2x.png +0 -0
  375. psychopy/app/Resources/dark/edit.png +0 -0
  376. psychopy/app/Resources/dark/edit@2x.png +0 -0
  377. psychopy/app/Resources/dark/editbtn16.png +0 -0
  378. psychopy/app/Resources/dark/editbtn16@2x.png +0 -0
  379. psychopy/app/Resources/dark/email.png +0 -0
  380. psychopy/app/Resources/dark/email@2x.png +0 -0
  381. psychopy/app/Resources/dark/experiment.png +0 -0
  382. psychopy/app/Resources/dark/experiment@2x.png +0 -0
  383. psychopy/app/Resources/dark/expsettings.png +0 -0
  384. psychopy/app/Resources/dark/expsettings@2x.png +0 -0
  385. psychopy/app/Resources/dark/file.png +0 -0
  386. psychopy/app/Resources/dark/file@16w.png +0 -0
  387. psychopy/app/Resources/dark/file@16w@2x.png +0 -0
  388. psychopy/app/Resources/dark/file@2x.png +0 -0
  389. psychopy/app/Resources/dark/filecsv16.png +0 -0
  390. psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
  391. psychopy/app/Resources/dark/fileimage16.png +0 -0
  392. psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
  393. psychopy/app/Resources/dark/filenew.png +0 -0
  394. psychopy/app/Resources/dark/filenew32.png +0 -0
  395. psychopy/app/Resources/dark/filenew32@2x.png +0 -0
  396. psychopy/app/Resources/dark/filenew@2x.png +0 -0
  397. psychopy/app/Resources/dark/fileopen.png +0 -0
  398. psychopy/app/Resources/dark/fileopen32.png +0 -0
  399. psychopy/app/Resources/dark/fileopen32@2x.png +0 -0
  400. psychopy/app/Resources/dark/fileopen@2x.png +0 -0
  401. psychopy/app/Resources/dark/filesave.png +0 -0
  402. psychopy/app/Resources/dark/filesave32.png +0 -0
  403. psychopy/app/Resources/dark/filesave32@2x.png +0 -0
  404. psychopy/app/Resources/dark/filesave@2x.png +0 -0
  405. psychopy/app/Resources/dark/filesaveas.png +0 -0
  406. psychopy/app/Resources/dark/filesaveas32.png +0 -0
  407. psychopy/app/Resources/dark/filesaveas32@2x.png +0 -0
  408. psychopy/app/Resources/dark/filesaveas@2x.png +0 -0
  409. psychopy/app/Resources/dark/fileunknown16.png +0 -0
  410. psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
  411. psychopy/app/Resources/dark/filter.png +0 -0
  412. psychopy/app/Resources/dark/filter@2x.png +0 -0
  413. psychopy/app/Resources/dark/folder-open16.png +0 -0
  414. psychopy/app/Resources/dark/folder-open16@2x.png +0 -0
  415. psychopy/app/Resources/dark/folder16.png +0 -0
  416. psychopy/app/Resources/dark/folder16@2x.png +0 -0
  417. psychopy/app/Resources/dark/foldernew16.png +0 -0
  418. psychopy/app/Resources/dark/foldernew16@2x.png +0 -0
  419. psychopy/app/Resources/dark/fork.png +0 -0
  420. psychopy/app/Resources/dark/fork@2x.png +0 -0
  421. psychopy/app/Resources/dark/github.png +0 -0
  422. psychopy/app/Resources/dark/github@2x.png +0 -0
  423. psychopy/app/Resources/dark/globe.png +0 -0
  424. psychopy/app/Resources/dark/globe@2x.png +0 -0
  425. psychopy/app/Resources/dark/globe_bug.png +0 -0
  426. psychopy/app/Resources/dark/globe_bug@2x.png +0 -0
  427. psychopy/app/Resources/dark/globe_greensync.png +0 -0
  428. psychopy/app/Resources/dark/globe_greensync@2x.png +0 -0
  429. psychopy/app/Resources/dark/globe_info.png +0 -0
  430. psychopy/app/Resources/dark/globe_info@2x.png +0 -0
  431. psychopy/app/Resources/dark/globe_magnifier.png +0 -0
  432. psychopy/app/Resources/dark/globe_magnifier@2x.png +0 -0
  433. psychopy/app/Resources/dark/globe_run.png +0 -0
  434. psychopy/app/Resources/dark/globe_run@2x.png +0 -0
  435. psychopy/app/Resources/dark/globe_user.png +0 -0
  436. psychopy/app/Resources/dark/globe_user@2x.png +0 -0
  437. psychopy/app/Resources/dark/goto.png +0 -0
  438. psychopy/app/Resources/dark/goto@2x.png +0 -0
  439. psychopy/app/Resources/dark/greendot.png +0 -0
  440. psychopy/app/Resources/dark/greendot@2x.png +0 -0
  441. psychopy/app/Resources/dark/greenglobe.png +0 -0
  442. psychopy/app/Resources/dark/greenglobe@2x.png +0 -0
  443. psychopy/app/Resources/dark/greenglobe_bug.png +0 -0
  444. psychopy/app/Resources/dark/greenglobe_bug@2x.png +0 -0
  445. psychopy/app/Resources/dark/greenglobe_greensync.png +0 -0
  446. psychopy/app/Resources/dark/greenglobe_greensync@2x.png +0 -0
  447. psychopy/app/Resources/dark/greenglobe_info.png +0 -0
  448. psychopy/app/Resources/dark/greenglobe_info@2x.png +0 -0
  449. psychopy/app/Resources/dark/greenglobe_magnifier.png +0 -0
  450. psychopy/app/Resources/dark/greenglobe_magnifier@2x.png +0 -0
  451. psychopy/app/Resources/dark/greenglobe_run.png +0 -0
  452. psychopy/app/Resources/dark/greenglobe_run@2x.png +0 -0
  453. psychopy/app/Resources/dark/greenglobe_user.png +0 -0
  454. psychopy/app/Resources/dark/greenglobe_user@2x.png +0 -0
  455. psychopy/app/Resources/dark/greydot.png +0 -0
  456. psychopy/app/Resources/dark/greydot@2x.png +0 -0
  457. psychopy/app/Resources/dark/greytick.png +0 -0
  458. psychopy/app/Resources/dark/greytick@2x.png +0 -0
  459. psychopy/app/Resources/dark/invalid_img.png +0 -0
  460. psychopy/app/Resources/dark/jsPilot.png +0 -0
  461. psychopy/app/Resources/dark/jsPilot@2x.png +0 -0
  462. psychopy/app/Resources/dark/jsRun.png +0 -0
  463. psychopy/app/Resources/dark/jsRun@2x.png +0 -0
  464. psychopy/app/Resources/dark/libroot16.png +0 -0
  465. psychopy/app/Resources/dark/libroot16@2x.png +0 -0
  466. psychopy/app/Resources/dark/monitor16.png +0 -0
  467. psychopy/app/Resources/dark/monitor16@2x.png +0 -0
  468. psychopy/app/Resources/dark/monitors.png +0 -0
  469. psychopy/app/Resources/dark/monitors32.png +0 -0
  470. psychopy/app/Resources/dark/monitors32@2x.png +0 -0
  471. psychopy/app/Resources/dark/monitors@2x.png +0 -0
  472. psychopy/app/Resources/dark/orangedot.png +0 -0
  473. psychopy/app/Resources/dark/orangedot@2x.png +0 -0
  474. psychopy/app/Resources/dark/pavlovia.png +0 -0
  475. psychopy/app/Resources/dark/pavlovia16.png +0 -0
  476. psychopy/app/Resources/dark/pavlovia16@2x.png +0 -0
  477. psychopy/app/Resources/dark/pavlovia@2x.png +0 -0
  478. psychopy/app/Resources/dark/pavsync.png +0 -0
  479. psychopy/app/Resources/dark/pavsync@2x.png +0 -0
  480. psychopy/app/Resources/dark/person_off.png +0 -0
  481. psychopy/app/Resources/dark/person_off@2x.png +0 -0
  482. psychopy/app/Resources/dark/person_on.png +0 -0
  483. psychopy/app/Resources/dark/person_on@2x.png +0 -0
  484. psychopy/app/Resources/dark/plugins32.png +0 -0
  485. psychopy/app/Resources/dark/plugins32@2x.png +0 -0
  486. psychopy/app/Resources/dark/plus.png +0 -0
  487. psychopy/app/Resources/dark/plus@2x.png +0 -0
  488. psychopy/app/Resources/dark/preferences-app.png +0 -0
  489. psychopy/app/Resources/dark/preferences-app48.png +0 -0
  490. psychopy/app/Resources/dark/preferences-app48@2x.png +0 -0
  491. psychopy/app/Resources/dark/preferences-app@2x.png +0 -0
  492. psychopy/app/Resources/dark/preferences-conn.png +0 -0
  493. psychopy/app/Resources/dark/preferences-conn48.png +0 -0
  494. psychopy/app/Resources/dark/preferences-conn48@2x.png +0 -0
  495. psychopy/app/Resources/dark/preferences-conn@2x.png +0 -0
  496. psychopy/app/Resources/dark/preferences-debug.png +0 -0
  497. psychopy/app/Resources/dark/preferences-debug@2x.png +0 -0
  498. psychopy/app/Resources/dark/preferences-general.png +0 -0
  499. psychopy/app/Resources/dark/preferences-general48.png +0 -0
  500. psychopy/app/Resources/dark/preferences-general48@2x.png +0 -0
  501. psychopy/app/Resources/dark/preferences-general@2x.png +0 -0
  502. psychopy/app/Resources/dark/preferences-hardware.png +0 -0
  503. psychopy/app/Resources/dark/preferences-hardware48.png +0 -0
  504. psychopy/app/Resources/dark/preferences-hardware48@2x.png +0 -0
  505. psychopy/app/Resources/dark/preferences-hardware@2x.png +0 -0
  506. psychopy/app/Resources/dark/preferences-keyboard.png +0 -0
  507. psychopy/app/Resources/dark/preferences-keyboard48.png +0 -0
  508. psychopy/app/Resources/dark/preferences-keyboard48@2x.png +0 -0
  509. psychopy/app/Resources/dark/preferences-keyboard@2x.png +0 -0
  510. psychopy/app/Resources/dark/preferences-pilot.png +0 -0
  511. psychopy/app/Resources/dark/preferences-pilot@2x.png +0 -0
  512. psychopy/app/Resources/dark/preferences32.png +0 -0
  513. psychopy/app/Resources/dark/preferences32@2x.png +0 -0
  514. psychopy/app/Resources/dark/pyPilot.png +0 -0
  515. psychopy/app/Resources/dark/pyPilot@2x.png +0 -0
  516. psychopy/app/Resources/dark/pyRun.png +0 -0
  517. psychopy/app/Resources/dark/pyRun@2x.png +0 -0
  518. psychopy/app/Resources/dark/reddot.png +0 -0
  519. psychopy/app/Resources/dark/reddot@2x.png +0 -0
  520. psychopy/app/Resources/dark/redglobe.png +0 -0
  521. psychopy/app/Resources/dark/redglobe@2x.png +0 -0
  522. psychopy/app/Resources/dark/redglobe_bug.png +0 -0
  523. psychopy/app/Resources/dark/redglobe_bug@2x.png +0 -0
  524. psychopy/app/Resources/dark/redglobe_greensync.png +0 -0
  525. psychopy/app/Resources/dark/redglobe_greensync@2x.png +0 -0
  526. psychopy/app/Resources/dark/redglobe_info.png +0 -0
  527. psychopy/app/Resources/dark/redglobe_info@2x.png +0 -0
  528. psychopy/app/Resources/dark/redglobe_magnifier.png +0 -0
  529. psychopy/app/Resources/dark/redglobe_magnifier@2x.png +0 -0
  530. psychopy/app/Resources/dark/redglobe_run.png +0 -0
  531. psychopy/app/Resources/dark/redglobe_run@2x.png +0 -0
  532. psychopy/app/Resources/dark/redglobe_user.png +0 -0
  533. psychopy/app/Resources/dark/redglobe_user@2x.png +0 -0
  534. psychopy/app/Resources/dark/redo.png +0 -0
  535. psychopy/app/Resources/dark/redo32.png +0 -0
  536. psychopy/app/Resources/dark/redo32@2x.png +0 -0
  537. psychopy/app/Resources/dark/redo@2x.png +0 -0
  538. psychopy/app/Resources/dark/removeExp32.png +0 -0
  539. psychopy/app/Resources/dark/removeExp32@2x.png +0 -0
  540. psychopy/app/Resources/dark/rename16.png +0 -0
  541. psychopy/app/Resources/dark/rename16@2x.png +0 -0
  542. psychopy/app/Resources/dark/restart.png +0 -0
  543. psychopy/app/Resources/dark/restart@2x.png +0 -0
  544. psychopy/app/Resources/dark/runner.png +0 -0
  545. psychopy/app/Resources/dark/runner@2x.png +0 -0
  546. psychopy/app/Resources/dark/runnerPilot.png +0 -0
  547. psychopy/app/Resources/dark/runnerPilot@2x.png +0 -0
  548. psychopy/app/Resources/dark/savebtn16.png +0 -0
  549. psychopy/app/Resources/dark/savebtn16@2x.png +0 -0
  550. psychopy/app/Resources/dark/search.png +0 -0
  551. psychopy/app/Resources/dark/search@2x.png +0 -0
  552. psychopy/app/Resources/dark/showBuilder.png +0 -0
  553. psychopy/app/Resources/dark/showBuilder@2x.png +0 -0
  554. psychopy/app/Resources/dark/showCoder.png +0 -0
  555. psychopy/app/Resources/dark/showCoder@2x.png +0 -0
  556. psychopy/app/Resources/dark/showRunner.png +0 -0
  557. psychopy/app/Resources/dark/showRunner@2x.png +0 -0
  558. psychopy/app/Resources/dark/starred.png +0 -0
  559. psychopy/app/Resources/dark/starred@2x.png +0 -0
  560. psychopy/app/Resources/dark/start.png +0 -0
  561. psychopy/app/Resources/dark/start@2x.png +0 -0
  562. psychopy/app/Resources/dark/stdout.png +0 -0
  563. psychopy/app/Resources/dark/stdout@2x.png +0 -0
  564. psychopy/app/Resources/dark/stop.png +0 -0
  565. psychopy/app/Resources/dark/stop32.png +0 -0
  566. psychopy/app/Resources/dark/stop32@2x.png +0 -0
  567. psychopy/app/Resources/dark/stop@2x.png +0 -0
  568. psychopy/app/Resources/dark/switchCtrlBot.png +0 -0
  569. psychopy/app/Resources/dark/switchCtrlBot@2x.png +0 -0
  570. psychopy/app/Resources/dark/switchCtrlLeft.png +0 -0
  571. psychopy/app/Resources/dark/switchCtrlLeft@2x.png +0 -0
  572. psychopy/app/Resources/dark/switchCtrlRight.png +0 -0
  573. psychopy/app/Resources/dark/switchCtrlRight@2x.png +0 -0
  574. psychopy/app/Resources/dark/switchCtrlTop.png +0 -0
  575. psychopy/app/Resources/dark/switchCtrlTop@2x.png +0 -0
  576. psychopy/app/Resources/dark/tick.png +0 -0
  577. psychopy/app/Resources/dark/tick@2x.png +0 -0
  578. psychopy/app/Resources/dark/undo.png +0 -0
  579. psychopy/app/Resources/dark/undo32.png +0 -0
  580. psychopy/app/Resources/dark/undo32@2x.png +0 -0
  581. psychopy/app/Resources/dark/undo@2x.png +0 -0
  582. psychopy/app/Resources/dark/unstarred.png +0 -0
  583. psychopy/app/Resources/dark/unstarred@2x.png +0 -0
  584. psychopy/app/Resources/dark/user_none.png +0 -0
  585. psychopy/app/Resources/dark/view-refresh16.png +0 -0
  586. psychopy/app/Resources/dark/view-refresh16@2x.png +0 -0
  587. psychopy/app/Resources/dark/viewbtn16.png +0 -0
  588. psychopy/app/Resources/dark/viewbtn16@2x.png +0 -0
  589. psychopy/app/Resources/dark/windows16.png +0 -0
  590. psychopy/app/Resources/dark/windows16@2x.png +0 -0
  591. psychopy/app/Resources/default.mp3 +0 -0
  592. psychopy/app/Resources/default.mp4 +0 -0
  593. psychopy/app/Resources/default.png +0 -0
  594. psychopy/app/Resources/fonts/Arvo-Bold.ttf +0 -0
  595. psychopy/app/Resources/fonts/Arvo-BoldItalic.ttf +0 -0
  596. psychopy/app/Resources/fonts/Arvo-Italic.ttf +0 -0
  597. psychopy/app/Resources/fonts/Arvo-Regular.ttf +0 -0
  598. psychopy/app/Resources/fonts/DejaVuSerif.ttf +0 -0
  599. psychopy/app/Resources/fonts/IndieFlower-Regular.ttf +0 -0
  600. psychopy/app/Resources/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
  601. psychopy/app/Resources/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
  602. psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
  603. psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
  604. psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
  605. psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  606. psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
  607. psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
  608. psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
  609. psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
  610. psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
  611. psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
  612. psychopy/app/Resources/instruct1.png +0 -0
  613. psychopy/app/Resources/instruct2.png +0 -0
  614. psychopy/app/Resources/light/FlowBottom_CompLeft.png +0 -0
  615. psychopy/app/Resources/light/FlowBottom_CompRight.png +0 -0
  616. psychopy/app/Resources/light/FlowTop_CompLeft.png +0 -0
  617. psychopy/app/Resources/light/FlowTop_CompRight.png +0 -0
  618. psychopy/app/Resources/light/README.txt +3 -0
  619. psychopy/app/Resources/light/__init__.py +0 -0
  620. psychopy/app/Resources/light/add.png +0 -0
  621. psychopy/app/Resources/light/add@2x.png +0 -0
  622. psychopy/app/Resources/light/addExp32.png +0 -0
  623. psychopy/app/Resources/light/addExp32@2x.png +0 -0
  624. psychopy/app/Resources/light/alerts.png +0 -0
  625. psychopy/app/Resources/light/alerts@2x.png +0 -0
  626. psychopy/app/Resources/light/beta.png +0 -0
  627. psychopy/app/Resources/light/beta@2x.png +0 -0
  628. psychopy/app/Resources/light/browser.png +0 -0
  629. psychopy/app/Resources/light/browser@2x.png +0 -0
  630. psychopy/app/Resources/light/bug16.png +0 -0
  631. psychopy/app/Resources/light/bug16@2x.png +0 -0
  632. psychopy/app/Resources/light/circle_mask.png +0 -0
  633. psychopy/app/Resources/light/circle_mask@2x.png +0 -0
  634. psychopy/app/Resources/light/clear.png +0 -0
  635. psychopy/app/Resources/light/clear@2x.png +0 -0
  636. psychopy/app/Resources/light/coderclass16.png +0 -0
  637. psychopy/app/Resources/light/coderclass16@2x.png +0 -0
  638. psychopy/app/Resources/light/coderfunc16.png +0 -0
  639. psychopy/app/Resources/light/coderfunc16@2x.png +0 -0
  640. psychopy/app/Resources/light/coderimport16.png +0 -0
  641. psychopy/app/Resources/light/coderimport16@2x.png +0 -0
  642. psychopy/app/Resources/light/coderjs.png +0 -0
  643. psychopy/app/Resources/light/coderjs@2x.png +0 -0
  644. psychopy/app/Resources/light/coderpython.png +0 -0
  645. psychopy/app/Resources/light/coderpython@2x.png +0 -0
  646. psychopy/app/Resources/light/codervar16.png +0 -0
  647. psychopy/app/Resources/light/codervar16@2x.png +0 -0
  648. psychopy/app/Resources/light/cogwindow32.png +0 -0
  649. psychopy/app/Resources/light/cogwindow32@2x.png +0 -0
  650. psychopy/app/Resources/light/color16.png +0 -0
  651. psychopy/app/Resources/light/color16@2x.png +0 -0
  652. psychopy/app/Resources/light/color32.png +0 -0
  653. psychopy/app/Resources/light/color32@2x.png +0 -0
  654. psychopy/app/Resources/light/compile_js.png +0 -0
  655. psychopy/app/Resources/light/compile_js@2x.png +0 -0
  656. psychopy/app/Resources/light/compile_py.png +0 -0
  657. psychopy/app/Resources/light/compile_py@2x.png +0 -0
  658. psychopy/app/Resources/light/copy16.png +0 -0
  659. psychopy/app/Resources/light/copy16@2x.png +0 -0
  660. psychopy/app/Resources/light/currentFile16.png +0 -0
  661. psychopy/app/Resources/light/currentFile16@2x.png +0 -0
  662. psychopy/app/Resources/light/delete16.png +0 -0
  663. psychopy/app/Resources/light/delete16@2x.png +0 -0
  664. psychopy/app/Resources/light/delete8.png +0 -0
  665. psychopy/app/Resources/light/desktop.png +0 -0
  666. psychopy/app/Resources/light/desktop@2x.png +0 -0
  667. psychopy/app/Resources/light/dirup16.png +0 -0
  668. psychopy/app/Resources/light/dirup16@2x.png +0 -0
  669. psychopy/app/Resources/light/docclose16.png +0 -0
  670. psychopy/app/Resources/light/docclose16@2x.png +0 -0
  671. psychopy/app/Resources/light/download.png +0 -0
  672. psychopy/app/Resources/light/download@2x.png +0 -0
  673. psychopy/app/Resources/light/edit.png +0 -0
  674. psychopy/app/Resources/light/edit@2x.png +0 -0
  675. psychopy/app/Resources/light/editbtn16.png +0 -0
  676. psychopy/app/Resources/light/editbtn16@2x.png +0 -0
  677. psychopy/app/Resources/light/email.png +0 -0
  678. psychopy/app/Resources/light/email@2x.png +0 -0
  679. psychopy/app/Resources/light/experiment.png +0 -0
  680. psychopy/app/Resources/light/experiment@2x.png +0 -0
  681. psychopy/app/Resources/light/expsettings.png +0 -0
  682. psychopy/app/Resources/light/expsettings@2x.png +0 -0
  683. psychopy/app/Resources/light/file.png +0 -0
  684. psychopy/app/Resources/light/file@2x.png +0 -0
  685. psychopy/app/Resources/light/filecsv16.png +0 -0
  686. psychopy/app/Resources/light/filecsv16@2x.png +0 -0
  687. psychopy/app/Resources/light/fileimage16.png +0 -0
  688. psychopy/app/Resources/light/fileimage16@2x.png +0 -0
  689. psychopy/app/Resources/light/filenew.png +0 -0
  690. psychopy/app/Resources/light/filenew32.png +0 -0
  691. psychopy/app/Resources/light/filenew32@2x.png +0 -0
  692. psychopy/app/Resources/light/filenew@2x.png +0 -0
  693. psychopy/app/Resources/light/fileopen.png +0 -0
  694. psychopy/app/Resources/light/fileopen32.png +0 -0
  695. psychopy/app/Resources/light/fileopen32@2x.png +0 -0
  696. psychopy/app/Resources/light/fileopen@2x.png +0 -0
  697. psychopy/app/Resources/light/filesave.png +0 -0
  698. psychopy/app/Resources/light/filesave32.png +0 -0
  699. psychopy/app/Resources/light/filesave32@2x.png +0 -0
  700. psychopy/app/Resources/light/filesave@2x.png +0 -0
  701. psychopy/app/Resources/light/filesaveas.png +0 -0
  702. psychopy/app/Resources/light/filesaveas32.png +0 -0
  703. psychopy/app/Resources/light/filesaveas32@2x.png +0 -0
  704. psychopy/app/Resources/light/filesaveas@2x.png +0 -0
  705. psychopy/app/Resources/light/fileunknown16.png +0 -0
  706. psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
  707. psychopy/app/Resources/light/filter.png +0 -0
  708. psychopy/app/Resources/light/filter@2x.png +0 -0
  709. psychopy/app/Resources/light/folder-open16.png +0 -0
  710. psychopy/app/Resources/light/folder-open16@2x.png +0 -0
  711. psychopy/app/Resources/light/folder16.png +0 -0
  712. psychopy/app/Resources/light/folder16@2x.png +0 -0
  713. psychopy/app/Resources/light/foldernew16.png +0 -0
  714. psychopy/app/Resources/light/foldernew16@2x.png +0 -0
  715. psychopy/app/Resources/light/fork.png +0 -0
  716. psychopy/app/Resources/light/fork@2x.png +0 -0
  717. psychopy/app/Resources/light/github.png +0 -0
  718. psychopy/app/Resources/light/github@2x.png +0 -0
  719. psychopy/app/Resources/light/globe.png +0 -0
  720. psychopy/app/Resources/light/globe@2x.png +0 -0
  721. psychopy/app/Resources/light/globe_bug.png +0 -0
  722. psychopy/app/Resources/light/globe_bug@2x.png +0 -0
  723. psychopy/app/Resources/light/globe_greensync.png +0 -0
  724. psychopy/app/Resources/light/globe_greensync@2x.png +0 -0
  725. psychopy/app/Resources/light/globe_info.png +0 -0
  726. psychopy/app/Resources/light/globe_info@2x.png +0 -0
  727. psychopy/app/Resources/light/globe_magnifier.png +0 -0
  728. psychopy/app/Resources/light/globe_magnifier@2x.png +0 -0
  729. psychopy/app/Resources/light/globe_run.png +0 -0
  730. psychopy/app/Resources/light/globe_run@2x.png +0 -0
  731. psychopy/app/Resources/light/globe_user.png +0 -0
  732. psychopy/app/Resources/light/globe_user@2x.png +0 -0
  733. psychopy/app/Resources/light/goto16.png +0 -0
  734. psychopy/app/Resources/light/goto16@2x.png +0 -0
  735. psychopy/app/Resources/light/greendot.png +0 -0
  736. psychopy/app/Resources/light/greendot@2x.png +0 -0
  737. psychopy/app/Resources/light/greenglobe.png +0 -0
  738. psychopy/app/Resources/light/greenglobe@2x.png +0 -0
  739. psychopy/app/Resources/light/greenglobe_bug.png +0 -0
  740. psychopy/app/Resources/light/greenglobe_bug@2x.png +0 -0
  741. psychopy/app/Resources/light/greenglobe_greensync.png +0 -0
  742. psychopy/app/Resources/light/greenglobe_greensync@2x.png +0 -0
  743. psychopy/app/Resources/light/greenglobe_info.png +0 -0
  744. psychopy/app/Resources/light/greenglobe_info@2x.png +0 -0
  745. psychopy/app/Resources/light/greenglobe_magnifier.png +0 -0
  746. psychopy/app/Resources/light/greenglobe_magnifier@2x.png +0 -0
  747. psychopy/app/Resources/light/greenglobe_run.png +0 -0
  748. psychopy/app/Resources/light/greenglobe_run@2x.png +0 -0
  749. psychopy/app/Resources/light/greenglobe_user.png +0 -0
  750. psychopy/app/Resources/light/greenglobe_user@2x.png +0 -0
  751. psychopy/app/Resources/light/greydot.png +0 -0
  752. psychopy/app/Resources/light/greydot@2x.png +0 -0
  753. psychopy/app/Resources/light/greytick.png +0 -0
  754. psychopy/app/Resources/light/greytick@2x.png +0 -0
  755. psychopy/app/Resources/light/invalid_img.png +0 -0
  756. psychopy/app/Resources/light/jsPilot.png +0 -0
  757. psychopy/app/Resources/light/jsPilot@2x.png +0 -0
  758. psychopy/app/Resources/light/jsRun.png +0 -0
  759. psychopy/app/Resources/light/jsRun@2x.png +0 -0
  760. psychopy/app/Resources/light/libroot16.png +0 -0
  761. psychopy/app/Resources/light/libroot16@2x.png +0 -0
  762. psychopy/app/Resources/light/monitor16.png +0 -0
  763. psychopy/app/Resources/light/monitor16@2x.png +0 -0
  764. psychopy/app/Resources/light/monitors.png +0 -0
  765. psychopy/app/Resources/light/monitors32.png +0 -0
  766. psychopy/app/Resources/light/monitors32@2x.png +0 -0
  767. psychopy/app/Resources/light/monitors@2x.png +0 -0
  768. psychopy/app/Resources/light/orangedot.png +0 -0
  769. psychopy/app/Resources/light/orangedot@2x.png +0 -0
  770. psychopy/app/Resources/light/pavlovia.png +0 -0
  771. psychopy/app/Resources/light/pavlovia16.png +0 -0
  772. psychopy/app/Resources/light/pavlovia16@2x.png +0 -0
  773. psychopy/app/Resources/light/pavlovia@2x.png +0 -0
  774. psychopy/app/Resources/light/pavsync.png +0 -0
  775. psychopy/app/Resources/light/pavsync@2x.png +0 -0
  776. psychopy/app/Resources/light/person_off.png +0 -0
  777. psychopy/app/Resources/light/person_off@2x.png +0 -0
  778. psychopy/app/Resources/light/person_on.png +0 -0
  779. psychopy/app/Resources/light/person_on@2x.png +0 -0
  780. psychopy/app/Resources/light/plugins32.png +0 -0
  781. psychopy/app/Resources/light/plugins32@2x.png +0 -0
  782. psychopy/app/Resources/light/plus.png +0 -0
  783. psychopy/app/Resources/light/plus@2x.png +0 -0
  784. psychopy/app/Resources/light/preferences-app.png +0 -0
  785. psychopy/app/Resources/light/preferences-app48.png +0 -0
  786. psychopy/app/Resources/light/preferences-app48@2x.png +0 -0
  787. psychopy/app/Resources/light/preferences-app@2x.png +0 -0
  788. psychopy/app/Resources/light/preferences-conn.png +0 -0
  789. psychopy/app/Resources/light/preferences-conn48.png +0 -0
  790. psychopy/app/Resources/light/preferences-conn48@2x.png +0 -0
  791. psychopy/app/Resources/light/preferences-conn@2x.png +0 -0
  792. psychopy/app/Resources/light/preferences-general.png +0 -0
  793. psychopy/app/Resources/light/preferences-general48.png +0 -0
  794. psychopy/app/Resources/light/preferences-general48@2x.png +0 -0
  795. psychopy/app/Resources/light/preferences-general@2x.png +0 -0
  796. psychopy/app/Resources/light/preferences-hardware.png +0 -0
  797. psychopy/app/Resources/light/preferences-hardware48.png +0 -0
  798. psychopy/app/Resources/light/preferences-hardware48@2x.png +0 -0
  799. psychopy/app/Resources/light/preferences-hardware@2x.png +0 -0
  800. psychopy/app/Resources/light/preferences-keyboard.png +0 -0
  801. psychopy/app/Resources/light/preferences-keyboard48.png +0 -0
  802. psychopy/app/Resources/light/preferences-keyboard48@2x.png +0 -0
  803. psychopy/app/Resources/light/preferences-keyboard@2x.png +0 -0
  804. psychopy/app/Resources/light/preferences-pilot.png +0 -0
  805. psychopy/app/Resources/light/preferences-pilot@2x.png +0 -0
  806. psychopy/app/Resources/light/preferences32.png +0 -0
  807. psychopy/app/Resources/light/preferences32@2x.png +0 -0
  808. psychopy/app/Resources/light/pyPilot.png +0 -0
  809. psychopy/app/Resources/light/pyPilot@2x.png +0 -0
  810. psychopy/app/Resources/light/pyRun.png +0 -0
  811. psychopy/app/Resources/light/pyRun@2x.png +0 -0
  812. psychopy/app/Resources/light/reddot.png +0 -0
  813. psychopy/app/Resources/light/reddot@2x.png +0 -0
  814. psychopy/app/Resources/light/redglobe.png +0 -0
  815. psychopy/app/Resources/light/redglobe@2x.png +0 -0
  816. psychopy/app/Resources/light/redglobe_bug.png +0 -0
  817. psychopy/app/Resources/light/redglobe_bug@2x.png +0 -0
  818. psychopy/app/Resources/light/redglobe_greensync.png +0 -0
  819. psychopy/app/Resources/light/redglobe_greensync@2x.png +0 -0
  820. psychopy/app/Resources/light/redglobe_info.png +0 -0
  821. psychopy/app/Resources/light/redglobe_info@2x.png +0 -0
  822. psychopy/app/Resources/light/redglobe_magnifier.png +0 -0
  823. psychopy/app/Resources/light/redglobe_magnifier@2x.png +0 -0
  824. psychopy/app/Resources/light/redglobe_run.png +0 -0
  825. psychopy/app/Resources/light/redglobe_run@2x.png +0 -0
  826. psychopy/app/Resources/light/redglobe_user.png +0 -0
  827. psychopy/app/Resources/light/redglobe_user@2x.png +0 -0
  828. psychopy/app/Resources/light/redo.png +0 -0
  829. psychopy/app/Resources/light/redo32.png +0 -0
  830. psychopy/app/Resources/light/redo32@2x.png +0 -0
  831. psychopy/app/Resources/light/redo@2x.png +0 -0
  832. psychopy/app/Resources/light/removeExp32.png +0 -0
  833. psychopy/app/Resources/light/removeExp32@2x.png +0 -0
  834. psychopy/app/Resources/light/rename16.png +0 -0
  835. psychopy/app/Resources/light/rename16@2x.png +0 -0
  836. psychopy/app/Resources/light/restart.png +0 -0
  837. psychopy/app/Resources/light/restart@2x.png +0 -0
  838. psychopy/app/Resources/light/runner.png +0 -0
  839. psychopy/app/Resources/light/runner@2x.png +0 -0
  840. psychopy/app/Resources/light/runnerPilot.png +0 -0
  841. psychopy/app/Resources/light/runnerPilot@2x.png +0 -0
  842. psychopy/app/Resources/light/savebtn16.png +0 -0
  843. psychopy/app/Resources/light/savebtn16@2x.png +0 -0
  844. psychopy/app/Resources/light/search.png +0 -0
  845. psychopy/app/Resources/light/search@2x.png +0 -0
  846. psychopy/app/Resources/light/showBuilder.png +0 -0
  847. psychopy/app/Resources/light/showBuilder@2x.png +0 -0
  848. psychopy/app/Resources/light/showCoder.png +0 -0
  849. psychopy/app/Resources/light/showCoder@2x.png +0 -0
  850. psychopy/app/Resources/light/showRunner.png +0 -0
  851. psychopy/app/Resources/light/showRunner@2x.png +0 -0
  852. psychopy/app/Resources/light/starred.png +0 -0
  853. psychopy/app/Resources/light/starred@2x.png +0 -0
  854. psychopy/app/Resources/light/start.png +0 -0
  855. psychopy/app/Resources/light/start@2x.png +0 -0
  856. psychopy/app/Resources/light/stdout.png +0 -0
  857. psychopy/app/Resources/light/stdout@2x.png +0 -0
  858. psychopy/app/Resources/light/stop.png +0 -0
  859. psychopy/app/Resources/light/stop32.png +0 -0
  860. psychopy/app/Resources/light/stop32@2x.png +0 -0
  861. psychopy/app/Resources/light/stop@2x.png +0 -0
  862. psychopy/app/Resources/light/switchCtrlBot.png +0 -0
  863. psychopy/app/Resources/light/switchCtrlBot@2x.png +0 -0
  864. psychopy/app/Resources/light/switchCtrlLeft.png +0 -0
  865. psychopy/app/Resources/light/switchCtrlLeft@2x.png +0 -0
  866. psychopy/app/Resources/light/switchCtrlRight.png +0 -0
  867. psychopy/app/Resources/light/switchCtrlRight@2x.png +0 -0
  868. psychopy/app/Resources/light/switchCtrlTop.png +0 -0
  869. psychopy/app/Resources/light/switchCtrlTop@2x.png +0 -0
  870. psychopy/app/Resources/light/tick.png +0 -0
  871. psychopy/app/Resources/light/tick@2x.png +0 -0
  872. psychopy/app/Resources/light/undo.png +0 -0
  873. psychopy/app/Resources/light/undo32.png +0 -0
  874. psychopy/app/Resources/light/undo32@2x.png +0 -0
  875. psychopy/app/Resources/light/undo@2x.png +0 -0
  876. psychopy/app/Resources/light/unstarred.png +0 -0
  877. psychopy/app/Resources/light/unstarred@2x.png +0 -0
  878. psychopy/app/Resources/light/user_none.png +0 -0
  879. psychopy/app/Resources/light/view-refresh16.png +0 -0
  880. psychopy/app/Resources/light/view-refresh16@2x.png +0 -0
  881. psychopy/app/Resources/light/viewbtn16.png +0 -0
  882. psychopy/app/Resources/light/viewbtn16@2x.png +0 -0
  883. psychopy/app/Resources/light/windows16.png +0 -0
  884. psychopy/app/Resources/light/windows16@2x.png +0 -0
  885. psychopy/app/Resources/moveComponentIcons.py +50 -0
  886. psychopy/app/Resources/next.png +0 -0
  887. psychopy/app/Resources/psychopy.desktop +13 -0
  888. psychopy/app/Resources/psychopy.icns +0 -0
  889. psychopy/app/Resources/psychopy.ico +0 -0
  890. psychopy/app/Resources/psychopy.png +0 -0
  891. psychopy/app/Resources/psychopy.xml +9 -0
  892. psychopy/app/Resources/psychopy@2x.png +0 -0
  893. psychopy/app/Resources/psychopySplash.png +0 -0
  894. psychopy/app/Resources/psychopySplash@2x.png +0 -0
  895. psychopy/app/Resources/routine_templates/Basic.psyexp +345 -0
  896. psychopy/app/Resources/routine_templates/Misc.psyexp +229 -0
  897. psychopy/app/Resources/routine_templates/Online.psyexp +202 -0
  898. psychopy/app/Resources/routine_templates/Trials.psyexp +736 -0
  899. psychopy/app/Resources/routine_templates/readme.md +14 -0
  900. psychopy/app/Resources/runner.ico +0 -0
  901. psychopy/app/Resources/tips.txt +45 -0
  902. psychopy/app/Resources/tips_ar_001.txt +45 -0
  903. psychopy/app/Resources/tips_fr_FR.txt +45 -0
  904. psychopy/app/Resources/tips_ja_JP.txt +42 -0
  905. psychopy/app/Resources/tips_zh_CN.txt +45 -0
  906. psychopy/app/Resources/window.ico +0 -0
  907. psychopy/app/__init__.py +224 -0
  908. psychopy/app/_psychopyApp.py +1224 -0
  909. psychopy/app/appData.spec +58 -0
  910. psychopy/app/builder/__init__.py +5 -0
  911. psychopy/app/builder/builder.py +4658 -0
  912. psychopy/app/builder/dialogs/__init__.py +2014 -0
  913. psychopy/app/builder/dialogs/dlgsCode.py +610 -0
  914. psychopy/app/builder/dialogs/dlgsConditions.py +670 -0
  915. psychopy/app/builder/dialogs/findDlg.py +189 -0
  916. psychopy/app/builder/dialogs/paramCtrls.py +1213 -0
  917. psychopy/app/builder/localizedStrings.py +225 -0
  918. psychopy/app/builder/validators.py +581 -0
  919. psychopy/app/coder/__init__.py +8 -0
  920. psychopy/app/coder/codeEditorBase.py +460 -0
  921. psychopy/app/coder/coder.py +3086 -0
  922. psychopy/app/coder/fileBrowser.py +668 -0
  923. psychopy/app/coder/folding.py +128 -0
  924. psychopy/app/coder/psychoParser.py +139 -0
  925. psychopy/app/coder/repl.py +493 -0
  926. psychopy/app/coder/sourceTree.py +302 -0
  927. psychopy/app/colorpicker/__init__.py +594 -0
  928. psychopy/app/colorpicker/ui.py +336 -0
  929. psychopy/app/connections/__init__.py +10 -0
  930. psychopy/app/connections/news.py +104 -0
  931. psychopy/app/connections/sendusage.py +61 -0
  932. psychopy/app/connections/updates.py +642 -0
  933. psychopy/app/console.py +164 -0
  934. psychopy/app/dialogs.py +632 -0
  935. psychopy/app/errorDlg.py +238 -0
  936. psychopy/app/frametracker.py +8 -0
  937. psychopy/app/idle.py +143 -0
  938. psychopy/app/jobs.py +648 -0
  939. psychopy/app/linuxconfig/__init__.py +144 -0
  940. psychopy/app/linuxconfig/ui.py +88 -0
  941. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  942. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +9554 -0
  943. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  944. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.po +24 -0
  945. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  946. psychopy/app/locale/da_DK/LC_MESSAGE/messages.po +24 -0
  947. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  948. psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +9712 -0
  949. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  950. psychopy/app/locale/el_GR/LC_MESSAGE/messages.po +25 -0
  951. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  952. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.po +25 -0
  953. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  954. psychopy/app/locale/en_US/LC_MESSAGE/messages.po +18 -0
  955. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  956. psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +9100 -0
  957. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  958. psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +9094 -0
  959. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  960. psychopy/app/locale/es_US/LC_MESSAGE/messages.po +9100 -0
  961. psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
  962. psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +9569 -0
  963. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  964. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +5806 -0
  965. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  966. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.po +24 -0
  967. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  968. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +9577 -0
  969. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  970. psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +9549 -0
  971. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  972. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +9559 -0
  973. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  974. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.po +25 -0
  975. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  976. psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +9560 -0
  977. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  978. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +11687 -0
  979. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  980. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.po +24 -0
  981. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  982. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +8757 -0
  983. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  984. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.po +25 -0
  985. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  986. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.po +25 -0
  987. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  988. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.po +25 -0
  989. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  990. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +24 -0
  991. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  992. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.po +25 -0
  993. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  994. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.po +24 -0
  995. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  996. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +8747 -0
  997. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  998. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +9545 -0
  999. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  1000. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +8268 -0
  1001. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  1002. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +8022 -0
  1003. psychopy/app/pavlovia_ui/__init__.py +22 -0
  1004. psychopy/app/pavlovia_ui/_base.py +237 -0
  1005. psychopy/app/pavlovia_ui/functions.py +176 -0
  1006. psychopy/app/pavlovia_ui/menu.py +140 -0
  1007. psychopy/app/pavlovia_ui/project.py +943 -0
  1008. psychopy/app/pavlovia_ui/search.py +445 -0
  1009. psychopy/app/pavlovia_ui/sync.py +137 -0
  1010. psychopy/app/pavlovia_ui/user.py +264 -0
  1011. psychopy/app/plugin_manager/__init__.py +5 -0
  1012. psychopy/app/plugin_manager/dialog.py +400 -0
  1013. psychopy/app/plugin_manager/output.py +132 -0
  1014. psychopy/app/plugin_manager/packages.py +502 -0
  1015. psychopy/app/plugin_manager/plugins.py +1315 -0
  1016. psychopy/app/plugin_manager/utils.py +115 -0
  1017. psychopy/app/preferencesDlg.py +790 -0
  1018. psychopy/app/psychopyApp.py +103 -0
  1019. psychopy/app/ribbon.py +907 -0
  1020. psychopy/app/runner/__init__.py +1 -0
  1021. psychopy/app/runner/runner.py +1262 -0
  1022. psychopy/app/runner/scriptProcess.py +353 -0
  1023. psychopy/app/stdout/__init__.py +1 -0
  1024. psychopy/app/stdout/stdOutRich.py +380 -0
  1025. psychopy/app/sysInfoDlg.py +242 -0
  1026. psychopy/app/themes/__init__.py +78 -0
  1027. psychopy/app/themes/colors.py +201 -0
  1028. psychopy/app/themes/css/contrast_black.css +112 -0
  1029. psychopy/app/themes/css/contrast_white.css +115 -0
  1030. psychopy/app/themes/css/dark.css +112 -0
  1031. psychopy/app/themes/css/light.css +115 -0
  1032. psychopy/app/themes/fonts.py +629 -0
  1033. psychopy/app/themes/handlers.py +321 -0
  1034. psychopy/app/themes/icons.py +250 -0
  1035. psychopy/app/themes/spec/Classic.json +154 -0
  1036. psychopy/app/themes/spec/ClassicDark.json +154 -0
  1037. psychopy/app/themes/spec/GitHub.json +154 -0
  1038. psychopy/app/themes/spec/HiVisDark.json +153 -0
  1039. psychopy/app/themes/spec/HiVisLight.json +154 -0
  1040. psychopy/app/themes/spec/MinimalDark.json +154 -0
  1041. psychopy/app/themes/spec/MinimalLight.json +153 -0
  1042. psychopy/app/themes/spec/PsychopyDark.json +231 -0
  1043. psychopy/app/themes/spec/PsychopyLight.json +236 -0
  1044. psychopy/app/themes/ui.py +74 -0
  1045. psychopy/app/ui/__init__.py +184 -0
  1046. psychopy/app/urls.py +31 -0
  1047. psychopy/app/utils.py +1680 -0
  1048. psychopy/app/viewer/__init__.py +0 -0
  1049. psychopy/clock.py +612 -0
  1050. psychopy/colors.py +1050 -0
  1051. psychopy/compatibility.py +95 -0
  1052. psychopy/constants.py +87 -0
  1053. psychopy/contrib/__init__.py +0 -0
  1054. psychopy/contrib/configobj/LICENSE +39 -0
  1055. psychopy/contrib/configobj/__init__.py +2453 -0
  1056. psychopy/contrib/configobj/_version.py +2 -0
  1057. psychopy/contrib/configobj/validate.py +1458 -0
  1058. psychopy/contrib/lazy_import.py +402 -0
  1059. psychopy/contrib/mseq.py +273 -0
  1060. psychopy/contrib/mseqSearch.py +183 -0
  1061. psychopy/contrib/psi.py +100 -0
  1062. psychopy/contrib/quest.py +484 -0
  1063. psychopy/contrib/tesselate.py +188 -0
  1064. psychopy/core.py +167 -0
  1065. psychopy/data/__init__.py +44 -0
  1066. psychopy/data/base.py +566 -0
  1067. psychopy/data/counterbalance.py +210 -0
  1068. psychopy/data/experiment.py +708 -0
  1069. psychopy/data/fit.py +248 -0
  1070. psychopy/data/shelf.py +237 -0
  1071. psychopy/data/staircase.py +2247 -0
  1072. psychopy/data/trial.py +1978 -0
  1073. psychopy/data/utils.py +783 -0
  1074. psychopy/demos/__init__.py +0 -0
  1075. psychopy/demos/builder/Design Templates/branchedExperiment/README.md +5 -0
  1076. psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +239 -0
  1077. psychopy/demos/builder/Design Templates/branchedExperiment/trialTypes.xlsx +0 -0
  1078. psychopy/demos/builder/Design Templates/psychophysicsStaircase/README.md +20 -0
  1079. psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +264 -0
  1080. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/README.md +14 -0
  1081. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +201 -0
  1082. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/stairDefinitions.xlsx +0 -0
  1083. psychopy/demos/builder/Design Templates/randomisedBlocks/README.md +18 -0
  1084. psychopy/demos/builder/Design Templates/randomisedBlocks/chooseBlock.xlsx +0 -0
  1085. psychopy/demos/builder/Design Templates/randomisedBlocks/facesBlock.xlsx +0 -0
  1086. psychopy/demos/builder/Design Templates/randomisedBlocks/housesBlock.xlsx +0 -0
  1087. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +131 -0
  1088. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face01.jpg +0 -0
  1089. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face02.jpg +0 -0
  1090. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face03.jpg +0 -0
  1091. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house01.jpg +0 -0
  1092. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house02.jpg +0 -0
  1093. psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house03.jpg +0 -0
  1094. psychopy/demos/builder/Experiments/BART/README.md +30 -0
  1095. psychopy/demos/builder/Experiments/BART/assets/background.png +0 -0
  1096. psychopy/demos/builder/Experiments/BART/assets/bang.mp3 +0 -0
  1097. psychopy/demos/builder/Experiments/BART/assets/bang.wav +0 -0
  1098. psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
  1099. psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
  1100. psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
  1101. psychopy/demos/builder/Experiments/BART/bart.psyexp +931 -0
  1102. psychopy/demos/builder/Experiments/BART/spreadsheets/conditions.xlsx +0 -0
  1103. psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +193 -0
  1104. psychopy/demos/builder/Experiments/BigFiveInventory/README.md +23 -0
  1105. psychopy/demos/builder/Experiments/BigFiveInventory/TIPI.xlsx +0 -0
  1106. psychopy/demos/builder/Experiments/BigFiveInventory/bigFiveItems.xlsx +0 -0
  1107. psychopy/demos/builder/Experiments/BigFiveInventory/demographics.xlsx +0 -0
  1108. psychopy/demos/builder/Experiments/BigFiveInventory/mini_IPIP.xlsx +0 -0
  1109. psychopy/demos/builder/Experiments/dragAndDrop/README.md +40 -0
  1110. psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
  1111. psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +1221 -0
  1112. psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +61 -0
  1113. psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +91 -0
  1114. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
  1115. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
  1116. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
  1117. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
  1118. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
  1119. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
  1120. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
  1121. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
  1122. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
  1123. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
  1124. psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
  1125. psychopy/demos/builder/Experiments/goNoGo/conditions.xlsx +0 -0
  1126. psychopy/demos/builder/Experiments/goNoGo/gng.psyexp +449 -0
  1127. psychopy/demos/builder/Experiments/goNoGo/go.png +0 -0
  1128. psychopy/demos/builder/Experiments/goNoGo/nogo.png +0 -0
  1129. psychopy/demos/builder/Experiments/goNoGo/readme.md +14 -0
  1130. psychopy/demos/builder/Experiments/mentalRotation/F.png +0 -0
  1131. psychopy/demos/builder/Experiments/mentalRotation/FR.png +0 -0
  1132. psychopy/demos/builder/Experiments/mentalRotation/MentalRot.csv +33 -0
  1133. psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +605 -0
  1134. psychopy/demos/builder/Experiments/mentalRotation/README.md +23 -0
  1135. psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +478 -0
  1136. psychopy/demos/builder/Experiments/navon/README.md +26 -0
  1137. psychopy/demos/builder/Experiments/navon/bigHsmallH.png +0 -0
  1138. psychopy/demos/builder/Experiments/navon/bigHsmallS.png +0 -0
  1139. psychopy/demos/builder/Experiments/navon/bigSsmallH.png +0 -0
  1140. psychopy/demos/builder/Experiments/navon/bigSsmallS.png +0 -0
  1141. psychopy/demos/builder/Experiments/navon/mask.png +0 -0
  1142. psychopy/demos/builder/Experiments/navon/stimuli.pptx +0 -0
  1143. psychopy/demos/builder/Experiments/navon/trialTypes.xlsx +0 -0
  1144. psychopy/demos/builder/Experiments/sternberg/README.md +14 -0
  1145. psychopy/demos/builder/Experiments/sternberg/mainTrials.xlsx +0 -0
  1146. psychopy/demos/builder/Experiments/sternberg/pracTrials.xlsx +0 -0
  1147. psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +611 -0
  1148. psychopy/demos/builder/Experiments/stroop/README.md +15 -0
  1149. psychopy/demos/builder/Experiments/stroop/stroop.psyexp +225 -0
  1150. psychopy/demos/builder/Experiments/stroop/trialTypes.csv +7 -0
  1151. psychopy/demos/builder/Experiments/stroopExtended/README.md +14 -0
  1152. psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +243 -0
  1153. psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +243 -0
  1154. psychopy/demos/builder/Experiments/stroopExtended/trialTypes.xlsx +0 -0
  1155. psychopy/demos/builder/Experiments/stroopExtended/trialTypesReverse.xlsx +0 -0
  1156. psychopy/demos/builder/Experiments/stroopVoice/README.md +27 -0
  1157. psychopy/demos/builder/Experiments/stroopVoice/conditions.xlsx +0 -0
  1158. psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +366 -0
  1159. psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +298 -0
  1160. psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +341 -0
  1161. psychopy/demos/builder/Feature Demos/gratings/readme.md +8 -0
  1162. psychopy/demos/builder/Feature Demos/noise/face.jpg +0 -0
  1163. psychopy/demos/builder/Feature Demos/noise/noise.psyexp +424 -0
  1164. psychopy/demos/builder/Feature Demos/noise/readme.md +3 -0
  1165. psychopy/demos/builder/Feature Demos/panorama/panImg.jpg +0 -0
  1166. psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +142 -0
  1167. psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +423 -0
  1168. psychopy/demos/builder/Feature Demos/progress/readme.md +1 -0
  1169. psychopy/demos/builder/Feature Demos/sliders/README.md +8 -0
  1170. psychopy/demos/builder/Feature Demos/sliders/fruitConditions.xlsx +0 -0
  1171. psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +938 -0
  1172. psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +621 -0
  1173. psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +404 -0
  1174. psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +641 -0
  1175. psychopy/demos/builder/Hardware/EGI_netstation/README.md +17 -0
  1176. psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +254 -0
  1177. psychopy/demos/builder/Hardware/EGI_netstation/trialTypesEEG.csv +7 -0
  1178. psychopy/demos/builder/Hardware/Eyetracking_visual_search/readme.md +19 -0
  1179. psychopy/demos/builder/Hardware/Eyetracking_visual_search/trials_params.xlsx +0 -0
  1180. psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +691 -0
  1181. psychopy/demos/builder/Hardware/camera/camera.psyexp +263 -0
  1182. psychopy/demos/builder/Hardware/camera/readme.md +6 -0
  1183. psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +354 -0
  1184. psychopy/demos/builder/Hardware/eyetracking/readme.md +7 -0
  1185. psychopy/demos/builder/Hardware/eyetracking_custom_cal/Bullseye_grey.mov +0 -0
  1186. psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +349 -0
  1187. psychopy/demos/builder/Hardware/eyetracking_custom_cal/readme.md +7 -0
  1188. psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +202 -0
  1189. psychopy/demos/builder/Hardware/fMRI/readme.md +7 -0
  1190. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +349 -0
  1191. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +304 -0
  1192. psychopy/demos/builder/Hardware/microphone/microphone.psyexp +451 -0
  1193. psychopy/demos/builder/Hardware/microphone/phrases.xlsx +0 -0
  1194. psychopy/demos/builder/Hardware/microphone/readme.md +9 -0
  1195. psychopy/demos/builder/Hardware/pump/README.md +19 -0
  1196. psychopy/demos/builder/Hardware/pump/pump.psyexp +382 -0
  1197. psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +288 -0
  1198. psychopy/demos/builder/Helper Tools/achorVSalignment/readme.md +5 -0
  1199. psychopy/demos/builder/Helper Tools/clockFace/README.md +3 -0
  1200. psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +160 -0
  1201. psychopy/demos/builder/Helper Tools/colors/README.md +5 -0
  1202. psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -0
  1203. psychopy/demos/builder/Helper Tools/drawPolygon/README.md +5 -0
  1204. psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +591 -0
  1205. psychopy/demos/builder/Helper Tools/keyNameFinder/README.md +14 -0
  1206. psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +169 -0
  1207. psychopy/demos/builder/Helper Tools/spatialUnits/README.md +6 -0
  1208. psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +157 -0
  1209. psychopy/demos/builder/README.txt +43 -0
  1210. psychopy/demos/builder/__init__.py +0 -0
  1211. psychopy/demos/coder/__init__.py +0 -0
  1212. psychopy/demos/coder/basic/hello_world.py +37 -0
  1213. psychopy/demos/coder/csvFromPsydat.py +29 -0
  1214. psychopy/demos/coder/experiment control/JND_staircase_analysis.py +85 -0
  1215. psychopy/demos/coder/experiment control/JND_staircase_exp.py +110 -0
  1216. psychopy/demos/coder/experiment control/TrialHandler.py +64 -0
  1217. psychopy/demos/coder/experiment control/TrialHandler2.py +42 -0
  1218. psychopy/demos/coder/experiment control/__init__.py +0 -0
  1219. psychopy/demos/coder/experiment control/autoDraw_autoLog.py +50 -0
  1220. psychopy/demos/coder/experiment control/experimentHandler.py +57 -0
  1221. psychopy/demos/coder/experiment control/fMRI_launchScan.py +74 -0
  1222. psychopy/demos/coder/experiment control/gammaMotionAnalysis.py +68 -0
  1223. psychopy/demos/coder/experiment control/gammaMotionNull.py +169 -0
  1224. psychopy/demos/coder/experiment control/logFiles.py +55 -0
  1225. psychopy/demos/coder/experiment control/piloting.py +65 -0
  1226. psychopy/demos/coder/experiment control/runtimeInfo.py +79 -0
  1227. psychopy/demos/coder/hardware/CRS_BitsBox.py +75 -0
  1228. psychopy/demos/coder/hardware/CRS_BitsPlusPlus.py +73 -0
  1229. psychopy/demos/coder/hardware/RiftHeadTrackingExample.py +95 -0
  1230. psychopy/demos/coder/hardware/RiftMinimal.py +44 -0
  1231. psychopy/demos/coder/hardware/VSHD_Distortion.py +49 -0
  1232. psychopy/demos/coder/hardware/__init__.py +0 -0
  1233. psychopy/demos/coder/hardware/camera.py +90 -0
  1234. psychopy/demos/coder/hardware/cedrusRB730.py +38 -0
  1235. psychopy/demos/coder/hardware/crsBitsAdvancedDemo.py +780 -0
  1236. psychopy/demos/coder/hardware/egi_netstation.py +45 -0
  1237. psychopy/demos/coder/hardware/ioLab_bbox.py +62 -0
  1238. psychopy/demos/coder/hardware/labjack_u3.py +61 -0
  1239. psychopy/demos/coder/hardware/monitorDemo.py +28 -0
  1240. psychopy/demos/coder/hardware/parallelPortOutput.py +49 -0
  1241. psychopy/demos/coder/hardware/qmixPump.py +79 -0
  1242. psychopy/demos/coder/hardware/testSoundLatency.py +127 -0
  1243. psychopy/demos/coder/input/GUI.py +52 -0
  1244. psychopy/demos/coder/input/__init__.py +0 -0
  1245. psychopy/demos/coder/input/customMouse.py +51 -0
  1246. psychopy/demos/coder/input/joystick_universal.py +84 -0
  1247. psychopy/demos/coder/input/keyNameFinder.py +39 -0
  1248. psychopy/demos/coder/input/mic.png +0 -0
  1249. psychopy/demos/coder/input/mouse.py +66 -0
  1250. psychopy/demos/coder/iohub/delaytest.py +231 -0
  1251. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/canal.jpg +0 -0
  1252. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/fall.jpg +0 -0
  1253. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/lake.jpg +0 -0
  1254. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/party.jpg +0 -0
  1255. psychopy/demos/coder/iohub/eyetracking/gcCursor/images/swimming.jpg +0 -0
  1256. psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByConditionVariables.py +67 -0
  1257. psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByMessages.py +34 -0
  1258. psychopy/demos/coder/iohub/eyetracking/gcCursor/run.py +323 -0
  1259. psychopy/demos/coder/iohub/eyetracking/gcCursor/trial_conditions.xlsx +0 -0
  1260. psychopy/demos/coder/iohub/eyetracking/simple.py +147 -0
  1261. psychopy/demos/coder/iohub/eyetracking/validation.py +251 -0
  1262. psychopy/demos/coder/iohub/iodatastore/saveEventReport.py +56 -0
  1263. psychopy/demos/coder/iohub/keyboard.py +189 -0
  1264. psychopy/demos/coder/iohub/keyboardreactiontime.py +88 -0
  1265. psychopy/demos/coder/iohub/launchHub.py +160 -0
  1266. psychopy/demos/coder/iohub/mouse.py +112 -0
  1267. psychopy/demos/coder/iohub/mouse_multi_window.py +124 -0
  1268. psychopy/demos/coder/iohub/serial/_parseserial.py +53 -0
  1269. psychopy/demos/coder/iohub/serial/customparser.py +84 -0
  1270. psychopy/demos/coder/iohub/serial/pstbox.py +166 -0
  1271. psychopy/demos/coder/iohub/wintab/_wintabgraphics.py +281 -0
  1272. psychopy/demos/coder/iohub/wintab/pen_demo.py +260 -0
  1273. psychopy/demos/coder/misc/encrypt_data.py +48 -0
  1274. psychopy/demos/coder/misc/makeMovie.py +28 -0
  1275. psychopy/demos/coder/misc/rigidBodyTransform.py +76 -0
  1276. psychopy/demos/coder/stimuli/Campaign.ttf +0 -0
  1277. psychopy/demos/coder/stimuli/MovieStim.py +65 -0
  1278. psychopy/demos/coder/stimuli/__init__.py +0 -0
  1279. psychopy/demos/coder/stimuli/aperture.py +37 -0
  1280. psychopy/demos/coder/stimuli/beach.jpg +0 -0
  1281. psychopy/demos/coder/stimuli/bufferImageStim.py +78 -0
  1282. psychopy/demos/coder/stimuli/clockface.py +43 -0
  1283. psychopy/demos/coder/stimuli/colorPalette.py +134 -0
  1284. psychopy/demos/coder/stimuli/compare_text_timing.py +193 -0
  1285. psychopy/demos/coder/stimuli/counterphase.py +43 -0
  1286. psychopy/demos/coder/stimuli/customTextures.py +57 -0
  1287. psychopy/demos/coder/stimuli/dot_gabors.py +35 -0
  1288. psychopy/demos/coder/stimuli/dots.py +35 -0
  1289. psychopy/demos/coder/stimuli/elementArrays.py +92 -0
  1290. psychopy/demos/coder/stimuli/embeddedOpenGL.py +35 -0
  1291. psychopy/demos/coder/stimuli/face.jpg +0 -0
  1292. psychopy/demos/coder/stimuli/face_jpg.py +48 -0
  1293. psychopy/demos/coder/stimuli/gabor.py +30 -0
  1294. psychopy/demos/coder/stimuli/imagesAndPatches.py +51 -0
  1295. psychopy/demos/coder/stimuli/jwpIntro.mp4 +0 -0
  1296. psychopy/demos/coder/stimuli/kanizsa.py +41 -0
  1297. psychopy/demos/coder/stimuli/maskReveal.py +63 -0
  1298. psychopy/demos/coder/stimuli/plaid.py +43 -0
  1299. psychopy/demos/coder/stimuli/ratingScale.py +183 -0
  1300. psychopy/demos/coder/stimuli/rotatingFlashingWedge.py +37 -0
  1301. psychopy/demos/coder/stimuli/screensAndWindows.py +58 -0
  1302. psychopy/demos/coder/stimuli/secondOrderGratings.py +66 -0
  1303. psychopy/demos/coder/stimuli/shapeContains.py +50 -0
  1304. psychopy/demos/coder/stimuli/shapes.py +63 -0
  1305. psychopy/demos/coder/stimuli/soundStimuli.py +49 -0
  1306. psychopy/demos/coder/stimuli/starField.py +48 -0
  1307. psychopy/demos/coder/stimuli/stim3d.py +107 -0
  1308. psychopy/demos/coder/stimuli/textBoxStim/textbox_glyph_placement.py +93 -0
  1309. psychopy/demos/coder/stimuli/textBoxStim/textbox_simple.py +71 -0
  1310. psychopy/demos/coder/stimuli/textStimuli.py +106 -0
  1311. psychopy/demos/coder/stimuli/textbox_editable.py +64 -0
  1312. psychopy/demos/coder/stimuli/variousVisualStims.py +47 -0
  1313. psychopy/demos/coder/stimuli/visual_noise.py +31 -0
  1314. psychopy/demos/coder/sysInfo.py +56 -0
  1315. psychopy/demos/coder/timing/__init__.py +0 -0
  1316. psychopy/demos/coder/timing/callOnFlip.py +39 -0
  1317. psychopy/demos/coder/timing/clocksAndTimers.py +46 -0
  1318. psychopy/demos/coder/timing/millikeyKeyboardTimingTest.py +323 -0
  1319. psychopy/demos/coder/timing/timeByFrames.py +74 -0
  1320. psychopy/demos/coder/timing/timeByFramesEx.py +107 -0
  1321. psychopy/demos/coder/understanding psychopy/colors.py +70 -0
  1322. psychopy/demos/coder/understanding psychopy/fontLayout.py +69 -0
  1323. psychopy/demos/demo_migration.py +214 -0
  1324. psychopy/demos/modernizeDemos.py +16 -0
  1325. psychopy/demos/test_demo_migration.py +155 -0
  1326. psychopy/devices/__init__.py +8 -0
  1327. psychopy/event.py +1333 -0
  1328. psychopy/exceptions.py +59 -0
  1329. psychopy/experiment/__init__.py +51 -0
  1330. psychopy/experiment/_experiment.py +1392 -0
  1331. psychopy/experiment/blankTemplate.xltx +0 -0
  1332. psychopy/experiment/components/__init__.py +411 -0
  1333. psychopy/experiment/components/_base.py +1351 -0
  1334. psychopy/experiment/components/aperture/__init__.py +149 -0
  1335. psychopy/experiment/components/aperture/classic/aperture.png +0 -0
  1336. psychopy/experiment/components/aperture/classic/aperture@2x.png +0 -0
  1337. psychopy/experiment/components/aperture/dark/aperture.png +0 -0
  1338. psychopy/experiment/components/aperture/dark/aperture@2x.png +0 -0
  1339. psychopy/experiment/components/aperture/light/aperture.png +0 -0
  1340. psychopy/experiment/components/aperture/light/aperture@2x.png +0 -0
  1341. psychopy/experiment/components/brush/__init__.py +163 -0
  1342. psychopy/experiment/components/brush/classic/brush.png +0 -0
  1343. psychopy/experiment/components/brush/classic/brush@2x.png +0 -0
  1344. psychopy/experiment/components/brush/dark/brush.png +0 -0
  1345. psychopy/experiment/components/brush/dark/brush@2x.png +0 -0
  1346. psychopy/experiment/components/brush/light/brush.png +0 -0
  1347. psychopy/experiment/components/brush/light/brush@2x.png +0 -0
  1348. psychopy/experiment/components/button/__init__.py +489 -0
  1349. psychopy/experiment/components/button/classic/button.png +0 -0
  1350. psychopy/experiment/components/button/classic/button@2x.png +0 -0
  1351. psychopy/experiment/components/button/dark/button.png +0 -0
  1352. psychopy/experiment/components/button/dark/button@2x.png +0 -0
  1353. psychopy/experiment/components/button/light/button.png +0 -0
  1354. psychopy/experiment/components/button/light/button@2x.png +0 -0
  1355. psychopy/experiment/components/buttonBox/__init__.py +316 -0
  1356. psychopy/experiment/components/buttonBox/classic/buttonBox.png +0 -0
  1357. psychopy/experiment/components/buttonBox/classic/buttonBox@2x.png +0 -0
  1358. psychopy/experiment/components/buttonBox/dark/buttonBox.png +0 -0
  1359. psychopy/experiment/components/buttonBox/dark/buttonBox@2x.png +0 -0
  1360. psychopy/experiment/components/buttonBox/light/buttonBox.png +0 -0
  1361. psychopy/experiment/components/buttonBox/light/buttonBox@2x.png +0 -0
  1362. psychopy/experiment/components/camera/__init__.py +591 -0
  1363. psychopy/experiment/components/camera/classic/webcam.png +0 -0
  1364. psychopy/experiment/components/camera/classic/webcam@2x.png +0 -0
  1365. psychopy/experiment/components/camera/dark/webcam.png +0 -0
  1366. psychopy/experiment/components/camera/dark/webcam@2x.png +0 -0
  1367. psychopy/experiment/components/camera/light/webcam.png +0 -0
  1368. psychopy/experiment/components/camera/light/webcam@2x.png +0 -0
  1369. psychopy/experiment/components/code/__init__.py +266 -0
  1370. psychopy/experiment/components/code/classic/code.png +0 -0
  1371. psychopy/experiment/components/code/classic/code@2x.png +0 -0
  1372. psychopy/experiment/components/code/dark/code.png +0 -0
  1373. psychopy/experiment/components/code/dark/code@2x.png +0 -0
  1374. psychopy/experiment/components/code/light/code.png +0 -0
  1375. psychopy/experiment/components/code/light/code@2x.png +0 -0
  1376. psychopy/experiment/components/dots/__init__.py +199 -0
  1377. psychopy/experiment/components/dots/classic/dots.png +0 -0
  1378. psychopy/experiment/components/dots/classic/dots@2x.png +0 -0
  1379. psychopy/experiment/components/dots/dark/dots.png +0 -0
  1380. psychopy/experiment/components/dots/dark/dots@2x.png +0 -0
  1381. psychopy/experiment/components/dots/dots.xcf +0 -0
  1382. psychopy/experiment/components/dots/light/dots.png +0 -0
  1383. psychopy/experiment/components/dots/light/dots@2x.png +0 -0
  1384. psychopy/experiment/components/eyetracker_record/__init__.py +128 -0
  1385. psychopy/experiment/components/eyetracker_record/classic/eyetracker_record.png +0 -0
  1386. psychopy/experiment/components/eyetracker_record/classic/eyetracker_record@2x.png +0 -0
  1387. psychopy/experiment/components/eyetracker_record/dark/eyetracker_record.png +0 -0
  1388. psychopy/experiment/components/eyetracker_record/dark/eyetracker_record@2x.png +0 -0
  1389. psychopy/experiment/components/eyetracker_record/light/eyetracker_record.png +0 -0
  1390. psychopy/experiment/components/eyetracker_record/light/eyetracker_record@2x.png +0 -0
  1391. psychopy/experiment/components/form/__init__.py +223 -0
  1392. psychopy/experiment/components/form/classic/form.png +0 -0
  1393. psychopy/experiment/components/form/classic/form@2x.png +0 -0
  1394. psychopy/experiment/components/form/dark/form.png +0 -0
  1395. psychopy/experiment/components/form/dark/form@2x.png +0 -0
  1396. psychopy/experiment/components/form/formItems.xltx +0 -0
  1397. psychopy/experiment/components/form/light/form.png +0 -0
  1398. psychopy/experiment/components/form/light/form@2x.png +0 -0
  1399. psychopy/experiment/components/grating/__init__.py +192 -0
  1400. psychopy/experiment/components/grating/classic/grating.png +0 -0
  1401. psychopy/experiment/components/grating/classic/grating@2x.png +0 -0
  1402. psychopy/experiment/components/grating/dark/grating.png +0 -0
  1403. psychopy/experiment/components/grating/dark/grating@2x.png +0 -0
  1404. psychopy/experiment/components/grating/light/grating.png +0 -0
  1405. psychopy/experiment/components/grating/light/grating@2x.png +0 -0
  1406. psychopy/experiment/components/image/__init__.py +184 -0
  1407. psychopy/experiment/components/image/classic/image.png +0 -0
  1408. psychopy/experiment/components/image/classic/image@2x.png +0 -0
  1409. psychopy/experiment/components/image/dark/image.png +0 -0
  1410. psychopy/experiment/components/image/dark/image@2x.png +0 -0
  1411. psychopy/experiment/components/image/light/image.png +0 -0
  1412. psychopy/experiment/components/image/light/image@2x.png +0 -0
  1413. psychopy/experiment/components/joyButtons/__init__.py +453 -0
  1414. psychopy/experiment/components/joyButtons/classic/joyButtons.png +0 -0
  1415. psychopy/experiment/components/joyButtons/classic/joybuttons@2x.png +0 -0
  1416. psychopy/experiment/components/joyButtons/dark/joyButtons.png +0 -0
  1417. psychopy/experiment/components/joyButtons/dark/joyButtons@2x.png +0 -0
  1418. psychopy/experiment/components/joyButtons/light/joyButtons.png +0 -0
  1419. psychopy/experiment/components/joyButtons/light/joyButtons@2x.png +0 -0
  1420. psychopy/experiment/components/joyButtons/virtualJoyButtons.py +34 -0
  1421. psychopy/experiment/components/joystick/__init__.py +572 -0
  1422. psychopy/experiment/components/joystick/classic/joystick.png +0 -0
  1423. psychopy/experiment/components/joystick/classic/joystick@2x.png +0 -0
  1424. psychopy/experiment/components/joystick/dark/joystick.png +0 -0
  1425. psychopy/experiment/components/joystick/dark/joystick@2x.png +0 -0
  1426. psychopy/experiment/components/joystick/light/joystick.png +0 -0
  1427. psychopy/experiment/components/joystick/light/joystick@2x.png +0 -0
  1428. psychopy/experiment/components/joystick/virtualJoystick.py +40 -0
  1429. psychopy/experiment/components/keyboard/__init__.py +587 -0
  1430. psychopy/experiment/components/keyboard/classic/keyboard.png +0 -0
  1431. psychopy/experiment/components/keyboard/classic/keyboard@2x.png +0 -0
  1432. psychopy/experiment/components/keyboard/dark/keyboard.png +0 -0
  1433. psychopy/experiment/components/keyboard/dark/keyboard@2x.png +0 -0
  1434. psychopy/experiment/components/keyboard/light/keyboard.png +0 -0
  1435. psychopy/experiment/components/keyboard/light/keyboard@2x.png +0 -0
  1436. psychopy/experiment/components/keyboard.xcf +0 -0
  1437. psychopy/experiment/components/microphone/__init__.py +664 -0
  1438. psychopy/experiment/components/microphone/classic/microphone.png +0 -0
  1439. psychopy/experiment/components/microphone/classic/microphone@2x.png +0 -0
  1440. psychopy/experiment/components/microphone/dark/microphone.png +0 -0
  1441. psychopy/experiment/components/microphone/dark/microphone@2x.png +0 -0
  1442. psychopy/experiment/components/microphone/light/microphone.png +0 -0
  1443. psychopy/experiment/components/microphone/light/microphone@2x.png +0 -0
  1444. psychopy/experiment/components/mouse/__init__.py +747 -0
  1445. psychopy/experiment/components/mouse/classic/mouse.png +0 -0
  1446. psychopy/experiment/components/mouse/classic/mouse@2x.png +0 -0
  1447. psychopy/experiment/components/mouse/dark/mouse.png +0 -0
  1448. psychopy/experiment/components/mouse/dark/mouse@2x.png +0 -0
  1449. psychopy/experiment/components/mouse/light/mouse.png +0 -0
  1450. psychopy/experiment/components/mouse/light/mouse@2x.png +0 -0
  1451. psychopy/experiment/components/movie/__init__.py +367 -0
  1452. psychopy/experiment/components/movie/classic/movie.png +0 -0
  1453. psychopy/experiment/components/movie/classic/movie@2x.png +0 -0
  1454. psychopy/experiment/components/movie/dark/movie.png +0 -0
  1455. psychopy/experiment/components/movie/dark/movie@2x.png +0 -0
  1456. psychopy/experiment/components/movie/light/movie.png +0 -0
  1457. psychopy/experiment/components/movie/light/movie@2x.png +0 -0
  1458. psychopy/experiment/components/panorama/__init__.py +456 -0
  1459. psychopy/experiment/components/panorama/classic/panorama.png +0 -0
  1460. psychopy/experiment/components/panorama/classic/panorama@2x.png +0 -0
  1461. psychopy/experiment/components/panorama/dark/panorama.png +0 -0
  1462. psychopy/experiment/components/panorama/dark/panorama@2x.png +0 -0
  1463. psychopy/experiment/components/panorama/light/panorama.png +0 -0
  1464. psychopy/experiment/components/panorama/light/panorama@2x.png +0 -0
  1465. psychopy/experiment/components/parallelOut/__init__.py +178 -0
  1466. psychopy/experiment/components/parallelOut/classic/parallel.png +0 -0
  1467. psychopy/experiment/components/parallelOut/classic/parallel@2x.png +0 -0
  1468. psychopy/experiment/components/parallelOut/dark/parallel.png +0 -0
  1469. psychopy/experiment/components/parallelOut/dark/parallel@2x.png +0 -0
  1470. psychopy/experiment/components/parallelOut/light/parallel.png +0 -0
  1471. psychopy/experiment/components/parallelOut/light/parallel@2x.png +0 -0
  1472. psychopy/experiment/components/patch/__init__.py +121 -0
  1473. psychopy/experiment/components/patch/classic/patch.png +0 -0
  1474. psychopy/experiment/components/patch/dark/patch.png +0 -0
  1475. psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
  1476. psychopy/experiment/components/patch/light/patch.png +0 -0
  1477. psychopy/experiment/components/patch/light/patch@2x.png +0 -0
  1478. psychopy/experiment/components/polygon/__init__.py +303 -0
  1479. psychopy/experiment/components/polygon/classic/polygon.png +0 -0
  1480. psychopy/experiment/components/polygon/classic/polygon@2x.png +0 -0
  1481. psychopy/experiment/components/polygon/dark/polygon.png +0 -0
  1482. psychopy/experiment/components/polygon/dark/polygon@2x.png +0 -0
  1483. psychopy/experiment/components/polygon/light/polygon.png +0 -0
  1484. psychopy/experiment/components/polygon/light/polygon@2x.png +0 -0
  1485. psychopy/experiment/components/progress/__init__.py +130 -0
  1486. psychopy/experiment/components/progress/classic/progress.png +0 -0
  1487. psychopy/experiment/components/progress/classic/progress@2x.png +0 -0
  1488. psychopy/experiment/components/progress/dark/progress.png +0 -0
  1489. psychopy/experiment/components/progress/dark/progress@2x.png +0 -0
  1490. psychopy/experiment/components/progress/light/progress.png +0 -0
  1491. psychopy/experiment/components/progress/light/progress@2x.png +0 -0
  1492. psychopy/experiment/components/ratingScale/__init__.py +337 -0
  1493. psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
  1494. psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
  1495. psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
  1496. psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
  1497. psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
  1498. psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
  1499. psychopy/experiment/components/resourceManager/__init__.py +176 -0
  1500. psychopy/experiment/components/resourceManager/classic/resource_manager.png +0 -0
  1501. psychopy/experiment/components/resourceManager/classic/resource_manager@2x.png +0 -0
  1502. psychopy/experiment/components/resourceManager/dark/resource_manager.png +0 -0
  1503. psychopy/experiment/components/resourceManager/dark/resource_manager@2x.png +0 -0
  1504. psychopy/experiment/components/resourceManager/light/resource_manager.png +0 -0
  1505. psychopy/experiment/components/resourceManager/light/resource_manager@2x.png +0 -0
  1506. psychopy/experiment/components/roi/__init__.py +311 -0
  1507. psychopy/experiment/components/roi/classic/eyetracker_roi.png +0 -0
  1508. psychopy/experiment/components/roi/classic/eyetracker_roi@2x.png +0 -0
  1509. psychopy/experiment/components/roi/dark/eyetracker_roi.png +0 -0
  1510. psychopy/experiment/components/roi/dark/eyetracker_roi@2X.png +0 -0
  1511. psychopy/experiment/components/roi/light/eyetracker_roi.png +0 -0
  1512. psychopy/experiment/components/roi/light/eyetracker_roi@2X.png +0 -0
  1513. psychopy/experiment/components/routineSettings/__init__.py +338 -0
  1514. psychopy/experiment/components/routineSettings/classic/routineSettings.png +0 -0
  1515. psychopy/experiment/components/routineSettings/classic/routineSettings@2x.png +0 -0
  1516. psychopy/experiment/components/routineSettings/dark/routineSettings.png +0 -0
  1517. psychopy/experiment/components/routineSettings/dark/routineSettings@2x.png +0 -0
  1518. psychopy/experiment/components/routineSettings/light/routineSettings.png +0 -0
  1519. psychopy/experiment/components/routineSettings/light/routineSettings@2x.png +0 -0
  1520. psychopy/experiment/components/serialOut/__init__.py +205 -0
  1521. psychopy/experiment/components/serialOut/classic/serial.png +0 -0
  1522. psychopy/experiment/components/serialOut/classic/serial@2x.png +0 -0
  1523. psychopy/experiment/components/serialOut/dark/serial.png +0 -0
  1524. psychopy/experiment/components/serialOut/dark/serial@2x.png +0 -0
  1525. psychopy/experiment/components/serialOut/light/serial.png +0 -0
  1526. psychopy/experiment/components/serialOut/light/serial@2x.png +0 -0
  1527. psychopy/experiment/components/settings/JS_htmlHeader.tmpl +23 -0
  1528. psychopy/experiment/components/settings/JS_setupExp.tmpl +28 -0
  1529. psychopy/experiment/components/settings/__init__.py +2155 -0
  1530. psychopy/experiment/components/settings/classic/settings.png +0 -0
  1531. psychopy/experiment/components/settings/classic/settings@2x.png +0 -0
  1532. psychopy/experiment/components/settings/dark/settings.png +0 -0
  1533. psychopy/experiment/components/settings/dark/settings@2x.png +0 -0
  1534. psychopy/experiment/components/settings/light/settings.png +0 -0
  1535. psychopy/experiment/components/settings/light/settings@2x.png +0 -0
  1536. psychopy/experiment/components/slider/__init__.py +410 -0
  1537. psychopy/experiment/components/slider/classic/slider.png +0 -0
  1538. psychopy/experiment/components/slider/classic/slider@2x.png +0 -0
  1539. psychopy/experiment/components/slider/dark/slider.png +0 -0
  1540. psychopy/experiment/components/slider/dark/slider@2x.png +0 -0
  1541. psychopy/experiment/components/slider/light/slider.png +0 -0
  1542. psychopy/experiment/components/slider/light/slider@2x.png +0 -0
  1543. psychopy/experiment/components/sound/__init__.py +307 -0
  1544. psychopy/experiment/components/sound/classic/sound.png +0 -0
  1545. psychopy/experiment/components/sound/classic/sound@2x.png +0 -0
  1546. psychopy/experiment/components/sound/dark/sound.png +0 -0
  1547. psychopy/experiment/components/sound/dark/sound@2x.png +0 -0
  1548. psychopy/experiment/components/sound/light/sound.png +0 -0
  1549. psychopy/experiment/components/sound/light/sound@2x.png +0 -0
  1550. psychopy/experiment/components/static/__init__.py +267 -0
  1551. psychopy/experiment/components/static/classic/static.png +0 -0
  1552. psychopy/experiment/components/static/classic/static@2x.png +0 -0
  1553. psychopy/experiment/components/static/dark/static.png +0 -0
  1554. psychopy/experiment/components/static/dark/static@2x.png +0 -0
  1555. psychopy/experiment/components/static/light/static.png +0 -0
  1556. psychopy/experiment/components/static/light/static@2x.png +0 -0
  1557. psychopy/experiment/components/text/__init__.py +169 -0
  1558. psychopy/experiment/components/text/classic/text.png +0 -0
  1559. psychopy/experiment/components/text/classic/text@2x.png +0 -0
  1560. psychopy/experiment/components/text/dark/text.png +0 -0
  1561. psychopy/experiment/components/text/dark/text@2x.png +0 -0
  1562. psychopy/experiment/components/text/light/text.png +0 -0
  1563. psychopy/experiment/components/text/light/text@2x.png +0 -0
  1564. psychopy/experiment/components/textbox/__init__.py +330 -0
  1565. psychopy/experiment/components/textbox/classic/textbox.png +0 -0
  1566. psychopy/experiment/components/textbox/classic/textbox@2x.png +0 -0
  1567. psychopy/experiment/components/textbox/dark/textbox.png +0 -0
  1568. psychopy/experiment/components/textbox/dark/textbox@2x.png +0 -0
  1569. psychopy/experiment/components/textbox/light/textbox.png +0 -0
  1570. psychopy/experiment/components/textbox/light/textbox@2x.png +0 -0
  1571. psychopy/experiment/components/unknown/__init__.py +86 -0
  1572. psychopy/experiment/components/unknown/classic/unknown.png +0 -0
  1573. psychopy/experiment/components/unknown/classic/unknown@2x.png +0 -0
  1574. psychopy/experiment/components/unknown/dark/unknown.png +0 -0
  1575. psychopy/experiment/components/unknown/dark/unknown@2x.png +0 -0
  1576. psychopy/experiment/components/unknown/light/unknown.png +0 -0
  1577. psychopy/experiment/components/unknown/light/unknown@2x.png +0 -0
  1578. psychopy/experiment/components/unknownPlugin/__init__.py +84 -0
  1579. psychopy/experiment/components/unknownPlugin/classic/unknownPlugin.png +0 -0
  1580. psychopy/experiment/components/unknownPlugin/classic/unknownPlugin@2x.png +0 -0
  1581. psychopy/experiment/components/unknownPlugin/dark/unknownPlugin.png +0 -0
  1582. psychopy/experiment/components/unknownPlugin/dark/unknownPlugin@2x.png +0 -0
  1583. psychopy/experiment/components/unknownPlugin/light/unknownPlugin.png +0 -0
  1584. psychopy/experiment/components/unknownPlugin/light/unknownPlugin@2x.png +0 -0
  1585. psychopy/experiment/components/utils.py +0 -0
  1586. psychopy/experiment/components/variable/__init__.py +184 -0
  1587. psychopy/experiment/components/variable/classic/variable.png +0 -0
  1588. psychopy/experiment/components/variable/classic/variable@2x.png +0 -0
  1589. psychopy/experiment/components/variable/dark/variable.png +0 -0
  1590. psychopy/experiment/components/variable/dark/variable@2x.png +0 -0
  1591. psychopy/experiment/components/variable/light/variable.png +0 -0
  1592. psychopy/experiment/components/variable/light/variable@2x.png +0 -0
  1593. psychopy/experiment/experiment.xsd +223 -0
  1594. psychopy/experiment/exports.py +388 -0
  1595. psychopy/experiment/flow.py +531 -0
  1596. psychopy/experiment/localization.py +11 -0
  1597. psychopy/experiment/loopTemplate.xltx +0 -0
  1598. psychopy/experiment/loops.py +952 -0
  1599. psychopy/experiment/params.py +437 -0
  1600. psychopy/experiment/plugins.py +115 -0
  1601. psychopy/experiment/py2js.py +183 -0
  1602. psychopy/experiment/py2js_transpiler.py +606 -0
  1603. psychopy/experiment/questPlusTemplate.xltx +0 -0
  1604. psychopy/experiment/questTemplate.xltx +0 -0
  1605. psychopy/experiment/routines/__init__.py +108 -0
  1606. psychopy/experiment/routines/_base.py +907 -0
  1607. psychopy/experiment/routines/counterbalance/__init__.py +315 -0
  1608. psychopy/experiment/routines/counterbalance/classic/counterbalance.png +0 -0
  1609. psychopy/experiment/routines/counterbalance/classic/counterbalance@2x.png +0 -0
  1610. psychopy/experiment/routines/counterbalance/counterbalanceItems.xltx +0 -0
  1611. psychopy/experiment/routines/counterbalance/dark/counterbalance.png +0 -0
  1612. psychopy/experiment/routines/counterbalance/dark/counterbalance@2x.png +0 -0
  1613. psychopy/experiment/routines/counterbalance/light/counterbalance.png +0 -0
  1614. psychopy/experiment/routines/counterbalance/light/counterbalance@2x.png +0 -0
  1615. psychopy/experiment/routines/eyetracker_calibrate/__init__.py +275 -0
  1616. psychopy/experiment/routines/eyetracker_calibrate/classic/eyetracker_calib.png +0 -0
  1617. psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib.png +0 -0
  1618. psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib@2x.png +0 -0
  1619. psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib.png +0 -0
  1620. psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib@2x.png +0 -0
  1621. psychopy/experiment/routines/eyetracker_validate/__init__.py +354 -0
  1622. psychopy/experiment/routines/eyetracker_validate/classic/eyetracker_valid.png +0 -0
  1623. psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid.png +0 -0
  1624. psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid@2x.png +0 -0
  1625. psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid.png +0 -0
  1626. psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid@2x.png +0 -0
  1627. psychopy/experiment/routines/pavlovia_survey/__init__.py +236 -0
  1628. psychopy/experiment/routines/pavlovia_survey/classic/survey.png +0 -0
  1629. psychopy/experiment/routines/pavlovia_survey/classic/survey@2x.png +0 -0
  1630. psychopy/experiment/routines/pavlovia_survey/dark/survey.png +0 -0
  1631. psychopy/experiment/routines/pavlovia_survey/dark/survey@2x.png +0 -0
  1632. psychopy/experiment/routines/pavlovia_survey/light/survey.png +0 -0
  1633. psychopy/experiment/routines/pavlovia_survey/light/survey@2x.png +0 -0
  1634. psychopy/experiment/routines/photodiodeValidator/__init__.py +429 -0
  1635. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
  1636. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
  1637. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
  1638. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
  1639. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
  1640. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
  1641. psychopy/experiment/routines/unknown/__init__.py +28 -0
  1642. psychopy/experiment/routines/unknown/classic/eyetracker_record.png +0 -0
  1643. psychopy/experiment/routines/unknown/classic/unknown.png +0 -0
  1644. psychopy/experiment/routines/unknown/dark/eyetracker_record.png +0 -0
  1645. psychopy/experiment/routines/unknown/dark/eyetracker_record@2x.png +0 -0
  1646. psychopy/experiment/routines/unknown/dark/unknown.png +0 -0
  1647. psychopy/experiment/routines/unknown/dark/unknown@2x.png +0 -0
  1648. psychopy/experiment/routines/unknown/light/eyetracker_record.png +0 -0
  1649. psychopy/experiment/routines/unknown/light/eyetracker_record@2x.png +0 -0
  1650. psychopy/experiment/routines/unknown/light/unknown.png +0 -0
  1651. psychopy/experiment/routines/unknown/light/unknown@2x.png +0 -0
  1652. psychopy/experiment/routines/utils.py +0 -0
  1653. psychopy/experiment/staircaseTemplate.xltx +0 -0
  1654. psychopy/experiment/utils.py +44 -0
  1655. psychopy/filters.py +11 -0
  1656. psychopy/gamma.py +9 -0
  1657. psychopy/gui/__init__.py +47 -0
  1658. psychopy/gui/qtgui.py +866 -0
  1659. psychopy/gui/util.py +78 -0
  1660. psychopy/gui/wxgui.py +414 -0
  1661. psychopy/hardware/__init__.py +216 -0
  1662. psychopy/hardware/base.py +323 -0
  1663. psychopy/hardware/bbtk/__init__.py +30 -0
  1664. psychopy/hardware/brainproducts.py +31 -0
  1665. psychopy/hardware/button.py +205 -0
  1666. psychopy/hardware/buttonbox/__init__.py +122 -0
  1667. psychopy/hardware/camera/__init__.py +2809 -0
  1668. psychopy/hardware/cedrus.py +36 -0
  1669. psychopy/hardware/crs/__init__.py +46 -0
  1670. psychopy/hardware/crs/bits.py +34 -0
  1671. psychopy/hardware/crs/colorcal.py +30 -0
  1672. psychopy/hardware/crs/optical.py +46 -0
  1673. psychopy/hardware/crs/shaders.py +21 -0
  1674. psychopy/hardware/emotiv.py +33 -0
  1675. psychopy/hardware/emulator.py +37 -0
  1676. psychopy/hardware/eyetracker.py +208 -0
  1677. psychopy/hardware/forp.py +42 -0
  1678. psychopy/hardware/gammasci.py +32 -0
  1679. psychopy/hardware/iolab.py +35 -0
  1680. psychopy/hardware/joystick/__init__.py +597 -0
  1681. psychopy/hardware/keyboard.py +880 -0
  1682. psychopy/hardware/knownDevices.json +52 -0
  1683. psychopy/hardware/labhackers.py +27 -0
  1684. psychopy/hardware/labjacks.py +30 -0
  1685. psychopy/hardware/listener.py +323 -0
  1686. psychopy/hardware/manager.py +963 -0
  1687. psychopy/hardware/microphone.py +1074 -0
  1688. psychopy/hardware/minolta.py +30 -0
  1689. psychopy/hardware/mouse/__init__.py +885 -0
  1690. psychopy/hardware/photodiode.py +639 -0
  1691. psychopy/hardware/photometer/__init__.py +176 -0
  1692. psychopy/hardware/pr.py +30 -0
  1693. psychopy/hardware/qmix.py +41 -0
  1694. psychopy/hardware/serialdevice.py +342 -0
  1695. psychopy/hardware/speaker.py +54 -0
  1696. psychopy/hardware/triggerbox/__init__.py +56 -0
  1697. psychopy/hardware/triggerbox/base.py +170 -0
  1698. psychopy/hardware/triggerbox/parallel.py +362 -0
  1699. psychopy/info.py +790 -0
  1700. psychopy/iohub/__init__.py +45 -0
  1701. psychopy/iohub/client/__init__.py +1454 -0
  1702. psychopy/iohub/client/connect.py +260 -0
  1703. psychopy/iohub/client/eyetracker/__init__.py +4 -0
  1704. psychopy/iohub/client/eyetracker/validation/__init__.py +8 -0
  1705. psychopy/iohub/client/eyetracker/validation/posgrid.py +274 -0
  1706. psychopy/iohub/client/eyetracker/validation/procedure.py +1292 -0
  1707. psychopy/iohub/client/eyetracker/validation/trigger.py +240 -0
  1708. psychopy/iohub/client/keyboard.py +508 -0
  1709. psychopy/iohub/client/wintab.py +378 -0
  1710. psychopy/iohub/constants.py +1176 -0
  1711. psychopy/iohub/datastore/__init__.py +439 -0
  1712. psychopy/iohub/datastore/default_datastore.yaml +8 -0
  1713. psychopy/iohub/datastore/util.py +868 -0
  1714. psychopy/iohub/default_config.yaml +17 -0
  1715. psychopy/iohub/devices/__init__.py +960 -0
  1716. psychopy/iohub/devices/computer.py +607 -0
  1717. psychopy/iohub/devices/default_device.yaml +15 -0
  1718. psychopy/iohub/devices/deviceConfigValidation.py +517 -0
  1719. psychopy/iohub/devices/display/__init__.py +755 -0
  1720. psychopy/iohub/devices/display/default_display.yaml +118 -0
  1721. psychopy/iohub/devices/display/supported_config_settings.yaml +69 -0
  1722. psychopy/iohub/devices/eventfilters.py +3572 -0
  1723. psychopy/iohub/devices/experiment/__init__.py +316 -0
  1724. psychopy/iohub/devices/experiment/default_experiment.yaml +63 -0
  1725. psychopy/iohub/devices/experiment/supported_config_settings.yaml +22 -0
  1726. psychopy/iohub/devices/eyetracker/__init__.py +436 -0
  1727. psychopy/iohub/devices/eyetracker/calibration/__init__.py +1 -0
  1728. psychopy/iohub/devices/eyetracker/calibration/procedure.py +409 -0
  1729. psychopy/iohub/devices/eyetracker/default_eyetracker.yaml +18 -0
  1730. psychopy/iohub/devices/eyetracker/eye_events.py +1751 -0
  1731. psychopy/iohub/devices/eyetracker/filters/__init__.py +4 -0
  1732. psychopy/iohub/devices/eyetracker/filters/parser.py +913 -0
  1733. psychopy/iohub/devices/eyetracker/hw/__init__.py +4 -0
  1734. psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +17 -0
  1735. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +28 -0
  1736. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/calibration.py +18 -0
  1737. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +21 -0
  1738. psychopy/iohub/devices/eyetracker/hw/mouse/__init__.py +8 -0
  1739. psychopy/iohub/devices/eyetracker/hw/mouse/calibration.py +10 -0
  1740. psychopy/iohub/devices/eyetracker/hw/mouse/default_eyetracker.yaml +102 -0
  1741. psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +444 -0
  1742. psychopy/iohub/devices/eyetracker/hw/mouse/supported_config_settings.yaml +110 -0
  1743. psychopy/iohub/devices/eyetracker/hw/pupil_labs/__init__.py +4 -0
  1744. psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +26 -0
  1745. psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/eyetracker.py +18 -0
  1746. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/__init__.py +29 -0
  1747. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/bisector.py +20 -0
  1748. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/constants.py +19 -0
  1749. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/data_parse.py +22 -0
  1750. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/eyetracker.py +18 -0
  1751. psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/pupil_remote.py +18 -0
  1752. psychopy/iohub/devices/eyetracker/hw/sr_research/__init__.py +4 -0
  1753. psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/__init__.py +28 -0
  1754. psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/calibration.py +22 -0
  1755. psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/eyetracker.py +38 -0
  1756. psychopy/iohub/devices/eyetracker/hw/tobii/__init__.py +29 -0
  1757. psychopy/iohub/devices/eyetracker/hw/tobii/calibration.py +19 -0
  1758. psychopy/iohub/devices/eyetracker/hw/tobii/eyetracker.py +17 -0
  1759. psychopy/iohub/devices/eyetracker/hw/tobii/tobiiwrapper.py +19 -0
  1760. psychopy/iohub/devices/eyetracker/supported_config_settings.yaml +44 -0
  1761. psychopy/iohub/devices/keyboard/__init__.py +309 -0
  1762. psychopy/iohub/devices/keyboard/darwin.py +428 -0
  1763. psychopy/iohub/devices/keyboard/darwinkey.py +94 -0
  1764. psychopy/iohub/devices/keyboard/default_keyboard.yaml +94 -0
  1765. psychopy/iohub/devices/keyboard/linux2.py +102 -0
  1766. psychopy/iohub/devices/keyboard/supported_config_settings.yaml +39 -0
  1767. psychopy/iohub/devices/keyboard/win32.py +356 -0
  1768. psychopy/iohub/devices/mouse/__init__.py +709 -0
  1769. psychopy/iohub/devices/mouse/darwin.py +414 -0
  1770. psychopy/iohub/devices/mouse/default_mouse.yaml +92 -0
  1771. psychopy/iohub/devices/mouse/linux2.py +167 -0
  1772. psychopy/iohub/devices/mouse/supported_config_settings.yaml +39 -0
  1773. psychopy/iohub/devices/mouse/win32.py +279 -0
  1774. psychopy/iohub/devices/pyXHook.py +619 -0
  1775. psychopy/iohub/devices/serial/__init__.py +779 -0
  1776. psychopy/iohub/devices/serial/default_pstbox.yaml +108 -0
  1777. psychopy/iohub/devices/serial/default_serial.yaml +108 -0
  1778. psychopy/iohub/devices/serial/supported_config_settings.yaml +85 -0
  1779. psychopy/iohub/devices/serial/supported_config_settings_pstbox.yaml +85 -0
  1780. psychopy/iohub/devices/supported_config_settings.yaml +36 -0
  1781. psychopy/iohub/devices/wintab/__init__.py +580 -0
  1782. psychopy/iohub/devices/wintab/default_wintab.yaml +89 -0
  1783. psychopy/iohub/devices/wintab/supported_config_settings.yaml +42 -0
  1784. psychopy/iohub/devices/wintab/win32.py +722 -0
  1785. psychopy/iohub/devices/xlib.py +6795 -0
  1786. psychopy/iohub/errors.py +61 -0
  1787. psychopy/iohub/lazy_import.py +582 -0
  1788. psychopy/iohub/net.py +349 -0
  1789. psychopy/iohub/server.py +1075 -0
  1790. psychopy/iohub/start_iohub_process.py +118 -0
  1791. psychopy/iohub/util/__init__.py +841 -0
  1792. psychopy/iohub/util/visualangle.py +126 -0
  1793. psychopy/layout.py +916 -0
  1794. psychopy/liaison.py +419 -0
  1795. psychopy/locale_setup.py +31 -0
  1796. psychopy/localization/__init__.py +22 -0
  1797. psychopy/localization/_localization.py +155 -0
  1798. psychopy/localization/generateTranslationTemplate.py +139 -0
  1799. psychopy/localization/mappings.txt +170 -0
  1800. psychopy/localization/messages.pot +7516 -0
  1801. psychopy/localization/readme.txt +68 -0
  1802. psychopy/logging.py +406 -0
  1803. psychopy/microphone.py +54 -0
  1804. psychopy/misc.py +40 -0
  1805. psychopy/monitors/MonitorCenter.py +1254 -0
  1806. psychopy/monitors/__init__.py +30 -0
  1807. psychopy/monitors/calibData.py +78 -0
  1808. psychopy/monitors/calibTools.py +1300 -0
  1809. psychopy/monitors/getLumSeries.py +50 -0
  1810. psychopy/monitors/psychopy-icon.svg +395 -0
  1811. psychopy/monitors/psychopy.ico +0 -0
  1812. psychopy/parallel/__init__.py +206 -0
  1813. psychopy/parallel/_dlportio.py +150 -0
  1814. psychopy/parallel/_inpout.py +120 -0
  1815. psychopy/parallel/_linux.py +105 -0
  1816. psychopy/piloting.py +61 -0
  1817. psychopy/platform_specific/__init__.py +48 -0
  1818. psychopy/platform_specific/darwin.py +328 -0
  1819. psychopy/platform_specific/linux.py +79 -0
  1820. psychopy/platform_specific/posix.py +16 -0
  1821. psychopy/platform_specific/win32.py +99 -0
  1822. psychopy/plugins/__init__.py +1354 -0
  1823. psychopy/preferences/Darwin.spec +282 -0
  1824. psychopy/preferences/FreeBSD.spec +282 -0
  1825. psychopy/preferences/Linux.spec +282 -0
  1826. psychopy/preferences/Windows.spec +282 -0
  1827. psychopy/preferences/__init__.py +20 -0
  1828. psychopy/preferences/baseNoArch.spec +278 -0
  1829. psychopy/preferences/generateHints.py +91 -0
  1830. psychopy/preferences/generateSpec.py +80 -0
  1831. psychopy/preferences/hints.py +329 -0
  1832. psychopy/preferences/preferences.py +332 -0
  1833. psychopy/projects/__init__.py +11 -0
  1834. psychopy/projects/gitignore.py +45 -0
  1835. psychopy/projects/pavlovia.py +1566 -0
  1836. psychopy/projects/sshkeys.py +107 -0
  1837. psychopy/psychojs.zip +0 -0
  1838. psychopy/pylintrc +69 -0
  1839. psychopy/scripts/__init__.py +0 -0
  1840. psychopy/scripts/psyexpCompile.py +233 -0
  1841. psychopy/session.py +1450 -0
  1842. psychopy/sound/__init__.py +279 -0
  1843. psychopy/sound/_base.py +282 -0
  1844. psychopy/sound/audioclip.py +851 -0
  1845. psychopy/sound/audiodevice.py +857 -0
  1846. psychopy/sound/backend_ptb.py +660 -0
  1847. psychopy/sound/backend_pygame.py +309 -0
  1848. psychopy/sound/backend_pyo.py +33 -0
  1849. psychopy/sound/backend_pysound.py +341 -0
  1850. psychopy/sound/backend_sounddevice.py +32 -0
  1851. psychopy/sound/exceptions.py +115 -0
  1852. psychopy/sound/microphone.py +274 -0
  1853. psychopy/sound/transcribe.py +1248 -0
  1854. psychopy/tests/.DS_Store +0 -0
  1855. psychopy/tests/README.md +344 -0
  1856. psychopy/tests/__init__.py +47 -0
  1857. psychopy/tests/data/Electronic_Chime-KevanGC-495939803.wav +0 -0
  1858. psychopy/tests/data/TestCircle_w128h128_bottom_left.png +0 -0
  1859. psychopy/tests/data/TestCircle_w128h128_bottom_right.png +0 -0
  1860. psychopy/tests/data/TestCircle_w128h128_center_center.png +0 -0
  1861. psychopy/tests/data/TestCircle_w128h128_top_left.png +0 -0
  1862. psychopy/tests/data/TestCircle_w128h128_top_right.png +0 -0
  1863. psychopy/tests/data/TestCircle_w128h64_bottom_left.png +0 -0
  1864. psychopy/tests/data/TestCircle_w128h64_bottom_right.png +0 -0
  1865. psychopy/tests/data/TestCircle_w128h64_center_center.png +0 -0
  1866. psychopy/tests/data/TestCircle_w128h64_top_left.png +0 -0
  1867. psychopy/tests/data/TestCircle_w128h64_top_right.png +0 -0
  1868. psychopy/tests/data/TestCircle_w64h128_bottom_left.png +0 -0
  1869. psychopy/tests/data/TestCircle_w64h128_bottom_right.png +0 -0
  1870. psychopy/tests/data/TestCircle_w64h128_center_center.png +0 -0
  1871. psychopy/tests/data/TestCircle_w64h128_top_left.png +0 -0
  1872. psychopy/tests/data/TestCircle_w64h128_top_right.png +0 -0
  1873. psychopy/tests/data/TestCircle_w64h64_bottom_left.png +0 -0
  1874. psychopy/tests/data/TestCircle_w64h64_bottom_right.png +0 -0
  1875. psychopy/tests/data/TestCircle_w64h64_center_center.png +0 -0
  1876. psychopy/tests/data/TestCircle_w64h64_top_left.png +0 -0
  1877. psychopy/tests/data/TestCircle_w64h64_top_right.png +0 -0
  1878. psychopy/tests/data/TestForm_scrolling_nq10_s0.5.png +0 -0
  1879. psychopy/tests/data/TestForm_scrolling_nq10_s0.png +0 -0
  1880. psychopy/tests/data/TestForm_scrolling_nq10_s1.png +0 -0
  1881. psychopy/tests/data/TestForm_scrolling_nq1_s0.5.png +0 -0
  1882. psychopy/tests/data/TestForm_scrolling_nq1_s0.png +0 -0
  1883. psychopy/tests/data/TestForm_scrolling_nq1_s1.png +0 -0
  1884. psychopy/tests/data/TestForm_scrolling_nq3_s0.5.png +0 -0
  1885. psychopy/tests/data/TestForm_scrolling_nq3_s0.png +0 -0
  1886. psychopy/tests/data/TestForm_scrolling_nq3_s1.png +0 -0
  1887. psychopy/tests/data/TestImage_w128h128_bottom_left.png +0 -0
  1888. psychopy/tests/data/TestImage_w128h128_bottom_right.png +0 -0
  1889. psychopy/tests/data/TestImage_w128h128_center_center.png +0 -0
  1890. psychopy/tests/data/TestImage_w128h128_top_left.png +0 -0
  1891. psychopy/tests/data/TestImage_w128h128_top_right.png +0 -0
  1892. psychopy/tests/data/TestImage_w128h64_bottom_left.png +0 -0
  1893. psychopy/tests/data/TestImage_w128h64_bottom_right.png +0 -0
  1894. psychopy/tests/data/TestImage_w128h64_center_center.png +0 -0
  1895. psychopy/tests/data/TestImage_w128h64_top_left.png +0 -0
  1896. psychopy/tests/data/TestImage_w128h64_top_right.png +0 -0
  1897. psychopy/tests/data/TestImage_w64h128_bottom_left.png +0 -0
  1898. psychopy/tests/data/TestImage_w64h128_bottom_right.png +0 -0
  1899. psychopy/tests/data/TestImage_w64h128_center_center.png +0 -0
  1900. psychopy/tests/data/TestImage_w64h128_top_left.png +0 -0
  1901. psychopy/tests/data/TestImage_w64h128_top_right.png +0 -0
  1902. psychopy/tests/data/TestImage_w64h64_bottom_left.png +0 -0
  1903. psychopy/tests/data/TestImage_w64h64_bottom_right.png +0 -0
  1904. psychopy/tests/data/TestImage_w64h64_center_center.png +0 -0
  1905. psychopy/tests/data/TestImage_w64h64_top_left.png +0 -0
  1906. psychopy/tests/data/TestImage_w64h64_top_right.png +0 -0
  1907. psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.3.png +0 -0
  1908. psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.6.png +0 -0
  1909. psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.3.png +0 -0
  1910. psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.6.png +0 -0
  1911. psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.3.png +0 -0
  1912. psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.6.png +0 -0
  1913. psychopy/tests/data/TestProgress_testValue_minmax_0.png +0 -0
  1914. psychopy/tests/data/TestProgress_testValue_minmax_1.png +0 -0
  1915. psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.3.png +0 -0
  1916. psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.6.png +0 -0
  1917. psychopy/tests/data/TestProgress_testValue_vertical_center center_0.3.png +0 -0
  1918. psychopy/tests/data/TestProgress_testValue_vertical_center center_0.6.png +0 -0
  1919. psychopy/tests/data/TestProgress_testValue_vertical_top center_0.3.png +0 -0
  1920. psychopy/tests/data/TestProgress_testValue_vertical_top center_0.6.png +0 -0
  1921. psychopy/tests/data/TestProgress_w128h128_bottom_left.png +0 -0
  1922. psychopy/tests/data/TestProgress_w128h128_bottom_right.png +0 -0
  1923. psychopy/tests/data/TestProgress_w128h128_center_center.png +0 -0
  1924. psychopy/tests/data/TestProgress_w128h128_top_left.png +0 -0
  1925. psychopy/tests/data/TestProgress_w128h128_top_right.png +0 -0
  1926. psychopy/tests/data/TestProgress_w128h64_bottom_left.png +0 -0
  1927. psychopy/tests/data/TestProgress_w128h64_bottom_right.png +0 -0
  1928. psychopy/tests/data/TestProgress_w128h64_center_center.png +0 -0
  1929. psychopy/tests/data/TestProgress_w128h64_top_left.png +0 -0
  1930. psychopy/tests/data/TestProgress_w128h64_top_right.png +0 -0
  1931. psychopy/tests/data/TestProgress_w64h128_bottom_left.png +0 -0
  1932. psychopy/tests/data/TestProgress_w64h128_bottom_right.png +0 -0
  1933. psychopy/tests/data/TestProgress_w64h128_center_center.png +0 -0
  1934. psychopy/tests/data/TestProgress_w64h128_top_left.png +0 -0
  1935. psychopy/tests/data/TestProgress_w64h128_top_right.png +0 -0
  1936. psychopy/tests/data/TestProgress_w64h64_bottom_left.png +0 -0
  1937. psychopy/tests/data/TestProgress_w64h64_bottom_right.png +0 -0
  1938. psychopy/tests/data/TestProgress_w64h64_center_center.png +0 -0
  1939. psychopy/tests/data/TestProgress_w64h64_top_left.png +0 -0
  1940. psychopy/tests/data/TestProgress_w64h64_top_right.png +0 -0
  1941. psychopy/tests/data/TestROI_w128h128_bottom_left.png +0 -0
  1942. psychopy/tests/data/TestROI_w128h128_bottom_right.png +0 -0
  1943. psychopy/tests/data/TestROI_w128h128_center_center.png +0 -0
  1944. psychopy/tests/data/TestROI_w128h128_top_left.png +0 -0
  1945. psychopy/tests/data/TestROI_w128h128_top_right.png +0 -0
  1946. psychopy/tests/data/TestROI_w128h64_bottom_left.png +0 -0
  1947. psychopy/tests/data/TestROI_w128h64_bottom_right.png +0 -0
  1948. psychopy/tests/data/TestROI_w128h64_center_center.png +0 -0
  1949. psychopy/tests/data/TestROI_w128h64_top_left.png +0 -0
  1950. psychopy/tests/data/TestROI_w128h64_top_right.png +0 -0
  1951. psychopy/tests/data/TestROI_w64h128_bottom_left.png +0 -0
  1952. psychopy/tests/data/TestROI_w64h128_bottom_right.png +0 -0
  1953. psychopy/tests/data/TestROI_w64h128_center_center.png +0 -0
  1954. psychopy/tests/data/TestROI_w64h128_top_left.png +0 -0
  1955. psychopy/tests/data/TestROI_w64h128_top_right.png +0 -0
  1956. psychopy/tests/data/TestROI_w64h64_bottom_left.png +0 -0
  1957. psychopy/tests/data/TestROI_w64h64_bottom_right.png +0 -0
  1958. psychopy/tests/data/TestROI_w64h64_center_center.png +0 -0
  1959. psychopy/tests/data/TestROI_w64h64_top_left.png +0 -0
  1960. psychopy/tests/data/TestROI_w64h64_top_right.png +0 -0
  1961. psychopy/tests/data/TestSession_exp1.png +0 -0
  1962. psychopy/tests/data/TestSession_exp2.png +0 -0
  1963. psychopy/tests/data/TestShape_w128h128_bottom_left.png +0 -0
  1964. psychopy/tests/data/TestShape_w128h128_bottom_right.png +0 -0
  1965. psychopy/tests/data/TestShape_w128h128_center_center.png +0 -0
  1966. psychopy/tests/data/TestShape_w128h128_top_left.png +0 -0
  1967. psychopy/tests/data/TestShape_w128h128_top_right.png +0 -0
  1968. psychopy/tests/data/TestShape_w128h64_bottom_left.png +0 -0
  1969. psychopy/tests/data/TestShape_w128h64_bottom_right.png +0 -0
  1970. psychopy/tests/data/TestShape_w128h64_center_center.png +0 -0
  1971. psychopy/tests/data/TestShape_w128h64_top_left.png +0 -0
  1972. psychopy/tests/data/TestShape_w128h64_top_right.png +0 -0
  1973. psychopy/tests/data/TestShape_w64h128_bottom_left.png +0 -0
  1974. psychopy/tests/data/TestShape_w64h128_bottom_right.png +0 -0
  1975. psychopy/tests/data/TestShape_w64h128_center_center.png +0 -0
  1976. psychopy/tests/data/TestShape_w64h128_top_left.png +0 -0
  1977. psychopy/tests/data/TestShape_w64h128_top_right.png +0 -0
  1978. psychopy/tests/data/TestShape_w64h64_bottom_left.png +0 -0
  1979. psychopy/tests/data/TestShape_w64h64_bottom_right.png +0 -0
  1980. psychopy/tests/data/TestShape_w64h64_center_center.png +0 -0
  1981. psychopy/tests/data/TestShape_w64h64_top_left.png +0 -0
  1982. psychopy/tests/data/TestShape_w64h64_top_right.png +0 -0
  1983. psychopy/tests/data/TestTarget_w128h128_bottom_left.png +0 -0
  1984. psychopy/tests/data/TestTarget_w128h128_bottom_right.png +0 -0
  1985. psychopy/tests/data/TestTarget_w128h128_center_center.png +0 -0
  1986. psychopy/tests/data/TestTarget_w128h128_top_left.png +0 -0
  1987. psychopy/tests/data/TestTarget_w128h128_top_right.png +0 -0
  1988. psychopy/tests/data/TestTarget_w128h64_bottom_left.png +0 -0
  1989. psychopy/tests/data/TestTarget_w128h64_bottom_right.png +0 -0
  1990. psychopy/tests/data/TestTarget_w128h64_center_center.png +0 -0
  1991. psychopy/tests/data/TestTarget_w128h64_top_left.png +0 -0
  1992. psychopy/tests/data/TestTarget_w128h64_top_right.png +0 -0
  1993. psychopy/tests/data/TestTarget_w64h128_bottom_left.png +0 -0
  1994. psychopy/tests/data/TestTarget_w64h128_bottom_right.png +0 -0
  1995. psychopy/tests/data/TestTarget_w64h128_center_center.png +0 -0
  1996. psychopy/tests/data/TestTarget_w64h128_top_left.png +0 -0
  1997. psychopy/tests/data/TestTarget_w64h128_top_right.png +0 -0
  1998. psychopy/tests/data/TestTarget_w64h64_bottom_left.png +0 -0
  1999. psychopy/tests/data/TestTarget_w64h64_bottom_right.png +0 -0
  2000. psychopy/tests/data/TestTarget_w64h64_center_center.png +0 -0
  2001. psychopy/tests/data/TestTarget_w64h64_top_left.png +0 -0
  2002. psychopy/tests/data/TestTarget_w64h64_top_right.png +0 -0
  2003. psychopy/tests/data/TestTextbox_testLetterSpacing_0p6.png +0 -0
  2004. psychopy/tests/data/TestTextbox_testLetterSpacing_0p8.png +0 -0
  2005. psychopy/tests/data/TestTextbox_testLetterSpacing_1.png +0 -0
  2006. psychopy/tests/data/TestTextbox_testLetterSpacing_1p2.png +0 -0
  2007. psychopy/tests/data/TestTextbox_testLetterSpacing_1p4.png +0 -0
  2008. psychopy/tests/data/TestTextbox_testLetterSpacing_1p6.png +0 -0
  2009. psychopy/tests/data/TestTextbox_testLetterSpacing_1p8.png +0 -0
  2010. psychopy/tests/data/TestTextbox_testLetterSpacing_2p0.png +0 -0
  2011. psychopy/tests/data/TestTextbox_testLetterSpacing_None.png +0 -0
  2012. psychopy/tests/data/Test_textbox_testSpeechpoint_-3ovr8_0ovr8.png +0 -0
  2013. psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_-3ovr8.png +0 -0
  2014. psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_3ovr8.png +0 -0
  2015. psychopy/tests/data/Test_textbox_testSpeechpoint_3ovr8_0ovr8.png +0 -0
  2016. psychopy/tests/data/Test_textbox_w128h128_bottom_left.png +0 -0
  2017. psychopy/tests/data/Test_textbox_w128h128_bottom_right.png +0 -0
  2018. psychopy/tests/data/Test_textbox_w128h128_center_center.png +0 -0
  2019. psychopy/tests/data/Test_textbox_w128h128_top_left.png +0 -0
  2020. psychopy/tests/data/Test_textbox_w128h128_top_right.png +0 -0
  2021. psychopy/tests/data/Test_textbox_w128h64_bottom_left.png +0 -0
  2022. psychopy/tests/data/Test_textbox_w128h64_bottom_right.png +0 -0
  2023. psychopy/tests/data/Test_textbox_w128h64_center_center.png +0 -0
  2024. psychopy/tests/data/Test_textbox_w128h64_top_left.png +0 -0
  2025. psychopy/tests/data/Test_textbox_w128h64_top_right.png +0 -0
  2026. psychopy/tests/data/Test_textbox_w64h128_bottom_left.png +0 -0
  2027. psychopy/tests/data/Test_textbox_w64h128_bottom_right.png +0 -0
  2028. psychopy/tests/data/Test_textbox_w64h128_center_center.png +0 -0
  2029. psychopy/tests/data/Test_textbox_w64h128_top_left.png +0 -0
  2030. psychopy/tests/data/Test_textbox_w64h128_top_right.png +0 -0
  2031. psychopy/tests/data/Test_textbox_w64h64_bottom_left.png +0 -0
  2032. psychopy/tests/data/Test_textbox_w64h64_bottom_right.png +0 -0
  2033. psychopy/tests/data/Test_textbox_w64h64_center_center.png +0 -0
  2034. psychopy/tests/data/Test_textbox_w64h64_top_left.png +0 -0
  2035. psychopy/tests/data/Test_textbox_w64h64_top_right.png +0 -0
  2036. psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_left.png +0 -0
  2037. psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_right.png +0 -0
  2038. psychopy/tests/data/Test_uax14_textbox_w128h128_center_center.png +0 -0
  2039. psychopy/tests/data/Test_uax14_textbox_w128h128_top_left.png +0 -0
  2040. psychopy/tests/data/Test_uax14_textbox_w128h128_top_right.png +0 -0
  2041. psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_left.png +0 -0
  2042. psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_right.png +0 -0
  2043. psychopy/tests/data/Test_uax14_textbox_w128h64_center_center.png +0 -0
  2044. psychopy/tests/data/Test_uax14_textbox_w128h64_top_left.png +0 -0
  2045. psychopy/tests/data/Test_uax14_textbox_w128h64_top_right.png +0 -0
  2046. psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_left.png +0 -0
  2047. psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_right.png +0 -0
  2048. psychopy/tests/data/Test_uax14_textbox_w64h128_center_center.png +0 -0
  2049. psychopy/tests/data/Test_uax14_textbox_w64h128_top_left.png +0 -0
  2050. psychopy/tests/data/Test_uax14_textbox_w64h128_top_right.png +0 -0
  2051. psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_left.png +0 -0
  2052. psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_right.png +0 -0
  2053. psychopy/tests/data/Test_uax14_textbox_w64h64_center_center.png +0 -0
  2054. psychopy/tests/data/Test_uax14_textbox_w64h64_top_left.png +0 -0
  2055. psychopy/tests/data/Test_uax14_textbox_w64h64_top_right.png +0 -0
  2056. psychopy/tests/data/TextComponent_disabled.psyexp +63 -0
  2057. psychopy/tests/data/TextComponent_not_disabled.psyexp +63 -0
  2058. psychopy/tests/data/aperture1_deg.png +0 -0
  2059. psychopy/tests/data/aperture1_degFlat.png +0 -0
  2060. psychopy/tests/data/aperture1_degFlatPos.png +0 -0
  2061. psychopy/tests/data/aperture1_norm.png +0 -0
  2062. psychopy/tests/data/aperture1_normHexbackground.png +0 -0
  2063. psychopy/tests/data/aperture1_normNoShade.png +0 -0
  2064. psychopy/tests/data/aperture1_pix.png +0 -0
  2065. psychopy/tests/data/aperture1_stencil.png +0 -0
  2066. psychopy/tests/data/aperture2_deg.png +0 -0
  2067. psychopy/tests/data/aperture2_degFlat.png +0 -0
  2068. psychopy/tests/data/aperture2_degFlatPos.png +0 -0
  2069. psychopy/tests/data/aperture2_norm.png +0 -0
  2070. psychopy/tests/data/aperture2_normHexbackground.png +0 -0
  2071. psychopy/tests/data/aperture2_normNoShade.png +0 -0
  2072. psychopy/tests/data/aperture2_pix.png +0 -0
  2073. psychopy/tests/data/aperture2_stencil.png +0 -0
  2074. psychopy/tests/data/beatandrcos_cm.png +0 -0
  2075. psychopy/tests/data/beatandrcos_deg.png +0 -0
  2076. psychopy/tests/data/beatandrcos_degFlat.png +0 -0
  2077. psychopy/tests/data/beatandrcos_degFlatPos.png +0 -0
  2078. psychopy/tests/data/beatandrcos_height.png +0 -0
  2079. psychopy/tests/data/beatandrcos_norm.png +0 -0
  2080. psychopy/tests/data/beatandrcos_normAddBlend.png +0 -0
  2081. psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
  2082. psychopy/tests/data/beatandrcos_normHexbackground.png +0 -0
  2083. psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
  2084. psychopy/tests/data/beatandrcos_norm_local.png +0 -0
  2085. psychopy/tests/data/beatandrcos_pix.png +0 -0
  2086. psychopy/tests/data/beatandrcos_stencil.png +0 -0
  2087. psychopy/tests/data/blend_add_cm.png +0 -0
  2088. psychopy/tests/data/blend_add_deg.png +0 -0
  2089. psychopy/tests/data/blend_add_degFlat.png +0 -0
  2090. psychopy/tests/data/blend_add_degFlatPos.png +0 -0
  2091. psychopy/tests/data/blend_add_height.png +0 -0
  2092. psychopy/tests/data/blend_add_norm.png +0 -0
  2093. psychopy/tests/data/blend_add_normAddBlend.png +0 -0
  2094. psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
  2095. psychopy/tests/data/blend_add_normHexbackground.png +0 -0
  2096. psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
  2097. psychopy/tests/data/blend_add_normNoShade.png +0 -0
  2098. psychopy/tests/data/blend_add_norm_local.png +0 -0
  2099. psychopy/tests/data/blend_add_pix.png +0 -0
  2100. psychopy/tests/data/blend_add_stencil.png +0 -0
  2101. psychopy/tests/data/broken2020_2_5_resources/broken_resources.psyexp +84 -0
  2102. psychopy/tests/data/broken2020_2_5_resources/psychopy72.png +0 -0
  2103. psychopy/tests/data/bufferimg_gabor_cm.png +0 -0
  2104. psychopy/tests/data/bufferimg_gabor_deg.png +0 -0
  2105. psychopy/tests/data/bufferimg_gabor_degFlat.png +0 -0
  2106. psychopy/tests/data/bufferimg_gabor_degFlatPos.png +0 -0
  2107. psychopy/tests/data/bufferimg_gabor_height.png +0 -0
  2108. psychopy/tests/data/bufferimg_gabor_norm.png +0 -0
  2109. psychopy/tests/data/bufferimg_gabor_normAddBlend.png +0 -0
  2110. psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
  2111. psychopy/tests/data/bufferimg_gabor_normHexbackground.png +0 -0
  2112. psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
  2113. psychopy/tests/data/bufferimg_gabor_normNoShade.png +0 -0
  2114. psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
  2115. psychopy/tests/data/bufferimg_gabor_pix.png +0 -0
  2116. psychopy/tests/data/bufferimg_gabor_stencil.png +0 -0
  2117. psychopy/tests/data/circleHex_cm.png +0 -0
  2118. psychopy/tests/data/circleHex_deg.png +0 -0
  2119. psychopy/tests/data/circleHex_degFlat.png +0 -0
  2120. psychopy/tests/data/circleHex_degFlatPos.png +0 -0
  2121. psychopy/tests/data/circleHex_height.png +0 -0
  2122. psychopy/tests/data/circleHex_norm.png +0 -0
  2123. psychopy/tests/data/circleHex_normAddBlend.png +0 -0
  2124. psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
  2125. psychopy/tests/data/circleHex_normHexbackground.png +0 -0
  2126. psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
  2127. psychopy/tests/data/circleHex_normNoShade.png +0 -0
  2128. psychopy/tests/data/circleHex_norm_local.png +0 -0
  2129. psychopy/tests/data/circleHex_pix.png +0 -0
  2130. psychopy/tests/data/circleHex_stencil.png +0 -0
  2131. psychopy/tests/data/corrFullRandom.csv +16 -0
  2132. psychopy/tests/data/corrFullRandom.tsv +6 -0
  2133. psychopy/tests/data/corrFullRandomTH2.csv +16 -0
  2134. psychopy/tests/data/corrMultiKeyExpWide.csv +3 -0
  2135. psychopy/tests/data/corrMultiKeyTrials.csv +8 -0
  2136. psychopy/tests/data/corrMultiKeyTrials.xlsx +0 -0
  2137. psychopy/tests/data/corrRandom.csv +16 -0
  2138. psychopy/tests/data/corrRandom.tsv +6 -0
  2139. psychopy/tests/data/corrRandomTH2.csv +16 -0
  2140. psychopy/tests/data/corrXlsx.xlsx +0 -0
  2141. psychopy/tests/data/correctScript/js/correctCodeComponent.js +181 -0
  2142. psychopy/tests/data/correctScript/js/correctImageComponent.js +204 -0
  2143. psychopy/tests/data/correctScript/js/correctKeyboardComponent.js +225 -0
  2144. psychopy/tests/data/correctScript/js/correctMouseComponent.js +221 -0
  2145. psychopy/tests/data/correctScript/js/correctMovieComponent.js +210 -0
  2146. psychopy/tests/data/correctScript/js/correctPolygonComponent.js +205 -0
  2147. psychopy/tests/data/correctScript/js/correctSliderComponent.js +209 -0
  2148. psychopy/tests/data/correctScript/js/correctSoundComponent.js +205 -0
  2149. psychopy/tests/data/correctScript/js/correctTextComponent.js +207 -0
  2150. psychopy/tests/data/correctScript/python/correctApertureComponent.py +157 -0
  2151. psychopy/tests/data/correctScript/python/correctCodeComponent.py +135 -0
  2152. psychopy/tests/data/correctScript/python/correctDotsComponent.py +161 -0
  2153. psychopy/tests/data/correctScript/python/correctEnvGratingComponent.py +167 -0
  2154. psychopy/tests/data/correctScript/python/correctFormComponent.py +150 -0
  2155. psychopy/tests/data/correctScript/python/correctGratingComponent.py +158 -0
  2156. psychopy/tests/data/correctScript/python/correctImageComponent.py +160 -0
  2157. psychopy/tests/data/correctScript/python/correctJoyButtonsComponent.py +204 -0
  2158. psychopy/tests/data/correctScript/python/correctJoystickComponent.py +214 -0
  2159. psychopy/tests/data/correctScript/python/correctKeyboardComponent.py +169 -0
  2160. psychopy/tests/data/correctScript/python/correctMicrophoneComponent.py +163 -0
  2161. psychopy/tests/data/correctScript/python/correctMouseComponent.py +174 -0
  2162. psychopy/tests/data/correctScript/python/correctMovieComponent.py +160 -0
  2163. psychopy/tests/data/correctScript/python/correctNoiseStimComponent.py +169 -0
  2164. psychopy/tests/data/correctScript/python/correctParallelOutComponent.py +156 -0
  2165. psychopy/tests/data/correctScript/python/correctPatchComponent.py +159 -0
  2166. psychopy/tests/data/correctScript/python/correctPolygonComponent.py +159 -0
  2167. psychopy/tests/data/correctScript/python/correctQmixPumpComponent.py +174 -0
  2168. psychopy/tests/data/correctScript/python/correctRatingScaleComponent.py +152 -0
  2169. psychopy/tests/data/correctScript/python/correctSliderComponent.py +159 -0
  2170. psychopy/tests/data/correctScript/python/correctSoundComponent.py +157 -0
  2171. psychopy/tests/data/correctScript/python/correctStaticComponent.py +176 -0
  2172. psychopy/tests/data/correctScript/python/correctTextComponent.py +159 -0
  2173. psychopy/tests/data/correctScript/python/correctVariableComponent.py +139 -0
  2174. psychopy/tests/data/correctScript/python/correctcedrusButtonBoxComponent.py +199 -0
  2175. psychopy/tests/data/correctScript/python/correctioLabsButtonBoxComponent.py +187 -0
  2176. psychopy/tests/data/dataTest.xlsx +0 -0
  2177. psychopy/tests/data/dots_cm.png +0 -0
  2178. psychopy/tests/data/dots_deg.png +0 -0
  2179. psychopy/tests/data/dots_degFlat.png +0 -0
  2180. psychopy/tests/data/dots_degFlatPos.png +0 -0
  2181. psychopy/tests/data/dots_height.png +0 -0
  2182. psychopy/tests/data/dots_norm.png +0 -0
  2183. psychopy/tests/data/dots_normAddBlend.png +0 -0
  2184. psychopy/tests/data/dots_normAddBlend_local.png +0 -0
  2185. psychopy/tests/data/dots_normHexbackground.png +0 -0
  2186. psychopy/tests/data/dots_normHexbackground_local.png +0 -0
  2187. psychopy/tests/data/dots_normNoShade.png +0 -0
  2188. psychopy/tests/data/dots_norm_local.png +0 -0
  2189. psychopy/tests/data/dots_pix.png +0 -0
  2190. psychopy/tests/data/dots_stencil.png +0 -0
  2191. psychopy/tests/data/elarray1_cm.png +0 -0
  2192. psychopy/tests/data/elarray1_deg.png +0 -0
  2193. psychopy/tests/data/elarray1_degFlat.png +0 -0
  2194. psychopy/tests/data/elarray1_degFlatPos.png +0 -0
  2195. psychopy/tests/data/elarray1_height.png +0 -0
  2196. psychopy/tests/data/elarray1_norm.png +0 -0
  2197. psychopy/tests/data/elarray1_normAddBlend.png +0 -0
  2198. psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
  2199. psychopy/tests/data/elarray1_normHexbackground.png +0 -0
  2200. psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
  2201. psychopy/tests/data/elarray1_norm_local.png +0 -0
  2202. psychopy/tests/data/elarray1_pix.png +0 -0
  2203. psychopy/tests/data/elarray1_stencil.png +0 -0
  2204. psychopy/tests/data/envelopeandrcos_cm.png +0 -0
  2205. psychopy/tests/data/envelopeandrcos_deg.png +0 -0
  2206. psychopy/tests/data/envelopeandrcos_degFlat.png +0 -0
  2207. psychopy/tests/data/envelopeandrcos_degFlatPos.png +0 -0
  2208. psychopy/tests/data/envelopeandrcos_height.png +0 -0
  2209. psychopy/tests/data/envelopeandrcos_norm.png +0 -0
  2210. psychopy/tests/data/envelopeandrcos_normAddBlend.png +0 -0
  2211. psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
  2212. psychopy/tests/data/envelopeandrcos_normHexbackground.png +0 -0
  2213. psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
  2214. psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
  2215. psychopy/tests/data/envelopeandrcos_pix.png +0 -0
  2216. psychopy/tests/data/envelopeandrcos_stencil.png +0 -0
  2217. psychopy/tests/data/envelopepowerandrcos_cm.png +0 -0
  2218. psychopy/tests/data/envelopepowerandrcos_deg.png +0 -0
  2219. psychopy/tests/data/envelopepowerandrcos_degFlat.png +0 -0
  2220. psychopy/tests/data/envelopepowerandrcos_degFlatPos.png +0 -0
  2221. psychopy/tests/data/envelopepowerandrcos_height.png +0 -0
  2222. psychopy/tests/data/envelopepowerandrcos_norm.png +0 -0
  2223. psychopy/tests/data/envelopepowerandrcos_normAddBlend.png +0 -0
  2224. psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
  2225. psychopy/tests/data/envelopepowerandrcos_normHexbackground.png +0 -0
  2226. psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
  2227. psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
  2228. psychopy/tests/data/envelopepowerandrcos_pix.png +0 -0
  2229. psychopy/tests/data/envelopepowerandrcos_stencil.png +0 -0
  2230. psychopy/tests/data/filltext.png +0 -0
  2231. psychopy/tests/data/form_font_demographics.png +0 -0
  2232. psychopy/tests/data/form_font_demographics.xlsx +0 -0
  2233. psychopy/tests/data/form_font_languages.png +0 -0
  2234. psychopy/tests/data/form_font_languages.xlsx +0 -0
  2235. psychopy/tests/data/form_font_nonstandard.png +0 -0
  2236. psychopy/tests/data/futureParams.psyexp +150 -0
  2237. psychopy/tests/data/gabor1_cm.png +0 -0
  2238. psychopy/tests/data/gabor1_deg.png +0 -0
  2239. psychopy/tests/data/gabor1_degFlat.png +0 -0
  2240. psychopy/tests/data/gabor1_degFlatPos.png +0 -0
  2241. psychopy/tests/data/gabor1_height.png +0 -0
  2242. psychopy/tests/data/gabor1_norm.png +0 -0
  2243. psychopy/tests/data/gabor1_normAddBlend.png +0 -0
  2244. psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
  2245. psychopy/tests/data/gabor1_normHexbackground.png +0 -0
  2246. psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
  2247. psychopy/tests/data/gabor1_normNoShade.png +0 -0
  2248. psychopy/tests/data/gabor1_norm_local.png +0 -0
  2249. psychopy/tests/data/gabor1_pix.png +0 -0
  2250. psychopy/tests/data/gabor1_stencil.png +0 -0
  2251. psychopy/tests/data/gabor2_cm.png +0 -0
  2252. psychopy/tests/data/gabor2_deg.png +0 -0
  2253. psychopy/tests/data/gabor2_degFlat.png +0 -0
  2254. psychopy/tests/data/gabor2_degFlatPos.png +0 -0
  2255. psychopy/tests/data/gabor2_height.png +0 -0
  2256. psychopy/tests/data/gabor2_norm.png +0 -0
  2257. psychopy/tests/data/gabor2_normAddBlend.png +0 -0
  2258. psychopy/tests/data/gabor2_normHexbackground.png +0 -0
  2259. psychopy/tests/data/gabor2_normNoShade.png +0 -0
  2260. psychopy/tests/data/gabor2_pix.png +0 -0
  2261. psychopy/tests/data/gabor2_stencil.png +0 -0
  2262. psychopy/tests/data/ghost_stroop.psyexp +131 -0
  2263. psychopy/tests/data/ghost_trialTypes.xlsx +0 -0
  2264. psychopy/tests/data/green_48000.flac.dist +0 -0
  2265. psychopy/tests/data/greyscale.jpg +0 -0
  2266. psychopy/tests/data/greyscale2.png +0 -0
  2267. psychopy/tests/data/greyscale2_cm.png +0 -0
  2268. psychopy/tests/data/greyscale2_deg.png +0 -0
  2269. psychopy/tests/data/greyscale2_degFlat.png +0 -0
  2270. psychopy/tests/data/greyscale2_degFlatPos.png +0 -0
  2271. psychopy/tests/data/greyscale2_height.png +0 -0
  2272. psychopy/tests/data/greyscale2_norm.png +0 -0
  2273. psychopy/tests/data/greyscale2_normAddBlend.png +0 -0
  2274. psychopy/tests/data/greyscale2_normHexbackground.png +0 -0
  2275. psychopy/tests/data/greyscale2_normNoShade.png +0 -0
  2276. psychopy/tests/data/greyscale2_pix.png +0 -0
  2277. psychopy/tests/data/greyscale2_stencil.png +0 -0
  2278. psychopy/tests/data/greyscaleLowContr_cm.png +0 -0
  2279. psychopy/tests/data/greyscaleLowContr_deg.png +0 -0
  2280. psychopy/tests/data/greyscaleLowContr_degFlat.png +0 -0
  2281. psychopy/tests/data/greyscaleLowContr_degFlatPos.png +0 -0
  2282. psychopy/tests/data/greyscaleLowContr_height.png +0 -0
  2283. psychopy/tests/data/greyscaleLowContr_norm.png +0 -0
  2284. psychopy/tests/data/greyscaleLowContr_normAddBlend.png +0 -0
  2285. psychopy/tests/data/greyscaleLowContr_normHexbackground.png +0 -0
  2286. psychopy/tests/data/greyscaleLowContr_normNoShade.png +0 -0
  2287. psychopy/tests/data/greyscaleLowContr_pix.png +0 -0
  2288. psychopy/tests/data/greyscaleLowContr_stencil.png +0 -0
  2289. psychopy/tests/data/greyscale_cm.png +0 -0
  2290. psychopy/tests/data/greyscale_deg.png +0 -0
  2291. psychopy/tests/data/greyscale_degFlat.png +0 -0
  2292. psychopy/tests/data/greyscale_degFlatPos.png +0 -0
  2293. psychopy/tests/data/greyscale_height.png +0 -0
  2294. psychopy/tests/data/greyscale_norm.png +0 -0
  2295. psychopy/tests/data/greyscale_normAddBlend.png +0 -0
  2296. psychopy/tests/data/greyscale_normHexbackground.png +0 -0
  2297. psychopy/tests/data/greyscale_normNoShade.png +0 -0
  2298. psychopy/tests/data/greyscale_pix.png +0 -0
  2299. psychopy/tests/data/greyscale_stencil.png +0 -0
  2300. psychopy/tests/data/imageAndGauss_cm.png +0 -0
  2301. psychopy/tests/data/imageAndGauss_deg.png +0 -0
  2302. psychopy/tests/data/imageAndGauss_degFlat.png +0 -0
  2303. psychopy/tests/data/imageAndGauss_degFlatPos.png +0 -0
  2304. psychopy/tests/data/imageAndGauss_height.png +0 -0
  2305. psychopy/tests/data/imageAndGauss_norm.png +0 -0
  2306. psychopy/tests/data/imageAndGauss_normAddBlend.png +0 -0
  2307. psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
  2308. psychopy/tests/data/imageAndGauss_normHexbackground.png +0 -0
  2309. psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
  2310. psychopy/tests/data/imageAndGauss_normNoShade.png +0 -0
  2311. psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
  2312. psychopy/tests/data/imageAndGauss_pix.png +0 -0
  2313. psychopy/tests/data/imageAndGauss_stencil.png +0 -0
  2314. psychopy/tests/data/movFrame1_cm.png +0 -0
  2315. psychopy/tests/data/movFrame1_deg.png +0 -0
  2316. psychopy/tests/data/movFrame1_degFlat.png +0 -0
  2317. psychopy/tests/data/movFrame1_degFlatPos.png +0 -0
  2318. psychopy/tests/data/movFrame1_height.png +0 -0
  2319. psychopy/tests/data/movFrame1_norm.png +0 -0
  2320. psychopy/tests/data/movFrame1_normAddBlend.png +0 -0
  2321. psychopy/tests/data/movFrame1_normHexbackground.png +0 -0
  2322. psychopy/tests/data/movFrame1_normNoShade.png +0 -0
  2323. psychopy/tests/data/movFrame1_pix.png +0 -0
  2324. psychopy/tests/data/movFrame1_stencil.png +0 -0
  2325. psychopy/tests/data/multiKeypressExperiment.psydat +357 -0
  2326. psychopy/tests/data/multiKeypressTrialhandler.psydat +252 -0
  2327. psychopy/tests/data/multiStairConds.xlsx +0 -0
  2328. psychopy/tests/data/multiStairQuestPlus.xlsx +0 -0
  2329. psychopy/tests/data/newstyle.psydat +6155 -0
  2330. psychopy/tests/data/noiseAndRcos_cm.png +0 -0
  2331. psychopy/tests/data/noiseAndRcos_deg.png +0 -0
  2332. psychopy/tests/data/noiseAndRcos_degFlat.png +0 -0
  2333. psychopy/tests/data/noiseAndRcos_degFlatPos.png +0 -0
  2334. psychopy/tests/data/noiseAndRcos_height.png +0 -0
  2335. psychopy/tests/data/noiseAndRcos_norm.png +0 -0
  2336. psychopy/tests/data/noiseAndRcos_normAddBlend.png +0 -0
  2337. psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
  2338. psychopy/tests/data/noiseAndRcos_normHexbackground.png +0 -0
  2339. psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
  2340. psychopy/tests/data/noiseAndRcos_normNoShade.png +0 -0
  2341. psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
  2342. psychopy/tests/data/noiseAndRcos_pix.png +0 -0
  2343. psychopy/tests/data/noiseAndRcos_stencil.png +0 -0
  2344. psychopy/tests/data/noiseFiltersAndRcos_cm.png +0 -0
  2345. psychopy/tests/data/noiseFiltersAndRcos_deg.png +0 -0
  2346. psychopy/tests/data/noiseFiltersAndRcos_degFlat.png +0 -0
  2347. psychopy/tests/data/noiseFiltersAndRcos_degFlatPos.png +0 -0
  2348. psychopy/tests/data/noiseFiltersAndRcos_height.png +0 -0
  2349. psychopy/tests/data/noiseFiltersAndRcos_norm.png +0 -0
  2350. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend.png +0 -0
  2351. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
  2352. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground.png +0 -0
  2353. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
  2354. psychopy/tests/data/noiseFiltersAndRcos_normNoShade.png +0 -0
  2355. psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
  2356. psychopy/tests/data/noiseFiltersAndRcos_pix.png +0 -0
  2357. psychopy/tests/data/noiseFiltersAndRcos_stencil.png +0 -0
  2358. psychopy/tests/data/numpyImage_cm.png +0 -0
  2359. psychopy/tests/data/numpyImage_deg.png +0 -0
  2360. psychopy/tests/data/numpyImage_degFlat.png +0 -0
  2361. psychopy/tests/data/numpyImage_degFlatPos.png +0 -0
  2362. psychopy/tests/data/numpyImage_height.png +0 -0
  2363. psychopy/tests/data/numpyImage_norm.png +0 -0
  2364. psychopy/tests/data/numpyImage_normAddBlend.png +0 -0
  2365. psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
  2366. psychopy/tests/data/numpyImage_normHexbackground.png +0 -0
  2367. psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
  2368. psychopy/tests/data/numpyImage_normNoShade.png +0 -0
  2369. psychopy/tests/data/numpyImage_norm_local.png +0 -0
  2370. psychopy/tests/data/numpyImage_pix.png +0 -0
  2371. psychopy/tests/data/numpyImage_stencil.png +0 -0
  2372. psychopy/tests/data/numpyLowContr_cm.png +0 -0
  2373. psychopy/tests/data/numpyLowContr_deg.png +0 -0
  2374. psychopy/tests/data/numpyLowContr_degFlat.png +0 -0
  2375. psychopy/tests/data/numpyLowContr_degFlatPos.png +0 -0
  2376. psychopy/tests/data/numpyLowContr_height.png +0 -0
  2377. psychopy/tests/data/numpyLowContr_norm.png +0 -0
  2378. psychopy/tests/data/numpyLowContr_normAddBlend.png +0 -0
  2379. psychopy/tests/data/numpyLowContr_normHexbackground.png +0 -0
  2380. psychopy/tests/data/numpyLowContr_normNoShade.png +0 -0
  2381. psychopy/tests/data/numpyLowContr_pix.png +0 -0
  2382. psychopy/tests/data/numpyLowContr_stencil.png +0 -0
  2383. psychopy/tests/data/oldstyle.psydat +1534 -0
  2384. psychopy/tests/data/oldstyle_stair.psydat +263 -0
  2385. psychopy/tests/data/ratingscale1_cm.png +0 -0
  2386. psychopy/tests/data/ratingscale1_deg.png +0 -0
  2387. psychopy/tests/data/ratingscale1_degFlat.png +0 -0
  2388. psychopy/tests/data/ratingscale1_degFlatPos.png +0 -0
  2389. psychopy/tests/data/ratingscale1_height.png +0 -0
  2390. psychopy/tests/data/ratingscale1_norm.png +0 -0
  2391. psychopy/tests/data/ratingscale1_normAddBlend.png +0 -0
  2392. psychopy/tests/data/ratingscale1_normHexbackground.png +0 -0
  2393. psychopy/tests/data/ratingscale1_normNoShade.png +0 -0
  2394. psychopy/tests/data/ratingscale1_pix.png +0 -0
  2395. psychopy/tests/data/ratingscale1_stencil.png +0 -0
  2396. psychopy/tests/data/red_16000.flac.dist +0 -0
  2397. psychopy/tests/data/retroListParam.psyexp +82 -0
  2398. psychopy/tests/data/right_to_left_unidcode.xlsx +0 -0
  2399. psychopy/tests/data/sample.meshwarp.data +11522 -0
  2400. psychopy/tests/data/shape2_1_cm.png +0 -0
  2401. psychopy/tests/data/shape2_1_deg.png +0 -0
  2402. psychopy/tests/data/shape2_1_degFlat.png +0 -0
  2403. psychopy/tests/data/shape2_1_degFlatPos.png +0 -0
  2404. psychopy/tests/data/shape2_1_height.png +0 -0
  2405. psychopy/tests/data/shape2_1_norm.png +0 -0
  2406. psychopy/tests/data/shape2_1_normAddBlend.png +0 -0
  2407. psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
  2408. psychopy/tests/data/shape2_1_normHexbackground.png +0 -0
  2409. psychopy/tests/data/shape2_1_normNoShade.png +0 -0
  2410. psychopy/tests/data/shape2_1_norm_local.png +0 -0
  2411. psychopy/tests/data/shape2_1_pix.png +0 -0
  2412. psychopy/tests/data/shape2_1_stencil.png +0 -0
  2413. psychopy/tests/data/shape2_2_cm.png +0 -0
  2414. psychopy/tests/data/shape2_2_deg.png +0 -0
  2415. psychopy/tests/data/shape2_2_degFlat.png +0 -0
  2416. psychopy/tests/data/shape2_2_degFlatPos.png +0 -0
  2417. psychopy/tests/data/shape2_2_height.png +0 -0
  2418. psychopy/tests/data/shape2_2_norm.png +0 -0
  2419. psychopy/tests/data/shape2_2_normAddBlend.png +0 -0
  2420. psychopy/tests/data/shape2_2_normHexbackground.png +0 -0
  2421. psychopy/tests/data/shape2_2_normNoShade.png +0 -0
  2422. psychopy/tests/data/shape2_2_pix.png +0 -0
  2423. psychopy/tests/data/shape2_2_stencil.png +0 -0
  2424. psychopy/tests/data/simpleimage1_cm.png +0 -0
  2425. psychopy/tests/data/simpleimage1_deg.png +0 -0
  2426. psychopy/tests/data/simpleimage1_degFlat.png +0 -0
  2427. psychopy/tests/data/simpleimage1_degFlatPos.png +0 -0
  2428. psychopy/tests/data/simpleimage1_height.png +0 -0
  2429. psychopy/tests/data/simpleimage1_norm.png +0 -0
  2430. psychopy/tests/data/simpleimage1_normAddBlend.png +0 -0
  2431. psychopy/tests/data/simpleimage1_normHexbackground.png +0 -0
  2432. psychopy/tests/data/simpleimage1_normNoShade.png +0 -0
  2433. psychopy/tests/data/simpleimage1_pix.png +0 -0
  2434. psychopy/tests/data/simpleimage1_stencil.png +0 -0
  2435. psychopy/tests/data/test001EntryImporting.psyexp +66 -0
  2436. psychopy/tests/data/testMovie.mp4 +0 -0
  2437. psychopy/tests/data/test_circle_radius_.1height.png +0 -0
  2438. psychopy/tests/data/test_circle_radius_.2height.png +0 -0
  2439. psychopy/tests/data/test_circle_radius_10pix.png +0 -0
  2440. psychopy/tests/data/test_circle_radius_20pix.png +0 -0
  2441. psychopy/tests/data/test_form_combinations_choice_bigItem.png +0 -0
  2442. psychopy/tests/data/test_form_combinations_choice_bigItemOverflow.png +0 -0
  2443. psychopy/tests/data/test_form_combinations_choice_bigResp.png +0 -0
  2444. psychopy/tests/data/test_form_combinations_choice_bigRespOverflow.png +0 -0
  2445. psychopy/tests/data/test_form_combinations_description_bigItem.png +0 -0
  2446. psychopy/tests/data/test_form_combinations_description_bigItemOverflow.png +0 -0
  2447. psychopy/tests/data/test_form_combinations_description_bigResp.png +0 -0
  2448. psychopy/tests/data/test_form_combinations_description_bigRespOverflow.png +0 -0
  2449. psychopy/tests/data/test_form_combinations_free text_bigItem.png +0 -0
  2450. psychopy/tests/data/test_form_combinations_free text_bigItemOverflow.png +0 -0
  2451. psychopy/tests/data/test_form_combinations_free text_bigResp.png +0 -0
  2452. psychopy/tests/data/test_form_combinations_free text_bigRespOverflow.png +0 -0
  2453. psychopy/tests/data/test_form_combinations_heading_bigItem.png +0 -0
  2454. psychopy/tests/data/test_form_combinations_heading_bigItemOverflow.png +0 -0
  2455. psychopy/tests/data/test_form_combinations_heading_bigResp.png +0 -0
  2456. psychopy/tests/data/test_form_combinations_heading_bigRespOverflow.png +0 -0
  2457. psychopy/tests/data/test_form_combinations_radio_bigItem.png +0 -0
  2458. psychopy/tests/data/test_form_combinations_radio_bigItemOverflow.png +0 -0
  2459. psychopy/tests/data/test_form_combinations_radio_bigResp.png +0 -0
  2460. psychopy/tests/data/test_form_combinations_radio_bigRespOverflow.png +0 -0
  2461. psychopy/tests/data/test_form_combinations_rating_bigItem.png +0 -0
  2462. psychopy/tests/data/test_form_combinations_rating_bigItemOverflow.png +0 -0
  2463. psychopy/tests/data/test_form_combinations_rating_bigResp.png +0 -0
  2464. psychopy/tests/data/test_form_combinations_rating_bigRespOverflow.png +0 -0
  2465. psychopy/tests/data/test_form_combinations_slider_bigItem.png +0 -0
  2466. psychopy/tests/data/test_form_combinations_slider_bigItemOverflow.png +0 -0
  2467. psychopy/tests/data/test_form_combinations_slider_bigResp.png +0 -0
  2468. psychopy/tests/data/test_form_combinations_slider_bigRespOverflow.png +0 -0
  2469. psychopy/tests/data/test_get_resources/blue.png +0 -0
  2470. psychopy/tests/data/test_get_resources/groupA.csv +3 -0
  2471. psychopy/tests/data/test_get_resources/groupB.csv +3 -0
  2472. psychopy/tests/data/test_get_resources/groups.csv +3 -0
  2473. psychopy/tests/data/test_get_resources/handledbyrm_constrloop.psyexp +143 -0
  2474. psychopy/tests/data/test_get_resources/handledbyrm_noloop.psyexp +114 -0
  2475. psychopy/tests/data/test_get_resources/handledbyrm_recurloop.psyexp +138 -0
  2476. psychopy/tests/data/test_get_resources/handledbyrm_strloop.psyexp +126 -0
  2477. psychopy/tests/data/test_get_resources/handledbystatic_constrloop.psyexp +141 -0
  2478. psychopy/tests/data/test_get_resources/handledbystatic_noloop.psyexp +112 -0
  2479. psychopy/tests/data/test_get_resources/handledbystatic_recurloop.psyexp +136 -0
  2480. psychopy/tests/data/test_get_resources/handledbystatic_strloop.psyexp +124 -0
  2481. psychopy/tests/data/test_get_resources/unhandled_constrloop.psyexp +128 -0
  2482. psychopy/tests/data/test_get_resources/unhandled_noloop.psyexp +99 -0
  2483. psychopy/tests/data/test_get_resources/unhandled_recurloop.psyexp +123 -0
  2484. psychopy/tests/data/test_get_resources/unhandled_strloop.psyexp +111 -0
  2485. psychopy/tests/data/test_get_resources/white.png +0 -0
  2486. psychopy/tests/data/test_get_resources/yellow.png +0 -0
  2487. psychopy/tests/data/test_image_aspect_default_None.png +0 -0
  2488. psychopy/tests/data/test_image_aspect_default_xFull_yNone.png +0 -0
  2489. psychopy/tests/data/test_image_aspect_default_xNone_yFull.png +0 -0
  2490. psychopy/tests/data/test_image_aspect_default_xNone_yNone.png +0 -0
  2491. psychopy/tests/data/test_image_flip_anchor_horiz.png +0 -0
  2492. psychopy/tests/data/test_image_flip_anchor_vert.png +0 -0
  2493. psychopy/tests/data/test_loops/testLoopsBlocks.psyexp +161 -0
  2494. psychopy/tests/data/test_loops/testStaircase.psyexp +105 -0
  2495. psychopy/tests/data/test_loops/test_current_loop_attr.psyexp +185 -0
  2496. psychopy/tests/data/test_panorama/panoramaTestImage.png +0 -0
  2497. psychopy/tests/data/test_panorama/panoramaTestImage.svg +1 -0
  2498. psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_-0.3.png +0 -0
  2499. psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_0.3.png +0 -0
  2500. psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_-0.3.png +0 -0
  2501. psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_0.3.png +0 -0
  2502. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_-1.0.png +0 -0
  2503. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_1.0.png +0 -0
  2504. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_-0.3.png +0 -0
  2505. psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_0.3.png +0 -0
  2506. psychopy/tests/data/test_resources.psyexp +491 -0
  2507. psychopy/tests/data/test_session/outside_root/externalExp.psyexp +116 -0
  2508. psychopy/tests/data/test_session/root/annotation/annotation.psyexp +161 -0
  2509. psychopy/tests/data/test_session/root/error/error.psyexp +93 -0
  2510. psychopy/tests/data/test_session/root/exp1/exp1.psyexp +133 -0
  2511. psychopy/tests/data/test_session/root/exp2/exp2.psyexp +133 -0
  2512. psychopy/tests/data/test_session/root/frameRate/frameRate.psyexp +114 -0
  2513. psychopy/tests/data/test_session/root/invUseVersion/invUseVersion.psyexp +133 -0
  2514. psychopy/tests/data/test_session/root/testClockFormat/testClockFormat.psyexp +122 -0
  2515. psychopy/tests/data/test_session/root/testCtrls/testCtrls.psyexp +115 -0
  2516. psychopy/tests/data/test_session/root/testEditExpInfo/testEditExpInfo.psyexp +135 -0
  2517. psychopy/tests/data/test_session/root/testNamedButtonBox/testNamedButtonBox.psyexp +145 -0
  2518. psychopy/tests/data/test_slider_horiz_accute_horiz.png +0 -0
  2519. psychopy/tests/data/test_slider_horiz_accute_vert.png +0 -0
  2520. psychopy/tests/data/test_slider_horiz_horiz.png +0 -0
  2521. psychopy/tests/data/test_slider_horiz_obtuse_horiz.png +0 -0
  2522. psychopy/tests/data/test_slider_horiz_obtuse_vert.png +0 -0
  2523. psychopy/tests/data/test_slider_horiz_vert.png +0 -0
  2524. psychopy/tests/data/test_slider_ticklabelloc_blanks.png +0 -0
  2525. psychopy/tests/data/test_slider_ticklabelloc_clustered.png +0 -0
  2526. psychopy/tests/data/test_slider_ticklabelloc_morelabels.png +0 -0
  2527. psychopy/tests/data/test_slider_ticklabelloc_morelabelsclustered.png +0 -0
  2528. psychopy/tests/data/test_slider_ticklabelloc_moreticks.png +0 -0
  2529. psychopy/tests/data/test_slider_ticklabelloc_moreticksclustered.png +0 -0
  2530. psychopy/tests/data/test_slider_ticklabelloc_nolabels.png +0 -0
  2531. psychopy/tests/data/test_slider_ticklabelloc_noticks.png +0 -0
  2532. psychopy/tests/data/test_slider_ticklabelloc_simple.png +0 -0
  2533. psychopy/tests/data/test_slider_triangle_horiz_False_flip_False.png +0 -0
  2534. psychopy/tests/data/test_slider_triangle_horiz_False_flip_True.png +0 -0
  2535. psychopy/tests/data/test_slider_triangle_horiz_True_flip_False.png +0 -0
  2536. psychopy/tests/data/test_slider_triangle_horiz_True_flip_True.png +0 -0
  2537. psychopy/tests/data/test_static_component_script.psyexp +76 -0
  2538. psychopy/tests/data/test_win_bg_large_256_default.png +0 -0
  2539. psychopy/tests/data/test_win_bg_large_500_default.png +0 -0
  2540. psychopy/tests/data/test_win_bg_small_200_default.png +0 -0
  2541. psychopy/tests/data/test_win_bg_small_256_default.png +0 -0
  2542. psychopy/tests/data/test_win_bg_tall_200_default.png +0 -0
  2543. psychopy/tests/data/test_win_bg_tall_256_default.png +0 -0
  2544. psychopy/tests/data/test_win_bg_tall_500_default.png +0 -0
  2545. psychopy/tests/data/test_win_bg_tall_fill_default.png +0 -0
  2546. psychopy/tests/data/test_win_bg_wide_200_default.png +0 -0
  2547. psychopy/tests/data/test_win_bg_wide_256_default.png +0 -0
  2548. psychopy/tests/data/test_win_bg_wide_500_default.png +0 -0
  2549. psychopy/tests/data/test_win_bg_wide_fill_default.png +0 -0
  2550. psychopy/tests/data/test_win_bgcolor_blue.png +0 -0
  2551. psychopy/tests/data/test_win_bgcolor_green.png +0 -0
  2552. psychopy/tests/data/test_win_bgcolor_red.png +0 -0
  2553. psychopy/tests/data/testimage.jpg +0 -0
  2554. psychopy/tests/data/testimagegray.jpg +0 -0
  2555. psychopy/tests/data/testpixels.png +0 -0
  2556. psychopy/tests/data/testwedges.png +0 -0
  2557. psychopy/tests/data/text1_cm.png +0 -0
  2558. psychopy/tests/data/text1_deg.png +0 -0
  2559. psychopy/tests/data/text1_degFlat.png +0 -0
  2560. psychopy/tests/data/text1_degFlatPos.png +0 -0
  2561. psychopy/tests/data/text1_height.png +0 -0
  2562. psychopy/tests/data/text1_norm.png +0 -0
  2563. psychopy/tests/data/text1_normAddBlend.png +0 -0
  2564. psychopy/tests/data/text1_normAddBlend_local.png +0 -0
  2565. psychopy/tests/data/text1_normHexbackground.png +0 -0
  2566. psychopy/tests/data/text1_normHexbackground_local.png +0 -0
  2567. psychopy/tests/data/text1_normNoShade.png +0 -0
  2568. psychopy/tests/data/text1_norm_local.png +0 -0
  2569. psychopy/tests/data/text1_pix.png +0 -0
  2570. psychopy/tests/data/text1_stencil.png +0 -0
  2571. psychopy/tests/data/text2_cm.png +0 -0
  2572. psychopy/tests/data/text2_deg.png +0 -0
  2573. psychopy/tests/data/text2_degFlat.png +0 -0
  2574. psychopy/tests/data/text2_degFlatPos.png +0 -0
  2575. psychopy/tests/data/text2_height.png +0 -0
  2576. psychopy/tests/data/text2_norm.png +0 -0
  2577. psychopy/tests/data/text2_normNoShade.png +0 -0
  2578. psychopy/tests/data/text2_pix.png +0 -0
  2579. psychopy/tests/data/text2_stencil.png +0 -0
  2580. psychopy/tests/data/textbox_charcolors_default_roygbiv.png +0 -0
  2581. psychopy/tests/data/textbox_charcolors_default_white_hello_black_there.png +0 -0
  2582. psychopy/tests/data/textbox_default_align_bottom_center.png +0 -0
  2583. psychopy/tests/data/textbox_default_align_bottom_left.png +0 -0
  2584. psychopy/tests/data/textbox_default_align_bottom_right.png +0 -0
  2585. psychopy/tests/data/textbox_default_align_center.png +0 -0
  2586. psychopy/tests/data/textbox_default_align_center_center.png +0 -0
  2587. psychopy/tests/data/textbox_default_align_center_left.png +0 -0
  2588. psychopy/tests/data/textbox_default_align_center_right.png +0 -0
  2589. psychopy/tests/data/textbox_default_align_centre.png +0 -0
  2590. psychopy/tests/data/textbox_default_align_centre_centre.png +0 -0
  2591. psychopy/tests/data/textbox_default_align_more_than_two_words.png +0 -0
  2592. psychopy/tests/data/textbox_default_align_someword.png +0 -0
  2593. psychopy/tests/data/textbox_default_align_top_center.png +0 -0
  2594. psychopy/tests/data/textbox_default_align_top_left.png +0 -0
  2595. psychopy/tests/data/textbox_default_align_top_right.png +0 -0
  2596. psychopy/tests/data/textbox_default_colors_WOB.png +0 -0
  2597. psychopy/tests/data/textbox_default_colors_exemplar1.png +0 -0
  2598. psychopy/tests/data/textbox_default_colors_exemplar2.png +0 -0
  2599. psychopy/tests/data/textbox_default_colors_exemplar3.png +0 -0
  2600. psychopy/tests/data/textbox_default_colors_tyke1.png +0 -0
  2601. psychopy/tests/data/textbox_default_colors_tyke2.png +0 -0
  2602. psychopy/tests/data/textbox_default_colors_tyke3.png +0 -0
  2603. psychopy/tests/data/textbox_default_cutoff_top.png +0 -0
  2604. psychopy/tests/data/textbox_default_exemplar_1.png +0 -0
  2605. psychopy/tests/data/textbox_default_exemplar_2.png +0 -0
  2606. psychopy/tests/data/textbox_default_exemplar_3.png +0 -0
  2607. psychopy/tests/data/textbox_default_exemplar_4.png +0 -0
  2608. psychopy/tests/data/textbox_default_tyke_1.png +0 -0
  2609. psychopy/tests/data/textbox_default_tyke_2.png +0 -0
  2610. psychopy/tests/data/textbox_typing_blank.png +0 -0
  2611. psychopy/tests/data/textbox_typing_longKoeran.png +0 -0
  2612. psychopy/tests/data/textbox_typing_longWord.png +0 -0
  2613. psychopy/tests/data/textbox_typing_navDel.png +0 -0
  2614. psychopy/tests/data/textbox_typing_navLR.png +0 -0
  2615. psychopy/tests/data/textbox_typing_newline.png +0 -0
  2616. psychopy/tests/data/textbox_typing_pangram.png +0 -0
  2617. psychopy/tests/data/textbox_uax14_align_bottom_center.png +0 -0
  2618. psychopy/tests/data/textbox_uax14_align_bottom_left.png +0 -0
  2619. psychopy/tests/data/textbox_uax14_align_bottom_right.png +0 -0
  2620. psychopy/tests/data/textbox_uax14_align_center.png +0 -0
  2621. psychopy/tests/data/textbox_uax14_align_center_center.png +0 -0
  2622. psychopy/tests/data/textbox_uax14_align_center_left.png +0 -0
  2623. psychopy/tests/data/textbox_uax14_align_center_right.png +0 -0
  2624. psychopy/tests/data/textbox_uax14_align_centre.png +0 -0
  2625. psychopy/tests/data/textbox_uax14_align_centre_centre.png +0 -0
  2626. psychopy/tests/data/textbox_uax14_align_more_than_two_words.png +0 -0
  2627. psychopy/tests/data/textbox_uax14_align_someword.png +0 -0
  2628. psychopy/tests/data/textbox_uax14_align_top_center.png +0 -0
  2629. psychopy/tests/data/textbox_uax14_align_top_left.png +0 -0
  2630. psychopy/tests/data/textbox_uax14_align_top_right.png +0 -0
  2631. psychopy/tests/data/textbox_uax14_colors_WOB.png +0 -0
  2632. psychopy/tests/data/textbox_uax14_colors_exemplar1.png +0 -0
  2633. psychopy/tests/data/textbox_uax14_colors_exemplar2.png +0 -0
  2634. psychopy/tests/data/textbox_uax14_colors_exemplar3.png +0 -0
  2635. psychopy/tests/data/textbox_uax14_colors_tyke1.png +0 -0
  2636. psychopy/tests/data/textbox_uax14_colors_tyke2.png +0 -0
  2637. psychopy/tests/data/textbox_uax14_colors_tyke3.png +0 -0
  2638. psychopy/tests/data/textbox_uax14_cutoff_top.png +0 -0
  2639. psychopy/tests/data/textbox_uax14_exemplar_1.png +0 -0
  2640. psychopy/tests/data/textbox_uax14_exemplar_2.png +0 -0
  2641. psychopy/tests/data/textbox_uax14_exemplar_3.png +0 -0
  2642. psychopy/tests/data/textbox_uax14_exemplar_4.png +0 -0
  2643. psychopy/tests/data/textbox_uax14_tyke_1.png +0 -0
  2644. psychopy/tests/data/textbox_uax14_tyke_2.png +0 -0
  2645. psychopy/tests/data/trialTypes.csv +1 -0
  2646. psychopy/tests/data/trialTypes.docx +0 -0
  2647. psychopy/tests/data/trialTypes.pkl +0 -0
  2648. psychopy/tests/data/trialTypes.tsv +7 -0
  2649. psychopy/tests/data/trialTypes.xls +0 -0
  2650. psychopy/tests/data/trialTypes.xlsx +0 -0
  2651. psychopy/tests/data/trialTypes_eu.csv +7 -0
  2652. psychopy/tests/data/trialsBlankCols.xlsx +0 -0
  2653. psychopy/tests/data/wedge1_cm.png +0 -0
  2654. psychopy/tests/data/wedge1_deg.png +0 -0
  2655. psychopy/tests/data/wedge1_degFlat.png +0 -0
  2656. psychopy/tests/data/wedge1_degFlatPos.png +0 -0
  2657. psychopy/tests/data/wedge1_height.png +0 -0
  2658. psychopy/tests/data/wedge1_norm.png +0 -0
  2659. psychopy/tests/data/wedge1_normAddBlend.png +0 -0
  2660. psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
  2661. psychopy/tests/data/wedge1_normHexbackground.png +0 -0
  2662. psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
  2663. psychopy/tests/data/wedge1_normNoShade.png +0 -0
  2664. psychopy/tests/data/wedge1_norm_local.png +0 -0
  2665. psychopy/tests/data/wedge1_pix.png +0 -0
  2666. psychopy/tests/data/wedge1_stencil.png +0 -0
  2667. psychopy/tests/data/wedge2_cm.png +0 -0
  2668. psychopy/tests/data/wedge2_deg.png +0 -0
  2669. psychopy/tests/data/wedge2_degFlat.png +0 -0
  2670. psychopy/tests/data/wedge2_degFlatPos.png +0 -0
  2671. psychopy/tests/data/wedge2_height.png +0 -0
  2672. psychopy/tests/data/wedge2_norm.png +0 -0
  2673. psychopy/tests/data/wedge2_normAddBlend.png +0 -0
  2674. psychopy/tests/data/wedge2_normHexbackground.png +0 -0
  2675. psychopy/tests/data/wedge2_normNoShade.png +0 -0
  2676. psychopy/tests/data/wedge2_pix.png +0 -0
  2677. psychopy/tests/data/wedge2_stencil.png +0 -0
  2678. psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos-0.4_0.png +0 -0
  2679. psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos0_0.png +0 -0
  2680. psychopy/tests/data/winScalePos_ori0_scale-1_1_pos-0.4_0.png +0 -0
  2681. psychopy/tests/data/winScalePos_ori0_scale-1_1_pos0_0.png +0 -0
  2682. psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos-0.4_0.png +0 -0
  2683. psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos0_0.png +0 -0
  2684. psychopy/tests/data/winScalePos_ori0_scale-2_2_pos-0.4_0.png +0 -0
  2685. psychopy/tests/data/winScalePos_ori0_scale-2_2_pos0_0.png +0 -0
  2686. psychopy/tests/data/winScalePos_ori0_scale1_-1_pos-0.4_0.png +0 -0
  2687. psychopy/tests/data/winScalePos_ori0_scale1_-1_pos0_0.png +0 -0
  2688. psychopy/tests/data/winScalePos_ori0_scale1_1_pos-0.4_0.png +0 -0
  2689. psychopy/tests/data/winScalePos_ori0_scale1_1_pos0_0.png +0 -0
  2690. psychopy/tests/data/winScalePos_ori0_scale2_-2_pos-0.4_0.png +0 -0
  2691. psychopy/tests/data/winScalePos_ori0_scale2_-2_pos0_0.png +0 -0
  2692. psychopy/tests/data/winScalePos_ori0_scale2_2_pos-0.4_0.png +0 -0
  2693. psychopy/tests/data/winScalePos_ori0_scale2_2_pos0_0.png +0 -0
  2694. psychopy/tests/data/winScalePos_ori45_scale-1_-1_pos0_0.png +0 -0
  2695. psychopy/tests/data/winScalePos_ori45_scale-1_1_pos0_0.png +0 -0
  2696. psychopy/tests/data/winScalePos_ori45_scale-2_-2_pos0_0.png +0 -0
  2697. psychopy/tests/data/winScalePos_ori45_scale-2_2_pos0_0.png +0 -0
  2698. psychopy/tests/data/winScalePos_ori45_scale1_-1_pos0_0.png +0 -0
  2699. psychopy/tests/data/winScalePos_ori45_scale1_1_pos0_0.png +0 -0
  2700. psychopy/tests/data/winScalePos_ori45_scale2_-2_pos0_0.png +0 -0
  2701. psychopy/tests/data/winScalePos_ori45_scale2_2_pos0_0.png +0 -0
  2702. psychopy/tests/doc/run_btn.png +0 -0
  2703. psychopy/tests/doc/test-suite-bugs.jpg +0 -0
  2704. psychopy/tests/doc/user-bugs.jpg +0 -0
  2705. psychopy/tests/dummy_xorg.conf +21 -0
  2706. psychopy/tests/run.py +50 -0
  2707. psychopy/tests/test_Installation.py +38 -0
  2708. psychopy/tests/test_alerts/test_alerts.py +37 -0
  2709. psychopy/tests/test_alerts/test_alerttools.py +131 -0
  2710. psychopy/tests/test_app/__init__.py +0 -0
  2711. psychopy/tests/test_app/conftest.py +41 -0
  2712. psychopy/tests/test_app/test_builder/__init__.py +0 -0
  2713. psychopy/tests/test_app/test_builder/test_BuilderFrame.py +151 -0
  2714. psychopy/tests/test_app/test_builder/test_CompileFromBuilder.py +135 -0
  2715. psychopy/tests/test_app/test_builder/test_ComponentDialogs.py +98 -0
  2716. psychopy/tests/test_app/test_runner/__init__.py +0 -0
  2717. psychopy/tests/test_app/test_runner/test_RunnerFrame.py +166 -0
  2718. psychopy/tests/test_app/test_speed.py +144 -0
  2719. psychopy/tests/test_app/test_themes/test_icons.py +79 -0
  2720. psychopy/tests/test_codecov.py +29 -0
  2721. psychopy/tests/test_colors/test_Color.py +41 -0
  2722. psychopy/tests/test_data/dataPrev.xlsx +0 -0
  2723. psychopy/tests/test_data/test_ExperimentHandler.py +171 -0
  2724. psychopy/tests/test_data/test_MultiStairHandler.py +174 -0
  2725. psychopy/tests/test_data/test_StairHandlers.py +1241 -0
  2726. psychopy/tests/test_data/test_TrialHandler.py +335 -0
  2727. psychopy/tests/test_data/test_TrialHandler2.py +408 -0
  2728. psychopy/tests/test_data/test_TrialHandlerExt.py +359 -0
  2729. psychopy/tests/test_data/test_fitFunctions.py +101 -0
  2730. psychopy/tests/test_data/test_utils.py +169 -0
  2731. psychopy/tests/test_data/test_xlsx.py +92 -0
  2732. psychopy/tests/test_demos/test_builder_demos.py +52 -0
  2733. psychopy/tests/test_experiment/__init__.py +0 -0
  2734. psychopy/tests/test_experiment/known_py_diffs.txt +47 -0
  2735. psychopy/tests/test_experiment/needs_wx/__init__.py +0 -0
  2736. psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +13730 -0
  2737. psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +130 -0
  2738. psychopy/tests/test_experiment/needs_wx/test_Experiment.py +406 -0
  2739. psychopy/tests/test_experiment/needs_wx/test_components.py +170 -0
  2740. psychopy/tests/test_experiment/test_component_compile_js.py +59 -0
  2741. psychopy/tests/test_experiment/test_component_compile_python.py +165 -0
  2742. psychopy/tests/test_experiment/test_components/__init__.py +1 -0
  2743. psychopy/tests/test_experiment/test_components/test_ButtonBox.py +216 -0
  2744. psychopy/tests/test_experiment/test_components/test_Code.py +82 -0
  2745. psychopy/tests/test_experiment/test_components/test_Image.py +24 -0
  2746. psychopy/tests/test_experiment/test_components/test_Mouse.py +149 -0
  2747. psychopy/tests/test_experiment/test_components/test_Polygon.py +81 -0
  2748. psychopy/tests/test_experiment/test_components/test_ResourceManager.py +60 -0
  2749. psychopy/tests/test_experiment/test_components/test_Settings.py +82 -0
  2750. psychopy/tests/test_experiment/test_components/test_Static.py +60 -0
  2751. psychopy/tests/test_experiment/test_components/test_all_components.py +162 -0
  2752. psychopy/tests/test_experiment/test_components/test_base_components.py +323 -0
  2753. psychopy/tests/test_experiment/test_experiment.py +103 -0
  2754. psychopy/tests/test_experiment/test_loops.py +95 -0
  2755. psychopy/tests/test_experiment/test_params.py +350 -0
  2756. psychopy/tests/test_experiment/test_py2js.py +230 -0
  2757. psychopy/tests/test_experiment/test_routines/__init__.py +1 -0
  2758. psychopy/tests/test_experiment/test_routines/test_EyetrackerCalibrationRoutine.py +9 -0
  2759. psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +9 -0
  2760. psychopy/tests/test_experiment/test_routines/test_all_routines.py +23 -0
  2761. psychopy/tests/test_experiment/test_routines/test_base_routine.py +154 -0
  2762. psychopy/tests/test_experiment/test_routines/test_standalone_routines.py +36 -0
  2763. psychopy/tests/test_gui/test_DlgFromDictQt.py +82 -0
  2764. psychopy/tests/test_gui/test_DlgFromDictWx.py +82 -0
  2765. psychopy/tests/test_hardware/__init__.py +0 -0
  2766. psychopy/tests/test_hardware/test_CRS_BitsSharp.py +67 -0
  2767. psychopy/tests/test_hardware/test_CRS_bitsShaders.py +110 -0
  2768. psychopy/tests/test_hardware/test_device_manager.py +36 -0
  2769. psychopy/tests/test_hardware/test_emulator.py +106 -0
  2770. psychopy/tests/test_hardware/test_gammasci.py +35 -0
  2771. psychopy/tests/test_hardware/test_keyboard.py +73 -0
  2772. psychopy/tests/test_hardware/test_keyboard_events.py +362 -0
  2773. psychopy/tests/test_hardware/test_ports.py +151 -0
  2774. psychopy/tests/test_iohub/__init__.py +1 -0
  2775. psychopy/tests/test_iohub/test_computer.py +124 -0
  2776. psychopy/tests/test_iohub/test_event_get_and_clear.py +94 -0
  2777. psychopy/tests/test_iohub/test_keyboard.py +91 -0
  2778. psychopy/tests/test_iohub/test_launch.py +19 -0
  2779. psychopy/tests/test_iohub/testutil.py +54 -0
  2780. psychopy/tests/test_liaison/test_Liaison.py +228 -0
  2781. psychopy/tests/test_misc/__init__.py +0 -0
  2782. psychopy/tests/test_misc/memory_usage.py +164 -0
  2783. psychopy/tests/test_misc/test_GammaFun.py +15 -0
  2784. psychopy/tests/test_misc/test_clock.py +61 -0
  2785. psychopy/tests/test_misc/test_color.py +203 -0
  2786. psychopy/tests/test_misc/test_core.py +446 -0
  2787. psychopy/tests/test_misc/test_event.py +307 -0
  2788. psychopy/tests/test_misc/test_info.py +18 -0
  2789. psychopy/tests/test_misc/test_layout.py +49 -0
  2790. psychopy/tests/test_misc/test_locale.py +38 -0
  2791. psychopy/tests/test_misc/test_web.py +22 -0
  2792. psychopy/tests/test_monitors/test_monitors.py +91 -0
  2793. psychopy/tests/test_preferences/__init__.py +0 -0
  2794. psychopy/tests/test_preferences/test_prefs.py +28 -0
  2795. psychopy/tests/test_session/test_Session.py +253 -0
  2796. psychopy/tests/test_sound/__init__.py +0 -0
  2797. psychopy/tests/test_sound/test_audioclip.py +331 -0
  2798. psychopy/tests/test_sound/test_hamming.py +45 -0
  2799. psychopy/tests/test_sound/test_microphone.py +217 -0
  2800. psychopy/tests/test_sound/test_sound.py +67 -0
  2801. psychopy/tests/test_sound/test_sound_pygame.py +67 -0
  2802. psychopy/tests/test_tools/test_animationtools.py +51 -0
  2803. psychopy/tests/test_tools/test_arraytools.py +130 -0
  2804. psychopy/tests/test_tools/test_attributetools.py +257 -0
  2805. psychopy/tests/test_tools/test_colorspacetools.py +149 -0
  2806. psychopy/tests/test_tools/test_environmenttools.py +52 -0
  2807. psychopy/tests/test_tools/test_fileerrortools.py +97 -0
  2808. psychopy/tests/test_tools/test_filetools.py +104 -0
  2809. psychopy/tests/test_tools/test_imagetools.py +57 -0
  2810. psychopy/tests/test_tools/test_mathtools.py +688 -0
  2811. psychopy/tests/test_tools/test_stringtools.py +143 -0
  2812. psychopy/tests/test_tools/test_versionchooser.py +178 -0
  2813. psychopy/tests/test_tools/test_viewtools.py +67 -0
  2814. psychopy/tests/test_visual/__init__.py +0 -0
  2815. psychopy/tests/test_visual/measure_parity.py +243 -0
  2816. psychopy/tests/test_visual/test_all_stimuli.py +752 -0
  2817. psychopy/tests/test_visual/test_basevisual.py +534 -0
  2818. psychopy/tests/test_visual/test_brush.py +68 -0
  2819. psychopy/tests/test_visual/test_button.py +15 -0
  2820. psychopy/tests/test_visual/test_circle.py +66 -0
  2821. psychopy/tests/test_visual/test_contains_overlaps.py +242 -0
  2822. psychopy/tests/test_visual/test_custommouse.py +47 -0
  2823. psychopy/tests/test_visual/test_dots.py +155 -0
  2824. psychopy/tests/test_visual/test_form.py +414 -0
  2825. psychopy/tests/test_visual/test_framepacking.py +41 -0
  2826. psychopy/tests/test_visual/test_gamma.py +152 -0
  2827. psychopy/tests/test_visual/test_glfw_backend.py +14 -0
  2828. psychopy/tests/test_visual/test_image.py +218 -0
  2829. psychopy/tests/test_visual/test_panorama.py +41 -0
  2830. psychopy/tests/test_visual/test_progress.py +96 -0
  2831. psychopy/tests/test_visual/test_projections.py +215 -0
  2832. psychopy/tests/test_visual/test_projections_interactive.py +163 -0
  2833. psychopy/tests/test_visual/test_ratingScale.py +299 -0
  2834. psychopy/tests/test_visual/test_roi.py +99 -0
  2835. psychopy/tests/test_visual/test_shape.py +23 -0
  2836. psychopy/tests/test_visual/test_slider.py +328 -0
  2837. psychopy/tests/test_visual/test_target.py +35 -0
  2838. psychopy/tests/test_visual/test_textbox.py +474 -0
  2839. psychopy/tests/test_visual/test_winFlipTiming.py +95 -0
  2840. psychopy/tests/test_visual/test_winScalePos.py +77 -0
  2841. psychopy/tests/test_visual/test_window.py +107 -0
  2842. psychopy/tests/utils.py +318 -0
  2843. psychopy/tools/LineBreak.txt +3597 -0
  2844. psychopy/tools/__init__.py +9 -0
  2845. psychopy/tools/animationtools.py +49 -0
  2846. psychopy/tools/apptools.py +32 -0
  2847. psychopy/tools/arraytools.py +514 -0
  2848. psychopy/tools/attributetools.py +205 -0
  2849. psychopy/tools/audiotools.py +358 -0
  2850. psychopy/tools/colorspacetools.py +715 -0
  2851. psychopy/tools/coordinatetools.py +104 -0
  2852. psychopy/tools/environmenttools.py +62 -0
  2853. psychopy/tools/fileerrortools.py +54 -0
  2854. psychopy/tools/filetools.py +406 -0
  2855. psychopy/tools/fontmanager.py +1041 -0
  2856. psychopy/tools/gltools.py +4959 -0
  2857. psychopy/tools/imagetools.py +65 -0
  2858. psychopy/tools/linebreak.py +322 -0
  2859. psychopy/tools/mathtools.py +4040 -0
  2860. psychopy/tools/monitorunittools.py +270 -0
  2861. psychopy/tools/movietools.py +1071 -0
  2862. psychopy/tools/pkgtools.py +601 -0
  2863. psychopy/tools/plottools.py +25 -0
  2864. psychopy/tools/rifttools.py +76 -0
  2865. psychopy/tools/stereotools.py +9 -0
  2866. psychopy/tools/stimulustools.py +28 -0
  2867. psychopy/tools/stringtools.py +421 -0
  2868. psychopy/tools/systemtools.py +1331 -0
  2869. psychopy/tools/typetools.py +52 -0
  2870. psychopy/tools/unittools.py +16 -0
  2871. psychopy/tools/versionchooser.py +602 -0
  2872. psychopy/tools/viewtools.py +1084 -0
  2873. psychopy/tools/wizard.py +804 -0
  2874. psychopy/visual/__init__.py +124 -0
  2875. psychopy/visual/aperture.py +330 -0
  2876. psychopy/visual/backends/__init__.py +77 -0
  2877. psychopy/visual/backends/_base.py +481 -0
  2878. psychopy/visual/backends/gamma.py +349 -0
  2879. psychopy/visual/backends/glfwbackend.py +28 -0
  2880. psychopy/visual/backends/pygamebackend.py +343 -0
  2881. psychopy/visual/backends/pygletbackend.py +920 -0
  2882. psychopy/visual/basevisual.py +1952 -0
  2883. psychopy/visual/brush.py +204 -0
  2884. psychopy/visual/bufferimage.py +231 -0
  2885. psychopy/visual/button.py +206 -0
  2886. psychopy/visual/circle.py +173 -0
  2887. psychopy/visual/custommouse.py +263 -0
  2888. psychopy/visual/dot.py +668 -0
  2889. psychopy/visual/dropdown.py +165 -0
  2890. psychopy/visual/elementarray.py +728 -0
  2891. psychopy/visual/filters.py +419 -0
  2892. psychopy/visual/form.py +1180 -0
  2893. psychopy/visual/globalVars.py +24 -0
  2894. psychopy/visual/grating.py +501 -0
  2895. psychopy/visual/helpers.py +334 -0
  2896. psychopy/visual/image.py +440 -0
  2897. psychopy/visual/line.py +238 -0
  2898. psychopy/visual/movie.py +12 -0
  2899. psychopy/visual/movie2.py +829 -0
  2900. psychopy/visual/movie3.py +599 -0
  2901. psychopy/visual/movies/__init__.py +850 -0
  2902. psychopy/visual/movies/frame.py +255 -0
  2903. psychopy/visual/movies/metadata.py +242 -0
  2904. psychopy/visual/movies/players/__init__.py +62 -0
  2905. psychopy/visual/movies/players/_base.py +364 -0
  2906. psychopy/visual/movies/players/ffpyplayer_player.py +1399 -0
  2907. psychopy/visual/nnlvs.py +827 -0
  2908. psychopy/visual/noise.py +34 -0
  2909. psychopy/visual/panorama.py +313 -0
  2910. psychopy/visual/patch.py +29 -0
  2911. psychopy/visual/pie.py +248 -0
  2912. psychopy/visual/polygon.py +229 -0
  2913. psychopy/visual/progress.py +313 -0
  2914. psychopy/visual/radial.py +33 -0
  2915. psychopy/visual/ratingscale.py +1424 -0
  2916. psychopy/visual/rect.py +204 -0
  2917. psychopy/visual/rift.py +2654 -0
  2918. psychopy/visual/roi.py +141 -0
  2919. psychopy/visual/secondorder.py +29 -0
  2920. psychopy/visual/shaders.py +453 -0
  2921. psychopy/visual/shape.py +701 -0
  2922. psychopy/visual/simpleimage.py +303 -0
  2923. psychopy/visual/slider.py +1169 -0
  2924. psychopy/visual/stim3d.py +2712 -0
  2925. psychopy/visual/target.py +278 -0
  2926. psychopy/visual/text.py +759 -0
  2927. psychopy/visual/textbox/__init__.py +1280 -0
  2928. psychopy/visual/textbox/fontmanager.py +574 -0
  2929. psychopy/visual/textbox/parsedtext.py +317 -0
  2930. psychopy/visual/textbox/textgrid.py +278 -0
  2931. psychopy/visual/textbox/textureatlas.py +248 -0
  2932. psychopy/visual/textbox2/__init__.py +4 -0
  2933. psychopy/visual/textbox2/textbox2.py +1817 -0
  2934. psychopy/visual/vlcmoviestim.py +1294 -0
  2935. psychopy/visual/window.py +3706 -0
  2936. psychopy/visual/windowframepack.py +86 -0
  2937. psychopy/visual/windowwarp.py +457 -0
  2938. psychopy/voicekey/__init__.py +684 -0
  2939. psychopy/voicekey/demo_vks.py +12 -0
  2940. psychopy/voicekey/labjack_vks.py +50 -0
  2941. psychopy/voicekey/parallel_vks.py +44 -0
  2942. psychopy/voicekey/signal.py +42 -0
  2943. psychopy/voicekey/vk_tools.py +280 -0
  2944. psychopy/web.py +286 -0
  2945. psychopy-2024.1.0.dist-info/METADATA +154 -0
  2946. psychopy-2024.1.0.dist-info/RECORD +2950 -0
  2947. psychopy-2024.1.0.dist-info/WHEEL +4 -0
  2948. psychopy-2024.1.0.dist-info/entry_points.txt +3 -0
  2949. psychopy-2024.1.0.dist-info/licenses/AUTHORS.md +138 -0
  2950. psychopy-2024.1.0.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,2809 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """Classes and functions for reading and writing camera streams.
4
+
5
+ A camera may be used to document participant responses on video or used by the
6
+ experimenter to create movie stimuli or instructions.
7
+
8
+ """
9
+
10
+ # Part of the PsychoPy library
11
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
12
+ # Distributed under the terms of the GNU General Public License (GPL).
13
+
14
+ __all__ = [
15
+ 'VIDEO_DEVICE_ROOT_LINUX',
16
+ 'CAMERA_UNKNOWN_VALUE',
17
+ 'CAMERA_NULL_VALUE',
18
+ # 'CAMERA_MODE_VIDEO',
19
+ # 'CAMERA_MODE_CV',
20
+ # 'CAMERA_MODE_PHOTO',
21
+ 'CAMERA_TEMP_FILE_VIDEO',
22
+ 'CAMERA_TEMP_FILE_AUDIO',
23
+ 'CAMERA_API_AVFOUNDATION',
24
+ 'CAMERA_API_DIRECTSHOW',
25
+ 'CAMERA_API_VIDEO4LINUX2',
26
+ 'CAMERA_API_ANY',
27
+ 'CAMERA_API_UNKNOWN',
28
+ 'CAMERA_API_NULL',
29
+ 'CAMERA_LIB_FFPYPLAYER',
30
+ 'CAMERA_LIB_OPENCV',
31
+ 'CAMERA_LIB_UNKNOWN',
32
+ 'CAMERA_LIB_NULL',
33
+ 'CameraError',
34
+ 'CameraNotReadyError',
35
+ 'CameraNotFoundError',
36
+ 'CameraFormatNotSupportedError',
37
+ 'CameraFrameRateNotSupportedError',
38
+ 'CameraFrameSizeNotSupportedError',
39
+ 'FormatNotFoundError',
40
+ 'PlayerNotAvailableError',
41
+ 'CameraInterfaceFFmpeg',
42
+ 'CameraInterfaceOpenCV',
43
+ 'Camera',
44
+ 'CameraInfo',
45
+ 'getCameras',
46
+ 'getCameraDescriptions',
47
+ 'getOpenCameras',
48
+ 'closeAllOpenCameras',
49
+ 'renderVideo'
50
+ ]
51
+
52
+ import platform
53
+ import inspect
54
+ import os
55
+ import os.path
56
+ import sys
57
+ import math
58
+ import uuid
59
+ import threading
60
+ import queue
61
+ import time
62
+ import numpy as np
63
+
64
+ from psychopy.constants import NOT_STARTED
65
+ from psychopy.hardware import DeviceManager
66
+ from psychopy.visual.movies.frame import MovieFrame, NULL_MOVIE_FRAME_INFO
67
+ from psychopy.sound.microphone import Microphone
68
+ from psychopy.hardware.microphone import MicrophoneDevice
69
+ from psychopy.tools import systemtools as st
70
+ import psychopy.tools.movietools as movietools
71
+ import psychopy.logging as logging
72
+ from psychopy.localization import _translate
73
+
74
+
75
+ # ------------------------------------------------------------------------------
76
+ # Constants
77
+ #
78
+
79
+ VIDEO_DEVICE_ROOT_LINUX = '/dev'
80
+ CAMERA_UNKNOWN_VALUE = u'Unknown' # fields where we couldn't get a value
81
+ CAMERA_NULL_VALUE = u'Null' # fields where we couldn't get a value
82
+ # camera operating modes
83
+ # CAMERA_MODE_VIDEO = u'video'
84
+ # CAMERA_MODE_CV = u'cv'
85
+ # CAMERA_MODE_PHOTO = u'photo'
86
+
87
+ # camera status
88
+ CAMERA_STATUS_OK = 'ok'
89
+ CAMERA_STATUS_PAUSED = 'paused'
90
+ CAMERA_STATUS_EOF = 'eof'
91
+
92
+ # camera API flags, these specify which API camera settings were queried with
93
+ CAMERA_API_AVFOUNDATION = u'AVFoundation' # mac
94
+ CAMERA_API_DIRECTSHOW = u'DirectShow' # windows
95
+ CAMERA_API_VIDEO4LINUX2 = u'Video4Linux2' # linux
96
+ CAMERA_API_ANY = u'Any' # any API (OpenCV only)
97
+ CAMERA_API_UNKNOWN = u'Unknown' # unknown API
98
+ CAMERA_API_NULL = u'Null' # empty field
99
+
100
+ # camera libraries for playback nad recording
101
+ CAMERA_LIB_FFPYPLAYER = u'FFPyPlayer'
102
+ CAMERA_LIB_OPENCV = u'OpenCV'
103
+ CAMERA_LIB_UNKNOWN = u'Unknown'
104
+ CAMERA_LIB_NULL = u'Null'
105
+
106
+ # special values
107
+ CAMERA_FRAMERATE_NOMINAL_NTSC = '30.000030'
108
+ CAMERA_FRAMERATE_NTSC = 30.000030
109
+
110
+ # FourCC and pixel format mappings, mostly used with AVFoundation to determine
111
+ # the FFMPEG decoder which is most suitable for it. Please expand this if you
112
+ # know any more!
113
+ pixelFormatTbl = {
114
+ 'yuvs': 'yuyv422', # 4:2:2
115
+ '420v': 'nv12', # 4:2:0
116
+ '2vuy': 'uyvy422' # QuickTime 4:2:2
117
+ }
118
+
119
+ # Camera standards to help with selection. Some standalone cameras sometimes
120
+ # support an insane number of formats, this will help narrow them down.
121
+ standardResolutions = {
122
+ 'vga': (640, 480),
123
+ 'svga': (800, 600),
124
+ 'xga': (1024, 768),
125
+ 'wxga': (1280, 768),
126
+ 'wxga+': (1440, 900),
127
+ 'sxga': (1280, 1024),
128
+ 'wsxga+': (1680, 1050),
129
+ 'uxga': (1600, 1200),
130
+ 'wuxga': (1920, 1200),
131
+ 'wqxga': (2560, 1600),
132
+ 'wquxga': (3840, 2400),
133
+ '720p': (1280, 720), # also known as HD
134
+ '1080p': (1920, 1080),
135
+ '2160p': (3840, 2160),
136
+ 'uhd': (3840, 2160),
137
+ 'dci': (4096, 2160)
138
+ }
139
+
140
+
141
+ # ------------------------------------------------------------------------------
142
+ # Exceptions
143
+ #
144
+
145
+ class CameraError(Exception):
146
+ """Base class for errors around the camera."""
147
+
148
+
149
+ class CameraNotReadyError(CameraError):
150
+ """Camera is not ready."""
151
+
152
+
153
+ class CameraNotFoundError(CameraError):
154
+ """Raised when a camera cannot be found on the system."""
155
+
156
+
157
+ class CameraFormatNotSupportedError(CameraError):
158
+ """Raised when a camera cannot use the settings requested by the user."""
159
+
160
+ class CameraFrameRateNotSupportedError(CameraFormatNotSupportedError):
161
+ """Raised when a camera cannot use the frame rate settings requested by the
162
+ user."""
163
+
164
+ class CameraFrameSizeNotSupportedError(CameraFormatNotSupportedError):
165
+ """Raised when a camera cannot use the frame size settings requested by the
166
+ user."""
167
+
168
+ class FormatNotFoundError(CameraError):
169
+ """Cannot find a suitable pixel format for the camera."""
170
+
171
+
172
+ class PlayerNotAvailableError(Exception):
173
+ """Raised when a player object is not available but is required."""
174
+
175
+
176
+ # ------------------------------------------------------------------------------
177
+ # Classes
178
+ #
179
+
180
+ class CameraInfo:
181
+ """Information about a specific operating mode for a camera attached to the
182
+ system.
183
+
184
+ Parameters
185
+ ----------
186
+ index : int
187
+ Index of the camera. This is the enumeration for the camera which is
188
+ used to identify and select it by the `cameraLib`. This value may differ
189
+ between operating systems and the `cameraLib` being used.
190
+ name : str
191
+ Camera name retrieved by the OS. This may be a human-readable name
192
+ (i.e. DirectShow on Windows), an index on MacOS or a path (e.g.,
193
+ `/dev/video0` on Linux). If the `cameraLib` does not support this
194
+ feature, then this value will be generated.
195
+ frameSize : ArrayLike
196
+ Resolution of the frame `(w, h)` in pixels.
197
+ frameRate : ArrayLike
198
+ Allowable framerate for this camera mode.
199
+ pixelFormat : str
200
+ Pixel format for the stream. If `u'Null'`, then `codecFormat` is being
201
+ used to configure the camera.
202
+ codecFormat : str
203
+ Codec format for the stream. If `u'Null'`, then `pixelFormat` is being
204
+ used to configure the camera. Usually this value is used for high-def
205
+ stream formats.
206
+ cameraLib : str
207
+ Library used to access the camera. This can be either, 'ffpyplayer',
208
+ 'opencv'.
209
+ cameraAPI : str
210
+ API used to access the camera. This relates to the external interface
211
+ being used by `cameraLib` to access the camera. This value can be:
212
+ 'AVFoundation', 'DirectShow' or 'Video4Linux2'.
213
+
214
+ """
215
+ __slots__ = [
216
+ '_index',
217
+ '_name',
218
+ '_frameSize',
219
+ '_frameRate',
220
+ '_pixelFormat',
221
+ '_codecFormat',
222
+ '_cameraLib',
223
+ '_cameraAPI' # API in use, e.g. DirectShow on Windows
224
+ ]
225
+
226
+ def __init__(self,
227
+ index=-1,
228
+ name=CAMERA_NULL_VALUE,
229
+ frameSize=(-1, -1),
230
+ frameRate=-1.0,
231
+ pixelFormat=CAMERA_UNKNOWN_VALUE,
232
+ codecFormat=CAMERA_UNKNOWN_VALUE,
233
+ cameraLib=CAMERA_NULL_VALUE,
234
+ cameraAPI=CAMERA_API_NULL):
235
+
236
+ self.index = index
237
+ self.name = name
238
+ self.frameSize = frameSize
239
+ self.frameRate = frameRate
240
+ self.pixelFormat = pixelFormat
241
+ self.codecFormat = codecFormat
242
+ self.cameraLib = cameraLib
243
+ self.cameraAPI = cameraAPI
244
+
245
+ def __repr__(self):
246
+ return (f"CameraInfo(index={repr(self.index)}, "
247
+ f"name={repr(self.name)}, "
248
+ f"frameSize={repr(self.frameSize)}, "
249
+ f"frameRate={self.frameRate}, "
250
+ f"pixelFormat={repr(self.pixelFormat)}, "
251
+ f"codecFormat={repr(self.codecFormat)}, "
252
+ f"cameraLib={repr(self.cameraLib)}, "
253
+ f"cameraAPI={repr(self.cameraAPI)})")
254
+
255
+ def __str__(self):
256
+ return self.description()
257
+
258
+ @property
259
+ def index(self):
260
+ """Camera index (`int`). This is the enumerated index of this camera.
261
+ """
262
+ return self._index
263
+
264
+ @index.setter
265
+ def index(self, value):
266
+ self._index = int(value)
267
+
268
+ @property
269
+ def name(self):
270
+ """Camera name (`str`). This is the camera name retrieved by the OS.
271
+ """
272
+ return self._name
273
+
274
+ @name.setter
275
+ def name(self, value):
276
+ self._name = str(value)
277
+
278
+ @property
279
+ def frameSize(self):
280
+ """Resolution (w, h) in pixels (`ArrayLike` or `None`).
281
+ """
282
+ return self._frameSize
283
+
284
+ @frameSize.setter
285
+ def frameSize(self, value):
286
+ if value is None:
287
+ self._frameSize = None
288
+ return
289
+
290
+ assert len(value) == 2, "Value for `frameSize` must have length 2."
291
+ assert all([isinstance(i, int) for i in value]), (
292
+ "Values for `frameSize` must be integers.")
293
+
294
+ self._frameSize = value
295
+
296
+ @property
297
+ def frameRate(self):
298
+ """Frame rate (`float`) or range (`ArrayLike`).
299
+
300
+ Depends on the backend being used. If a range is provided, then the
301
+ first value is the maximum and the second value is the minimum frame
302
+ rate.
303
+ """
304
+ return self._frameRate
305
+
306
+ @frameRate.setter
307
+ def frameRate(self, value):
308
+ # assert len(value) == 2, "Value for `frameRateRange` must have length 2."
309
+ # assert all([isinstance(i, int) for i in value]), (
310
+ # "Values for `frameRateRange` must be integers.")
311
+ # assert value[0] <= value[1], (
312
+ # "Value for `frameRateRange` must be `min` <= `max`.")
313
+
314
+ self._frameRate = value
315
+
316
+ @property
317
+ def pixelFormat(self):
318
+ """Video pixel format (`str`). An empty string indicates this field is
319
+ not initialized.
320
+ """
321
+ return self._pixelFormat
322
+
323
+ @pixelFormat.setter
324
+ def pixelFormat(self, value):
325
+ self._pixelFormat = str(value)
326
+
327
+ @property
328
+ def codecFormat(self):
329
+ """Codec format, may be used instead of `pixelFormat` for some
330
+ configurations. Default is `''`.
331
+ """
332
+ return self._codecFormat
333
+
334
+ @codecFormat.setter
335
+ def codecFormat(self, value):
336
+ self._codecFormat = str(value)
337
+
338
+ @property
339
+ def cameraLib(self):
340
+ """Camera library these settings are targeted towards (`str`).
341
+ """
342
+ return self._cameraLib
343
+
344
+ @cameraLib.setter
345
+ def cameraLib(self, value):
346
+ self._cameraLib = str(value)
347
+
348
+ @property
349
+ def cameraAPI(self):
350
+ """Camera API in use to obtain this information (`str`).
351
+ """
352
+ return self._cameraAPI
353
+
354
+ @cameraAPI.setter
355
+ def cameraAPI(self, value):
356
+ self._cameraAPI = str(value)
357
+
358
+ def frameSizeAsFormattedString(self):
359
+ """Get image size as as formatted string.
360
+
361
+ Returns
362
+ -------
363
+ str
364
+ Size formatted as `'WxH'` (e.g. `'480x320'`).
365
+
366
+ """
367
+ return '{width}x{height}'.format(
368
+ width=self.frameSize[0],
369
+ height=self.frameSize[1])
370
+
371
+ def description(self):
372
+ """Get a description as a string.
373
+
374
+ For all backends, this value is guaranteed to be valid after the camera
375
+ has been opened. Some backends may be able to provide this information
376
+ before the camera is opened.
377
+
378
+ Returns
379
+ -------
380
+ str
381
+ Description of the camera format as a human readable string.
382
+
383
+ """
384
+ codecFormat = self._codecFormat
385
+ pixelFormat = self._pixelFormat
386
+ codec = codecFormat if not pixelFormat else pixelFormat
387
+
388
+ if self.frameSize is None:
389
+ frameSize = (-1, -1)
390
+ else:
391
+ frameSize = self.frameSize
392
+
393
+ return "[{name}] {width}x{height}@{frameRate}fps, {codec}".format(
394
+ #index=self.index,
395
+ name=self.name,
396
+ width=str(frameSize[0]),
397
+ height=str(frameSize[1]),
398
+ frameRate=str(self.frameRate),
399
+ codec=codec
400
+ )
401
+
402
+
403
+ class CameraInterface:
404
+ """Base class providing an interface with a camera attached to the system.
405
+
406
+ This interface handles the opening, closing, and reading of camera streams.
407
+ Subclasses provide a specific implementation for a camera interface.
408
+
409
+ Calls to any instance methods should be asynchronous and non-blocking,
410
+ returning immediately with the same data as before if no new frame data is
411
+ available. This is to ensure that the main thread is not blocked by the
412
+ camera interface and can continue to process other events.
413
+
414
+ Parameters
415
+ ----------
416
+ device : Any
417
+ Camera device to open a stream with. The type of this value is platform
418
+ dependent. Calling `start()` will open a stream with this device.
419
+ Afterwards, `getRecentFrame()` can be called to get the most recent
420
+ frame from the camera.
421
+
422
+ """
423
+ # default values for class variables, these are read-only and should not be
424
+ # changed at runtime
425
+ _cameraLib = u'Null'
426
+ _frameIndex = 0
427
+ _lastPTS = 0.0 # presentation timestamp of the last frame
428
+ _supportedPlatforms = ['linux', 'windows', 'darwin']
429
+ _device = None
430
+ _lastFrame = None
431
+ _isReady = False # `True` if the camera is 'hot' and yielding frames
432
+
433
+ def __init__(self, device):
434
+ self._device = device
435
+ self._mic = None
436
+
437
+ @staticmethod
438
+ def getCameras():
439
+ """Get a list of devices this interface can open.
440
+
441
+ Returns
442
+ -------
443
+ list
444
+ List of objects which represent cameras that can be opened by this
445
+ interface. Pass any of these values to `device` to open a stream.
446
+
447
+ """
448
+ return []
449
+
450
+ @property
451
+ def device(self):
452
+ """Camera device this interface is using (`Any`).
453
+ """
454
+ return self._device
455
+
456
+ @property
457
+ def frameCount(self):
458
+ """Number of new frames read from the camera since initialization
459
+ (`int`).
460
+ """
461
+ return self._frameCount
462
+
463
+ @property
464
+ def streamTime(self):
465
+ """Current stream time in seconds (`float`). This time increases
466
+ monotonically from startup.
467
+ """
468
+ return self._streamTime
469
+
470
+ def lastFrame(self):
471
+ """The last frame read from the camera. If `None`, no frames have been
472
+ read yet.
473
+ """
474
+ return self._lastFrame
475
+
476
+ def _assertMediaPlayer(self):
477
+ """Assert that the media player is available.
478
+
479
+ Returns
480
+ -------
481
+ bool
482
+ `True` if the media player is available.
483
+
484
+ """
485
+ return False
486
+
487
+ def open(self):
488
+ """Open the camera stream.
489
+ """
490
+ pass
491
+
492
+ def isOpen(self):
493
+ """Check if the camera stream is open.
494
+
495
+ Returns
496
+ -------
497
+ bool
498
+ `True` if the camera stream is open.
499
+
500
+ """
501
+ return False
502
+
503
+ def enable(self):
504
+ """Enable passing camera frames to the main thread.
505
+ """
506
+ pass
507
+
508
+ def disable(self):
509
+ """Disable passing camera frames to the main thread.
510
+ """
511
+ pass
512
+
513
+ def close(self):
514
+ """Close the camera stream.
515
+ """
516
+ pass
517
+
518
+ def getMetadata(self):
519
+ """Get metadata about the camera stream.
520
+
521
+ Returns
522
+ -------
523
+ dict
524
+ Dictionary containing metadata about the camera stream. Returns an
525
+ empty dictionary if no metadata is available.
526
+
527
+ """
528
+ return {}
529
+
530
+ def _enqueueFrame(self):
531
+ """Enqueue a frame from the camera stream.
532
+ """
533
+ pass
534
+
535
+ def update(self):
536
+ """Update the camera stream.
537
+ """
538
+ pass
539
+
540
+ def getRecentFrame(self):
541
+ """Get the most recent frame from the camera stream.
542
+
543
+ Returns
544
+ -------
545
+ numpy.ndarray
546
+ Most recent frame from the camera stream. Returns `None` if no
547
+ frames are available.
548
+
549
+ """
550
+ return NULL_MOVIE_FRAME_INFO
551
+
552
+
553
+ class CameraInterfaceFFmpeg(CameraInterface):
554
+ """Camera interface using FFmpeg (ffpyplayer) to open and read camera
555
+ streams.
556
+
557
+ Parameters
558
+ ----------
559
+ device : CameraInfo
560
+ Camera device to open a stream with. Calling `start()` will open a
561
+ stream with this device. Afterwards, `getRecentFrame()` can be called
562
+ to get the most recent frame from the camera.
563
+ mic : MicrophoneInterface or None
564
+ Microphone interface to use for audio recording. If `None`, no audio
565
+ recording is performed.
566
+
567
+ """
568
+ _cameraLib = u'ffpyplayer'
569
+
570
+ def __init__(self, device, mic=None):
571
+ super().__init__(device=device)
572
+
573
+ self._bufferSecs = 0.5 # number of seconds to buffer
574
+ self._cameraInfo = device
575
+ self._mic = mic # microphone interface
576
+ self._frameQueue = queue.Queue()
577
+ self._enableEvent = threading.Event()
578
+ self._enableEvent.clear()
579
+ self._exitEvent = threading.Event()
580
+ self._exitEvent.clear()
581
+ self._syncBarrier = None
582
+ self._recordBarrier = None # created in `open()`
583
+ self._playerThread = None
584
+
585
+ def _assertMediaPlayer(self):
586
+ return self._playerThread is not None
587
+
588
+ def _getCameraInfo(self):
589
+ """Get camera information in the format expected by FFmpeg.
590
+ """
591
+ pass
592
+
593
+ def getCameras():
594
+ """Get a list of devices this interface can open.
595
+
596
+ Returns
597
+ -------
598
+ list
599
+ List of objects which represent cameras that can be opened by this
600
+ interface. Pass any of these values to `device` to open a stream.
601
+
602
+ """
603
+ global _cameraGetterFuncTbl
604
+ systemName = platform.system() # get the system name
605
+
606
+ # lookup the function for the given platform
607
+ getCamerasFunc = _cameraGetterFuncTbl.get(systemName, None)
608
+ if getCamerasFunc is None: # if unsupported
609
+ raise OSError(
610
+ "Cannot get cameras, unsupported platform '{}'.".format(
611
+ systemName))
612
+
613
+ return getCamerasFunc()
614
+
615
+ @property
616
+ def frameRate(self):
617
+ """Frame rate of the camera stream (`float`).
618
+ """
619
+ return self._cameraInfo.frameRate
620
+
621
+ @property
622
+ def frameSize(self):
623
+ """Frame size of the camera stream (`tuple`).
624
+ """
625
+ return self._cameraInfo.frameSize
626
+
627
+ @property
628
+ def framesWaiting(self):
629
+ """Get the number of frames currently buffered (`int`).
630
+
631
+ Returns the number of frames which have been pulled from the stream and
632
+ are waiting to be processed. This value is decremented by calls to
633
+ `_enqueueFrame()`.
634
+
635
+ """
636
+ return self._frameQueue.qsize()
637
+
638
+ def isOpen(self):
639
+ """Check if the camera stream is open (`bool`).
640
+ """
641
+ if self._playerThread is not None:
642
+ return self._playerThread.is_alive()
643
+
644
+ return False
645
+
646
+ def open(self):
647
+ """Open the camera stream and begin decoding frames (if available).
648
+
649
+ The value of `lastFrame` will be updated as new frames from the camera
650
+ arrive.
651
+
652
+ """
653
+ if self._playerThread is not None:
654
+ raise RuntimeError('Cannot open `MediaPlayer`, already opened.')
655
+
656
+ self._exitEvent.clear() # signal the thread to stop
657
+
658
+ def _frameGetterAsync(videoCapture, frameQueue, exitEvent, recordEvent,
659
+ warmUpBarrier, recordingBarrier, audioCapture):
660
+ """Get frames from the camera stream asynchronously.
661
+
662
+ Parameters
663
+ ----------
664
+ videoCapture : ffpyplayer.player.MediaPlayer
665
+ FFmpeg media player object. This object will be under direct
666
+ control of this function.
667
+ frameQueue : queue.Queue
668
+ Queue to put frames into. The queue has an unlimited size, so
669
+ be careful with memory use. This queue should be flushed when
670
+ camera thread is paused.
671
+ exitEvent : threading.Event
672
+ Event used to signal the thread to stop.
673
+ recordEvent : threading.Event
674
+ Event used to signal the thread to pass frames along to the main
675
+ thread.
676
+ warmUpBarrier : threading.Barrier
677
+ Barrier which is used hold until camera capture is ready.
678
+ recordingBarrier : threading.Barrier
679
+ Barrier which is used to synchronize audio and video recording.
680
+ This ensures that the audio device is ready before buffering
681
+ frames captured by the camera.
682
+ audioCapture : psychopy.sound.Microphone or None
683
+ Microphone object to use for audio capture. This will be used to
684
+ synchronize the audio and video streams. If `None`, no audio
685
+ will be captured.
686
+
687
+ """
688
+ # warmup the stream, wait for metadata
689
+ ptsStart = 0.0 # may be used in the future
690
+ while True:
691
+ frame, val = videoCapture.get_frame()
692
+ if frame is not None:
693
+ ptsStart = videoCapture.get_pts()
694
+ break
695
+
696
+ time.sleep(0.001)
697
+
698
+ # if we have a valid frame, determine the polling rate
699
+ metadata = videoCapture.get_metadata()
700
+ numer, divisor = metadata['frame_rate']
701
+
702
+ # poll interval is half the frame period, this makes sure we don't
703
+ # miss frames while not wasting CPU cycles
704
+ pollInterval = (1.0 / float(numer / divisor)) * 0.5
705
+
706
+ # holds main-thread execution until its ready for frames
707
+ # frameQueue.put((frame, val, metadata)) # put the first frame
708
+
709
+ warmUpBarrier.wait() # wait for main thread to be ready
710
+
711
+ # start capturing frames in background thread
712
+ isRecording = False
713
+ lastAbsTime = -1.0 # presentation timestamp of the last frame
714
+ while not exitEvent.is_set(): # quit if signaled
715
+ # pull a frame from the stream, we keep this running 'hot' so
716
+ # that we don't miss frames, we just discard them if we don't
717
+ # need them
718
+ frame, val = videoCapture.get_frame(force_refresh=False)
719
+
720
+ if val == 'eof': # thread should exit if stream is done
721
+ break
722
+ elif val == 'paused':
723
+ continue
724
+ elif frame is None:
725
+ continue
726
+ else:
727
+ # don't queue frames unless they are newer than the last
728
+ if isRecording:
729
+ thisFrameAbsTime = videoCapture.get_pts()
730
+ if lastAbsTime < thisFrameAbsTime:
731
+ frameQueue.put((frame, val, metadata))
732
+ lastAbsTime = thisFrameAbsTime
733
+
734
+ if recordEvent.is_set() and not isRecording:
735
+ if audioCapture is not None:
736
+ audioCapture.start(waitForStart=1)
737
+ recordingBarrier.wait()
738
+ isRecording = True
739
+ elif not recordEvent.is_set() and isRecording:
740
+ if audioCapture is not None:
741
+ audioCapture.stop(blockUntilStopped=1)
742
+ recordingBarrier.wait()
743
+ isRecording = False
744
+
745
+ if not isRecording:
746
+ time.sleep(pollInterval)
747
+ continue
748
+
749
+ if audioCapture is not None:
750
+ if audioCapture.isRecording:
751
+ audioCapture.poll()
752
+
753
+ time.sleep(pollInterval)
754
+
755
+ videoCapture.close_player()
756
+
757
+ if audioCapture is not None:
758
+ audioCapture.stop(blockUntilStopped=1)
759
+
760
+ # thread is dead when we get here
761
+
762
+ # configure the camera stream reader
763
+ ff_opts = {} # ffmpeg options
764
+ lib_opts = {} # ffpyplayer options
765
+ _camera = CAMERA_NULL_VALUE
766
+ _frameRate = CAMERA_NULL_VALUE
767
+ _cameraInfo = self._cameraInfo
768
+
769
+ # setup commands for FFMPEG
770
+ if _cameraInfo.cameraAPI == CAMERA_API_DIRECTSHOW: # windows
771
+ ff_opts['f'] = 'dshow'
772
+ _camera = 'video={}'.format(_cameraInfo.name)
773
+ _frameRate = _cameraInfo.frameRate
774
+ if _cameraInfo.pixelFormat:
775
+ ff_opts['pixel_format'] = _cameraInfo.pixelFormat
776
+ if _cameraInfo.codecFormat:
777
+ ff_opts['vcodec'] = _cameraInfo.codecFormat
778
+ elif _cameraInfo.cameraAPI == CAMERA_API_AVFOUNDATION: # darwin
779
+ ff_opts['f'] = 'avfoundation'
780
+ ff_opts['i'] = _camera = self._cameraInfo.name
781
+
782
+ # handle pixel formats using FourCC
783
+ global pixelFormatTbl
784
+ ffmpegPixFmt = pixelFormatTbl.get(_cameraInfo.pixelFormat, None)
785
+
786
+ if ffmpegPixFmt is None:
787
+ raise FormatNotFoundError(
788
+ "Cannot find suitable FFMPEG pixel format for '{}'. Try a "
789
+ "different format or camera.".format(
790
+ _cameraInfo.pixelFormat))
791
+
792
+ _cameraInfo.pixelFormat = ffmpegPixFmt
793
+
794
+ # this needs to be exactly specified if using NTSC
795
+ if math.isclose(CAMERA_FRAMERATE_NTSC, _cameraInfo.frameRate):
796
+ _frameRate = CAMERA_FRAMERATE_NOMINAL_NTSC
797
+ else:
798
+ _frameRate = str(_cameraInfo.frameRate)
799
+
800
+ # need these since hardware acceleration is not possible on Mac yet
801
+ lib_opts['fflags'] = 'nobuffer'
802
+ lib_opts['flags'] = 'low_delay'
803
+ lib_opts['pixel_format'] = _cameraInfo.pixelFormat
804
+ ff_opts['framedrop'] = True
805
+ ff_opts['fast'] = True
806
+ elif _cameraInfo.cameraAPI == CAMERA_API_VIDEO4LINUX2:
807
+ raise OSError(
808
+ "Sorry, camera does not support Linux at this time. However, "
809
+ "it will in future versions.")
810
+
811
+ else:
812
+ raise RuntimeError("Unsupported camera API specified.")
813
+
814
+ # set library options
815
+ camWidth = _cameraInfo.frameSize[0]
816
+ camHeight = _cameraInfo.frameSize[1]
817
+
818
+ # configure the real-time buffer size
819
+ _bufferSize = camWidth * camHeight * 3 * self._bufferSecs
820
+
821
+ # common settings across libraries
822
+ lib_opts['rtbufsize'] = str(int(_bufferSize))
823
+ lib_opts['video_size'] = _cameraInfo.frameSizeAsFormattedString()
824
+ lib_opts['framerate'] = str(_frameRate)
825
+
826
+ self._warmupBarrier = threading.Barrier(2)
827
+ self._recordBarrier = threading.Barrier(2)
828
+
829
+ # open the media player
830
+ from ffpyplayer.player import MediaPlayer
831
+ cap = MediaPlayer(_camera, ff_opts=ff_opts, lib_opts=lib_opts)
832
+
833
+ # open a stream thread and pause wait until ready
834
+ self._playerThread = threading.Thread(
835
+ target=_frameGetterAsync,
836
+ args=(cap,
837
+ self._frameQueue,
838
+ self._exitEvent,
839
+ self._enableEvent,
840
+ self._warmupBarrier,
841
+ self._recordBarrier,
842
+ self._mic))
843
+ self._playerThread.daemon=True
844
+ self._playerThread.start()
845
+
846
+ self._warmupBarrier.wait()
847
+
848
+ # pass off the player to the thread which will process the stream
849
+ self._enqueueFrame() # pull metadata from first frame
850
+
851
+ def _enqueueFrame(self):
852
+ """Grab the latest frame from the stream.
853
+
854
+ Returns
855
+ -------
856
+ bool
857
+ `True` if a frame has been enqueued. Returns `False` if the camera
858
+ has not acquired a new frame yet.
859
+
860
+ """
861
+ self._assertMediaPlayer()
862
+
863
+ try:
864
+ frameData = self._frameQueue.get_nowait()
865
+ except queue.Empty:
866
+ return False
867
+
868
+ frame, val, metadata = frameData # update the frame
869
+
870
+ if val == CAMERA_STATUS_EOF: # handle end of stream
871
+ return False
872
+ elif val == CAMERA_STATUS_PAUSED: # handle when paused
873
+ return False
874
+ elif frame is None: # handle when no frame is available
875
+ return False
876
+
877
+ frameImage, pts = frame # otherwise, unpack the frame
878
+
879
+ # if we have a new frame, update the frame information
880
+ videoBuffer = frameImage.to_bytearray()[0]
881
+ videoFrameArray = np.frombuffer(videoBuffer, dtype=np.uint8)
882
+
883
+ # provide the last frame
884
+ self._lastFrame = MovieFrame(
885
+ frameIndex=self._frameIndex,
886
+ absTime=pts,
887
+ # displayTime=self._recentMetadata['frame_size'],
888
+ size=frameImage.get_size(),
889
+ colorData=videoFrameArray,
890
+ audioChannels=0,
891
+ audioSamples=None,
892
+ metadata=metadata,
893
+ movieLib=self._cameraLib,
894
+ userData=None)
895
+
896
+ return True
897
+
898
+ def close(self):
899
+ """Close the camera stream and release resources.
900
+
901
+ This blocks until the camera stream thread is no longer alive.
902
+
903
+ """
904
+ if self._playerThread is None:
905
+ raise RuntimeError('Cannot close `MediaPlayer`, already closed.')
906
+
907
+ self._exitEvent.set() # signal the thread to stop
908
+ self._playerThread.join() # wait for the thread to stop
909
+
910
+ self._playerThread = None
911
+
912
+ @property
913
+ def isEnabled(self):
914
+ """`True` if the camera is enabled.
915
+ """
916
+ return self._enableEvent.is_set()
917
+
918
+ def enable(self, state=True):
919
+ """Start passing frames to the frame queue.
920
+
921
+ This method returns when the video and audio stream are both starting to
922
+ record or stop recording.
923
+
924
+ Parameters
925
+ ----------
926
+ state : bool
927
+ `True` to enable recording frames to the queue, `False` to disable.
928
+ On state change, the audio interface will be started or stopped.
929
+
930
+ """
931
+ if state:
932
+ self._enableEvent.set()
933
+ else:
934
+ self._enableEvent.clear()
935
+
936
+ self._recordBarrier.wait()
937
+ self._enqueueFrame()
938
+
939
+ def disable(self):
940
+ """Stop passing frames to the frame queue.
941
+
942
+ Calling this is equivalent to calling `enable(False)`.
943
+
944
+ """
945
+ self.enable(False)
946
+
947
+ def getFrames(self):
948
+ """Get all frames from the camera stream which are waiting to be
949
+ processed.
950
+
951
+ Returns
952
+ -------
953
+ list
954
+ List of `MovieFrame` objects. The most recent frame is the last one
955
+ in the list.
956
+
957
+ """
958
+ self._assertMediaPlayer()
959
+
960
+ frames = []
961
+ while self._enqueueFrame():
962
+ frames.append(self._lastFrame)
963
+
964
+ return frames
965
+
966
+ def getRecentFrame(self):
967
+ """Get the most recent frame captured from the camera, discarding all
968
+ others.
969
+
970
+ Returns
971
+ -------
972
+ MovieFrame
973
+ The most recent frame from the stream.
974
+
975
+ """
976
+ while self._enqueueFrame():
977
+ pass
978
+
979
+ return self._lastFrame
980
+
981
+
982
+ class CameraInterfaceOpenCV(CameraInterface):
983
+ """Camera interface using OpenCV to open and read camera streams.
984
+
985
+ Parameters
986
+ ----------
987
+ device : int
988
+ Camera device to open a stream with. This value is platform dependent.
989
+ mic : MicrophoneInterface or None
990
+ Microphone interface to use for audio recording. If `None`, no audio
991
+ recording is performed.
992
+
993
+ """
994
+ _cameraLib = u'opencv'
995
+
996
+ def __init__(self, device, mic=None):
997
+ super().__init__(device)
998
+ try:
999
+ import cv2 # just import to check if it's available
1000
+ except ImportError:
1001
+ raise ImportError(
1002
+ "Could not import `cv2`. Please install OpenCV2 to use this "
1003
+ "camera interface.")
1004
+
1005
+ self._cameraInfo = device
1006
+ self._mic = mic # microphone interface
1007
+ self._frameQueue = queue.Queue()
1008
+ self._enableEvent = threading.Event()
1009
+ self._exitEvent = threading.Event()
1010
+ self._warmUpBarrier = None
1011
+ self._recordBarrier = None
1012
+
1013
+ def _assertMediaPlayer(self):
1014
+ """Assert that the media player thread is running.
1015
+ """
1016
+ return self._playerThread is not None
1017
+
1018
+ @staticmethod
1019
+ def getCameras(maxCameraEnum=16):
1020
+ """Get information about available cameras.
1021
+
1022
+ OpenCV is not capable of enumerating cameras and getting information
1023
+ about them. Therefore, we must open a stream with each camera index
1024
+ and query the information from the stream. This process is quite slow
1025
+ on systems with many cameras. It's best to run this function once and
1026
+ save the results for later use if the camera configuration is not
1027
+ expected to change.
1028
+
1029
+ Parameters
1030
+ ----------
1031
+ maxCameraEnum : int
1032
+ Maximum number of cameras to check. This is the maximum camera index
1033
+ to check. For example, if `maxCameraEnum` is 16, then cameras 0-15
1034
+ will be checked.
1035
+
1036
+ Returns
1037
+ -------
1038
+ dict
1039
+ Mapping containing information about each camera. The keys are the
1040
+ camera index, and the values are `CameraInfo` objects.
1041
+
1042
+ """
1043
+ import cv2
1044
+
1045
+ # recommended camera drivers for each platform
1046
+ cameraPlatformDrivers = {
1047
+ 'Linux': (cv2.CAP_V4L2, CAMERA_API_VIDEO4LINUX2),
1048
+ 'Windows': (cv2.CAP_DSHOW, CAMERA_API_DIRECTSHOW),
1049
+ 'Darwin': (cv2.CAP_AVFOUNDATION, CAMERA_API_AVFOUNDATION)
1050
+ }
1051
+
1052
+ # select the camera interface for the platform
1053
+ cameraDriver, cameraAPI = cameraPlatformDrivers.get(
1054
+ platform.system(), (cv2.CAP_ANY, CAMERA_API_ANY))
1055
+
1056
+ logging.info(
1057
+ 'Searching for connected cameras, this may take a while...')
1058
+
1059
+ cameras = {}
1060
+ for cameraIndex in range(maxCameraEnum):
1061
+ # open a camera
1062
+ thisCamera = cv2.VideoCapture(cameraIndex, cameraDriver)
1063
+
1064
+ # if the camera is not opened, we're done
1065
+ if not thisCamera.isOpened():
1066
+ break
1067
+
1068
+ # get information about camera capabilities
1069
+ frameRate = thisCamera.get(cv2.CAP_PROP_FPS)
1070
+ frameSize = (
1071
+ int(thisCamera.get(cv2.CAP_PROP_FRAME_WIDTH)),
1072
+ int(thisCamera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
1073
+
1074
+ genName = 'camera:{}'.format(cameraIndex)
1075
+ cameraInfo = CameraInfo(
1076
+ index=cameraIndex,
1077
+ name=genName,
1078
+ frameSize=frameSize or (-1, -1),
1079
+ frameRate=frameRate or -1.0,
1080
+ pixelFormat='bgr24', # always BGR with 8 bpc for OpenCV
1081
+ cameraLib=CameraInterfaceOpenCV._cameraLib,
1082
+ cameraAPI=cameraAPI
1083
+ )
1084
+
1085
+ cameras.update({genName: [cameraInfo]})
1086
+ thisCamera.release()
1087
+
1088
+ logging.info('Found {} cameras.'.format(len(cameras)))
1089
+
1090
+ return cameras
1091
+
1092
+ @property
1093
+ def framesWaiting(self):
1094
+ """Get the number of frames currently buffered (`int`).
1095
+
1096
+ Returns the number of frames which have been pulled from the stream and
1097
+ are waiting to be processed. This value is decremented by calls to
1098
+ `_enqueueFrame()`.
1099
+
1100
+ """
1101
+ return self._frameQueue.qsize()
1102
+
1103
+ @property
1104
+ def frameRate(self):
1105
+ """Get the frame rate of the camera stream (`float`).
1106
+ """
1107
+ if self._cameraInfo is None:
1108
+ return -1.0
1109
+
1110
+ return self._cameraInfo.frameRate
1111
+
1112
+ @property
1113
+ def frameSize(self):
1114
+ """Get the frame size of the camera stream (`tuple`).
1115
+ """
1116
+ if self._cameraInfo is None:
1117
+ return (-1, -1)
1118
+
1119
+ return self._cameraInfo.frameSize
1120
+
1121
+ def isOpen(self):
1122
+ """Check if the camera stream is open (`bool`).
1123
+ """
1124
+ if self._playerThread is not None:
1125
+ return self._playerThread.is_alive()
1126
+
1127
+ return False
1128
+
1129
+ def open(self):
1130
+ """Open the camera stream and start reading frames using OpenCV2.
1131
+ """
1132
+ import cv2
1133
+
1134
+ def _frameGetterAsync(videoCapture, frameQueue, exitEvent, recordEvent,
1135
+ warmUpBarrier, recordingBarrier, audioCapture):
1136
+ """Get frames asynchronously from the camera stream.
1137
+
1138
+ Parameters
1139
+ ----------
1140
+ videoCapture : cv2.VideoCapture
1141
+ Handle for the video capture object. This is opened outside the
1142
+ thread and passed in.
1143
+ frameQueue : queue.Queue
1144
+ Queue to store frames in.
1145
+ exitEvent : threading.Event
1146
+ Event to signal when the thread should stop.
1147
+ recordEvent : threading.Event
1148
+ Event used to signal the thread to pass frames along to the main
1149
+ thread.
1150
+ warmUpBarrier : threading.Barrier
1151
+ Barrier which is used hold until camera capture is ready.
1152
+ recordingBarrier : threading.Barrier
1153
+ Barrier which is used to synchronize audio and video recording.
1154
+ This ensures that the audio device is ready before buffering
1155
+ frames captured by the camera.
1156
+ audioCapture : psychopy.sound.Microphone or None
1157
+ Microphone object to use for audio capture. This will be used to
1158
+ synchronize the audio and video streams. If `None`, no audio
1159
+ will be captured.
1160
+
1161
+ """
1162
+ # poll interval is half the frame period, this makes sure we don't
1163
+ # miss frames while not wasting CPU cycles
1164
+ # fps = videoCapture.get(cv2.CAP_PROP_FPS)
1165
+ # if fps > 0.0:
1166
+ # pollInterval = (1.0 / fps) * 0.5
1167
+ # else:
1168
+ # pollInterval = 1 / 60.0
1169
+
1170
+ # if the camera is opened, wait until the main thread is ready to
1171
+ # take frames
1172
+ warmUpBarrier.wait()
1173
+
1174
+ # start capturing frames
1175
+ isRecording = False
1176
+ while not exitEvent.is_set():
1177
+ # Capture frame-by-frame
1178
+ ret, frame = videoCapture.read()
1179
+
1180
+ # if frame is read correctly ret is True
1181
+ if not ret: # eol or something else
1182
+ # val = 'eof'
1183
+ break
1184
+ else:
1185
+ # don't queue frames unless they are newer than the last
1186
+ if isRecording:
1187
+ # color conversion is done in the thread here
1188
+ colorData = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
1189
+ # colorData = frame
1190
+ frameQueue.put((colorData, 0.0, None))
1191
+
1192
+ # check if we should start or stop recording
1193
+ if recordEvent.is_set() and not isRecording:
1194
+ if audioCapture is not None:
1195
+ audioCapture.start(waitForStart=1)
1196
+ recordingBarrier.wait()
1197
+ isRecording = True
1198
+ elif not recordEvent.is_set() and isRecording:
1199
+ if audioCapture is not None:
1200
+ audioCapture.stop(blockUntilStopped=1)
1201
+ recordingBarrier.wait()
1202
+ isRecording = False
1203
+
1204
+ if not isRecording:
1205
+ # time.sleep(pollInterval)
1206
+ continue
1207
+
1208
+ if audioCapture is not None:
1209
+ if audioCapture.isRecording:
1210
+ audioCapture.poll()
1211
+
1212
+ # when everything done, release the capture device
1213
+ videoCapture.release()
1214
+
1215
+ if audioCapture is not None: # stop audio capture
1216
+ audioCapture.stop(blockUntilStopped=1)
1217
+
1218
+ # thread is dead if we get here
1219
+
1220
+ # barriers used for synchronizing
1221
+ parties = 2 # main + recording threads
1222
+ self._warmUpBarrier = threading.Barrier(parties) # camera is ready
1223
+ self._recordBarrier = threading.Barrier(parties) # audio/video is ready
1224
+
1225
+ # drivers for the given camera API
1226
+ cameraDrivers = {
1227
+ CAMERA_API_ANY: cv2.CAP_ANY,
1228
+ CAMERA_API_VIDEO4LINUX2: cv2.CAP_V4L2,
1229
+ CAMERA_API_DIRECTSHOW: cv2.CAP_DSHOW,
1230
+ CAMERA_API_AVFOUNDATION: cv2.CAP_AVFOUNDATION
1231
+ }
1232
+ _cameraInfo = self._cameraInfo
1233
+
1234
+ # create the camera capture object, we keep this internal to the thread
1235
+ # so that we can control when it is released
1236
+ cap = cv2.VideoCapture(
1237
+ _cameraInfo.index,
1238
+ cameraDrivers[_cameraInfo.cameraAPI])
1239
+
1240
+ # check if the camera is opened
1241
+ if not cap.isOpened():
1242
+ raise RuntimeError("Cannot open camera using `cv2`")
1243
+
1244
+ # if the user didn't specify a frame rate or size, use the defaults
1245
+ # pulled from the camera
1246
+ usingDefaults = False
1247
+ if _cameraInfo.frameRate is None:
1248
+ _cameraInfo.frameRate = cap.get(cv2.CAP_PROP_FPS)
1249
+ usingDefaults = True
1250
+
1251
+ if _cameraInfo.frameSize is None:
1252
+ _cameraInfo.frameSize = (
1253
+ int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
1254
+ int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
1255
+ usingDefaults = True
1256
+
1257
+ if not usingDefaults:
1258
+ # set frame rate and size and check if they were set correctly
1259
+ cap.set(cv2.CAP_PROP_FPS, _cameraInfo.frameRate)
1260
+ cap.set(cv2.CAP_PROP_FRAME_WIDTH, _cameraInfo.frameSize[0])
1261
+ cap.set(cv2.CAP_PROP_FRAME_HEIGHT, _cameraInfo.frameSize[1])
1262
+
1263
+ if cap.get(cv2.CAP_PROP_FPS) != _cameraInfo.frameRate:
1264
+ raise CameraFormatNotSupportedError(
1265
+ "Unsupported frame rate (%s), try %s instead." % (
1266
+ _cameraInfo.frameRate, cap.get(cv2.CAP_PROP_FPS)))
1267
+
1268
+ frameSizeMismatch = (
1269
+ cap.get(cv2.CAP_PROP_FRAME_WIDTH) != _cameraInfo.frameSize[0] or
1270
+ cap.get(cv2.CAP_PROP_FRAME_HEIGHT) != _cameraInfo.frameSize[1])
1271
+ if frameSizeMismatch:
1272
+ raise CameraFormatNotSupportedError(
1273
+ "Unsupported frame size: %s" % str(_cameraInfo.frameSize))
1274
+
1275
+ # open a stream and pause it until ready
1276
+ self._playerThread = threading.Thread(
1277
+ target=_frameGetterAsync,
1278
+ args=(cap,
1279
+ self._frameQueue,
1280
+ self._exitEvent,
1281
+ self._enableEvent,
1282
+ self._warmUpBarrier,
1283
+ self._recordBarrier,
1284
+ self._mic))
1285
+ self._playerThread.daemon=True
1286
+ self._playerThread.start()
1287
+
1288
+ self._warmUpBarrier.wait() # wait until the camera is ready
1289
+
1290
+ # pass off the player to the thread which will process the stream
1291
+ self._enqueueFrame() # pull metadata from first frame
1292
+
1293
+ def _enqueueFrame(self):
1294
+ """Grab the latest frame from the stream.
1295
+
1296
+ Returns
1297
+ -------
1298
+ bool
1299
+ `True` if a frame has been enqueued. Returns `False` if the camera
1300
+ has not acquired a new frame yet.
1301
+
1302
+ """
1303
+ self._assertMediaPlayer()
1304
+
1305
+ try:
1306
+ frameData = self._frameQueue.get_nowait()
1307
+ except queue.Empty:
1308
+ return False
1309
+
1310
+ frame, val, _ = frameData # update the frame
1311
+
1312
+ if val == 'eof': # handle end of stream
1313
+ return False
1314
+ elif val == 'paused': # handle when paused, not used for OpenCV yet
1315
+ return False
1316
+ elif frame is None: # handle when no frame is available
1317
+ return False
1318
+
1319
+ frameImage = frame # otherwise, unpack the frame
1320
+
1321
+ # if we have a new frame, update the frame information
1322
+ # videoBuffer = frameImage.to_bytearray()[0]
1323
+ videoFrameArray = np.ascontiguousarray(
1324
+ frameImage.flatten(), dtype=np.uint8)
1325
+
1326
+ # provide the last frame
1327
+ self._lastFrame = MovieFrame(
1328
+ frameIndex=self._frameIndex,
1329
+ absTime=0.0,
1330
+ # displayTime=self._recentMetadata['frame_size'],
1331
+ size=self._cameraInfo.frameSize,
1332
+ colorFormat='rgb24', # converted in thread
1333
+ colorData=videoFrameArray,
1334
+ audioChannels=0,
1335
+ audioSamples=None,
1336
+ metadata=None,
1337
+ movieLib=self._cameraLib,
1338
+ userData=None)
1339
+
1340
+ return True
1341
+
1342
+ def close(self):
1343
+ """Close the camera stream and release resources.
1344
+ """
1345
+ self._exitEvent.set() # signal the thread to stop
1346
+ self._playerThread.join() # hold the thread until it stops
1347
+
1348
+ self._playerThread = None
1349
+
1350
+ @property
1351
+ def isEnabled(self):
1352
+ """`True` if the camera is enabled.
1353
+ """
1354
+ return self._enableEvent.is_set()
1355
+
1356
+ def enable(self, state=True):
1357
+ """Start passing frames to the frame queue.
1358
+
1359
+ This method returns when the video and audio stream are both starting to
1360
+ record or stop recording. If no audio stream is being recorded, this
1361
+ method returns quicker.
1362
+
1363
+ Parameters
1364
+ ----------
1365
+ state : bool
1366
+ `True` to enable recording frames to the queue, `False` to disable.
1367
+ On state change, the audio interface will be started or stopped.
1368
+
1369
+ """
1370
+ if state:
1371
+ self._enableEvent.set()
1372
+ else:
1373
+ self._enableEvent.clear()
1374
+
1375
+ self._recordBarrier.wait()
1376
+ self._enqueueFrame()
1377
+
1378
+ def disable(self):
1379
+ """Stop passing frames to the frame queue.
1380
+
1381
+ Calling this is equivalent to calling `enable(False)`.
1382
+
1383
+ """
1384
+ self.enable(False)
1385
+
1386
+ def getFrames(self):
1387
+ """Get all frames from the camera stream which are waiting to be
1388
+ processed.
1389
+
1390
+ Returns
1391
+ -------
1392
+ list
1393
+ List of `MovieFrame` objects. The most recent frame is the last one
1394
+ in the list.
1395
+
1396
+ """
1397
+ self._assertMediaPlayer()
1398
+
1399
+ frames = []
1400
+ while self._enqueueFrame():
1401
+ frames.append(self._lastFrame)
1402
+
1403
+ return frames
1404
+
1405
+ def getRecentFrame(self):
1406
+ """Get the most recent frame captured from the camera, discarding all
1407
+ others.
1408
+
1409
+ Returns
1410
+ -------
1411
+ MovieFrame
1412
+ The most recent frame from the stream.
1413
+
1414
+ """
1415
+ while self._enqueueFrame():
1416
+ pass
1417
+
1418
+ return self._lastFrame
1419
+
1420
+
1421
+ # keep track of camera devices that are opened
1422
+ _openCameras = {}
1423
+
1424
+
1425
+ class Camera:
1426
+ """Class for displaying and recording video from a USB/PCI connected camera.
1427
+
1428
+ This class is capable of opening, recording, and saving camera video streams
1429
+ to disk. Camera stream reading/writing is done in a separate thread,
1430
+ allowing capture to occur in the background while the main thread is free to
1431
+ perform other tasks. This allows for capture to occur at higher frame rates
1432
+ than the display refresh rate. Audio recording is also supported if a
1433
+ microphone interface is provided, where recording will be synchronized with
1434
+ the video stream (as best as possible). Video and audio can be saved to disk
1435
+ either as a single file or as separate files.
1436
+
1437
+ GNU/Linux is supported only by the OpenCV backend (`cameraLib='opencv'`).
1438
+
1439
+ Parameters
1440
+ ----------
1441
+ device : str or int
1442
+ Camera to open a stream with. If the ID is not valid, an error will be
1443
+ raised when `open()` is called. Value can be a string or number. String
1444
+ values are platform-dependent: a DirectShow URI or camera name on
1445
+ Windows, or a camera name/index on MacOS. Specifying a number (>=0) is a
1446
+ platform-independent means of selecting a camera. PsychoPy enumerates
1447
+ possible camera devices and makes them selectable without explicitly
1448
+ having the name of the cameras attached to the system. Use caution when
1449
+ specifying an integer, as the same index may not reference the same
1450
+ camera every time.
1451
+ mic : :class:`~psychopy.sound.microphone.Microphone` or None
1452
+ Microphone to record audio samples from during recording. The microphone
1453
+ input device must not be in use when `record()` is called. The audio
1454
+ track will be merged with the video upon calling `save()`. Make sure
1455
+ that `Microphone.maxRecordingSize` is specified to a reasonable value to
1456
+ prevent the audio track from being truncated. Specifying a microphone
1457
+ adds some latency to starting and stopping camera recording due to the
1458
+ added overhead involved with synchronizing the audio and video streams.
1459
+ frameRate : int or None
1460
+ Frame rate to record the camera stream at. If `None`, the camera's
1461
+ default frame rate will be used.
1462
+ frameSize : tuple or None
1463
+ Size (width, height) of the camera stream frames to record. If `None`,
1464
+ the camera's default frame size will be used.
1465
+ cameraLib : str
1466
+ Interface library (backend) to use for accessing the camera. May either
1467
+ be `ffpyplayer` or `opencv`. If `None`, the default library for the
1468
+ recommended by the PsychoPy developers will be used. Switching camera
1469
+ libraries could help resolve issues with camera compatibility. More
1470
+ camera libraries may be installed via extension packages.
1471
+ bufferSecs : float
1472
+ Size of the real-time camera stream buffer specified in seconds (only
1473
+ valid on Windows and MacOS). This is not the same as the recording
1474
+ buffer size. This option might not be available for all camera
1475
+ libraries.
1476
+ win : :class:`~psychopy.visual.Window` or None
1477
+ Optional window associated with this camera. Some functionality may
1478
+ require an OpenGL context for presenting frames to the screen. If you
1479
+ are not planning to display the camera stream, this parameter can be
1480
+ safely ignored.
1481
+ name : str
1482
+ Label for the camera for logging purposes.
1483
+
1484
+ Examples
1485
+ --------
1486
+ Opening a camera stream and closing it::
1487
+
1488
+ camera = Camera(device=0)
1489
+ camera.open() # exception here on invalid camera
1490
+ camera.close()
1491
+
1492
+ Recording 5 seconds of video and saving it to disk::
1493
+
1494
+ cam = Camera(0)
1495
+ cam.open()
1496
+ cam.record() # starts recording
1497
+
1498
+ while cam.recordingTime < 5.0: # record for 5 seconds
1499
+ if event.getKeys('q'):
1500
+ break
1501
+ cam.update()
1502
+
1503
+ cam.stop() # stops recording
1504
+ cam.save('myVideo.mp4')
1505
+ cam.close()
1506
+
1507
+ Providing a microphone as follows enables audio recording::
1508
+
1509
+ mic = Microphone(0)
1510
+ cam = Camera(0, mic=mic)
1511
+
1512
+ Overriding the default frame rate and size (if `cameraLib` supports it)::
1513
+
1514
+ cam = Camera(0, frameRate=30, frameSize=(640, 480), cameraLib=u'opencv')
1515
+
1516
+ """
1517
+ def __init__(self, device=0, mic=None, cameraLib=u'ffpyplayer',
1518
+ frameRate=None, frameSize=None, bufferSecs=4, win=None,
1519
+ name='cam'):
1520
+ # add attributes for setters
1521
+ self.__dict__.update(
1522
+ {'_device': None,
1523
+ '_captureThread': None,
1524
+ '_mic': None,
1525
+ '_outFile': None,
1526
+ '_mode': u'video',
1527
+ '_frameRate': None,
1528
+ '_frameRateFrac': None,
1529
+ '_size': None,
1530
+ '_cameraLib': u''})
1531
+
1532
+ # ----------------------------------------------------------------------
1533
+ # Process camera settings
1534
+ #
1535
+
1536
+ # camera library in use
1537
+ self._cameraLib = cameraLib
1538
+
1539
+ if self._cameraLib == u'opencv':
1540
+ if device in (None, "None", "none", "Default", "default"):
1541
+ device = 0 # use the first enumerated camera
1542
+
1543
+ # handle all possible input for `frameRate` and `frameSize`
1544
+ if frameRate is None:
1545
+ pass # no change
1546
+ elif isinstance(frameRate, str):
1547
+ if frameRate in ("None", "none", "Default", "default"):
1548
+ frameRate = None
1549
+ elif frameRate.lower() == 'ntsc':
1550
+ frameRate = CAMERA_FRAMERATE_NTSC
1551
+ else:
1552
+ try: # try and convert to float
1553
+ frameRate = float(frameRate)
1554
+ except ValueError:
1555
+ raise ValueError(
1556
+ "`frameRate` must be a number, string or None")
1557
+
1558
+ # catch the value converted to float and process it
1559
+ if isinstance(frameRate, (int, float)):
1560
+ if frameRate <= 0:
1561
+ raise ValueError("`frameRate` must be a positive number")
1562
+
1563
+ if frameSize is None:
1564
+ pass # use the camera default
1565
+ elif isinstance(frameSize, str):
1566
+ if frameSize in ("None", "none", "Default", "default"):
1567
+ frameSize = None
1568
+ elif len(frameSize.split('x')) == 2:
1569
+ frameSize = tuple(map(int, frameSize.split('x')))
1570
+ elif frameSize.upper() in movietools.VIDEO_RESOLUTIONS.keys():
1571
+ frameSize = movietools.VIDEO_RESOLUTIONS[frameSize.upper()]
1572
+ else:
1573
+ raise ValueError("`frameSize` specified incorrectly")
1574
+ elif isinstance(frameSize, (tuple, list)):
1575
+ if len(frameSize) != 2:
1576
+ raise ValueError("`frameSize` must be a 2-tuple or 2-list")
1577
+ frameSize = tuple(map(int, frameSize))
1578
+ else:
1579
+ raise ValueError("`frameSize` specified incorrectly")
1580
+
1581
+ # recommended camera drivers for each platform
1582
+ cameraPlatformDrivers = {
1583
+ 'Linux': CAMERA_API_VIDEO4LINUX2,
1584
+ 'Windows': CAMERA_API_DIRECTSHOW,
1585
+ 'Darwin': CAMERA_API_AVFOUNDATION
1586
+ }
1587
+ # get the recommended camera driver for the current platform
1588
+ cameraAPI = cameraPlatformDrivers[platform.system()]
1589
+
1590
+ self._cameraInfo = CameraInfo(
1591
+ index=device,
1592
+ frameRate=frameRate, # dummy value
1593
+ frameSize=frameSize, # dummy value
1594
+ pixelFormat='bgr24',
1595
+ cameraLib=cameraLib,
1596
+ cameraAPI=cameraAPI)
1597
+
1598
+ self._device = self._cameraInfo.description()
1599
+
1600
+ elif self._cameraLib == u'ffpyplayer':
1601
+ supportedCameraSettings = CameraInterfaceFFmpeg.getCameras()
1602
+
1603
+ # create a mapping of supported camera formats
1604
+ _formatMapping = dict()
1605
+ for _, formats in supportedCameraSettings.items():
1606
+ for _format in formats:
1607
+ desc = _format.description()
1608
+ _formatMapping[desc] = _format
1609
+ # sort formats by resolution then frame rate
1610
+ orderedFormats = list(_formatMapping.values())
1611
+ orderedFormats.sort(key=lambda obj: obj.frameRate, reverse=True)
1612
+ orderedFormats.sort(key=lambda obj: np.prod(obj.frameSize),
1613
+ reverse=True)
1614
+
1615
+ # list of devices
1616
+ devList = list(_formatMapping)
1617
+
1618
+ if not devList: # no cameras found if list is empty
1619
+ raise CameraNotFoundError('No cameras found of the system!')
1620
+
1621
+ # Get best device
1622
+ bestDevice = _formatMapping[devList[-1]]
1623
+ for mode in orderedFormats:
1624
+ sameFrameRate = mode.frameRate == frameRate or frameRate is None
1625
+ sameFrameSize = mode.frameSize == frameSize or frameSize is None
1626
+ if sameFrameRate and sameFrameSize:
1627
+ bestDevice = mode
1628
+ break
1629
+
1630
+ # if given just device name, use frameRate and frameSize to match it
1631
+ # to a mode
1632
+ if device in supportedCameraSettings:
1633
+ match = None
1634
+ for mode in supportedCameraSettings[device]:
1635
+ sameFrameRate = \
1636
+ mode.frameRate == frameRate or frameRate is None
1637
+ sameFrameSize = \
1638
+ mode.frameSize == frameSize or frameSize is None
1639
+ if sameFrameRate and sameFrameSize:
1640
+ match = mode
1641
+ if match is not None:
1642
+ device = match
1643
+ else:
1644
+ # if no match found, find closest
1645
+ byWidth = sorted(
1646
+ supportedCameraSettings[device],
1647
+ key=lambda mode: abs(frameSize[0] - mode.frameSize[0])
1648
+ )
1649
+ byHeight = sorted(
1650
+ supportedCameraSettings[device],
1651
+ key=lambda mode: abs(frameSize[1] - mode.frameSize[1])
1652
+ )
1653
+ byFrameRate = sorted(
1654
+ supportedCameraSettings[device],
1655
+ key=lambda mode: abs(mode.frameRate)
1656
+ )
1657
+ deltas = [
1658
+ byWidth.index(mode) + byHeight.index(mode) + byFrameRate.index(mode)
1659
+ for mode in supportedCameraSettings[device]
1660
+ ]
1661
+ i = deltas.index(min(deltas))
1662
+ closest = supportedCameraSettings[device][i]
1663
+ # log warning that settings won't match requested
1664
+ logging.warn(_translate(
1665
+ "Device {device} does not support frame rate of "
1666
+ "{frameRate} and frame size of {frameSize}, using "
1667
+ "closest supported format: {desc}"
1668
+ ).format(device=device,
1669
+ frameRate=frameRate,
1670
+ frameSize=frameSize,
1671
+ desc=closest.description()))
1672
+ # use closest
1673
+ device = closest
1674
+
1675
+ # self._origDevSpecifier = device # what the user provided
1676
+ self._device = None # device identifier
1677
+
1678
+ # alias device None or Default as being device 0
1679
+ if device in (None, "None", "none", "Default", "default"):
1680
+ self._device = bestDevice.description()
1681
+ elif isinstance(device, CameraInfo):
1682
+ if self._cameraLib != device.cameraLib:
1683
+ raise CameraFormatNotSupportedError(
1684
+ 'Wrong configuration for camera library!')
1685
+ self._device = device.description()
1686
+ else:
1687
+ # resolve getting the camera identifier
1688
+ if isinstance(device, int): # get camera if integer
1689
+ try:
1690
+ self._device = devList[device]
1691
+ except IndexError:
1692
+ raise CameraNotFoundError(
1693
+ 'Cannot find camera at index={}'.format(device))
1694
+ elif isinstance(device, str):
1695
+ self._device = device
1696
+ else:
1697
+ raise TypeError(
1698
+ f"Incorrect type for `camera`, expected `int` or `str` but received {repr(device)}")
1699
+
1700
+ # get the camera information
1701
+ if self._device in _formatMapping:
1702
+ self._cameraInfo = _formatMapping[self._device]
1703
+ else:
1704
+ # raise error if couldn't find matching camera info
1705
+ raise CameraFormatNotSupportedError(
1706
+ f'Specified camera format {repr(self._device)} is not supported.')
1707
+
1708
+ # # operating mode
1709
+ # if mode not in (CAMERA_MODE_VIDEO, CAMERA_MODE_CV, CAMERA_MODE_PHOTO):
1710
+ # raise ValueError(
1711
+ # "Invalid value for parameter `mode`, expected one of `'video'` "
1712
+ # "`'cv'` or `'photo'`.")
1713
+ # self._mode = mode
1714
+
1715
+ _requestedMic = mic
1716
+ # if not given a Microphone or MicrophoneDevice, get it from DeviceManager
1717
+ if not isinstance(mic, (Microphone, MicrophoneDevice)):
1718
+ mic = DeviceManager.getDevice(mic)
1719
+ # if not known by name, try index
1720
+ if mic is None:
1721
+ mic = DeviceManager.getDeviceBy("index", mic, deviceClass="microphone")
1722
+ # if not known by name or index, raise error
1723
+ if mic is None:
1724
+ raise SystemError(f"Could not find microphone {_requestedMic}")
1725
+
1726
+ # current camera frame since the start of recording
1727
+ self._player = None # media player instance
1728
+ self._status = NOT_STARTED
1729
+ self._isRecording = False
1730
+ self._bufferSecs = float(bufferSecs)
1731
+ self._lastFrame = None # use None to avoid imports for ImageStim
1732
+
1733
+ # microphone instance, this is controlled by the camera interface and
1734
+ # is not meant to be used by the user
1735
+ self.mic = mic
1736
+ # other information
1737
+ self.name = name
1738
+ # timestamp data
1739
+ self._streamTime = 0.0
1740
+ # store win (unused but needs to be set/got safely for parity with JS)
1741
+ self.win = win
1742
+
1743
+ # movie writer instance, this runs in a separate thread
1744
+ self._movieWriter = None
1745
+ # if we begin receiving frames, change this flag to `True`
1746
+ self._captureThread = None
1747
+ # self._audioThread = None
1748
+ self._captureFrames = [] # array for storing frames
1749
+ # thread for polling the microphone
1750
+ self._audioTrack = None # audio track from the recent recording
1751
+ # used to sync threads spawned by this class, created on `open()`
1752
+ self._syncBarrier = None
1753
+ # keep track of the last video file saved
1754
+ self._lastVideoFile = None
1755
+
1756
+ def authorize(self):
1757
+ """Get permission to access the camera. Not implemented locally yet.
1758
+ """
1759
+ pass # NOP
1760
+
1761
+ @property
1762
+ def isReady(self):
1763
+ """Is the camera ready (`bool`)?
1764
+
1765
+ The camera is ready when the following conditions are met. First, we've
1766
+ created a player interface and opened it. Second, we have received
1767
+ metadata about the stream. At this point we can assume that the camera
1768
+ is 'hot' and the stream is being read.
1769
+
1770
+ This is a legacy property used to support older versions of PsychoPy.
1771
+ The `isOpened` property should be used instead.
1772
+
1773
+ """
1774
+ return self.isStarted
1775
+
1776
+ @property
1777
+ def frameSize(self):
1778
+ """Size of the video frame obtained from recent metadata (`float` or
1779
+ `None`).
1780
+
1781
+ Only valid after an `open()` and successive `_enqueueFrame()` call as
1782
+ metadata needs to be obtained from the stream. Returns `None` if not
1783
+ valid.
1784
+ """
1785
+ if self._cameraInfo is None:
1786
+ return None
1787
+
1788
+ return self._cameraInfo.frameSize
1789
+
1790
+ @property
1791
+ def frameRate(self):
1792
+ """Frame rate of the video stream (`float` or `None`).
1793
+
1794
+ Only valid after an `open()` and successive `_enqueueFrame()` call as
1795
+ metadata needs to be obtained from the stream. Returns `None` if not
1796
+ valid.
1797
+
1798
+ """
1799
+ if self._cameraInfo is None:
1800
+ return None
1801
+
1802
+ return self._cameraInfo.frameRate
1803
+
1804
+ def _assertCameraReady(self):
1805
+ """Assert that the camera is ready. Raises a `CameraNotReadyError` if
1806
+ the camera is not ready.
1807
+ """
1808
+ if not self.isReady:
1809
+ raise CameraNotReadyError("Camera is not ready.")
1810
+
1811
+ @property
1812
+ def isRecording(self):
1813
+ """`True` if the video is presently recording (`bool`)."""
1814
+ # Status flags as properties are pretty useful for users since they are
1815
+ # self documenting and prevent the user from touching the status flag
1816
+ # attribute directly.
1817
+ #
1818
+ return self._isRecording
1819
+
1820
+ @property
1821
+ def isStarted(self):
1822
+ """`True` if the stream has started (`bool`). This status is given after
1823
+ `open()` has been called on this object.
1824
+ """
1825
+ if self._captureThread is None:
1826
+ return False
1827
+
1828
+ return self._captureThread.isOpen()
1829
+
1830
+ @property
1831
+ def isNotStarted(self):
1832
+ """`True` if the stream may not have started yet (`bool`). This status
1833
+ is given before `open()` or after `close()` has been called on this
1834
+ object.
1835
+ """
1836
+ return not self.isStarted
1837
+
1838
+ @property
1839
+ def isStopped(self):
1840
+ """`True` if the recording has stopped (`bool`). This does not mean that
1841
+ the stream has stopped, `getVideoFrame()` will still yield frames until
1842
+ `close()` is called.
1843
+ """
1844
+ return not self._isRecording
1845
+
1846
+ @property
1847
+ def metadata(self):
1848
+ """Video metadata retrieved during the last frame update
1849
+ (`MovieMetadata`).
1850
+ """
1851
+ return self.getMetadata()
1852
+
1853
+ def getMetadata(self):
1854
+ """Get stream metadata.
1855
+
1856
+ Returns
1857
+ -------
1858
+ MovieMetadata
1859
+ Metadata about the video stream, retrieved during the last frame
1860
+ update (`_enqueueFrame` call).
1861
+
1862
+ """
1863
+ return self._recentMetadata
1864
+
1865
+ # @property
1866
+ # def mode(self):
1867
+ # """Operating mode in use for this camera.
1868
+ # """
1869
+ # return self._mode
1870
+
1871
+ _getCamerasCache = {}
1872
+
1873
+ @staticmethod
1874
+ def getCameras(cameraLib=None):
1875
+ """Get information about installed cameras on this system.
1876
+
1877
+ Returns
1878
+ -------
1879
+ dict
1880
+ Mapping of camera information objects.
1881
+
1882
+ """
1883
+ # not pluggable yet, needs to be made available via extensions
1884
+ if cameraLib == 'opencv':
1885
+ if 'opencv' not in Camera._getCamerasCache:
1886
+ Camera._getCamerasCache['opencv'] = \
1887
+ CameraInterfaceOpenCV.getCameras()
1888
+ return Camera._getCamerasCache['opencv']
1889
+ elif cameraLib == 'ffpyplayer':
1890
+ if 'ffpyplayer' not in Camera._getCamerasCache:
1891
+ Camera._getCamerasCache['ffpyplayer'] = \
1892
+ CameraInterfaceFFmpeg.getCameras()
1893
+ return Camera._getCamerasCache['ffpyplayer']
1894
+ else:
1895
+ raise ValueError("Invalid value for parameter `cameraLib`")
1896
+
1897
+ @staticmethod
1898
+ def getAvailableDevices():
1899
+ devices = []
1900
+ for dev in st.getCameras():
1901
+ for spec in dev:
1902
+ devices.append({
1903
+ 'device': spec['index'],
1904
+ 'frameRate': spec['frameRate'],
1905
+ 'frameSize': spec['frameSize'],
1906
+ })
1907
+
1908
+ return devices
1909
+
1910
+ @staticmethod
1911
+ def getCameraDescriptions(collapse=False):
1912
+ """Get a mapping or list of camera descriptions.
1913
+
1914
+ Camera descriptions are a compact way of representing camera settings
1915
+ and formats. Description strings can be used to specify which camera
1916
+ device and format to use with it to the `Camera` class.
1917
+
1918
+ Descriptions have the following format (example)::
1919
+
1920
+ '[Live! Cam Sync 1080p] 160x120@30fps, mjpeg'
1921
+
1922
+ This shows a specific camera format for the 'Live! Cam Sync 1080p'
1923
+ webcam which supports 160x120 frame size at 30 frames per second. The
1924
+ last value is the codec or pixel format used to decode the stream.
1925
+ Different pixel formats and codecs vary in performance.
1926
+
1927
+ Parameters
1928
+ ----------
1929
+ collapse : bool
1930
+ Return camera information as string descriptions instead of
1931
+ `CameraInfo` objects. This provides a more compact way of
1932
+ representing camera formats in a (reasonably) human-readable format.
1933
+
1934
+ Returns
1935
+ -------
1936
+ dict or list
1937
+ Mapping (`dict`) of camera descriptions, where keys are camera names
1938
+ (`str`) and values are a `list` of format description strings
1939
+ associated with the camera. If `collapse=True`, all descriptions
1940
+ will be returned in a single flat list. This might be more useful
1941
+ for specifying camera formats from a single GUI list control.
1942
+
1943
+ """
1944
+ return getCameraDescriptions(collapse=collapse)
1945
+
1946
+ @property
1947
+ def status(self):
1948
+ """Status flag for the camera (`int`).
1949
+
1950
+ Can be either `RECORDING`, `STOPPED`, `STOPPING`, or `NOT_STARTED`. This
1951
+ property used in Builder output scripts and does not update on its own.
1952
+
1953
+ """
1954
+ return self._status
1955
+
1956
+ @status.setter
1957
+ def status(self, value):
1958
+ self._status = value
1959
+
1960
+ @property
1961
+ def device(self):
1962
+ """Camera to use (`str` or `None`).
1963
+
1964
+ String specifying the name of the camera to open a stream with. This
1965
+ must be set prior to calling `start()`. If the name is not valid, an
1966
+ error will be raised when `start()` is called.
1967
+
1968
+ """
1969
+ return self._device
1970
+
1971
+ @device.setter
1972
+ def device(self, value):
1973
+ if value in (None, "None", "none", "Default", "default"):
1974
+ value = 0
1975
+
1976
+ self._device = value
1977
+
1978
+ @property
1979
+ def _hasPlayer(self):
1980
+ """`True` if we have an active media player instance.
1981
+ """
1982
+ # deprecated - remove in future versions and use `isStarted` instead
1983
+ return self.isStarted
1984
+
1985
+ @property
1986
+ def mic(self):
1987
+ """Microphone to record audio samples from during recording
1988
+ (:class:`~psychopy.sound.microphone.Microphone` or `None`).
1989
+
1990
+ If `None`, no audio will be recorded. Cannot be set after opening a
1991
+ camera stream.
1992
+ """
1993
+ return self._mic
1994
+
1995
+ @mic.setter
1996
+ def mic(self, value):
1997
+ if self.isStarted:
1998
+ raise CameraError("Cannot set microphone after starting camera.")
1999
+
2000
+ self._mic = value
2001
+
2002
+ @property
2003
+ def _hasAudio(self):
2004
+ """`True` if we have a microphone object for audio recording.
2005
+ """
2006
+ return self._mic is not None
2007
+
2008
+ @property
2009
+ def win(self):
2010
+ """Window which frames are being presented (`psychopy.visual.Window` or
2011
+ `None`).
2012
+ """
2013
+ return self._win
2014
+
2015
+ @win.setter
2016
+ def win(self, value):
2017
+ self._win = value
2018
+
2019
+ @property
2020
+ def frameCount(self):
2021
+ """Number of frames captured in the present recording (`int`).
2022
+ """
2023
+ if not self._isRecording:
2024
+ return 0
2025
+
2026
+ totalFramesBuffered = (
2027
+ len(self._captureFrames) + self._captureThread.framesWaiting)
2028
+
2029
+ return totalFramesBuffered
2030
+
2031
+ @property
2032
+ def streamTime(self):
2033
+ """Current stream time in seconds (`float`). This time increases
2034
+ monotonically from startup.
2035
+
2036
+ This is `-1.0` if there is no active stream running or if the backend
2037
+ does not support this feature.
2038
+
2039
+ """
2040
+ if self.isStarted and hasattr(self._captureThread, "streamTime"):
2041
+ return self._captureThread.streamTime
2042
+
2043
+ return -1.0
2044
+
2045
+ @property
2046
+ def recordingTime(self):
2047
+ """Current recording timestamp (`float`).
2048
+
2049
+ This returns the timestamp of the last frame captured in the recording.
2050
+
2051
+ This value increases monotonically from the last `record()` call. It
2052
+ will reset once `stop()` is called. This value is invalid outside
2053
+ `record()` and `stop()` calls.
2054
+
2055
+ """
2056
+ if not self._isRecording:
2057
+ return 0.0
2058
+
2059
+ frameInterval = 1.0 / float(self._captureThread.frameRate)
2060
+
2061
+ return self.frameCount * frameInterval
2062
+
2063
+ @property
2064
+ def recordingBytes(self):
2065
+ """Current size of the recording in bytes (`int`).
2066
+ """
2067
+ if not self._isRecording:
2068
+ return 0
2069
+
2070
+ return self._captureThread.recordingBytes
2071
+
2072
+ def _assertMediaPlayer(self):
2073
+ """Assert that we have a media player instance open.
2074
+
2075
+ This will raise a `RuntimeError` if there is no player open. Use this
2076
+ function to ensure that a player is present before running subsequent
2077
+ code.
2078
+ """
2079
+ if self._captureThread is not None:
2080
+ return
2081
+
2082
+ raise PlayerNotAvailableError('Media player not initialized.')
2083
+
2084
+ def _enqueueFrame(self):
2085
+ """Pull waiting frames from the capture thread.
2086
+
2087
+ This function will pull frames from the capture thread and add them to
2088
+ the buffer. The last frame in the buffer will be set as the most recent
2089
+ frame (`lastFrame`).
2090
+
2091
+ Returns
2092
+ -------
2093
+ bool
2094
+ `True` if a frame has been enqueued. Returns `False` if the camera
2095
+ is not ready or if the stream was closed.
2096
+
2097
+ """
2098
+ if self._captureThread is None:
2099
+ return False
2100
+
2101
+ newFrames = self._captureThread.getFrames()
2102
+ if not newFrames:
2103
+ return False
2104
+
2105
+ # add frames the the buffer
2106
+ self._captureFrames.extend(newFrames)
2107
+
2108
+ # set the last frame in the buffer as the most recent
2109
+ self._lastFrame = self._captureFrames[-1]
2110
+
2111
+ return True
2112
+
2113
+ def open(self):
2114
+ """Open the camera stream and begin decoding frames (if available).
2115
+
2116
+ This function returns when the camera is ready to start getting
2117
+ frames.
2118
+
2119
+ Call `record()` to start recording frames to memory. Captured frames
2120
+ came be saved to disk using `save()`.
2121
+
2122
+ """
2123
+ if self._hasPlayer:
2124
+ raise RuntimeError('Cannot open `MediaPlayer`, already opened.')
2125
+
2126
+ # Camera interface to use, these are hard coded but support for each is
2127
+ # provided by an extension.
2128
+ desc = self._cameraInfo.description()
2129
+ if self._cameraLib == u'ffpyplayer':
2130
+ logging.debug(
2131
+ "Opening camera stream using FFmpeg. (device={})".format(desc))
2132
+ self._captureThread = CameraInterfaceFFmpeg(
2133
+ device=self._cameraInfo,
2134
+ mic=self._mic)
2135
+ elif self._cameraLib == u'opencv':
2136
+ logging.debug(
2137
+ "Opening camera stream using OpenCV. (device={})".format(desc))
2138
+ self._captureThread = CameraInterfaceOpenCV(
2139
+ device=self._cameraInfo,
2140
+ mic=self._mic)
2141
+ else:
2142
+ raise ValueError(
2143
+ "Invalid value for parameter `cameraLib`, expected one of "
2144
+ "`'ffpyplayer'` or `'opencv'`.")
2145
+
2146
+ self._captureThread.open()
2147
+
2148
+ # def snapshot(self):
2149
+ # """Take a photo with the camera. The camera must be in `'photo'` mode
2150
+ # to use this method.
2151
+ # """
2152
+ # pass
2153
+
2154
+ def record(self):
2155
+ """Start recording frames.
2156
+
2157
+ This function will start recording frames and audio (if available). The
2158
+ value of `lastFrame` will be updated as new frames arrive and the
2159
+ `frameCount` will increase. You can access image data for the most
2160
+ recent frame to be captured using `lastFrame`.
2161
+
2162
+ If this is called before `open()` the camera stream will be opened
2163
+ automatically. This is not recommended as it may incur a longer than
2164
+ expected delay in the recording start time.
2165
+
2166
+ Warnings
2167
+ --------
2168
+ If a recording has been previously made without calling `save()` it will
2169
+ be discarded if `record()` is called again.
2170
+
2171
+ """
2172
+ if self.isNotStarted:
2173
+ self.open() # open the camera stream if we call record() first
2174
+ logging.warning(
2175
+ "Called `Camera.record()` before opening the camera stream, "
2176
+ "opening now. This is not recommended as it may incur a longer "
2177
+ "than expected delay in the recording start time."
2178
+ )
2179
+
2180
+ self._audioTrack = None
2181
+ self._lastFrame = None
2182
+
2183
+ # start recording audio if available
2184
+ if self._mic is not None:
2185
+ logging.debug(
2186
+ "Microphone interface available, starting audio recording.")
2187
+ else:
2188
+ logging.debug(
2189
+ "No microphone interface provided, not recording audio.")
2190
+
2191
+ self._captureThread.enable() # start passing frames to queue
2192
+ self._enqueueFrame()
2193
+
2194
+ self._isRecording = True
2195
+
2196
+ def stop(self):
2197
+ """Stop recording frames and audio (if available).
2198
+ """
2199
+ if not self._captureThread.isOpen():
2200
+ raise RuntimeError("Cannot stop recording, stream is not open.")
2201
+
2202
+ self._captureThread.disable() # stop passing frames to queue
2203
+ self._enqueueFrame()
2204
+
2205
+ # # stop audio recording if `mic` is available
2206
+ if self._mic is not None:
2207
+ self._audioTrack = self._mic.getRecording()
2208
+
2209
+ self._isRecording = False
2210
+
2211
+ def close(self):
2212
+ """Close the camera.
2213
+
2214
+ This will close the camera stream and free up any resources used by the
2215
+ device. If the camera is currently recording, this will stop the
2216
+ recording, but will not discard any frames. You may still call `save()`
2217
+ to save the frames to disk.
2218
+
2219
+ """
2220
+ if not self._captureThread.isOpen():
2221
+ raise RuntimeError("Cannot close stream, stream is not open.")
2222
+
2223
+ if self._isRecording:
2224
+ logging.warning(
2225
+ "Closing camera stream while recording, stopping recording "
2226
+ "first.")
2227
+ self.stop()
2228
+
2229
+ self._captureThread.close()
2230
+ self._captureThread = None
2231
+
2232
+ def save(self, filename, useThreads=True, mergeAudio=True,
2233
+ encoderLib=None, encoderOpts=None):
2234
+ """Save the last recording to file.
2235
+
2236
+ This will write frames to `filename` acquired since the last call of
2237
+ `record()` and subsequent `stop()`. If `record()` is called again before
2238
+ `save()`, the previous recording will be deleted and lost.
2239
+
2240
+ This is a slow operation and will block for some time depending on the
2241
+ length of the video. This can be sped up by setting `useThreads=True`.
2242
+
2243
+ Parameters
2244
+ ----------
2245
+ filename : str
2246
+ File to save the resulting video to, should include the extension.
2247
+ useThreads : bool
2248
+ Use threading where possible to speed up the saving process. If
2249
+ `True`, the video will be saved and composited in a separate thread
2250
+ and this function will return quickly. If `False`, the video will
2251
+ be saved and composited in the main thread and this function will
2252
+ block until the video is saved. Default is `True`.
2253
+ mergeAudio : bool
2254
+ Merge the audio track from the microphone with the video. If `True`,
2255
+ the audio track will be merged with the video. If `False`, the
2256
+ audio track will be saved to a separate file. Default is `True`.
2257
+ encoderLib : str or None
2258
+ Encoder library to use for saving the video. This can be either
2259
+ `'ffpyplayer'` or `'opencv'`. If `None`, the same library that was
2260
+ used to open the camera stream. Default is `None`.
2261
+ encoderOpts : dict
2262
+ Options to pass to the encoder. This is a dictionary of options
2263
+ specific to the encoder library being used. See the documentation
2264
+ for `~psychopy.tools.movietools.MovieFileWriter` for more details.
2265
+
2266
+ """
2267
+ if self._isRecording:
2268
+ raise RuntimeError(
2269
+ "Attempting to call `save()` before calling `stop()`.")
2270
+
2271
+ # check if a file exists at the given path, if so, delete it
2272
+ if os.path.exists(filename):
2273
+ msg = (
2274
+ "Video file '{}' already exists, overwriting.".format(filename))
2275
+ logging.warning(msg)
2276
+ os.remove(filename)
2277
+
2278
+ # determine if the `encoderLib` to use
2279
+ if encoderLib is None:
2280
+ encoderLib = self._cameraLib
2281
+
2282
+ logging.debug(
2283
+ "Using encoder library '{}' to save video.".format(encoderLib))
2284
+
2285
+ # check if the encoder library name string is valid
2286
+ if encoderLib not in ('ffpyplayer', 'opencv'):
2287
+ raise ValueError(
2288
+ "Invalid value for parameter `encoderLib`, expected one of "
2289
+ "`'ffpyplayer'` or `'opencv'`.")
2290
+
2291
+ # check if we have an audio track to save
2292
+ hasAudio = self._audioTrack is not None
2293
+
2294
+ # create a temporary file names for the video and audio
2295
+ if hasAudio:
2296
+ if mergeAudio:
2297
+ tempPrefix = (uuid.uuid4().hex)[:16] # 16 char prefix
2298
+ videoFileName = "{}_video.mp4".format(tempPrefix)
2299
+ audioFileName = "{}_audio.wav".format(tempPrefix)
2300
+ else:
2301
+ videoFileName = audioFileName = filename
2302
+ audioFileName += '.wav'
2303
+ else:
2304
+ videoFileName = filename
2305
+ audioFileName = None
2306
+
2307
+ # make sure filenames are absolute paths
2308
+ videoFileName = os.path.abspath(videoFileName)
2309
+ if audioFileName is not None:
2310
+ audioFileName = os.path.abspath(audioFileName)
2311
+
2312
+ # flush outstanding frames from the camera queue
2313
+ self._enqueueFrame()
2314
+
2315
+ # contain video and not audio
2316
+ logging.debug("Saving video to file: {}".format(videoFileName))
2317
+ self._movieWriter = movietools.MovieFileWriter(
2318
+ filename=videoFileName,
2319
+ size=self._cameraInfo.frameSize, # match camera params
2320
+ fps=self._cameraInfo.frameRate,
2321
+ codec=None, # mp4
2322
+ pixelFormat='rgb24',
2323
+ encoderLib=encoderLib,
2324
+ encoderOpts=encoderOpts)
2325
+ self._movieWriter.open() # blocks main thread until opened and ready
2326
+
2327
+ # flush remaining frames to the writer thread, this is really fast since
2328
+ # frames are not copied and don't require much conversion
2329
+ for frame in self._captureFrames:
2330
+ self._movieWriter.addFrame(frame.colorData)
2331
+
2332
+ # push all frames to the queue for the movie recorder
2333
+ self._movieWriter.close() # thread-safe call
2334
+ self._movieWriter = None
2335
+
2336
+ # save audio track if available
2337
+ if hasAudio:
2338
+ logging.debug(
2339
+ "Saving audio track to file: {}".format(audioFileName))
2340
+ self._audioTrack.save(audioFileName, 'wav')
2341
+
2342
+ # merge audio and video tracks
2343
+ if mergeAudio:
2344
+ logging.debug("Merging audio and video tracks.")
2345
+ movietools.addAudioToMovie(
2346
+ filename, # file after merging
2347
+ videoFileName,
2348
+ audioFileName,
2349
+ useThreads=useThreads,
2350
+ removeFiles=True) # disable threading for now
2351
+
2352
+ self._lastVideoFile = filename # remember the last video we saved
2353
+
2354
+ def _upload(self):
2355
+ """Upload video file to an online repository. Not implemented locally,
2356
+ needed for auto translate to JS.
2357
+ """
2358
+ pass # NOP
2359
+
2360
+ def _download(self):
2361
+ """Download video file to an online repository. Not implemented locally,
2362
+ needed for auto translate to JS.
2363
+ """
2364
+ pass # NOP
2365
+
2366
+ @property
2367
+ def lastClip(self):
2368
+ """File path to the last recording (`str` or `None`).
2369
+
2370
+ This value is only valid if a previous recording has been saved
2371
+ successfully (`save()` was called), otherwise it will be set to `None`.
2372
+
2373
+ """
2374
+ return self.getLastClip()
2375
+
2376
+ def getLastClip(self):
2377
+ """File path to the last saved recording.
2378
+
2379
+ This value is only valid if a previous recording has been saved to disk
2380
+ (`save()` was called).
2381
+
2382
+ Returns
2383
+ -------
2384
+ str or None
2385
+ Path to the file the most recent call to `save()` created. Returns
2386
+ `None` if no file is ready.
2387
+
2388
+ """
2389
+ return self._lastVideoFile
2390
+
2391
+ @property
2392
+ def lastFrame(self):
2393
+ """Most recent frame pulled from the camera (`VideoFrame`) since the
2394
+ last call of `getVideoFrame`.
2395
+ """
2396
+ return self._lastFrame
2397
+
2398
+ def update(self):
2399
+ """Acquire the newest data from the camera stream. If the `Camera`
2400
+ object is not being monitored by a `ImageStim`, this must be explicitly
2401
+ called.
2402
+ """
2403
+ self._assertMediaPlayer()
2404
+ self._enqueueFrame()
2405
+
2406
+ def getVideoFrame(self):
2407
+ """Pull the most recent frame from the stream (if available).
2408
+
2409
+ Returns
2410
+ -------
2411
+ MovieFrame
2412
+ Most recent video frame. Returns `NULL_MOVIE_FRAME_INFO` if no
2413
+ frame was available, or we timed out.
2414
+
2415
+ """
2416
+ self.update()
2417
+
2418
+ return self._lastFrame
2419
+
2420
+ def __del__(self):
2421
+ """Try to cleanly close the camera and output file.
2422
+ """
2423
+
2424
+ if hasattr(self, '_captureThread'):
2425
+ if self._captureThread is not None:
2426
+ try:
2427
+ self._captureThread.close()
2428
+ except AttributeError:
2429
+ pass
2430
+
2431
+ # close the microphone during teardown too
2432
+ if hasattr(self, '_mic'):
2433
+ if self._mic is not None:
2434
+ try:
2435
+ self._mic.close()
2436
+ except AttributeError:
2437
+ pass
2438
+
2439
+
2440
+ DeviceManager.registerClassAlias("camera", "psychopy.hardware.camera.Camera")
2441
+
2442
+
2443
+ # ------------------------------------------------------------------------------
2444
+ # Functions
2445
+ #
2446
+
2447
+ def _getCameraInfoMacOS():
2448
+ """Get a list of capabilities associated with a camera attached to the
2449
+ system.
2450
+
2451
+ This is used by `getCameraInfo()` for querying camera details on MacOS.
2452
+ Don't call this function directly unless testing.
2453
+
2454
+ Returns
2455
+ -------
2456
+ list of CameraInfo
2457
+ List of camera descriptors.
2458
+
2459
+ """
2460
+ if platform.system() != 'Darwin':
2461
+ raise OSError(
2462
+ "Cannot query cameras with this function, platform not 'Darwin'.")
2463
+
2464
+ # import objc # may be needed in the future for more advanced stuff
2465
+ import AVFoundation as avf # only works on MacOS
2466
+ import CoreMedia as cm
2467
+
2468
+ # get a list of capture devices
2469
+ allDevices = avf.AVCaptureDevice.devices()
2470
+
2471
+ # get video devices
2472
+ videoDevices = {}
2473
+ devIdx = 0
2474
+ for device in allDevices:
2475
+ devFormats = device.formats()
2476
+ if devFormats[0].mediaType() != 'vide': # not a video device
2477
+ continue
2478
+
2479
+ # camera details
2480
+ cameraName = device.localizedName()
2481
+
2482
+ # found video formats
2483
+ supportedFormats = []
2484
+ for _format in devFormats:
2485
+ # get the format description object
2486
+ formatDesc = _format.formatDescription()
2487
+
2488
+ # get dimensions in pixels of the video format
2489
+ dimensions = cm.CMVideoFormatDescriptionGetDimensions(formatDesc)
2490
+ frameHeight = dimensions.height
2491
+ frameWidth = dimensions.width
2492
+
2493
+ # Extract the codec in use, pretty useless since FFMPEG uses its
2494
+ # own conventions, we'll need to map these ourselves to those
2495
+ # values
2496
+ codecType = cm.CMFormatDescriptionGetMediaSubType(formatDesc)
2497
+
2498
+ # Convert codec code to a FourCC code using the following byte
2499
+ # operations.
2500
+ #
2501
+ # fourCC = ((codecCode >> 24) & 0xff,
2502
+ # (codecCode >> 16) & 0xff,
2503
+ # (codecCode >> 8) & 0xff,
2504
+ # codecCode & 0xff)
2505
+ #
2506
+ pixelFormat4CC = ''.join(
2507
+ [chr((codecType >> bits) & 0xff) for bits in (24, 16, 8, 0)])
2508
+
2509
+ # Get the range of supported framerate, use the largest since the
2510
+ # ranges are rarely variable within a format.
2511
+ frameRateRange = _format.videoSupportedFrameRateRanges()[0]
2512
+ frameRateMax = frameRateRange.maxFrameRate()
2513
+ # frameRateMin = frameRateRange.minFrameRate() # don't use for now
2514
+
2515
+ # Create a new camera descriptor
2516
+ thisCamInfo = CameraInfo(
2517
+ index=devIdx,
2518
+ name=cameraName,
2519
+ pixelFormat=pixelFormat4CC, # macs only use pixel format
2520
+ codecFormat=CAMERA_NULL_VALUE,
2521
+ frameSize=(int(frameWidth), int(frameHeight)),
2522
+ frameRate=frameRateMax,
2523
+ cameraAPI=CAMERA_API_AVFOUNDATION,
2524
+ cameraLib="ffpyplayer",
2525
+ )
2526
+
2527
+ supportedFormats.append(thisCamInfo)
2528
+
2529
+ devIdx += 1
2530
+
2531
+ # add to output dictionary
2532
+ videoDevices[cameraName] = supportedFormats
2533
+
2534
+ return videoDevices
2535
+
2536
+
2537
+ def _getCameraInfoWindows():
2538
+ """Get a list of capabilities for the specified associated with a camera
2539
+ attached to the system.
2540
+
2541
+ This is used by `getCameraInfo()` for querying camera details on Windows.
2542
+ Don't call this function directly unless testing.
2543
+
2544
+ Returns
2545
+ -------
2546
+ list of CameraInfo
2547
+ List of camera descriptors.
2548
+
2549
+ """
2550
+ if platform.system() != 'Windows':
2551
+ raise OSError(
2552
+ "Cannot query cameras with this function, platform not 'Windows'.")
2553
+
2554
+ # FFPyPlayer can query the OS via DirectShow for Windows cameras
2555
+ from ffpyplayer.tools import list_dshow_devices
2556
+ videoDevs, _, names = list_dshow_devices()
2557
+
2558
+ # get all the supported modes for the camera
2559
+ videoDevices = {}
2560
+
2561
+ # iterate over names
2562
+ devIndex = 0
2563
+ for devURI in videoDevs.keys():
2564
+ supportedFormats = []
2565
+ cameraName = names[devURI]
2566
+ for _format in videoDevs[devURI]:
2567
+ pixelFormat, codecFormat, frameSize, frameRateRng = _format
2568
+ _, frameRateMax = frameRateRng
2569
+ temp = CameraInfo(
2570
+ index=devIndex,
2571
+ name=cameraName,
2572
+ pixelFormat=pixelFormat,
2573
+ codecFormat=codecFormat,
2574
+ frameSize=frameSize,
2575
+ frameRate=frameRateMax,
2576
+ cameraAPI=CAMERA_API_DIRECTSHOW,
2577
+ cameraLib="ffpyplayer",
2578
+ )
2579
+ supportedFormats.append(temp)
2580
+ devIndex += 1
2581
+
2582
+ videoDevices[names[devURI]] = supportedFormats
2583
+
2584
+ return videoDevices
2585
+
2586
+
2587
+ # Mapping for platform specific camera getter functions used by `getCameras`.
2588
+ _cameraGetterFuncTbl = {
2589
+ 'Darwin': _getCameraInfoMacOS,
2590
+ 'Windows': _getCameraInfoWindows
2591
+ }
2592
+
2593
+
2594
+ def getCameras():
2595
+ """Get information about installed cameras and their formats on this system.
2596
+
2597
+ Use `getCameraDescriptions` to get a mapping or list of human-readable
2598
+ camera formats.
2599
+
2600
+ Returns
2601
+ -------
2602
+ dict
2603
+ Mapping where camera names (`str`) are keys and values are and array of
2604
+ `CameraInfo` objects.
2605
+
2606
+ """
2607
+ systemName = platform.system() # get the system name
2608
+
2609
+ # lookup the function for the given platform
2610
+ getCamerasFunc = _cameraGetterFuncTbl.get(systemName, None)
2611
+ if getCamerasFunc is None: # if unsupported
2612
+ raise OSError(
2613
+ "Cannot get cameras, unsupported platform '{}'.".format(
2614
+ systemName))
2615
+
2616
+ return getCamerasFunc()
2617
+
2618
+
2619
+ def getCameraDescriptions(collapse=False):
2620
+ """Get a mapping or list of camera descriptions.
2621
+
2622
+ Camera descriptions are a compact way of representing camera settings and
2623
+ formats. Description strings can be used to specify which camera device and
2624
+ format to use with it to the `Camera` class.
2625
+
2626
+ Descriptions have the following format (example)::
2627
+
2628
+ '[Live! Cam Sync 1080p] 160x120@30fps, mjpeg'
2629
+
2630
+ This shows a specific camera format for the 'Live! Cam Sync 1080p' webcam
2631
+ which supports 160x120 frame size at 30 frames per second. The last value
2632
+ is the codec or pixel format used to decode the stream. Different pixel
2633
+ formats and codecs vary in performance.
2634
+
2635
+ Parameters
2636
+ ----------
2637
+ collapse : bool
2638
+ Return camera information as string descriptions instead of `CameraInfo`
2639
+ objects. This provides a more compact way of representing camera formats
2640
+ in a (reasonably) human-readable format.
2641
+
2642
+ Returns
2643
+ -------
2644
+ dict or list
2645
+ Mapping (`dict`) of camera descriptions, where keys are camera names
2646
+ (`str`) and values are a `list` of format description strings associated
2647
+ with the camera. If `collapse=True`, all descriptions will be returned
2648
+ in a single flat list. This might be more useful for specifying camera
2649
+ formats from a single GUI list control.
2650
+
2651
+ """
2652
+ connectedCameras = getCameras()
2653
+
2654
+ cameraDescriptions = {}
2655
+ for devName, formats in connectedCameras.items():
2656
+ cameraDescriptions[devName] = [
2657
+ _format.description() for _format in formats]
2658
+
2659
+ if not collapse:
2660
+ return cameraDescriptions
2661
+
2662
+ # collapse to a list if requested
2663
+ collapsedList = []
2664
+ for _, formatDescs in cameraDescriptions.items():
2665
+ collapsedList.extend(formatDescs)
2666
+
2667
+ return collapsedList
2668
+
2669
+
2670
+ def getFormatsForDevice(device):
2671
+ """Get a list of formats available for the given device.
2672
+
2673
+ Parameters
2674
+ ----------
2675
+ device : str or int
2676
+ Name or index of the device
2677
+
2678
+ Returns
2679
+ -------
2680
+ list
2681
+ List of formats, specified as strings in the format
2682
+ `{width}x{height}@{frame rate}fps`
2683
+ """
2684
+ # get all devices
2685
+ connectedCameras = getCameras()
2686
+ # get formats for this device
2687
+ formats = connectedCameras.get(device, [])
2688
+ # sanitize
2689
+ formats = [f"{_format.frameSize[0]}x{_format.frameSize[1]}@{_format.frameRate}fps" for _format in formats]
2690
+
2691
+ return formats
2692
+
2693
+
2694
+ def getAllCameraInterfaces():
2695
+ """Get a list of all camera interfaces supported by the system.
2696
+
2697
+ Returns
2698
+ -------
2699
+ dict
2700
+ Mapping of camera interface class names and references to the class.
2701
+
2702
+ """
2703
+ # get all classes in this module
2704
+ classes = inspect.getmembers(sys.modules[__name__], inspect.isclass)
2705
+
2706
+ # filter for classes that are camera interfaces
2707
+ cameraInterfaces = {}
2708
+ for name, cls in classes:
2709
+ if issubclass(cls, CameraInterface):
2710
+ cameraInterfaces[name] = cls
2711
+
2712
+ return cameraInterfaces
2713
+
2714
+
2715
+ def getOpenCameras():
2716
+ """Get a list of all open cameras.
2717
+
2718
+ Returns
2719
+ -------
2720
+ list
2721
+ List of references to open camera objects.
2722
+
2723
+ """
2724
+ global _openCameras
2725
+
2726
+ return _openCameras.copy()
2727
+
2728
+
2729
+ def closeAllOpenCameras():
2730
+ """Close all open cameras.
2731
+
2732
+ This closes all open cameras and releases any resources associated with
2733
+ them. This should only be called before exiting the application or after you
2734
+ are done using the cameras.
2735
+
2736
+ This is automatically called when the application exits to cleanly free up
2737
+ resources, as it is registered with `atexit` when the module is imported.
2738
+
2739
+ Returns
2740
+ -------
2741
+ int
2742
+ Number of cameras closed. Useful for debugging to ensure all cameras
2743
+ were closed.
2744
+
2745
+ """
2746
+ global _openCameras
2747
+
2748
+ numCameras = len(_openCameras)
2749
+ for cam in _openCameras:
2750
+ cam.close()
2751
+
2752
+ _openCameras.clear()
2753
+
2754
+ return numCameras
2755
+
2756
+
2757
+ def renderVideo(outputFile, videoFile, audioFile=None, removeFiles=False):
2758
+ """Render a video.
2759
+
2760
+ Combine visual and audio streams into a single movie file. This is used
2761
+ mainly for compositing video and audio data for the camera. Video and audio
2762
+ should have roughly the same duration.
2763
+
2764
+ This is a legacy function used originally for compositing video and audio
2765
+ data from the camera. It is not used anymore internally, but is kept here
2766
+ for reference and may be removed in the future. If you need to composite
2767
+ video and audio data, use `movietools.addAudioToMovie` instead.
2768
+
2769
+ Parameters
2770
+ ----------
2771
+ outputFile : str
2772
+ Filename to write the movie to. Should have the extension of the file
2773
+ too.
2774
+ videoFile : str
2775
+ Video file path.
2776
+ audioFile : str or None
2777
+ Audio file path. If not provided the movie file will simply be copied
2778
+ to `outFile`.
2779
+ removeFiles : bool
2780
+ If `True`, the video (`videoFile`) and audio (`audioFile`) files will be
2781
+ deleted after the movie is rendered.
2782
+
2783
+ Returns
2784
+ -------
2785
+ int
2786
+ Size of the resulting file in bytes.
2787
+
2788
+ """
2789
+ # if no audio file, just copy the video file
2790
+ if audioFile is None:
2791
+ import shutil
2792
+ shutil.copyfile(videoFile, outputFile)
2793
+ if removeFiles:
2794
+ os.remove(videoFile) # delete the old movie file
2795
+ return os.path.getsize(outputFile)
2796
+
2797
+ # merge video and audio, now using the new `movietools` module
2798
+ movietools.addAudioToMovie(
2799
+ videoFile,
2800
+ audioFile,
2801
+ outputFile,
2802
+ useThreads=False, # didn't use this before
2803
+ removeFiles=removeFiles)
2804
+
2805
+ return os.path.getsize(outputFile)
2806
+
2807
+
2808
+ if __name__ == "__main__":
2809
+ pass