psychopy 2024.1.4__py3-none-any.whl → 2024.2.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 (325) hide show
  1. psychopy/.DS_Store +0 -0
  2. psychopy/CHANGELOG.txt +206 -0
  3. psychopy/GIT_SHA +1 -0
  4. psychopy/VERSION +1 -0
  5. psychopy/__init__.py +77 -15
  6. psychopy/app/Resources/classic/plugin16.png +0 -0
  7. psychopy/app/Resources/classic/plugin16@2x.png +0 -0
  8. psychopy/app/Resources/dark/plugin16.png +0 -0
  9. psychopy/app/Resources/dark/plugin16@2x.png +0 -0
  10. psychopy/app/Resources/light/plugin16.png +0 -0
  11. psychopy/app/Resources/light/plugin16@2x.png +0 -0
  12. psychopy/app/__init__.py +76 -2
  13. psychopy/app/_psychopyApp.py +126 -101
  14. psychopy/app/builder/builder.py +14 -10
  15. psychopy/app/builder/dialogs/__init__.py +8 -8
  16. psychopy/app/builder/dialogs/dlgsConditions.py +12 -13
  17. psychopy/app/builder/dialogs/paramCtrls.py +24 -57
  18. psychopy/app/builder/validators.py +2 -2
  19. psychopy/app/coder/codeEditorBase.py +8 -8
  20. psychopy/app/coder/coder.py +4 -4
  21. psychopy/app/connections/sendusage.py +2 -2
  22. psychopy/app/connections/updates.py +9 -9
  23. psychopy/app/dialogs.py +34 -2
  24. psychopy/app/idle.py +31 -0
  25. psychopy/app/jobs.py +21 -3
  26. psychopy/app/linuxconfig/__init__.py +9 -0
  27. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  28. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4602 -2540
  29. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  30. psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +56 -54
  31. psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +53 -43
  32. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  33. psychopy/app/locale/es_US/LC_MESSAGE/messages.po +56 -54
  34. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  35. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1011 -942
  36. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +9415 -5
  37. psychopy/app/pavlovia_ui/_base.py +33 -3
  38. psychopy/app/pavlovia_ui/search.py +0 -1
  39. psychopy/app/plugin_manager/dialog.py +104 -51
  40. psychopy/app/plugin_manager/packages.py +5 -0
  41. psychopy/app/plugin_manager/plugins.py +145 -67
  42. psychopy/app/preferencesDlg.py +8 -8
  43. psychopy/app/psychopyApp.py +11 -5
  44. psychopy/app/ribbon.py +124 -14
  45. psychopy/app/runner/runner.py +6 -1
  46. psychopy/app/stdout/stdOutRich.py +27 -11
  47. psychopy/app/themes/icons.py +52 -2
  48. psychopy/assets/__init__.py +0 -0
  49. psychopy/assets/click.png +0 -0
  50. psychopy/assets/clicknext.png +0 -0
  51. psychopy/assets/next.png +0 -0
  52. psychopy/assets/psychopy.ico +0 -0
  53. psychopy/assets/psychopy.png +0 -0
  54. psychopy/assets/templates/__init__.py +0 -0
  55. psychopy/assets/touch.png +0 -0
  56. psychopy/assets/touchnext.png +0 -0
  57. psychopy/assets/window.ico +0 -0
  58. psychopy/changes/2023.1.0.md +9 -0
  59. psychopy/changes/2024.1.0.md +16 -0
  60. psychopy/changes/__init__.py +0 -0
  61. psychopy/clock.py +2 -2
  62. psychopy/colors.py +2 -1
  63. psychopy/compatibility.py +53 -1
  64. psychopy/contrib/.DS_Store +0 -0
  65. psychopy/contrib/configobj/__init__.py +10 -8
  66. psychopy/data/__init__.py +3 -2
  67. psychopy/data/base.py +5 -5
  68. psychopy/data/experiment.py +130 -4
  69. psychopy/data/routine.py +56 -0
  70. psychopy/data/staircase.py +2 -2
  71. psychopy/data/trial.py +559 -97
  72. psychopy/data/utils.py +56 -21
  73. psychopy/demos/.DS_Store +0 -0
  74. psychopy/demos/builder/.DS_Store +0 -0
  75. psychopy/demos/builder/Design Templates/.DS_Store +0 -0
  76. psychopy/demos/builder/Experiments/.DS_Store +0 -0
  77. psychopy/demos/builder/Feature Demos/.DS_Store +0 -0
  78. psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +375 -0
  79. psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
  80. psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +433 -0
  81. psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
  82. psychopy/demos/builder/Hardware/.DS_Store +0 -0
  83. psychopy/demos/builder/Helper Tools/.DS_Store +0 -0
  84. psychopy/demos/coder/.DS_Store +0 -0
  85. psychopy/demos/coder/hardware/testSoundLatency.py +2 -2
  86. psychopy/demos/coder/iohub/.DS_Store +0 -0
  87. psychopy/demos/coder/misc/hdf5_2_csv +33 -0
  88. psychopy/event.py +30 -29
  89. psychopy/experiment/.DS_Store +0 -0
  90. psychopy/experiment/_experiment.py +6 -6
  91. psychopy/experiment/components/.DS_Store +0 -0
  92. psychopy/experiment/components/__init__.py +6 -3
  93. psychopy/experiment/components/_base.py +286 -131
  94. psychopy/experiment/components/aperture/.DS_Store +0 -0
  95. psychopy/experiment/components/brush/.DS_Store +0 -0
  96. psychopy/experiment/components/button/.DS_Store +0 -0
  97. psychopy/experiment/components/button/__init__.py +5 -1
  98. psychopy/experiment/components/buttonBox/.DS_Store +0 -0
  99. psychopy/experiment/components/camera/.DS_Store +0 -0
  100. psychopy/experiment/components/code/.DS_Store +0 -0
  101. psychopy/experiment/components/dots/.DS_Store +0 -0
  102. psychopy/experiment/components/eyetracker_record/.DS_Store +0 -0
  103. psychopy/experiment/components/eyetracker_record/__init__.py +92 -30
  104. psychopy/experiment/components/form/.DS_Store +0 -0
  105. psychopy/experiment/components/form/__init__.py +6 -2
  106. psychopy/experiment/components/grating/.DS_Store +0 -0
  107. psychopy/experiment/components/grating/__init__.py +14 -3
  108. psychopy/experiment/components/image/.DS_Store +0 -0
  109. psychopy/experiment/components/image/__init__.py +14 -3
  110. psychopy/experiment/components/joyButtons/.DS_Store +0 -0
  111. psychopy/experiment/components/joystick/.DS_Store +0 -0
  112. psychopy/experiment/components/keyboard/.DS_Store +0 -0
  113. psychopy/experiment/components/keyboard/__init__.py +22 -10
  114. psychopy/experiment/components/microphone/.DS_Store +0 -0
  115. psychopy/experiment/components/microphone/__init__.py +59 -39
  116. psychopy/experiment/components/mouse/.DS_Store +0 -0
  117. psychopy/experiment/components/mouse/__init__.py +44 -29
  118. psychopy/experiment/components/movie/.DS_Store +0 -0
  119. psychopy/experiment/components/movie/__init__.py +1 -1
  120. psychopy/experiment/components/panorama/.DS_Store +0 -0
  121. psychopy/experiment/components/parallelOut/.DS_Store +0 -0
  122. psychopy/experiment/components/patch/.DS_Store +0 -0
  123. psychopy/experiment/components/polygon/.DS_Store +0 -0
  124. psychopy/experiment/components/polygon/__init__.py +26 -6
  125. psychopy/experiment/components/progress/.DS_Store +0 -0
  126. psychopy/experiment/components/ratingScale/.DS_Store +0 -0
  127. psychopy/experiment/components/resourceManager/.DS_Store +0 -0
  128. psychopy/experiment/components/roi/.DS_Store +0 -0
  129. psychopy/experiment/components/roi/__init__.py +5 -0
  130. psychopy/experiment/components/routineSettings/.DS_Store +0 -0
  131. psychopy/experiment/components/routineSettings/__init__.py +57 -10
  132. psychopy/experiment/components/serialOut/.DS_Store +0 -0
  133. psychopy/experiment/components/settings/.DS_Store +0 -0
  134. psychopy/experiment/components/settings/__init__.py +117 -42
  135. psychopy/experiment/components/slider/.DS_Store +0 -0
  136. psychopy/experiment/components/sound/.DS_Store +0 -0
  137. psychopy/experiment/components/sound/__init__.py +54 -19
  138. psychopy/experiment/components/static/.DS_Store +0 -0
  139. psychopy/experiment/components/static/__init__.py +1 -1
  140. psychopy/experiment/components/text/.DS_Store +0 -0
  141. psychopy/experiment/components/text/__init__.py +28 -3
  142. psychopy/experiment/components/textbox/.DS_Store +0 -0
  143. psychopy/experiment/components/textbox/__init__.py +12 -2
  144. psychopy/experiment/components/unknown/.DS_Store +0 -0
  145. psychopy/experiment/components/unknown/__init__.py +1 -2
  146. psychopy/experiment/components/unknownPlugin/.DS_Store +0 -0
  147. psychopy/experiment/components/unknownPlugin/__init__.py +2 -2
  148. psychopy/experiment/components/variable/.DS_Store +0 -0
  149. psychopy/experiment/flow.py +11 -4
  150. psychopy/experiment/loops.py +85 -37
  151. psychopy/experiment/params.py +74 -32
  152. psychopy/experiment/py2js_transpiler.py +8 -1
  153. psychopy/experiment/routines/.DS_Store +0 -0
  154. psychopy/experiment/routines/_base.py +102 -22
  155. psychopy/experiment/routines/counterbalance/.DS_Store +0 -0
  156. psychopy/experiment/routines/counterbalance/__init__.py +5 -1
  157. psychopy/experiment/routines/eyetracker_calibrate/.DS_Store +0 -0
  158. psychopy/experiment/routines/eyetracker_validate/.DS_Store +0 -0
  159. psychopy/experiment/routines/pavlovia_survey/.DS_Store +0 -0
  160. psychopy/experiment/routines/photodiodeValidator/.DS_Store +0 -0
  161. psychopy/experiment/routines/photodiodeValidator/__init__.py +6 -5
  162. psychopy/experiment/routines/unknown/.DS_Store +0 -0
  163. psychopy/gui/wxgui.py +4 -4
  164. psychopy/hardware/.DS_Store +0 -0
  165. psychopy/hardware/__init__.py +1 -1
  166. psychopy/hardware/base.py +12 -0
  167. psychopy/hardware/camera/__init__.py +1 -15
  168. psychopy/hardware/cedrus.py +10 -11
  169. psychopy/hardware/crs/colorcal.py +13 -22
  170. psychopy/hardware/crs/optical.py +10 -20
  171. psychopy/hardware/emulator.py +17 -14
  172. psychopy/hardware/eyetracker.py +42 -118
  173. psychopy/hardware/gammasci.py +4 -15
  174. psychopy/hardware/keyboard.py +102 -10
  175. psychopy/hardware/listener.py +3 -0
  176. psychopy/hardware/microphone.py +148 -18
  177. psychopy/hardware/minolta.py +8 -15
  178. psychopy/hardware/photodiode.py +191 -16
  179. psychopy/hardware/photometer/__init__.py +11 -19
  180. psychopy/hardware/pr.py +8 -15
  181. psychopy/hardware/speaker.py +39 -4
  182. psychopy/info.py +0 -71
  183. psychopy/iohub/.DS_Store +0 -0
  184. psychopy/iohub/__init__.py +1 -1
  185. psychopy/iohub/client/__init__.py +30 -20
  186. psychopy/iohub/client/keyboard.py +24 -24
  187. psychopy/iohub/datastore/__init__.py +2 -2
  188. psychopy/iohub/datastore/util.py +2 -2
  189. psychopy/iohub/default_config.yaml +1 -1
  190. psychopy/iohub/devices/.DS_Store +0 -0
  191. psychopy/iohub/devices/__init__.py +112 -25
  192. psychopy/iohub/devices/deviceConfigValidation.py +2 -1
  193. psychopy/iohub/devices/experiment/default_experiment.yaml +12 -1
  194. psychopy/iohub/devices/experiment/supported_config_settings.yaml +5 -1
  195. psychopy/iohub/devices/eyetracker/.DS_Store +0 -0
  196. psychopy/iohub/devices/eyetracker/__init__.py +46 -0
  197. psychopy/iohub/devices/eyetracker/calibration/procedure.py +2 -2
  198. psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +14 -2
  199. psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +3 -4
  200. psychopy/iohub/server.py +2 -2
  201. psychopy/iohub/start_iohub_process.py +3 -0
  202. psychopy/iohub/util/__init__.py +62 -70
  203. psychopy/layout.py +5 -5
  204. psychopy/logging.py +8 -1
  205. psychopy/microphone.py +10 -37
  206. psychopy/platform_specific/__init__.py +0 -2
  207. psychopy/platform_specific/darwin.py +1 -3
  208. psychopy/platform_specific/linux.py +31 -33
  209. psychopy/platform_specific/win32.py +38 -13
  210. psychopy/plugins/__init__.py +148 -116
  211. psychopy/plugins/util.py +39 -0
  212. psychopy/preferences/Darwin.spec +4 -2
  213. psychopy/preferences/FreeBSD.spec +4 -2
  214. psychopy/preferences/Linux.spec +4 -2
  215. psychopy/preferences/Windows.spec +4 -2
  216. psychopy/preferences/baseNoArch.spec +4 -2
  217. psychopy/preferences/preferences.py +47 -24
  218. psychopy/projects/pavlovia.py +47 -4
  219. psychopy/scripts/psyexpCompile.py +0 -4
  220. psychopy/session.py +153 -21
  221. psychopy/sound/__init__.py +31 -21
  222. psychopy/sound/_base.py +20 -3
  223. psychopy/sound/audioclip.py +320 -33
  224. psychopy/sound/backend_ptb.py +47 -58
  225. psychopy/sound/backend_pygame.py +1 -1
  226. psychopy/sound/backend_pysound.py +6 -15
  227. psychopy/sound/transcribe.py +53 -0
  228. psychopy/tests/.DS_Store +0 -0
  229. psychopy/tests/data/.DS_Store +0 -0
  230. psychopy/tests/data/TestUnknownPluginComponent_load_resave.psyexp +135 -0
  231. psychopy/tests/data/Test_textbox/test_ori_0_bottom right.png +0 -0
  232. psychopy/tests/data/Test_textbox/test_ori_0_center.png +0 -0
  233. psychopy/tests/data/Test_textbox/test_ori_0_top left.png +0 -0
  234. psychopy/tests/data/Test_textbox/test_ori_120_bottom right.png +0 -0
  235. psychopy/tests/data/Test_textbox/test_ori_120_center.png +0 -0
  236. psychopy/tests/data/Test_textbox/test_ori_120_top left.png +0 -0
  237. psychopy/tests/data/Test_textbox/test_ori_180_bottom right.png +0 -0
  238. psychopy/tests/data/Test_textbox/test_ori_180_center.png +0 -0
  239. psychopy/tests/data/Test_textbox/test_ori_180_top left.png +0 -0
  240. psychopy/tests/data/Test_textbox/test_ori_240_bottom right.png +0 -0
  241. psychopy/tests/data/Test_textbox/test_ori_240_center.png +0 -0
  242. psychopy/tests/data/Test_textbox/test_ori_240_top left.png +0 -0
  243. psychopy/tests/data/correctScript/.DS_Store +0 -0
  244. psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
  245. psychopy/tests/data/test_session/.DS_Store +0 -0
  246. psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
  247. psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
  248. psychopy/tests/test_app/.DS_Store +0 -0
  249. psychopy/tests/test_app/conftest.py +2 -2
  250. psychopy/tests/test_app/test_speed.py +4 -1
  251. psychopy/tests/test_data/test_TrialHandler2.py +146 -1
  252. psychopy/tests/test_experiment/.DS_Store +0 -0
  253. psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +3 -3
  254. psychopy/tests/test_experiment/needs_wx/test_components.py +2 -2
  255. psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
  256. psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
  257. psychopy/tests/test_experiment/test_components/test_base_components.py +58 -0
  258. psychopy/tests/test_experiment/test_py2js.py +1 -1
  259. psychopy/tests/test_hardware/test_keyboard.py +31 -0
  260. psychopy/tests/test_hardware/test_ports.py +1 -11
  261. psychopy/tests/test_liaison/test_Liaison.py +47 -0
  262. psychopy/tests/test_misc/test_core.py +5 -0
  263. psychopy/tests/test_session/test_Session.py +5 -1
  264. psychopy/tests/test_tools/test_versionchooser.py +39 -8
  265. psychopy/tests/test_visual/test_all_stimuli.py +0 -97
  266. psychopy/tests/test_visual/test_image.py +6 -5
  267. psychopy/tests/test_visual/test_textbox.py +36 -0
  268. psychopy/tests/utils.py +4 -0
  269. psychopy/tools/filetools.py +1 -1
  270. psychopy/tools/pkgtools.py +160 -137
  271. psychopy/tools/versionchooser.py +10 -10
  272. psychopy/tools/wizard.py +3 -3
  273. psychopy/visual/.DS_Store +0 -0
  274. psychopy/visual/backends/pygletbackend.py +24 -13
  275. psychopy/visual/basevisual.py +5 -11
  276. psychopy/visual/button.py +2 -14
  277. psychopy/visual/helpers.py +5 -5
  278. psychopy/visual/line.py +1 -2
  279. psychopy/visual/movie2.py +7 -816
  280. psychopy/visual/movie3.py +7 -589
  281. psychopy/visual/movies/__init__.py +8 -11
  282. psychopy/visual/movies/frame.py +5 -2
  283. psychopy/visual/movies/players/ffpyplayer_player.py +5 -2
  284. psychopy/visual/noise.py +8 -7
  285. psychopy/visual/patch.py +7 -16
  286. psychopy/visual/radial.py +9 -7
  287. psychopy/visual/ratingscale.py +8 -1415
  288. psychopy/visual/secondorder.py +10 -9
  289. psychopy/visual/shape.py +7 -2
  290. psychopy/visual/text.py +1 -1
  291. psychopy/visual/textbox2/textbox2.py +28 -5
  292. {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/METADATA +8 -13
  293. {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/RECORD +307 -213
  294. {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/WHEEL +1 -1
  295. psychopy/app/Resources/click.png +0 -0
  296. psychopy/app/Resources/next.png +0 -0
  297. psychopy/experiment/components/patch/__init__.py +0 -121
  298. psychopy/experiment/components/patch/classic/patch.png +0 -0
  299. psychopy/experiment/components/patch/dark/patch.png +0 -0
  300. psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
  301. psychopy/experiment/components/patch/light/patch.png +0 -0
  302. psychopy/experiment/components/patch/light/patch@2x.png +0 -0
  303. psychopy/experiment/components/ratingScale/__init__.py +0 -337
  304. psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
  305. psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
  306. psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
  307. psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
  308. psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
  309. psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
  310. psychopy/platform_specific/posix.py +0 -16
  311. psychopy/tests/test_sound/test_microphone.py +0 -217
  312. psychopy/tests/test_visual/test_ratingScale.py +0 -299
  313. /psychopy/{app/Resources → assets}/Psychopy Window Favicon@16w.png +0 -0
  314. /psychopy/{app/Resources → assets}/Psychopy Window Favicon@32w.png +0 -0
  315. /psychopy/{app/Resources → assets}/USB-C.png +0 -0
  316. /psychopy/{app/Resources → assets}/USB.png +0 -0
  317. /psychopy/{app/Resources → assets}/creditCard.png +0 -0
  318. /psychopy/{app/Resources → assets}/default.mp3 +0 -0
  319. /psychopy/{app/Resources → assets}/default.mp4 +0 -0
  320. /psychopy/{app/Resources → assets}/default.png +0 -0
  321. /psychopy/{app/Resources → assets/templates}/instruct1.png +0 -0
  322. /psychopy/{app/Resources → assets/templates}/instruct2.png +0 -0
  323. {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/entry_points.txt +0 -0
  324. {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/AUTHORS.md +0 -0
  325. {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,217 +0,0 @@
1
- import pytest
2
- import shutil, os, glob
3
- from tempfile import mkdtemp
4
- from os.path import join
5
- from psychopy import microphone
6
- from psychopy.microphone import _getFlacPath
7
- from psychopy import core
8
-
9
- from psychopy.tests import skip_under_vm
10
-
11
- # py.test -k microphone --cov-report term-missing --cov microphone.py tests/
12
-
13
- # flac2wav will delete the .flac file unless given keep=True
14
- # Speech2Text can overwrite and then delete .flac if given a .wav of the same name
15
-
16
- from psychopy.tests.utils import TESTS_DATA_PATH
17
-
18
- @pytest.mark.needs_sound
19
- @pytest.mark.microphone
20
- @pytest.mark.slow
21
- @skip_under_vm
22
- class TestMicrophone:
23
- @classmethod
24
- def setup_class(self):
25
- global sound
26
- from psychopy import sound
27
- microphone.switchOn(48000)
28
- self.tmp = mkdtemp(prefix='psychopy-tests-microphone')
29
-
30
- @classmethod
31
- def teardown_class(self):
32
- if hasattr(self, 'tmp'):
33
- shutil.rmtree(self.tmp, ignore_errors=True)
34
- microphone.switchOff() # not needed, just get code coverage
35
-
36
- def test_AudioCapture_basics(self):
37
- microphone.haveMic = False
38
- with pytest.raises(microphone.MicrophoneError):
39
- microphone.AdvAudioCapture(autoLog=False)
40
- microphone.haveMic = True
41
-
42
- microphone.switchOn(16000, 1, 2048)
43
- microphone.switchOn(48000)
44
-
45
- mic = microphone.AdvAudioCapture(saveDir=self.tmp, autoLog=False)
46
- mic = microphone.AdvAudioCapture(saveDir=self.tmp+'_test', autoLog=False)
47
- mic.record(.10, block=False) # returns immediately
48
- core.wait(.02)
49
- mic.stop()
50
- mic.reset()
51
-
52
- mic.record(0.2, block=True)
53
- assert os.path.isfile(mic.savedFile)
54
-
55
- def test_AdvAudioCapture(self):
56
- filename = os.path.join(self.tmp, 'test_mic.wav')
57
- mic = microphone.AdvAudioCapture(autoLog=False)
58
- tone = sound.Sound(440, secs=.02, autoLog=False)
59
- mic.setMarker(tone=tone)
60
- mic = microphone.AdvAudioCapture(filename=filename, saveDir=self.tmp, autoLog=False)
61
-
62
- mic.record(1, block=True)
63
- mic.setFile(mic.savedFile) # same file name
64
- mic.getMarkerOnset()
65
-
66
- mic.compress()
67
- assert os.path.exists(mic.savedFile)
68
- assert mic.savedFile.endswith('.flac')
69
-
70
- mic.uncompress()
71
- assert mic.savedFile.endswith('.wav')
72
- assert os.path.exists(mic.savedFile)
73
-
74
- old_size = os.path.getsize(mic.savedFile)
75
- new_file = mic.resample(keep=False)
76
- assert (old_size / 3.1) < os.path.getsize(new_file) < (old_size / 2.9)
77
- mic.getLoudness()
78
-
79
- mic.playback()
80
- mic.playback(loops=2, block=False)
81
- mic.playback(stop=True)
82
-
83
- tmp = mic.savedFile
84
- mic.savedFile = None
85
- with pytest.raises(ValueError):
86
- mic.playback()
87
- with pytest.raises(ValueError):
88
- mic.getLoudness()
89
- mic.savedFile = tmp
90
-
91
- mic.resample(keep=False)
92
- mic.resample(newRate=48000, keep=False)
93
- tmp = mic.savedFile
94
- mic.savedFile = None
95
- with pytest.raises(ValueError):
96
- mic.resample(keep=False)
97
- mic.savedFile = tmp
98
- with pytest.raises(ValueError):
99
- mic.resample(newRate=-1)
100
-
101
- #@pytest.mark.needs_sound
102
- @pytest.mark.microphone
103
- @pytest.mark.speech
104
- @pytest.mark.mic_utils
105
- class TestMicrophoneNoSound():
106
- @classmethod
107
- def setup_class(self):
108
- try:
109
- assert _getFlacPath()
110
- except Exception:
111
- # some of the utils could be designed not to need flac but they
112
- # currently work on a file that is distributed in flac format
113
- pytest.skip()
114
- self.tmp = mkdtemp(prefix='psychopy-tests-microphone')
115
- for testFile in ['red_16000.flac.dist', 'green_48000.flac.dist']:
116
- t = join(TESTS_DATA_PATH, testFile)
117
- new_wav = join(self.tmp, testFile.replace('.dist', ''))
118
- shutil.copyfile(t, new_wav)
119
- microphone.flac2wav(new_wav)
120
- @classmethod
121
- def teardown_class(self):
122
- if hasattr(self, 'tmp'):
123
- shutil.rmtree(self.tmp, ignore_errors=True)
124
-
125
- # def test_getFlacPath(self):
126
- # microphone.FLAC_PATH = None
127
- # with pytest.raises(microphone.MicrophoneError):
128
- # _getFlacPath('this is not the flac you are looking for')
129
- #
130
- # microphone.FLAC_PATH = None
131
- # _getFlacPath('flac')
132
- #
133
- # microphone.FLAC_PATH = 'flac'
134
- # assert microphone.FLAC_PATH
135
- #
136
- # microphone.FLAC_PATH = None
137
- # _getFlacPath()
138
-
139
- def test_wav_flac(self):
140
- filename = os.path.join(self.tmp, 'test_bad_readWav')
141
- with open(filename, 'wb') as fd:
142
- fd.write(b'x')
143
- with pytest.raises(microphone.SoundFileError):
144
- microphone.readWavFile(filename)
145
-
146
- testFile = join(self.tmp, 'green_48000.wav')
147
- newFile = microphone.wav2flac(testFile, keep=True)
148
- microphone.flac2wav(newFile, keep=True)
149
-
150
- newFile0 = microphone.wav2flac(testFile, keep=True, level=0)
151
- newFile8 = microphone.wav2flac(testFile, keep=True, level=8)
152
- assert os.path.getsize(newFile0) >= os.path.getsize(newFile8)
153
-
154
- microphone.wav2flac('../test_misc', keep=True)
155
- microphone.flac2wav('../test_misc', keep=True)
156
- microphone.wav2flac('', keep=True)
157
- microphone.flac2wav('', keep=True)
158
-
159
- microphone.wav2flac(self.tmp, keep=True)
160
-
161
- def test_Speech2Text(self):
162
- pytest.skip() # google speech API gives Error 400: Bad request
163
- from psychopy import web
164
- try:
165
- web.requireInternetAccess()
166
- except web.NoInternetAccessError:
167
- pytest.skip()
168
-
169
- # load a known sound file
170
- testFile = join(self.tmp, 'red_16000.wav')
171
-
172
- gs = microphone.Speech2Text(filename=testFile)
173
- resp = gs.getResponse()
174
- assert resp.word == 'red'
175
-
176
- # test batch-discover files in a directory
177
- tmp = join(self.tmp, 'tmp')
178
- os.mkdir(tmp)
179
- shutil.copy(testFile, tmp)
180
- bs = microphone.BatchSpeech2Text(files=tmp)
181
-
182
- bs = microphone.BatchSpeech2Text(files=glob.glob(join(self.tmp, 'red_*.wav')))
183
- while bs._activeCount():
184
- core.wait(.1, 0)
185
- resp = bs[0][1]
186
- assert 0.6 < resp.confidence < 0.75 # 0.68801856
187
- assert resp.word == 'red'
188
-
189
- def test_DFT(self):
190
- testFile = join(self.tmp, 'red_16000.wav')
191
- data, sampleRate = microphone.readWavFile(testFile)
192
-
193
- with pytest.raises(OverflowError):
194
- microphone.getDft([])
195
- microphone.getDft(data)
196
- microphone.getDftBins(data)
197
- microphone.getDftBins(data, sampleRate=16000)
198
- microphone.getDft(data, sampleRate=sampleRate)
199
- microphone.getDft(data, wantPhase=True)
200
-
201
- def test_RMS(self):
202
- testFile = join(self.tmp, 'red_16000.wav')
203
- data, sampleRate = microphone.readWavFile(testFile)
204
-
205
- rms = microphone.getRMS(data)
206
- assert 588.60 < rms < 588.61
207
-
208
- rmsb = microphone.getRMSBins(data, chunk=64)
209
- assert 10.2 < rmsb[0] < 10.3
210
- assert len(rmsb) == 480
211
-
212
- def test_marker(self):
213
- testFile = join(self.tmp, 'green_48000.wav')
214
-
215
- marker = microphone.getMarkerOnset(testFile) # 19kHz marker sound
216
- assert 0.0666 < marker[0] < 0.06677 # start
217
- assert 0.0773 < marker[1] < 0.07734 # end
@@ -1,299 +0,0 @@
1
- from psychopy.colors import Color
2
- from psychopy.visual import RatingScale, Window, shape, TextStim
3
- from psychopy import event, core
4
- from psychopy.constants import (NOT_STARTED, FINISHED)
5
- from psychopy.tools import systemtools
6
- import pytest, copy
7
-
8
- """define RatingScale configurations, test the logic
9
-
10
- .draw() is to pick up coverage, not do a visual test (see test_all_visual).
11
- ~93% coverage; miss code that is conditional on mouse events
12
-
13
- test:
14
- cd psychopy/psychopy/
15
- py.test -k ratingscale --cov-report term-missing --cov visual/ratingscale.py
16
- """
17
-
18
-
19
- @pytest.mark.ratingscale
20
- class Test_class_RatingScale:
21
- """RatingScale internal logic, no check that its drawn correctly
22
- """
23
- def setup_class(self):
24
- self.win = Window([128,128], pos=[50,50], allowGUI=False, autoLog=False)
25
- self.winpix = Window([128,128], pos=[50,50], allowGUI=False, units='pix', autoLog=False)
26
- self.r = RatingScale(self.win, autoLog=False)
27
-
28
- def teardown_class(self):
29
- pass
30
-
31
- def test_init_scales(self):
32
- # ideally: give default, non-default, and bad values for all params
33
-
34
- # defaults: ---------
35
- r = copy.copy(self.r)
36
- assert (r.low, r.high, r.precision) == (1, 7, 1)
37
- assert (r.markerStyle, r.markerStart, r.markerPlaced) == ('triangle', None, False)
38
-
39
- # non-defaults and some bad: ---------
40
- r = RatingScale(self.win, low=-10., high=10., autoLog=False)
41
- assert (r.low, r.high) == (-10, 10)
42
- assert (type(r.low), type(r.high)) == (int, int)
43
- r = RatingScale(self.win, low='a', high='s', autoLog=False) # bad vals
44
- assert (r.low, r.high) == (1, 2)
45
- r = RatingScale(self.win, low=10, high=2, autoLog=False)
46
- assert r.high == r.low + 1 == 11
47
- assert r.precision == 100
48
-
49
- ch = ['a', 'b']
50
- r = RatingScale(self.win, choices=ch, precision=10, autoLog=False)
51
- assert r.precision == 1 # because choices
52
- assert r.respKeys == list(map(str, list(range(len(ch)))))
53
- r = RatingScale(self.win, choices=['a'], autoLog=False)
54
-
55
- r = RatingScale(self.win, tickMarks=[1,2,3], labels=['a','b'], autoLog=False)
56
-
57
- for i in [-1, 0.3, 1.2, 9, 12, 100, 1000]:
58
- r = RatingScale(self.win, precision=i, autoLog=False)
59
- assert r.precision in [1, 10, 100]
60
- r = RatingScale(self.win, textSize=3, textColor=0.3, autoLog=False)
61
-
62
- #r = RatingScale(self.win, textFont=utils.TESTS_FONT, autoLog=False)
63
- #assert r.accept.font == r.scaleDescription.font == utils.TESTS_FONT
64
-
65
- r = RatingScale(self.win, showValue=False, showAccept=False, acceptKeys=[], autoLog=False)
66
- r = RatingScale(self.win, showAccept=False, mouseOnly=True, singleClick=False, autoLog=False)
67
- assert r.mouseOnly == False
68
-
69
- r = RatingScale(self.win, acceptKeys='a', autoLog=False)
70
- r = RatingScale(self.win, acceptKeys=['a','b'], autoLog=False)
71
- r = RatingScale(self.win, acceptPreText='a', acceptText='a', acceptSize=2.1, autoLog=False)
72
-
73
- r = RatingScale(self.win, leftKeys=['a'], rightKeys=['a'], autoLog=False)
74
- assert r.respKeys == list(map(str, list(range(1,8))))
75
- r = RatingScale(self.win, respKeys=['a'], acceptKeys=['a'], autoLog=False)
76
- r = RatingScale(self.win, acceptKeys=['1'], autoLog=False)
77
- r = RatingScale(self.win, tickHeight=-1, autoLog=False)
78
-
79
- r = RatingScale(self.win, markerStart=3, tickHeight=False, autoLog=False)
80
- r = RatingScale(self.win, markerStart='a', choices=['a','b'], autoLog=False)
81
- assert r.choices == ['a', 'b']
82
- r = RatingScale(self.win, markerColor='dark red', lineColor='Black', autoLog=False)
83
- assert r.marker._fillColor == r.marker._borderColor == Color('darkred')
84
- assert r.line._borderColor == Color('Black')
85
- r = RatingScale(self.win, marker='glow', markerExpansion=0, autoLog=False)
86
- r.markerPlaced = True
87
- r.draw()
88
- r.markerExpansion = 10
89
- r.draw()
90
-
91
- r = RatingScale(self.win, skipKeys=None, mouseOnly=True, singleClick=True, autoLog=False)
92
- r = RatingScale(self.win, pos=(0,.5), skipKeys='space', autoLog=False)
93
- r = RatingScale(self.winpix, pos=[1], autoLog=False)
94
- r = RatingScale(self.winpix, pos=['a','x'], autoLog=False)
95
- assert r.pos == [0.0, (-50.0 / r.win.size[1])]
96
- x, y = -3, 17
97
- r = RatingScale(self.winpix, pos=(x, y), size=.2, stretch=2, autoLog=False)
98
- assert r.offsetHoriz == 2. * x / r.win.size[0]
99
- assert r.offsetVert == 2. * y / r.win.size[1]
100
- assert r.stretch == 2
101
- assert r.size == 0.2 * 0.6 # internal rescaling by 0.6
102
-
103
- r = RatingScale(self.win, stretch='foo', size='foo', autoLog=False)
104
- assert r.stretch == 1
105
- assert r.size == 0.6
106
- r = RatingScale(self.win, size=5, autoLog=False)
107
- assert r.size == 3
108
-
109
- r = RatingScale(self.win, minTime=0.001, maxTime=1, autoLog=False)
110
- assert r.minTime == 0.001 and r.maxTime == 1
111
- r = RatingScale(self.win, minTime='x', maxTime='s', name='name', autoLog=False)
112
- assert r.minTime == 1.0 and r.maxTime == 0.
113
- assert r.name == 'name' and r.autoLog == False
114
-
115
- def test_markers(self):
116
- for marker in ['triangle', 'glow', 'slider', 'circle', 'hover', None]:
117
- r = RatingScale(self.win, choices=['0', '1'], marker=marker, autoLog=False)
118
- r.draw()
119
- with pytest.raises(SystemExit):
120
- r = RatingScale(self.win, marker='hover', autoLog=False) # needs choices
121
-
122
- cm = TextStim(self.win, text='|')
123
- r = RatingScale(self.win, marker=cm, autoLog=False)
124
- r.noResponse = False
125
- r.markerPosFixed = False
126
- r.draw()
127
-
128
- class bad_customMarker():
129
- def __init__(self): pass
130
- r = RatingScale(self.win, marker=bad_customMarker(), autoLog=False)
131
- assert type(r.marker) == shape.ShapeStim
132
-
133
- def test_ratingscale_misc(self):
134
- r = copy.copy(self.r)
135
- assert r._getMarkerFromPos(0.2) == 5
136
- assert r._getMarkerFromTick(0) == 0
137
- r.setMarkerPos(2)
138
- assert r.markerPlacedAt == 2
139
- r.setDescription()
140
- assert r.flipVert == False # 'needed to test'
141
- r.setFlipVert(True)
142
-
143
- # test reset()
144
- r = RatingScale(self.win, markerStart=2)
145
- assert r.noResponse == True
146
- assert r.markerPlaced == True
147
- assert r.markerPlacedBySubject == False
148
- assert r.markerPlacedAt == r.markerStart - r.low
149
- assert r.firstDraw == True
150
- assert r.decisionTime == 0
151
- assert r.markerPosFixed == False
152
- assert r.frame == 0
153
- assert r.status == NOT_STARTED
154
- assert r.history is None
155
-
156
- assert r.autoRescaleFactor == 1
157
- r = RatingScale(self.win, low=0, high=30)
158
- assert r.autoRescaleFactor == 10
159
-
160
- def test_draw_conditionals(self):
161
- r = copy.copy(self.r)
162
-
163
- r.allowTimeOut = True
164
- r.timedOut = False
165
- r.maxTime = -1
166
- r.noResponse = False
167
- r.disappear = True
168
- r.draw()
169
-
170
- # miss lines: if self.myMouse.getPressed()[0]:
171
-
172
- r = copy.copy(self.r)
173
- r.beyondMinTime = True
174
- r.showAccept = True
175
- r.noResponse = False
176
- r.decisionTime = 0
177
- r.draw()
178
-
179
- r = RatingScale(self.win, singleClick=True, markerStart=1, marker='glow', markerExpansion=-10, autoLog=False)
180
- r.draw()
181
-
182
- r = RatingScale(self.win, singleClick=True, markerStart=-1, autoLog=False)
183
- r.draw()
184
-
185
- r = RatingScale(self.win, showAccept=True, choices=['a', 'b'], autoLog=False)
186
- r.showValue = True
187
- r.markerPlacedAt = 1
188
- r.markerPlaced = True
189
- r.draw()
190
- r.showvalue = False
191
- r.draw()
192
-
193
- r = RatingScale(self.win, labels=['a', 'b', 'c'], autoLog=False)
194
- r = RatingScale(self.win, tickMarks=[1,2,3], labels=None, autoLog=False)
195
- r = RatingScale(self.win, leftKeys=['s'], autoLog=False)
196
- r.markerPlaced = False
197
- event._onPygletKey(symbol='s', modifiers=0, emulated=True)
198
- r.draw()
199
-
200
- def test_obsolete_args(self):
201
- with pytest.raises(SystemExit):
202
- r = RatingScale(self.win, showScale=True, autoLog=False)
203
- with pytest.raises(SystemExit):
204
- r = RatingScale(self.win, ZZZshowScale=True, autoLog=False)
205
-
206
- def test_key_presses(self):
207
- # simulated keys are not being picked up in draw:
208
-
209
- r = copy.copy(self.r)
210
- r.markerPlaced = True
211
-
212
- r.mouseOnly = False
213
- event._onPygletKey(symbol='tab', modifiers=0, emulated=True)
214
- r.draw()
215
-
216
- r.respKeys = ['s']
217
- r.enableRespKeys = True
218
- event._onPygletKey(symbol='s', modifiers=0, emulated=True)
219
- r.draw()
220
-
221
- # test move left, move right:
222
- r = RatingScale(self.win, markerStart=3, autoLog=False)
223
- assert r.markerPlacedAt == 2
224
- event._onPygletKey(symbol='left', modifiers=0, emulated=True)
225
- r.draw()
226
- assert r.markerPlaced # and r.markerPlacedBySubject
227
- #assert r.markerPlacedAt == 1
228
- event._onPygletKey(symbol='right', modifiers=0, emulated=True)
229
- r.draw()
230
- #assert r.markerPlacedAt == 2
231
-
232
- r.acceptKeys = ['s']
233
- r.beyondMinTime = True
234
- event._onPygletKey(symbol='s', modifiers=0, emulated=True)
235
- r.draw()
236
-
237
- def test_somelines(self):
238
- r = copy.copy(self.r)
239
- r.skipKeys = []
240
- r.mouseOnly = False
241
- r.enableRespKeys = True
242
- r.respKeys = ['s']
243
- r.allKeys = ['s']
244
- r.tickFromKeyPress = {u's': 1}
245
- event._onPygletKey(symbol='s', modifiers=0, emulated=True)
246
- r.singleClick = True
247
- r.beyondMinTime = True
248
- r.draw()
249
-
250
- r.leftKeys = ['s']
251
- r.draw()
252
- r.leftKeys = []
253
- r.rightKeys = ['s']
254
- r.draw()
255
- r.rightKeys = []
256
-
257
- def test_getRating_RT_history(self):
258
- # 1139-43
259
- r = copy.copy(self.r)
260
- r.status = FINISHED
261
- r.noResponse = True
262
- r.timedOut = True
263
- assert r.getRT() == r.maxTime
264
- r.timedOut = False
265
- assert r.getRT() is None
266
- r.noResponse = False
267
- assert r.getRT() == r.decisionTime
268
-
269
- r.reset() # ---------------
270
- r.noResponse = True
271
- r.markerPlacedAt = 0
272
- r.status = FINISHED
273
- assert r.getRating() is None
274
-
275
- r.status = FINISHED + 1
276
- assert r.getRating() == 1
277
-
278
- r.precision = 1
279
- r.choices = ['a', 'b']
280
- assert r.getRating() == 'b'
281
-
282
- r = RatingScale(self.win, singleClick=True, autoLog=False)
283
- r.draw()
284
- core.wait(.001, 0)
285
- r.acceptKeys = r.allKeys = ['1']
286
- r.beyondMinTime = True
287
- event._onPygletKey(symbol='1', modifiers=0, emulated=True)
288
- r.draw()
289
- h = r.getHistory()
290
- assert h[0] == (None, 0)
291
- assert h[-1][0] == 1
292
- if systemtools.isVM_CI():
293
- assert 0.001 < h[-1][1] < 0.1 # virtual machines not usually great
294
- else:
295
- assert 0.001 < h[-1][1] < 0.03
296
-
297
- def test_labels_False(self):
298
- for anchor in [None, 'a']:
299
- r = RatingScale(self.win, labels=[anchor, anchor], autoLog=False)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes