1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
"""
Audio playback.
This module contains a class implementing audio playback.
"""
__author__ = 'Florian Krause <florian@expyriment.org>, \
Oliver Lindemann <oliver@expyriment.org>'
__version__ = '0.7.0'
__revision__ = '55a4e7e'
__date__ = 'Wed Mar 26 14:33:37 2014 +0100'
import os
try:
import android.mixer as mixer
except:
import pygame.mixer as mixer
import expyriment
from expyriment.misc import unicode2str
from _stimulus import Stimulus
class Audio(Stimulus):
"""A class implementing a general auditory stimulus.
Notes
-----
See also
- expyriment.control.start_audiosystem
- expyriment.control.stop_audiosystem
- expyriment.control.audiosystem_is_busy
- expyriment.control.audiosystem_wait_end
"""
def __init__(self, filename):
"""Create an audio stimulus.
Parameters
----------
filename : str
the filename
"""
Stimulus.__init__(self, filename)
self._filename = filename
self._file = None
self._is_preloaded = False
if not(os.path.isfile(self._filename)):
raise IOError("The audio file {0} does not exists".format(
unicode2str(self._filename)))
_getter_exception_message = "Cannot set {0} if preloaded!"
@property
def is_preloaded(self):
"""Getter for is_preloaded"""
return self._is_preloaded
@property
def filename(self):
"""Getter for filename"""
return self._filename
@filename.setter
def filename(self, value):
"""Setter for filename."""
if self._is_preloaded:
raise AttributeError(Audio._getter_exception_message.format(
"filename"))
else:
self._filename = value
def copy(self):
"""Copy the stimulus.
Returns
-------
copy: stimulus.Audio
Returned copy will NOT be is_preloaded!
"""
was_loaded = self._is_preloaded
self.unload()
rtn = Stimulus.copy(self)
if was_loaded:
self.preload()
return rtn
def preload(self):
"""Preload stimulus to memory."""
if not self._is_preloaded:
self._file = mixer.Sound(unicode2str(self._filename, fse=True))
self._is_preloaded = True
def unload(self):
"""Unload stimulus from memory.
This removes the reference to the object in memory.
It is up to the garbage collector to actually remove it from memory.
"""
if self._is_preloaded:
self._file = None
self._is_preloaded = False
def play(self, loops=0, maxtime=0, fade_ms=0):
"""Play the audio stimulus.
The function returns immediately after the sound started to play.
A pygame.mixer.Channel object is returned.
Parameters
----------
loops : int, optional
how often to repeat (-1 = forever) (default = 0)
maxtime : int
stop after given amount of milliseconds (default = 0)
fade_ms : int, optional
fade in time in milliseconds (default = 0)
"""
if not self._is_preloaded:
self.preload()
rtn = self._file.play(loops, maxtime, fade_ms)
if self._logging:
if isinstance(self._filename, unicode):
import sys
filename = self._filename.encode(sys.getfilesystemencoding())
else:
filename = self._filename
expyriment._active_exp._event_file_log(
"Stimulus,played,{0}".format(filename), 1)
return rtn
def stop(self):
"""Stop the audio stimulus"""
if self._is_preloaded:
self._file.stop()
def present(self):
"""Presents the sound.
The function is identical to Audio.play(loops=0, maxtime=0, fade_ms=0)
and returns also immediately after the sound started to play.
Notes
-----
See Audio.play for more information.
"""
self.play()
|