Guide to ATK Matrix Files:
Filter:
Guides (extension) | Libraries > Ambisonic Toolkit > Guides & Tutorials

Guide to ATK Matrix Files
ExtensionExtension

A guide to reading, writing, and storing ATK matrices.

Directory Structure

The ATK store assets in its Application Support directory:

This includes three default directories:

These folders store the files shipped with the ATK. We can also optionally add our own extensions folder, in which we can store kernels and matrices of our own design. Note this is different from SuperCollider's Extensions folder. If we haven't yet added an extensions directory, we can see where to put it by executing the following method:

There's a handy method that will build it for we in the expected structure:

This will create a directory structure that lives in our next to our default ATK assets. Note this creates both a matrices folder structure, and an identical kernels folder structure for storing our custom kernels. The full structure will look like this:

Each of the folders (FOA>encoders, HOA5>decoders, etc.) are empty and ready to store matrices (and kernels) for use with the ATK-SC3 (this package) and ATK-Reaper (more on that later). When we write a matrix using the ATK, it will store it in this directory structure by default, and will look here by default when asked to read in a matrix from file.

We can view this structure and any files you've stored there using the following method:

Each of these matrix subdirectories can have further subdirectories at your discretion, e.g. for particular projects or categories of matrices.

Writing Matrices

We'll start by writing a matrix file.

Let's create a first order A-format encoding matrix from a nine-point spherical t-design. For our purposes, we'll use a spherical designs with d = 2, giving a collection of uniformly distributed points on a sphere. The t-design we're using below can be found in Hardin and Sloan's Library of 3-D Designs. 1

This FoaEncoderMatrix is now ready to be used for encoding planewaves arriving from those nine uniformly distributed incidences. Within the ATK's classification hierarchy, ~encoder looks like this:

settypeopkind
'FOA''encoder''matrix''dirs'

For fun, let's inspect:

After all that hard work (thanks ATK!), we want to store the result to a file for use in the future, and to use in ATK-Reaper plugins! 2

There are three available file formats, each with a special purpose:

Let's write this encoder matrix out in all three formats:

Because we only specified a file name, not a full path, the ATK will store the matrix in the default location. As we're writing an FoaEncoderMatrix, ATK can infer that it's an encoder in the FOA set. (We also know, we're dealing with a matrix operation.) Therefore, the ATK knows to put it in: ../extensions/matrices/FOA/encoders.

Had we specified a full path instead, it would have saved to that location.

Writing Metadata

Because this matrix encoder is somewhat unique, it would be helpful to provide a bit more information about it for future reference. This is where the .yml file format comes in.

Note that the AtkMatrix: -writeToFile method has some optional arguments: note and attributeDictionary. A note can be a brief description, while an attributeDictionary is a Dictionary for storing any info you'd like in the form of key:value pairs. Information found in the attributeDictionary can be retrieved via AtkMatrix: -fileParse. An example of this is illustrated below.

NOTE: If keys in the attributeDictionary match instance variables of FoaEncoderMatrix, they can be retrieved with getters once loaded from the file.

Now write this matrix and metadata to file... Be sure to specify the .yml extension in order to write the metadata. Set overwrite = true to force overwrite the file we wrote before with the same name and extension.

Writing Raw Matrices

In the above examples, we've been reading/writing matrices encapsulated in the AtkMatrix subclasses. When writing from these objects, some the information can be inferred from them, such as the set (Ambisonic order, channel ordering, channel normalisation, e.g. 'FOA', 'HOA3', etc.) and type of matrix (e.g. 'encoder', 'decoder', 'xformer'). In the case of a raw matrix, the appropriate subclass must be called explicitly.

Metadata is useful to record more information about the matrix:

Now, given the matrix, a subclass instance can be created using the *newFromMatrix class method. In this case we'll be using FoaEncoderMatrix: *newFromMatrix, as we're making an encoder.

NOTE: If providing a file path relative to our /ATK/extension/matrices/...directory, set and type arguments are necessary when creating the AtkMatrix from our Matrix in order to locate the proper directory to store our file. If providing an absolute file path, set and type are recommended but not strictly enforced. This allows storing matrices outside the ATK paradigm, e.g. VBAP matrices, etc.

There it is:

Subfolders: Organizing our matrices

If you'll be generating many matrices, it's advisable to organize our matrices into subfolders. For example, if you're algorithmically generating hundreds of matrices for a particular project or process, it makes sense to store them in a subfolder.

To do this, we can create subfolders inside our /encoders, /decoders, and /xformers folders.

NOTE: Remember that because ~encoder is an FoaEncoderMatrix, the set ('FOA') and type ('encoder') arguments are inferred.

FoaEncoderMatrix: *newFromMatrix can be used to read the file back in. The ATK will know where to look (extensions/matrices/enocoders/FOA) so we can simply specify the relative path of our subfolder/file.yml:

Reading Matrices

We wrote three encoder matrix files earlier. Let's now read them in. As when writing, the ATK looks in the extensions/matrices directory by default. Unless the matrix file is somewhere outside the default location, a filename will suffice to read it in. The type ('encoder', 'decoder', 'xformer') is inferred from the object being instantiated.

We can even omit the file extension if we don't expect multiple file formats (.txt, .yml, .mosl.txt) stored under the same name:

So, we'll need to specify the extension. As mentioned before, each file format determines what kind of information is stored in the file.

Lets have a look at what each file format gives us back:

.txt format:

.mosl.txt format:

.yml format:

Test case: Creating a decoder from an FoaEncoderMatrix

We've now instantiated a new ~encoder by reading in the file that stored the matrix that we originally built using the planewave encoder: FoaEncoderMatrix: *newDirections (using the points of a nine-point t-design). As it turns out, a matrix encoder created by FoaEncoderMatrix: *newDirections can be used to build a decoder of the same geometry.3 Doing so just involves performing the Matrix: -pseudoInverse on the encoder's Matrix.4

Using these coefficients will return a 'velocity' decode (aka "strict soundfield" or "basic"). Loudspeakers should be positioned in the following directions (and in this order):

NOTE: Because we're inverting an encoder to produce a decoder, the original input directions of the encoder will now be the output directions of the decoder. The channel ordering will be in the same order the input directions were specified in the encoder. Therefore, in the above code we query the encoder for its -dirInputs to know where our output channel signals are expected to be sent (in space!).

Let's go ahead and finish off the job and use the resulting raw matrix to create a decoder instance:

And... have a go!

[1] - Hardin, R. H. and Sloane, N. J. A., "Sperical Designs", http://neilsloane.com/sphdesigns/, accessed on July 29, 2016.
[2] - ATK-Reaper will support matrix loading in an upcoming release.
[3] - Recall the ATK's matching A-format encoders and decoders!
[4] - This decoder design method is often described as pseudo-inverse or mode-matching.