SoundCard USB connection

class pybpod_soundcard_module.module_api.SampleRate[source]

Enumeration for the Sample rate of the sounds in the Sound Card

_96000HZ = 96000

96KHz sample rate

_192000HZ = 192000

192KHz sample rate

class pybpod_soundcard_module.module_api.DataType[source]

Type of the data to be send to the Sound Card

INT32 = 0

Integer 32 bits

FLOAT32 = 1

Single precision float

class pybpod_soundcard_module.module_api.SoundCardModule(device=None)[source]

Provides access to the Harp Sound Card. It allows to send and read the sounds in the Sound Card, through a normal USB connection.

If a libUSB’s device is given, it will try to open it. If none is given it will try to connect to the first Sound Card that is connected to the computer.

Parameters:device – (Optional) libUSB device to use. If nothing is passed, it will try to connect automatically.
open(device=None)[source]

Opens the connection to the Sound Card. If no device is given, it will try to connect to the first Sound Card that is connected to the computer.

Parameters:device – (Optional) Already initialized libUSB’s device to use.
close()[source]

Closes the connection with the Sound Card. It will close USB connection (to read and save sounds)

reset()[source]

Resets the device, waits 700ms and tries to connect again so that the current instance of the SoundCard object can still be used.

Note

Necessary at the moment after sending a sound.

read_sounds(output_folder=None, sound_index=None, clean_dst_folder=True)[source]

Reads sounds from the sound card.

Note

by default, it will clear the destination folder of all data. It will also write by default to a “from_soundcard” folder in the working directory if none is given.

Parameters:
  • output_folder – Destination folder’s path.
  • sound_index – If a sound_index is given, it will get only that sound, if nothing is passed it will gather all sounds from all indexes.
  • clean_dst_folder – Flag that defines if the method should clean the destination folder or not
send_sound(wave_int, sound_index, sample_rate, data_type, sound_filename=None, metadata_filename=None, description_filename=None)[source]

This method will send the sound to the Harp Sound Card as a byte array (int8)

Parameters:
  • wave_int – NumPy array as int32 that represents the sound data
  • sound_index – The destination index in the Sound Card (>=2 and <= 32)
  • sample_rate – The SampleRate enum value for either 96KHz or 192KHz
  • data_type – The DataType enum value for either Int32 or Float32 (not implemented yet in the hardware)
  • sound_filename – The name of the sound filename to be saved with the sound in the board (str)
  • metadata_filename – The name of the metadata filename to be saved with the sound in the board (str)
  • description_filename – The name of the description filename to be saved with the sound in the board (str)
class pybpod_soundcard_module.utils.generate_sound.WindowConfiguration(left_duration=0.1, left_apply_window_start=True, left_apply_window_end=True, left_window_function='Hanning', right_duration=0.1, right_apply_window_start=True, right_apply_window_end=True, right_window_function='Hanning')[source]
Parameters:
  • left_duration – (Optional) Duration of the window in seconds, for the left channel. If zero, no window will be created for this channel. Default: 0.1s
  • left_apply_window_start – (Optional) True if the window should be applied to the start of the sound for the left channel, False otherwise. Default: True
  • left_apply_window_end – (Optional) True if the window should be applied to the end of the sound for the left channel, False otherwise. Default: True
  • left_window_function – (Optional) Window function that should be used for the left channel. Possible values accepted: ‘Hanning’, ‘Hamming’, ‘Blackman’, ‘Bartlett’. Default: ‘Hanning”
  • right_duration – (Optional) Duration of the window in seconds, for the right channel. If zero, no window will be created for this channel. Default: 0.1s
  • right_apply_window_start – (Optional) True if the window should be applied to the start of the sound, for the right channel, False otherwise. Default: True
  • right_apply_window_end – (Optional) True if the window should be applied to the end of the sound for the right channel, False otherwise. Default: True
  • right_window_function – (Optional) Window function that should be used for the left channel. Possible values accepted: ‘Hanning’, ‘Hamming’, ‘Blackman’, ‘Bartlett’. Default: ‘Hanning”
pybpod_soundcard_module.utils.generate_sound.generate_sound(filename=None, fs=96000, duration=1, frequency_left=1000, frequency_right=1000, window_configuration: pybpod_soundcard_module.utils.generate_sound.WindowConfiguration = None)[source]

Helper method to dynamically generated a sound that can be used in with the Sound Card module.

Parameters:
  • filename – (Optional)
  • fs – (Optional) number of samples per second (standard)
  • duration – (Optional) sound duration in seconds
  • frequency_left – (Optional) number of cycles per second (Hz) (frequency of the sine wave for the left channel)
  • frequency_right – (Optional) number of cycles per second (Hz) (frequency of the sine wave for the right channel)
  • window_configuration – (Optional) WindowConfiguration object to apply to the generated sound.
Returns:

Returns the flatten generated sound as a numpy array (as np.int8)

pybpod_soundcard_module.utils.generate_sound.generate_window(fs, wave_int, duration, apply_start, apply_end, window_function)[source]
Parameters:
  • fs – number of samples per second (standard)
  • wave_int – base sound where the window will be applied
  • duration – duration of the window (it will be the same on the start and end)
  • apply_start – True if the window should be created at the start, False otherwise.
  • apply_end – True if the window should be created at the end, False otherwise.
  • window_function – window function to be generated. Possible values accepted: ‘Hanning’, ‘Hamming’, ‘Blackman’, ‘Bartlett’. It will revert to ‘Hanning’ if an unknown option is given.
