sounds¶
This module defines classes to generate different sounds.
These classes are currently implemented: * Tone : a sinuosoidal pure tone * Noise : a burst of white noise * File : read from a file * Speech * Gap
The behavior of this module depends on prefs.get(‘AUDIOSERVER’). * If this is ‘jack’, or True:
Then import jack, define Jack_Sound, and all sounds inherit from that.
- If this is ‘pyo’:
Then import pyo, define PyoSound, and all sounds inherit from that.
- If this is ‘docs’:
Then import both jack and pyo, define both Jack_Sound and PyoSound, and all sounds inherit from object.
- Otherwise:
Then do not import jack or pyo, or define either Jack_Sound or PyoSound, and all sounds inherit from object.
Todo
Implement sound level and filter calibration
Classes:
Metaclass for pyo sound objects. |
|
Base class for sounds that use the |
|
|
The Humble Sine Wave |
|
Generates a white noise burst with specified parameters |
|
A .wav file. |
|
A silent sound that does not pad its final chunk – used for creating precise silent gaps in a continuous noise. |
Data:
These parameters should be given string columns rather than float columns. |
Functions:
|
Convert 16 or 32 bit integer audio to 32 bit float. |
- class Pyo_Sound[source]¶
Bases:
object
Metaclass for pyo sound objects.
Note
Use of pyo is generally discouraged due to dropout issues and the general opacity of the module. As such this object is intentionally left undocumented.
Methods:
play
()table_wrap
(audio[, duration])Records a PyoAudio generator into a sound table, returns a tableread object which can play the audio with .out()
set_trigger
(trig_fn)- Parameters
trig_fn
- class Jack_Sound[source]¶
Bases:
object
Base class for sounds that use the
JackClient
audio server.- Variables
PARAMS (list) – List of strings of parameters that need to be defined for this sound
type (str) – Human readable name of sound type
duration (float) – Duration of sound in ms
amplitude (float) – Amplitude of sound as proportion of 1 (eg 0.5 is half amplitude)
table (
numpy.ndarray
) – A Numpy array of samplestrigger (callable) – A function that is called when the sound completes
nsamples (int) – Number of samples in the sound
padded (bool) – Whether the sound had to be padded with zeros when split into chunks (ie. sound duration was not a multiple of BLOCKSIZE).
fs (int) – sampling rate of client from
jackclient.FS
blocksize (int) – blocksize of client from
jackclient.BLOCKSIZE
server (
Jack_Client
) – Current Jack Clientq (
multiprocessing.Queue
) – Audio Buffer queue fromjackclient.QUEUE
q_lock (
multiprocessing.Lock
) – Audio Buffer lock fromjackclient.Q_LOCK
play_evt (
multiprocessing.Event
) – play event fromjackclient.PLAY
stop_evt (
multiprocessing.Event
) – stop event fromjackclient.STOP
buffered (bool) – has this sound been dumped into the
q
?buffered_continuous (bool) – Has the sound been dumped into the
continuous_q
?
Initialize a new Jack_Sound
This sets sound-specific parameters to None, set jack-specific parameters to their equivalents in jackclient, initializes some other flags and a logger.
Attributes:
list of strings of parameters to be defined
string human readable name of sound
type of server, always ‘jack’ for Jack_Sound s.
Methods:
chunk
([pad])Split our table up into a list of
Jack_Sound.blocksize
chunks.set_trigger
(trig_fn)Set a trigger function to be called when the
stop_evt
is set.Wait for the stop_evt trigger to be set for at least a second after the sound should have ended.
given our fs and duration, how many samples do we need?
quantize_duration
([ceiling])Extend or shorten a sound so that it is a multiple of
jackclient.BLOCKSIZE
buffer
()Dump chunks into the sound queue.
Dump chunks into the continuous sound queue for looping.
play
()Play ourselves.
play_continuous
([loop])Play the sound continuously.
Stop playing a continuous sound
end
()Release any resources held by this sound
- chunk(pad=True)[source]¶
Split our table up into a list of
Jack_Sound.blocksize
chunks.- Parameters
pad (bool) – If the sound is not evenly divisible into chunks,
pad with zeros (True, default)
with its continuous sound
- set_trigger(trig_fn)[source]¶
Set a trigger function to be called when the
stop_evt
is set.- Parameters
trig_fn (callable) – Some callable
- wait_trigger()[source]¶
Wait for the stop_evt trigger to be set for at least a second after the sound should have ended.
Call the trigger when the event is set.
- get_nsamples()[source]¶
given our fs and duration, how many samples do we need?
literally:
np.ceil((self.duration/1000.)*self.fs).astype(np.int)
- quantize_duration(ceiling=True)[source]¶
Extend or shorten a sound so that it is a multiple of
jackclient.BLOCKSIZE
- Parameters
ceiling (bool) – If true, extend duration, otherwise decrease duration.
- buffer()[source]¶
Dump chunks into the sound queue.
After the last chunk, a None is put into the queue. This tells the jack server that the sound is over and that it should clear the play flag.
- buffer_continuous()[source]¶
Dump chunks into the continuous sound queue for looping.
Continuous shoulds should always have full frames - ie. the number of samples in a sound should be a multiple of
jackclient.BLOCKSIZE
.This method will call
quantize_duration()
to force duration such that the sound has full frames.An exception will be raised if the sound has been padded.
- play()[source]¶
Play ourselves.
If we’re not buffered, be buffered.
Otherwise, set the play event and clear the stop event.
If we have a trigger, set a Thread to wait on it.
- play_continuous(loop=True)[source]¶
Play the sound continuously.
Sound will be paused if another sound has its ‘play’ method called.
Currently - only looping is implemented: the full sound is loaded by the jack client and repeated indefinitely.
In the future, sound generation methods will be refactored as python generators so sounds can be continuously generated and played.
- Parameters
loop (bool) – whether the sound will be stored by the jack client and looped (True), or whether the sound will be continuously streamed (False, not implemented)
Returns:
todo:
merge into single play method that changes behavior if continuous or not
- class Tone(frequency, duration, amplitude=0.01, **kwargs)[source]¶
Bases:
autopilot.stim.Stim
The Humble Sine Wave
- Parameters
frequency (float) – frequency of sin in Hz
duration (float) – duration of the sin in ms
amplitude (float) – amplitude of the sound as a proportion of 1.
**kwargs – extraneous parameters that might come along with instantiating us
Attributes:
Methods:
Create a sine wave table using pyo or numpy, depending on the server type.
- PARAMS = ['frequency', 'duration', 'amplitude']¶
- type = 'Tone'¶
- class Noise(duration, amplitude=0.01, channel=None, **kwargs)[source]¶
Bases:
autopilot.stim.Stim
Generates a white noise burst with specified parameters
The type attribute is always “Noise”.
Initialize a new white noise burst with specified parameters.
The sound itself is stored as the attribute self.table. This can be 1-dimensional or 2-dimensional, depending on channel. If it is 2-dimensional, then each channel is a column.
- Parameters
duration (float) – duration of the noise
amplitude (float) – amplitude of the sound as a proportion of 1.
channel (int or None) – which channel should be used If 0, play noise from the first channel If 1, play noise from the second channel If None, send the same information to all channels (“mono”)
**kwargs – extraneous parameters that might come along with instantiating us
Attributes:
Methods:
Defines self.table, the waveform that is played.
- PARAMS = ['duration', 'amplitude', 'channel']¶
- type = 'Noise'¶
- init_sound()[source]¶
Defines self.table, the waveform that is played.
The way this is generated depends on self.server_type, because parameters like the sampling rate cannot be known otherwise.
The sound is generated and then it is “chunked” (zero-padded and divided into chunks). Finally self.initialized is set True.
- class File(path, amplitude=0.01, **kwargs)[source]¶
Bases:
autopilot.stim.Stim
A .wav file.
Todo
Generalize this to other audio types if needed.
- Parameters
path (str) – Path to a .wav file relative to the prefs.get(‘SOUNDDIR’)
amplitude (float) – amplitude of the sound as a proportion of 1.
**kwargs – extraneous parameters that might come along with instantiating us
Attributes:
Methods:
Load the wavfile with
scipy.io.wavfile
, converting int to float as needed.- PARAMS = ['path', 'amplitude']¶
- type = 'File'¶
- init_sound()[source]¶
Load the wavfile with
scipy.io.wavfile
, converting int to float as needed.Create a sound table, resampling sound if needed.
- class Gap(duration, **kwargs)[source]¶
Bases:
autopilot.stim.Stim
A silent sound that does not pad its final chunk – used for creating precise silent gaps in a continuous noise.
- Parameters
duration (float) – duration of gap in ms
- Variables
gap_zero (bool) – True if duration is zero, effectively do nothing on play.
Attributes:
Methods:
Create and chunk an array of zeros according to
Gap.duration
chunk
([pad])If gap is not duration == 0, call parent
chunk
.buffer
()play
()- type = 'Gap'¶
- PARAMS = ['duration']¶
- STRING_PARAMS = ['path', 'type']¶
These parameters should be given string columns rather than float columns.
Bother Jonny to do this better bc it’s really bad.
- int_to_float(audio)[source]¶
Convert 16 or 32 bit integer audio to 32 bit float.
- Parameters
audio (
numpy.ndarray
) – a numpy array of audio- Returns
Audio that has been rescaled and converted to a 32 bit float.
- Return type