sounds

Classes to play sounds.

Each sound inherits a base type depending on prefs.get(‘AUDIOSERVER’)

  • prefs.get(‘AUDIOSERVER’) == ‘jack’ : Jack_Sound

  • prefs.get(‘AUDIOSERVER’) == ‘pyo’ : Pyo_Sound

To avoid unnecessary dependencies, Jack_Sound is not defined if AUDIOSERVER is ‘pyo’ and vice versa.

Todo

Implement sound level and filter calibration

Classes:

Pyo_Sound()

Metaclass for pyo sound objects.

Jack_Sound()

Base class for sounds that use the JackClient audio server.

Tone(frequency, duration[, amplitude])

The Humble Sine Wave

Noise(duration[, amplitude])

White Noise

File(path[, amplitude])

A .wav file.

Speech(path, speaker, consonant, vowel, token)

Speech subclass of File sound.

Gap(duration, **kwargs)

A silent sound that does not pad its final chunk – used for creating precise silent gaps in a continuous noise.

Data:

SOUND_LIST

Sounds must be added to this SOUND_LIST so they can be indexed by the string keys used elsewhere.

STRING_PARAMS

These parameters should be given string columns rather than float columns.

Functions:

int_to_float(audio)

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

play()[source]
table_wrap(audio, duration=None)[source]

Records a PyoAudio generator into a sound table, returns a tableread object which can play the audio with .out()

Parameters
  • audio

  • duration

set_trigger(trig_fn)[source]
Parameters

trig_fn

class Jack_Sound[source]

Bases: object

Base class for sounds that use the JackClient audio server.

Variables

Attributes:

PARAMS

list of strings of parameters to be defined

type

string human readable name of sound

server_type

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_trigger()

Wait for the stop_evt trigger to be set for at least a second after the sound should have ended.

get_nsamples()

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.

buffer_continuous()

Dump chunks into the continuous sound queue for looping.

play()

Play ourselves.

play_continuous([loop])

Play the sound continuously.

stop_continuous()

Stop playing a continuous sound

end()

Release any resources held by this sound

PARAMS = []

list of strings of parameters to be defined

Type

list

type = None

string human readable name of sound

Type

str

server_type = 'jack'

type of server, always ‘jack’ for Jack_Sound s.

Type

str

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), otherwise jackclient will pad 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.

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.

Returns:

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
stop_continuous()[source]

Stop playing a continuous sound

Should be merged into a general stop method

end()[source]

Release any resources held by this sound

class Tone(frequency, duration, amplitude=0.01, **kwargs)[source]

Bases: object

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:

PARAMS

type

Methods:

init_sound()

Create a sine wave table using pyo or numpy, depending on the server type.

PARAMS = ['frequency', 'duration', 'amplitude']
type = 'Tone'
init_sound()[source]

Create a sine wave table using pyo or numpy, depending on the server type.

class Noise(duration, amplitude=0.01, **kwargs)[source]

Bases: object

White Noise

Parameters
  • duration (float) – duration of the noise

  • amplitude (float) – amplitude of the sound as a proportion of 1.

  • **kwargs – extraneous parameters that might come along with instantiating us

Attributes:

PARAMS

type

Methods:

init_sound()

Create a table of Noise using pyo or numpy, depending on the server_type

PARAMS = ['duration', 'amplitude']
type = 'Noise'
init_sound()[source]

Create a table of Noise using pyo or numpy, depending on the server_type

class File(path, amplitude=0.01, **kwargs)[source]

Bases: object

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:

PARAMS

type

Methods:

init_sound()

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 Speech(path, speaker, consonant, vowel, token, amplitude=0.05, **kwargs)[source]

Bases: autopilot.stim.sound.sounds.File

Speech subclass of File sound.

Example of custom sound class - PARAMS are changed, but nothing else.

Parameters
  • speaker (str) – Which Speaker recorded this speech token?

  • consonant (str) – Which consonant is in this speech token?

  • vowel (str) – Which vowel is in this speech token?

  • token (int) – Which token is this for a given combination of speaker, consonant, and vowel

Attributes:

type

PARAMS

type = 'Speech'
PARAMS = ['path', 'amplitude', 'speaker', 'consonant', 'vowel', 'token']
class Gap(duration, **kwargs)[source]

Bases: object

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:

type

PARAMS

Methods:

init_sound()

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']
init_sound()[source]

Create and chunk an array of zeros according to Gap.duration

chunk(pad=False)[source]

If gap is not duration == 0, call parent chunk. :Parameters: pad (bool) – unused, passed to parent chunk

buffer()[source]
play()[source]
SOUND_LIST = { 'File': <class 'autopilot.stim.sound.sounds.File'>, 'Gap': <class 'autopilot.stim.sound.sounds.Gap'>, 'Noise': <class 'autopilot.stim.sound.sounds.Noise'>, 'Speech': <class 'autopilot.stim.sound.sounds.Speech'>, 'Tone': <class 'autopilot.stim.sound.sounds.Tone'>, 'speech': <class 'autopilot.stim.sound.sounds.Speech'>}

Sounds must be added to this SOUND_LIST so they can be indexed by the string keys used elsewhere.

STRING_PARAMS = ['path', 'speaker', 'consonant', 'vowel', 'type']

These parameters should be given string columns rather than float columns.

Bother Jonny to do this better.

v0.3 will be all about doing parameters better.

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

numpy.ndarray