Returns:

Returns the modified sound with the window applied to it.

Usage Example

import numpy as np
from pybpod_soundcard_module.module import SoundCard, SoundCommandType
from pybpod_soundcard_module.module_api import SoundCardModule, DataType, SampleRate
from pybpod_soundcard_module.utils.generate_sound import generate_sound

card = SoundCardModule()
card.open()

sound_filename = 'sound.bin'
sound_index = 4

# load file and read data (we are using the numpy's fromfile method)
wave_int = np.fromfile(sound_filename, dtype=np.int32)

# NOTE: As an alternative, we can generate a sound dynamically with the helper method generate_sound
wave_int = generate_sound(sound_filename,           # optional, if given, it will save the generated sound to the hard drive
                          fs=96000,                 # sample rate in Hz
                          duration=4,               # duration of the sound in seconds
                          frequency_left=1500,      # frequency of the sinusoidal signal generated in Hz for the left channel
                          frequency_right=1200)     # frequency of the sinusoidal signal generated in Hz for the right channel

# send sound
card.send_sound(wave_int,
                sound_index,
                SampleRate._96000HZ,
                DataType.INT32,
                sound_filename,
                'sound_metadata.bin',    # optional
                'sound_description.txt') # optional

# reads the files related with the sound in index 4, without cleaning the destination folder
card.read_sounds(output_folder='folder', sound_index=sound_index, clean_dst_folder=False)

card.close()

Usage Example (using ‘with’ statement)

import numpy as np
from pybpod_soundcard_module.module import SoundCard, SoundCommandType
from pybpod_soundcard_module.module_api import SoundCardModule, DataType, SampleRate
from pybpod_soundcard_module.utils.generate_sound import generate_sound

sound_filename = 'sound.bin'
sound_index = 4

# load file and read data (we are using the numpy's fromfile method)
wave_int = np.fromfile(sound_filename, dtype=np.int32)

# NOTE: As an alternative, we can generate a sound dynamically with the helper method generate_sound
wave_int = generate_sound(sound_filename,           # optional, if given, it will save the generated sound to the hard drive
                          fs=96000,                 # sample rate in Hz
                          duration=4,               # duration of the sound in seconds
                          frequency_left=1500,      # frequency of the sinusoidal signal generated in Hz for the left channel
                          frequency_right=1200)     # frequency of the sinusoidal signal generated in Hz for the right channel


# the with statement will call 'close' automatically at the end of the block
with SoundCardModule() as card:
    # send sound
    card.send_sound(wave_int,
                    sound_index,
                    SampleRate._96000HZ,
                    DataType.INT32,
                    sound_filename,
                    'sound_metadata.bin',    # optional
                    'sound_description.txt') # optional

    # reads the files related with the sound in index 4 without cleaning the destination folder
    card.read_sounds(output_folder='folder', sound_index=4, clean_dst_folder=False)

Usage Example (sound generation with WindowConfiguration)

import numpy as np
from pybpod_soundcard_module.module import SoundCard, SoundCommandType
from pybpod_soundcard_module.module_api import SoundCardModule, DataType, SampleRate
from pybpod_soundcard_module.utils.generate_sound import generate_sound, WindowConfiguration

sound_filename = 'sound.bin'
sound_index = 4

# create WindowConfiguration to later pass it to generate_sound
# NOTE: (exemplification of options available, change options according to your needs)
window_config = WindowConfiguration( left_duration = 0.2,                   # It is possible to define different durations for the left and right channel.
                                     left_apply_window_start = True,        # For this example, we want a start window
                                     left_apply_window_end = False,         # ... and no 'end' window for the left channel
                                     left_window_function = 'Blackman',     # ... and with 'Blackman' window function
                                     right_duration = 0.1,                  # It is possible to define different durations for the left and right channel.
                                     right_apply_window_start = False,      # For this example, we don't want a start window
                                     right_apply_window_end = True,         # ... and a 'end' window for the right channel
                                     right_window_function = 'Bartlett')    # ... and with 'Bartlett' window function

wave_int = generate_sound(sound_filename,                       # optional, if given, it will save the generated sound to the hard drive
                          fs=96000,                             # sample rate in Hz
                          duration=4,                           # duration of the sound in seconds
                          frequency_left=1500,                  # frequency of the sinusoidal signal generated in Hz for the left channel
                          frequency_right=1200,                 # frequency of the sinusoidal signal generated in Hz for the right channel
                          window_configuration=window_config)   # window configuration


# the with statement will call 'close' automatically at the end of the block
with SoundCardModule() as card:
    # send sound
    card.send_sound(wave_int,
                    sound_index,
                    SampleRate._96000HZ,
                    DataType.INT32,
                    sound_filename,
                    'sound_metadata.bin',    # optional
                    'sound_description.txt') # optional

    # reads the files related with the sound in index 4 without cleaning the destination folder
    card.read_sounds(output_folder='folder', sound_index=4, clean_dst_folder=False)