base - sound¶
Base classes for sound objects, depending on the selected audio backend. Use the 'AUDIOSERVER'
pref to select, or else
use the default_sound_class()
function.
Classes:
|
Dummy metaclass for sound base-classes. |
Metaclass for pyo sound objects. |
|
|
Base class for sounds that use the |
Functions:
|
Get the default sound class as defined by |
- class Sound(fs: int = None, duration: float = None, **kwargs)[source]¶
Bases:
autopilot.stim.stim.Stim
Dummy metaclass for sound base-classes. Allows Sounds to be used without a backend to, eg. synthesize waveforms and the like.
Placeholder pending a full refactoring of class structure
Attributes:
Methods:
given our fs and duration, how many samples do we need?
- PARAMS = []¶
- type = None¶
- server_type = 'dummy'¶
- class Pyo_Sound[source]¶
Bases:
autopilot.stim.stim.Stim
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(jack_client: Optional[autopilot.stim.sound.jackclient.JackClient] = None, **kwargs)[source]¶
Bases:
autopilot.stim.stim.Stim
Base class for sounds that use the
JackClient
audio server.- Variables
~Jack_Sound.PARAMS (list) – List of strings of parameters that need to be defined for this sound
~Jack_Sound.type (str) – Human readable name of sound type
~Jack_Sound.duration (float) – Duration of sound in ms
~Jack_Sound.amplitude (float) – Amplitude of sound as proportion of 1 (eg 0.5 is half amplitude)
~Jack_Sound.table (
numpy.ndarray
) – A Numpy array of samples~Jack_Sound.chunks (list) –
table
split up into chunks ofBLOCKSIZE
~Jack_Sound.trigger (callable) – A function that is called when the sound completes
~Jack_Sound.nsamples (int) – Number of samples in the sound
~Jack_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).
~Jack_Sound.fs (int) – sampling rate of client from
jackclient.FS
~Jack_Sound.blocksize (int) – blocksize of client from
jackclient.BLOCKSIZE
~Jack_Sound.server (
Jack_Client
) – Current Jack Client~Jack_Sound.q (
multiprocessing.Queue
) – Audio Buffer queue fromjackclient.QUEUE
~Jack_Sound.q_lock (
multiprocessing.Lock
) – Audio Buffer lock fromjackclient.Q_LOCK
~Jack_Sound.play_evt (
multiprocessing.Event
) – play event fromjackclient.PLAY
~Jack_Sound.stop_evt (
multiprocessing.Event
) – stop event fromjackclient.STOP
~Jack_Sound.buffered (bool) – has this sound been dumped into the
q
?~Jack_Sound.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:
Abstract method to initialize sound.
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.
Create a duration quantized table for playing continuously
Dump chunks into the continuous sound queue for looping.
play
()Play ourselves.
play_continuous
([loop])Play the sound continuously.
Continuously yield frames of audio.
Stop playing a continuous sound
end
()Release any resources held by this sound
- abstract init_sound()[source]¶
Abstract method to initialize sound. Should set the
table
attributeTodo
ideally should standardize by returning an array, but pyo objects don’t return arrays necessarily…
- 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
- iter_continuous() Generator [source]¶
Continuously yield frames of audio. If this method is not overridden, just wraps
table
in aitertools.cycle
object and returns from it.- Returns
A single frame of audio
- Return type
np.ndarray
- get_sound_class(server_type: Optional[str] = None) Union[Type[autopilot.stim.sound.base.Sound], Type[autopilot.stim.sound.base.Jack_Sound], Type[autopilot.stim.sound.base.Pyo_Sound]] [source]¶
Get the default sound class as defined by
'AUDIOSERVER'
This function is also a convenience class for testing whether a particular audio backend is available
Returns: