Although Syntacts does not yet officially provide a wrapper for MATLAB, it is still possible to load and use the raw Syntacts C library. This tutorial will demonstrate how to set this up and basic usage. For a comprehensive guide to Syntact’s API, refer to the C++ API tutorial. The interface will not be exactly the same since C does not have classes, but the names of the exported C functions are such that you should be able to figure things out (e.g.
Session.play(...) in C++ will be
Session_play(...) in C).
- compatible C/C++ compiler
- latest Syntacts Release
Setting Up the MATLAB Compiler
To import the Syntacts library into MATLAB, you first need to have installed a compatible C/C++ compiler. This table lists the various compilers compatible with each MATLAB release.
Unless you decide to build the Syntacts C library from source using your own compiler, you need to also ensure that your compiler is compatible with compiler that was used to build the Syntacts Release:
- On Windows, we use MSVC to build Syntacts. Versions 2015, 2017, and 2019 should work. MinGW may work. Feel free to try.
- On macOS, we use XCode (i.e. Apple Clang) to build Syntacts. Install the latest version of XCode from the Apple Store.
For this example, we will use MATLAB 2020b and MSVC 2019 on Windows 10.
Loading Syntacts into MATLAB
- From the
cfolder in the latest Syntacts Release, extract
libsyntacts_c.dylibon macOS) to a location of your choice.
- Open MATLAB and set the working directory to the location containing the header file and library.
- The following code can be used to load Syntacts:
- You can list the available functions with:
ADSR_create Session_open1 ASR_create Session_open2 Add_FltSig Session_open3 ...
Using Syntacts from MATLAB
Once the library is loaded, you can create a Syntacts Session and open a device:
s = calllib('syntacts_c','Session_create'); calllib('syntacts_c','Session_open1',s);
With an open device, you can proceed to create and play Signals:
% equivalent to Signal = Sine(440) * ASR(1,1,1,1) in C++ sine = calllib('syntacts_c','Sine_create2',440); asr = calllib('syntacts_c','ASR_create',1,1,1,1); sig = calllib('syntacts_c','Product_create',sine,asr); % play Signal on channel 0 (left speaker will be audible) calllib('syntacts_c','Session_play',s,0,sig); % close device calllib('syntacts_c','Session_close',s)
MATLAB doesn’t know how to free the resources that Syntacts creates, so we must do so explicitly to avoid memory leaks:
% free Signals calllib('syntacts_c','Signal_delete',sine); calllib('syntacts_c','Signal_delete',asr); calllib('syntacts_c','Signal_delete',sig); % free Session calllib('syntacts_c','Session_delete',s);
Finally, when you are done using Syntacts, don’t forget to unload the library:
As you can see, while it is possible to use Syntacts from MATLAB, doing so is quite cumbersome. Therefore, we recommend that you create wrapper classes or functions around the Syntacts library features you plan to use. For example:
% Syntacts.m classdef Syntacts < handle properties session end methods % constructor function obj = Syntacts(dev_idx) loadlibrary('syntacts_c','syntacts.h'); obj.session = calllib('syntacts_c','Session_create'); calllib('syntacts_c','Session_open2',obj.session,dev_idx); end % destructor function delete(obj) calllib('syntacts_c','Session_close',obj.session); calllib('syntacts_c','Session_delete',obj.session); unloadlibrary('syntacts_c'); end % play sine wave Signal function play(obj,ch,freq,amp,dur) sine = calllib('syntacts_c','Sine_create2',freq); env = calllib('syntacts_c','Envelope_create',dur,amp); sig = calllib('syntacts_c','Product_create',sine,env); calllib('syntacts_c','Session_play',obj.session,ch,sig); calllib('syntacts_c','Signal_delete',sine); calllib('syntacts_c','Signal_delete',env); calllib('syntacts_c','Signal_delete',sig); end end end
S = Syntacts(6); % make a Syntacts Session with device 6 S.play(0,250,1,1); % play a Signal on channel 0 S.play(1,175,0.5,1) % play a Signal on channel 1 clear S % resources will be automatically freed
Eventually we hope to support MATLAB in an official capacity using wrapper objects similar to that presented here. If this is something you would like to help with, feel free to contribute a Pull Request on the GitHub repository!