Sources
The Treble SDK supports two source types: point sources and CAD-based sources. Point sources are built upon the Source class, which defines a point source with a given directivity pattern. There are three common point source types you can create directly: omnidirectional, dipole, and cardioid. Through the directivity library, you can also assign a measured or custom directivity to a point source for use in simulations. CAD-based sources instead model sound radiation from the vibrating surfaces of imported geometry using a boundary velocity approach.
This page covers the creation and placement of point sources within a simulation. To model electro-acoustic or physical devices as CAD-based sources, see boundary velocity sources. The following how-tos demonstrate how to create primitive source types, use the directivity library, and create a source list for use in a simulation definition.
Simulations expect a list of sources, even if only one source is used. To format a single source as a list, see Source list.
Point sources are idealized radiators and may produce degraded results when placed close to a surface. As a conservative guideline, keep point sources at least 0.5 m away from any surface. If your application requires a source at or very near a surface — for example, a wall-mounted device or a vibrating panel — consider using a boundary velocity layer source instead.
Basic examples
Omnidirectional source
The following example creates an omnidirectional source at a given location:
from treble_tsdk import treble
source_omni = treble.Source.make_omni(
position=treble.Point3d(1, 1, 1.5),
label="Omni_source"
)
Dipole and cardioid sources
The following example creates sources with dipole and cardioid directivity patterns:
source_dipole = treble.Source.make_dipole(
position=treble.Point3d(2, 1, 1.5),
label="Dipole_source",
orientation=treble.Rotation(azimuth=90)
)
source_cardioid = treble.Source.make_cardioid(
position=treble.Point3d(4, 1, 1.5),
label="Cardioid_source",
orientation=treble.Rotation(azimuth=180)
)
All directive sources are inserted into a simulation with their internally defined front axis (0°) aligned with the +X axis, as described in the spatial conventions(/how-to/spatial-conventions/) page. The dipole's front axis is aligned with its positive lobe.
Directive source from the library
A directive source can be created using a directivity retrieved from the directivity library. The following example retrieves a speech directivity and assigns it to a source:
directivities = tsdk.source_directivity_library.query(name="speech")
dd.display(directivities)
speech_directivity = directivities[0]
source = treble.Source.make_directive(
position=treble.Point3d(1, 1, 1.5),
label="Speech_source",
orientation=treble.Rotation(10, 0, 0),
source_directivity=speech_directivity
)
Directivity library query
The directivity library contains all default directivities as well as any directivities uploaded by members of your organization. To retrieve the full list:
source_directivities = tsdk.source_directivity_library.query()
# display the results as a table; the "Private" column indicates organization-uploaded entries
dd.as_table(source_directivities)
You can filter the query by category and subcategory, manufacturer, name, or organization. The following examples demonstrate each approach.
Query by category
Use the SourceDirectivityCategory enum to filter by category.
Both category and subcategory are optional:
directivity = tsdk.source_directivity_library.query(
category=treble.SourceDirectivityCategory.natural
)
dd.as_table(directivity)
To filter by subcategory as well, pass a value from the corresponding subcategory enum. For example, to retrieve speech directivities from the natural category:
natural_directivities = tsdk.source_directivity_library.query(
category=treble.SourceDirectivityCategory.natural,
sub_category=treble.SourceDirectivityNatural.speech,
)
speech_directivity = natural_directivities[0]
Query by manufacturer
The manufacturer filter searches for entries whose manufacturer field contains the given string. The search is case-insensitive:
jbl_directivities = tsdk.source_directivity_library.query(manufacturer="jbl")
dd.display(jbl_directivities)
jbl_directivity = jbl_directivities[0]
Query by name
The name filter works identically to the manufacturer filter, searching for entries whose name contains the given string:
source_directivities_by_name = tsdk.source_directivity_library.query(name="speech")
Filter by organization
To retrieve only directivities uploaded by your organization:
source_directivities = tsdk.source_directivity_library.get_organization_directivities()
dd.display(source_directivities) # empty if your organization has not uploaded any directivities
Source directivity plot
Source directivities can be visualized using two methods. To plot the on-axis sound pressure level at 1 m:
speaker = tsdk.source_directivity_library.query(name="8020")[0]
speaker.plot_spl_on_axis()
To visualize the directivity pattern as a sound pressure balloon. The plot is interactive — use the frequency slider to inspect the pattern at different frequencies:
speaker.plot_directivity_pattern()
Source list
Combine sources into a list for use in a simulation definition:
sources = []
sources.append(source_omni)
sources.append(source_dipole)
sources.append(source_cardioid)
If your simulation uses only one source, format it as a single-element list:
sources = [source_omni]
Advanced examples
Directivity upload from measured or simulated data
You can upload a custom directivity created from measurement or simulation data.
Construct a DirectivityPatternInputData object from the frequencies, measurement points, and frequency responses, and pass it to create_source_directivity in place of a file path.
The following example loads previously saved directivity data, uploads it to the directivity library if an entry with the same name does not already exist, and plots the resulting pattern:
import pickle
with open("data/speech_directivity_data.pkl", "rb") as file:
frequencies_input, points_input, point_input_data = pickle.load(file)
dir_data = treble.DirectivityPatternInputData(
frequencies=frequencies_input,
points=points_input,
frequency_responses=point_input_data
)
source_directivity_name = "imported-speech-directivity-demo"
source_directivity_obj = tsdk.source_directivity_library.get_by_name(source_directivity_name)
if not source_directivity_obj:
source_directivity_obj = tsdk.source_directivity_library.create_source_directivity(
name=source_directivity_name,
source_directivity_file_path=dir_data,
category=treble.SourceDirectivityCategory.natural,
sub_category=treble.SourceDirectivityNatural.other,
description="my import directivity",
)
source_directivity_obj.plot_directivity_pattern()
Directivity upload from a CLF file
You can upload a source directivity to the directivity library by supplying a .clf file.
Name, category, and file path are required; all other parameters are optional:
my_source_directivity = tsdk.source_directivity_library.create_source_directivity(
name="My source directivity",
source_directivity_file_path="data/Genelec+Oy-8020.CF2",
category=treble.SourceDirectivityCategory.amplified,
sub_category=treble.SourceDirectivityAmplified.studio_and_broadcast_monitor, # optional
description="Uploaded by me", # optional
manufacturer="Genelec Oy", # optional
correct_ir_by_on_axis_spl_default=True # optional, default True
)