File: _audio.py

package info (click to toggle)
python-expyriment 0.7.0%2Bgit34-g55a4e7e-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,504 kB
  • ctags: 2,094
  • sloc: python: 12,766; makefile: 150
file content (167 lines) | stat: -rw-r--r-- 4,138 bytes parent folder | download | duplicates (2)
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()