Introduction
The interaction of sound waves with internal and external boundaries plays an integral role in defining the acoustical behaviour of a room. The boundary interaction is the where the sound waves will lose a majority of their energy, with attenuation due to air absorption making up the remainder of the energetic losses in the simulation. Treble simulations use locally-reacting boundaries with complex impedances to model this boundary interaction, in accordance with the state-of-the-art in computational room acoustics. More information on these methods may be found in the Material Inputs in Treble technical reference page.
The Treble SDK comes with an extensive database of realistic materials, but also allows a user to define custom materials shared within the organisation.
Materials

Treble materials contain three acoustical properties relevant to simulations: scattering coefficients, random-incidence absorption coeffficients defined at each octave band between 63 Hz and 8 kHz, and complex reflection coefficients defined at the associated one-third octave bands. These properties are used as inputs for the GA and DG solvers, with the GA solver using all three properties to determine the attenuation, scattering, and phase of the simulation, and the DG solver using only the reflection coefficients. All materials are restricted such that the random-incidence absorption coefficients fall between 0.0 and 0.95, ensuring that the material may be used at-will for both GA- and DG- based simulations. The relationship between these three properties will be further explored in the documentation on Importing a Material.
MaterialDtos
An individual material can be accessed in the SDK as a MaterialDto
, which contains the following properties:
Property | Type | Description | Example value |
---|---|---|---|
id | string | A unique alpha-numeric identifier of the material. | 'b9f93015-8519-4b7e-898e-cb7efd845f3d' |
name | string | The human-friendly material name. | 'Wood' |
description | string | Additional information associated with the material. | '50 mm thick wood' |
absorptionCoefficients | list | The random-incidence absorption coefficients associated with the material, defined at 8 octaves. | [0.16, 0.15, 0.12, 0.09, 0.08, 0.08, 0.08, 0.07] |
category | string | The category which the material belongs to. | 'Wood' |
materialJson | string | JSON containing information regarding the material fitting. | |
materialMetadataJson | string | JSON containing information regarding the fitted material's properties. | |
defaultScattering | float | A single value numeric float used within the geometrical acoustics solver. | 0.25 |
userId | string | Identifier of user that create this material if was user-created. | 'bc85283b-9285-45e8-8200-9c56d9ac7c2a' |
organizationId | string | Provided if material is owned by an organization. | '380a3980-721a-4e80-95df-484f519c525c' |
These properties can be accessed directly from a defined material, such as the following examples:
# we work with an example material, assigned to the variable name wood_floor
wood_floor = tsdk.material_library.get_by_id('6981aefb-9d76-4498-8c9f-83aeb133d827')
# access wood_floor's Material Name
wood_floor.name
# check the material's category
wood_floor.category
# load the material Metadata JSON
import json
json.loads(wood_floor.materialMetadataJson)
Layers
After defining a room using one of the methods discussed within the Geometry documentation, the geometry's layers must be assigned materials before a simulation can be run. The simulation definition takes a list of MaterialAssignment objects of equal length to the number of unique layers within the geometry. To define this MaterialAssignment objects list, you will need the names of all layers within the geometry, as well the associated Treble materials.
Assigning Materials
The following code snippet shows you how to assign materials to the layers of a shoebox room generated as described in the Create Room documentation. For the sake of this example, we will assume that the shoebox room was generated with joined wall layers, so that there are three unique layers. This example creates a list of MaterialAssignments to define a basic room with wooden flooring and gypsum-board walls and ceiling. In the Material Library section a deeper dive is taken into the wide range of materials that are readily available in the Treble SDK. While creating the material assignment list, it is possible to overwrite an included material's default scattering coefficient. The new scattering coefficient may be provided as either a single-number value, or an array of 8 values between 0 and 0.99. In this example, we change the default scattering coefficient of the material assigned to the ceiling to a new single-number value.
# define a wood floor material, using get_by_id
wood_floor = tsdk.material_library.get_by_id('6981aefb-9d76-4498-8c9f-83aeb133d827')
# define a gypsum-board wall material, using get_by_name
walls = tsdk.material_library.get_by_name('Gypsum board nailed to studs')
# reuse the gypsum board walls for the ceiling
ceiling = tsdk.material_library.get_by_name('Gypsum board nailed to studs')
# create a list of material assignments
# change the default scattering coefficient for the ceiling layer
material_assignment = [
treble.MaterialAssignment(layer_name="shoebox_walls",material=walls),
treble.MaterialAssignment(layer_name="shoebox_floor",material=wood_floor),
treble.MaterialAssignment(layer_name="shoebox_ceiling",material=ceiling,scattering_coefficient=0.1)
]
The resulting material_assignment list is then passed to treble.SimulationDefinition()
.
This will be covered in the section on Initializing a Simulation.
Inspecting Materials
Plot
Calling .plot()
on a material will return a table and graph of its random-incidence absorption coefficients (used in the geometrical acoustics solver) and a graph of its complex reflection coefficients (used in the wave-based solver).
# define a gypsum-board wall material, using get_by_name
walls = tsdk.material_library.get_by_name('Gypsum board nailed to studs')
# plot the material
walls.plot()

.plot()
may also be used to visualise a fitted material prior to its inclusion in the material library.
For more information on importing materials, please see Import Material.
# Material fitting on an example material, nothing is saved in this step
fitted_material = tsdk.material_library.perform_material_fitting(material_definition)
fitted_material.plot()

As Tree
The dd.as_tree()
function returns detailed information about a material included within the material library, including the material name and ID, description, category, default scattering coefficient, and random-incidence abosprtion coefficients of the material.
Unlike .plot()
, dd.as_tree()
can only be used to examine materials already within the the material library.
dd.as_tree(walls)

As Table
A group of materials within the material library may be examined using dd.as_table()
, which displays the same detailed material information as dd.as_tree()
in table form.
all_materials = tsdk.material_library.get()
dd.as_table(all_materials[0:9])

Individual components
Individual properties of a material may also be directly accessed from the material object.
# we work with an example material
wood_floor = tsdk.material_library.get_by_id('6981aefb-9d76-4498-8c9f-83aeb133d827')
# load the material JSON
import json
wood_json = json.loads(wood_floor.materialJson)
# retrieve the input absorption coefficients used in the original fitting
wood_original_abs = np.asarray(wood_json['InputAbsorptionCoefficients'])
# retrieve the fitted absorption coefficients that came from the material fitting
wood_fitted_abs = np.asarray(wood_json['FittedAbsorptionCoefficients'])
# Check the values of the poles used in the fitting equation
wood_poles = np.asarray(wood_json['RealPoles'])
Like .plot()
, accessing the components of the material object directly is possible even for materials that have not yet been added to the material library.
The fitted_material used here was created following the procedure outlined in the Import Material material page.
Now, the following code snippet extracts the random-incidence absorption coefficients of a fitted_material to compare with the normal-incidence absorption coefficients derived from the complex reflection coefficients:
import json
# Material fitting on an example material, nothing is saved in this step
fitted_material = tsdk.material_library.perform_material_fitting(material_definition)
# Access the reflection coefficients from the fitted material
fitted_material_refl_json = json.loads(fitted_material.materialMetadataJson)
# Reconstruct the full complex reflection coefficients
fitted_material_refl = np.asarray(fitted_material_refl_json['RealReflectionCoefficient']) + \
1j * np.asarray(fitted_material_refl_json['ImagReflectionCoefficient'])
# Access the random-incidence absorption coefficients directly
fitted_material_abs = fitted_material.absorptionCoefficients