mp4-sa-> the mp4-sa book-> SAOL->numbers and variables |
Sections
|
IntroductionIn this chapter, we describe the atoms of SAOL expressions:
We introduced these elements in the tutorial examples in Part I of this book. In this chapter, we provide a complete description of each element type. We explain the declaration syntax for variables, and define the rate and width properties for all elements. These properties are the foundation of the rate and width rules for SAOL expressions and statements covered in Part II/2. We also describe global parameters, and explain the rules for setting a-rate and k-rate values. |
|
NumbersNumbers in SAOL expressions are represented as 32-bit floating point quantities. The panel on the right shows correct and incorrect ways to write numbers in SAOL, in the context of a SAOL assignment statement. The SAOL language specification specifies the floating-point representation loosely ("32-bit") instead of requiring the IEEE 754 floating point format, so that digital signal processing chips that use non-standard floating-point formats may host compliant MP4-SA decoders. The rate and width rules we present in Part II/2 treat numbers as i-rate quantities with scalar width. There are several SAOL language constructs that use positive integers (for example, the width specifier in an array declaration). Unless otherwise noted, these integers may take any value up to 4,294,967,295. |
Legal number syntax:a = 32.0; // floating point number a = 32; // also floating point! a = -6.0; // a negative number a = .0923; // no digit before . ok a = -.0923; // even with minus sign a = 23e+12; // exponent may have plus, a = 23e-12; // minus, a = 23e12; // or neither a = 2.0e-12; // mantissa may have . a = .2e12; // no digit before . ok Illegal number syntax:a = +1; // illegal use of + a = 2e12.0; // illegal use of . a = 2 3e-1; // illegal space a = 2,302; // illegal comma Common error:a = 1/10; // is equal to 0.1, // not zero! |
NamesThe names chosen for variables must conform to SAOL naming rules. These rules also apply to other named elements in SAOL, such as buses and instrs. Names must start with a letter or the underscore symbol. The rest of the characters may be letters, digits, or the underscore symbol. SAOL names are case sensitive (abba and ABBA are different names in SAOL). Two names that share the first 16 characters are considered identical. SAOL language keywords, standard names, core opcode names, and core wavetable names may not be used as names. The right panel shows a list of these reserved words. In addition, all names starting with _sym_ are reserved. |
Reserved Wordsabs acos aexpon aexprand agaussrand aline alinrand allpass ampdb aopcode aphasor apoissonrand arand asig asin atan balance bandpass bandstop biquad buzz ceil channel chorus comb compressor concat cos cpsmidi cpsoct cpspch cpuload cubicseg data dbamp decimate delay delay1 destroy direction doscil downsamp dur else empty exp exports expseg extend fft fir firt flange floor frac fracdelay ftbasecps ftlen ftloop ftloopend ftsetbase ftsetend ftsetloop ftsetsr ftsr fx_speedc gain gettempo gettune global grain harm harm_phase hipass iexprand if ifft igaussrand iir iirt ilinrand imports inchan inchannels ingroup input input_bus inputmod instr int interp |
(continued)iopcode irand itime ivar k_rate kexpon kexprand kgaussrand kline klinrand kopcode koscil kphasor kpoissonrand krand krate ksig lineseg listenerDirection listenerPosition log log10 lopass loscil map max maxBack maxFront midicps midioct midipch min minBack minFront octcps octmidi octpch oparray opcode oscil outbus outchan outchannels output output_bus params pchcps pchmidi pchoct periodic pluck polynomial port position pow preset random released return reverb rms route s_rate samphold sample sasbf sblock send sequence settempo settune sgn sin soundfile spatialize speedt spline sqrt srate startup step table tablemap tableread tablewrite template time turnoff upsamp while window with xsig |
DeclarationsIf a signal variable appears in the code block of an instr definition, it also must appear in exactly one of two places in the instr definition: the parameter list of the instr preamble or the variable declaration block. Some instr variable declarations may also require a corresponding global declaration. The next three sections describe preamble parameter, instr variable, and global variable declarations. |
|
Instr ParametersParameter declarations are a part of the instr preamble. The panel on the right shows the three types of legal instr preambles, declaring zero, one, or many parameters. Each parameter and declared variable in an instr must have a unique name. Parameters hold 32-bit floating point values. Instr parameters are always scalar width and always i-rate. Syntactic elements such as ksig, imports, and [3] are illegal in a parameter declaration. As shown in the tutorial in Part I of the book, instrs may be instantiated by SASL instr commands or by SAOL send statements. In later chapters of the book, we show other ways to instantiate instrs in MP4-SA. Each type of instantiation has a method for initializing the value of the instr parameters. If the instantiation method does not supply an initialization value, the parameter is set to zero. Aside from the issues described above, instr parameters behave exactly like ivar scalar signal variables. |
Legal instr Preamblesinstr none () { } instr one (p1) { } instr many (p1, p2, p3) { } Illegal instr Preamblesinstr bad(imports p1) { } // illegal use of "import" instr bad1(ksig p1) { } // illegal: rates not allowed instr bad2(p1[4]) { } // illegal: array not allowed |
Instr VariablesSignal variable declarations in SAOL instrs occur after the open curly-brace of the instr preamble. The first SAOL statement in the instr marks the end of the variable declaration section: declarations and statements cannot be interspersed. Each declared variable and parameter in an instr must have a unique name. Signal variables hold 32-bit floating point values and are initialized to zero. ScalarsThe simplest variable declaration consists of a rate identifier (ivar for i-rate, ksig for k-rate, or asig for a-rate), a name, and a semicolon (see right panel for examples). These variables are scalars, and have width 1. Multiple variables can be declared on the same line, separated by commas. |
Legal Declarationsinstr foo () { ivar a; ksig b,c; asig d; b = a; } Illegal Declarationsinstr foo () { ivar a; // legal asig d; // legal a = 1; ksig b; // illegal: must precede a = 1; b = a; } |
ArraysArray declarations build on this syntax, by adding an open bracket, a width specifier and a closed bracket. Arrays and scalars may share the same declaration line. The width specifier, that sets the width of the array, is usually numeric (an integer greater than zero). Alternatively, the keyword inchannels or outchannels may serve as a width specifier. In an instr, arrays declared with the width specifier inchannels take the width of the audio input presented to the instrument. Arrays declared with the width specifier outchannels take the width of the audio data written by output statements in the instr. In Part II/5 we describe how to determine these widths for an instr. |
Legal Array Declarationsivar a[3]; ksig b,c[2]; asig d[inchannels],f[outchannels]; Illegal Array Declarationsivar a[0]; // illegal: must be >= 1 ksig c[2.0]; // illegal: must be integer |
Imports and ExportsGlobal variables are not visible inside of instrs by default. Global variables must be imported or exported by an instr to provide read or write access. This process involves declaring a variable in the instr with the same name and rate identifier as the global variable, prepended with the keywords imports and/or exports.Both scalar and array global variables may be imported or exported into an instr. The rate and width of the global and instr variables must be the same. Since globals may not be asig, neither may imported or exported instr declarations. See the right panel for examples. If an instr variable is declared with imports, then at the start of the i-pass (for ivars) or at the start of each k-pass (for ksigs), the value of the global variable is copied into the instr variable. If an instr variable is declared with exports, then at the end of the i-pass following instr instantiation (for ivars) or at the end of each k-pass (for ksigs), the final value of the instr variable is copied into the global variable. If both imports and exports are used, both behaviors described above happen. |
Legal imports and exportsglobal { ivar a, c; ksig b[3]; } instr example () { imports ivar a; exports ivar c; imports exports ksig b[3]; } Illegal imports and exportsglobal { ivar a; } instr example () { imports ivar a[2]; // illegal: size mismatch imports ksig a; // illegal: rate mismatch } |
Imports for SASLIf an instr signal variable is declared using the imports keyword, but no global variable of the same name exists in the global block, the import semantics described in the previous section do not apply. Instead, the imports keyword signifies that a variable may be targeted by a SASL labelled control command. This SASL command writes a new value into a ksig variable of an instr instance at the start of a k-pass. Only scalar ksig variables may be used in this construction, and only imports may be used in the declaration, not exports. An example in the tutorial in Part I shows this usage of the imports keyword in detail. A later section of this book explains SASL control statements in detail.
|
Imports for SASL:See tutorial example. |
Global VariablesGlobal signal variables are scalar or array variables declared in a global block of a SAOL program. Global signal variables may be declared ivar or ksig but not asig. The imports and exports keywords may not be used with global variables. Apart from these differences, global declarations share the same syntax as instr declarations. Global variable names must be unique among all the global variables. Array declarations may use the keywords inchannels or outchannels as width specifiers. For global arrays, these keywords indicate that the array should take the same width as the the input_bus or output_bus, respectively. These system buses are dedicated to external audio input and output, and are described in detail in Part II/5. Distributed Global BlocksThe MP4-SA standard states that only one global block may exist in a SAOL program. This restriction makes it difficult to develop modular SAOL libraries. Sfront relaxes this rule, and permits many global blocks in a SAOL program. To create MP4 files that comply with the standard, sfront collapses all global blocks into a single large global block when encoding .mp4 files. startupGlobal variables hold 32-bit floating-point numbers initialized to zero. To initialize global variable to non-zero values, define an instr named startup and assign initialization values to the global variables in its code block (using imports and exports to access the global variables). This method works because the SAOL instr execution rules ensure that if the instr startup is defined, it is instanced and run at i-rate as part of the start up sequence of a SAOL program, before the first k-cycle begins. In addition, by default the startup instrument executes first in each execution cycle, so that k-rate global variables may also be initialized. See Part II/5 for more details on the startup instrument. |
Legal Global Declarationsglobal { ivar a; ksig b[2],c; ivar d[outchannels]; ksig e[inchannels]; } Illegal Global Declarationsglobal { // all lines below are illegal asig a; // a-rate globals not allowed imports ksig c; // imports globals not allowed exports ksig c; // exports globals not allowed ivar d[0]; // width 0 not allowed } |
Standard NamesStandard names are read-only variables that hold system information. The panel on the right lists the SAOL standard names and the declaration each would have if it were a normal variable. This book describes most standard names in chapters related to their function. The list on the right panel includes links to the parts of chapters on buses, MIDI control, SAOL instrument control, and MPEG 4 integration that describe the standard names related to these topics. Two standard names are general purpose in nature, and we explain them now. The ivar standard name k_rate holds the k-rate of the SAOL program, and the ivar standard name s_rate holds the a-rate of the SAOL program. SAOL programs often compute constant values based on the value of k_rate and s_rate. The sfront distribution includes a library of SAOL utilities, called Slib, that defines a set of useful constants derived from k_rate and s_rate. |
Standard NamesDescribed in this sectionivar k_rate; ivar s_rate; For buses: see Part II/5ivar inchan; ivar outchan; asig input[inchannels]; ivar inGroup[inchannels]; For MIDI: see Part III/2ivar preset; ivar channel; ksig MIDIctrl[128]; ksig MIDItouch; ksig MIDIbend; For instr control: see Part III/3ivar dur; ksig itime; ksig released; ivar time; ksig cpuload; For AudioBIFS: see Sfront manualimports ksig position[3]; ksig direction[3]; ksig listenerPosition[3]; ksig listenerDirection[3]; ksig minFront; ksig maxFront; ksig minBack; ksig maxBack; imports exports ksig params[128]; |
Global ParametersGlobal parameters may be used to change system constants in SAOL. Global parameters are set in the global block, using the syntax shown in the right panel. Each global parameter may only be set once. Unlike instr parameters, global parameters may not be used as variables in SAOL expressions. Use the standard name related to the global parameter instead. There are five global parameters. The parameters inchannels and outchannels concern the special buses input_bus and output_bus and are explained in Part II/5. The parameter interp concerns wavetables and is explained in Part II/4. The last two global parameters, srate and krate, set the a-rate and k-rate of the system. The srate parameter may be set to an integer in the range 4000 Hz to 96000 Hz. The krate parameter may be set to an integer in the range 1 Hz to the audio sampling rate. The k-rate of a SAOL program defaults to 100 Hz. The a-rate of a SAOL program defaults to 32,000 Hz. (but see this exception if processing external audio input). If krate does not evenly divide into srate, the k-rate of the SAOL program is the first integer larger than krate which does evenly divide srate. |
Syntaxglobals { srate 48000; // note: no = } The Global ParametersDescribed in this sectionsrate krate For buses: see Part II/5inchannel outchannel For wavetables: see Part II/4interp |
Next section: Part II/2: Expressions and Statements |
|
mp4-sa-> the mp4-sa book-> SAOL->numbers and variables |