Introduction
Libaudioverse is a system for the development of realtime audio effects and synthesis. Its capabilities include filters, 3D simulation, oscillators, and a variety of other useful tools needed to construct engaging audio experiences. The readme provides a detailed overview from the perspective of why you might wish to use Libaudioverse, whereas this manual is focused on how it works. If you found this manual first, the readme is a much better place to start.
The rest of this manual discusses Libaudioverse from a technical point of view. You probably want to read in order, though advanced readers may prefer to skip to the technical overview. When demonstrating concepts, the programming language of choice for this manual is Python, but a discussion of the C API can be found here.
Libaudioverse is programming language agnostic. Where possible, language bindings will contain specific documentation in the format most common to your language of choice, but it is impractical for this manual to cover all languages. In order to find out if documentation is available for your language, see the readme.
Overview
This section tries to get you started with Libaudioverse quickly. A high-level technical overview can be found further along in this manual, but this section is probably what you actually want when you’re starting. Reading in order is recommended.
Each subsection starts with some Python code and follows it with an explanation. The translation to the C API should be fairly straightforward. In the cases where it is not, this manual will make an effort to tell you what you need to use.
Note that the following examples are written against Python 3, but the needed changes for Python 2 are minimal.
Playing a Sine Wave
Output a sine wave for 5 seconds:
import libaudioverse import time libaudioverse.initialize() #Create a server using the defaults. server = libaudioverse.Server() #A sine node synthesizes a sine wave: sine = libaudioverse.SineNode(server) #In order to output, we connect to the server. #See below for notes on the C API. sine.connect(0, server) #or sine.connect(0, sine.server) #The server will play once it has been told to use a specific output device. server.set_output_device("default") time.sleep(5.0) libaudioverse.shutdown()
This program synthesizes a sine wave for 5 seconds using a sine node. The default frequency for a sine node is 440 HZ.
The first and last lines are simple initialization, and every program needs them.
Failure to initialize Libaudioverse will lead to errors, as will attempting to access Libaudioverse objects after shutdown.
For exploration in a REPL, it is generally safe not to call shutdown
.
Failure to call shutdown
will crash rarely, but it is still very important to have it in production code as this can and will happen.
Nodes are referred to by their class names (SineNode
), their C enumerations (Lav_OBJTYPE_SINE_NODE
) or an English description derived from their name, depending on the context in this manual.
For the most part, nodes either synthesize, process, or analyze audio.
Almost all nodes have inputs and outputs, numbered starting at 0. Each output carries 1 or more channels of audio and each input accepts one or more channels of audio. The node referencedocuments the meanings of each input and output, as well as how many channels they have. With a few rare exceptions, nodes have at most one of each.
When we call the connect function (Lav_nodeConnect in the C API), we are telling Libaudioverse where to send the output. Though not shown here, it is possible to connect an output to multiple inputs at the same time.
When you connect outputs to destinations with different channel counts, Libaudioverse will automatically do the necessary conversions to make everything work. There is a detailed description of this algorithm elsewhere in this manual, but for the most part you need only know that Libaudioverse understands and automatically converts between mono, stereo, 4.0, 5.1, and 7.1 without input on your part.
Libaudioverse identifies output devices with strings. The special string "default" specifies the system’s default audio device. If it can, Libaudioverse will attempt to follow changes in the default audio device, as is expected on platforms like Windows.
Servers hold global state such as the current output device.
There are other ways to get audio from a server, but the one shown here is server.set_output_device
.
This call (Lav_serverSetOutputDevice in C)sets the output device.
If you want to change it later, you can simply call it again.
This example demonstrates one of the two special types of connection.
The line sine.connect(0, server)
connects output 0 of the sine node to the server.
Libaudioverse overloads the connect function in any language which supports function overloading.
because C doesn’t, the C bindings expose this functionality as Lav_nodeConnectServer.
Finally, it is worth discussing when nodes advance a block. Libaudioverse processes audio in blocks. The size of these blocks is set when you create the server. With the default settings, the duration of each block is about 23 milliseconds. The rules are simple, and mostly do what you want:
-
The server advances if it’s connected to an audio device or if you ask it for a block of audio.
-
A node never advances if its state is set to paused. This will be discussed later in this overview and is used to pause playing files, for example.
-
A node always advances if its state is set to always playing. This is not discussed much in this overview because it is something that you almost never need to do.
-
A node advances if it has an output connected directly to the server.
-
A node advances if it has an output connected to any node which is advancing.
-
In all other cases save one exception (see the section on 3D audio), a node never advances.
While this looks complicated, you can for the most part ignore it. If you build a chain of effects and the last effect is connected to the server, then it works exactly as you expect it will.
Automating Properties
import libaudioverse import time libaudioverse.initialize() s=libaudioverse.Server() n = libaudioverse.SineNode(s) n.frequency = 0 n.connect(0, n.server) s.set_output_device(-1) #Recall that Python omits the last value. for i in range(0, 1010, 10): n.mul.value = i/1000.0 n.frequency.value = i time.sleep(0.02)
This example has audible artifacts. The reasoning for this and how to fix it will be explained in a later section.
In addition to inputs, all nodes have properties.
Every node has at least mul
and add
.
Mul
represents volume and ranges from -INFINITY to INFINITY.
If you set mul
to a negative value, the node’s output will be negated.
Add
, not shown here, is the second of 3 standard properties, and adds a specific amount of DC offset.
Oscillators such as the sine node also have a number of other properties.
Every oscillator has frequency
, phase
, and frequency_multiplier
.
Frequency
is always in hertz, and phase
is on the range 0 to 1.
Frequency_multiplier
is an additional multiplier applied to the frequency of the oscillator, and is useful when building instruments; moving up and down by an octave on the musical scale is a doubling or halving of the frequency.
In the C API, properties are specified by numeric identifiers and set with functions like Lav_nodeSetIntProperty or Lav_nodeSetFloatProperty.
The identifiers for the properties used in the above example are Lav_NODE_MUL
, Lav_NODE_ADD
, and Lav_SINE_FREQUENCY
.
Other properties follow a similar nomenclature.
Buffers and Playing Files
The following loops a file. It understands three commands: play, pause, and quit.
import libaudioverse libaudioverse.initialize() server = libaudioverse.Server() print("Enter a path to a sound file.") path = input() buffer=libaudioverse.Buffer(server) buffer.load_from_file(path) buffer_player=libaudioverse.BufferNode(server) buffer_player.buffer = buffer buffer_player.looping = True buffer_player.connect(0, server) server.set_output_device("default") while True: print("Play, pause, or quit?") command = input() if command == "play": buffer_player.state = libaudioverse.NodeStates.playing elif command == "pause": buffer_player.state = libaudioverse.NodeStates.paused elif command == "quit": break libaudioverse.shutdown()
A buffer represents a chunk of decoded, resampled audio. They can be loaded from a number of sources, but by far the most common is from a file.
Buffer nodes play the specified buffer, and have some properties of interest:
-
buffer
is the buffer itself. -
position
is the position of the audio, in seconds. -
rate
is the playback rate of the buffer. 1.0 is identity. 2.0 is twice as fast and 0.5 is half as fast. -
looping
causes the buffer to loop, if true. -
ended_count
increments every time the buffer ends. You can reset it by writing to it.
As mentioned above, buffers store uncompressed, decoded audio data as float32, resampled to match the sampling rate of their server. This means they are quite large. Caching buffers is therefore very highly recommended, as 1 second of mono audio will take 176KB and a minute of stereo audio will take about 21 MB. You cannot share buffers between servers, but you can easily share them between buffer nodes.
Finally, this section introduces the above-mentioned node state.
A node’s state is set through the state
property, identified in C as Lav_NODE_STATE
.
Nodes have 3 states:
-
Playing or
Lav_NODESTATE_PLAYING
in C: this node advances if it is directly or indirectly connected to the server. The default. -
Paused or
Lav_NODESTATE_PAUSED
: this node never advances no matter what, and any nodes that would have advanced because of a connection to it won’t either. -
Always playing or
Lav_NODESTATE_ALWAYS_PLAYING
: This node always advances and any nodes connected to it always advance as well. You will probably never use this one, but it’s there for some advanced apps.
Panning
This sets up a panner that you can play with in the Python REPL. Use python -i test.py
or similar to run it.
import libaudioverse import time libaudioverse.initialize() s=libaudioverse.Server() buffer_player = libaudioverse.BufferNode(s) buffer = libaudioverse.Buffer(s) buffer.load_from_file("sound.wav") buffer_player.buffer = buffer buffer_player.looping = True panner=libaudioverse.MultipannerNode(s, "default") buffer_player.connect(output = 0, node = panner, input = 0) panner.connect(0, s) s.set_output_device(-1)
Multipanners are the most commonly used panner, as they support switching between HRTf, stereo, 4.0, 5.1, and 7.1 at runtime and without recreating objects.
The second parameter to the multipanner constructor is the path to an HRTF file. As a special case, Libaudioverse recognizes the string "default" in all contexts in which an HRTF path is required. This is an instruction to use the dataset embedded in the Libaudioverse assemlby, and will be what most applications want.
At this time, the default HRTF only works well if you use the default sample rate of the server: 44100 HZ. making Libaudioverse resample HRTF datasets is on the to-do list however, so you can expect this to improve.
The multipanner is an example of a node with an input. Inputs are also numbered starting at 0, and accept a specific number of audio channels. In this case, the multipanner has only one mono input.
The three properties of interest on a multipanner are azimuth
, elevation
, and strategy
.
All panners have the first two, but strategy
is unique to the multipanner.
Azimuth
is an angle in degrees, such that 0 is straight in front, 90 is straight to the right, 180 is behind, and 270 is to the left.
Angles greater than 359 will wrap and negative values are allowed.
Elevation
is an elevation from the horizontal plane, ranging from -90 to 90.
Unlike azimuth
, elevation does not wrap, and is only audible when using the HRTf strategy.
Finally, strategy
controls the panning strategy to use.
You may see the allowed values by inspecting the Lav_PANNING_STRATEGIES enumeration, bound in Python as libaudioverse.PanningStrategies.hrtf
, libaudioverse.PanningStrategies.stereo
, etc.
Higher-level 3D components
This example sets up a source and an environment with HRTF enabled.
As with the above example, copy it to a file and run with python -i
.
import libaudioverse libaudioverse.initialize() s=libaudioverse.Server() b=libaudioverse.Buffer(s) b.load_from_file("sound.wav") n=libaudioverse.BufferNode(s) n.buffer = b e = libaudioverse.EnvironmentNode(s, "default") e.panning_strategy = libaudioverse.PanningStrategies.hrtf e.output_channels = 2 e.connect(0, s) o=libaudioverse.SourceNode(s, e) n.connect(0, o, 0) s.set_output_device("default")
The 3D components of Libaudioverse primarily involve two objects: an environment and a source node.
Environments represent the listener, provide defaults for new sources, aggregate source output, and allow for the creation of effect sends (see the next section).
Sources act as simple speakers. A source takes the environment from which it is to be created as the second parameter to its constructor. All audio sent through sources is panned, aggregated, and sent through output 0 of the source’s environment.
It is important to note that unlike other nodes, sources are always connected to the environment with which they were created. This is the exception mentioned in the advancement rules above.
Unlike other nodes, this connection is implicit and weak. In the usual case, keeping a node alive will recursively keep all nodes connected to its inputs alive as well. Sources break this rule. As a consequence, you need to be sure to keep sources alive for as long as they are needed. If you do not hold a strong reference to them, they will be garbage collected. This is usually what you want. You can find more information on object lifetimes in the technical overview.
Environments and sources are the only nodes to make use of float3
and float6
properties, vectors of 3 and 6 floats respectively.
In Python, these are represented as 3-tuples and 6-tuples; changing only one component at a time is not allowed because vector updates need to always be atomic.
An environment has two properties of note, position
and orientation
.
Position
is the position of the listener, and orientation
the listener’s orientation.
Position
is represented as a float3, that is a vector of x, y, and z.
Without changing the orientation, the default coordinate system is as follows: positive x is right, positive y is up, and negative z is forward. This was chosen to match OpenGL and OpenAL.
Orientation is represented as a float6
.
The first three values of this are the at vector, a unit vector pointing in the direction that the listener is facing.
The second three are the up vector, a unit vector pointing in the direction of the top of the listener.
These vectors must always be perpendicular.
If they are not, undefined behavior results.
There are two useful values for the orientation
property.
The first, (0, 1, 0, 0, 0, 1)
orients the coordinate system such that positive x is right, positive y is forward, and positive z is up.
This is useful for side-scrollers or other applications that do not involve turning.
The second is provided as a reference for those who do not know trigonometry, you can import math and use (math.sin(theta), math.cos(theta), 0, 0, 0, 1)
to represent orientations as radians clockwise from north.
In this coordinate system, positive X is right and positive Y is north.
If you need to use degrees, note that theta = degrees*math.pi/180.0
.
There are two immediately interesting properties on sources.
The first is position
, the same as the environment’s position but for sources.
The coordinate system of a source depends greatly on how you calculate the orientation of the listener, but using either or both of the above-suggested values will allow you to make east positive x and north positive y.
The other is occlusion
, a value from 0 to 1.
This property controls an occlusion model, such that 0 is unoccluded and 1 is fully occluded.
Libaudioverse is unfortunately incapable of calculating occlusion for you, as this depends greatly on how you represent your level maps.
If you periodically update the occlusion
property on all sources, however, Libaudioverse is more than happy to synthesize it.
There are many other properties on sources controlling the distance model and panning technique, but this section is quite long enough as-is. You will want to be sure to read the Environment Node documentation and the Source Node documentation.
Finally, we must discuss output_channels
and panning_strategy
.
For technical reasons beyond the control of Libaudioverse, it is not possible to properly detect the type of audio device the user is using. For this reason, the environment defaults to normal, stereo panning. This is safe on basically every setup imaginable.
Every source has a panning_strategy
property which can be used to change it for that source.
By default, however, this is set to PanningStrategies.delegate
(Lav_PANNING_STRATEGY_DELEGATE
).
This special value behaves as stereo panning in any case save the 3D components.
In the context of a source, it tells the source to get its panning strategy from the environment by looking at the environment’s panning_strategy
property.
By default, all sources delegate.
this means that you can change the panning strategy of all sources by reconfiguring the environment.
Unfortunately, it is possible for sources to have different panning strategies from one another. This is somewhat intensional, as you might choose to use stereo on less-important sources and HRTF on more-important ones in order to save CPU processing power.
But it leads to a difficult-to-resolve ambiguity. If you set some of your sources to panning strategies with different channel counts, the environment is then unable to determine how many output channels it needs to have. You might have meant the one with the lower channel count, but you might also have meant the one with the higher channel count.
In order to make it explicit and deterministic, environments require you to also specify the output_channels
property.
Use 2 for stereo and HRTF, 4 for quad, 6 for 5.1, and 8 for 7.1.
Using Reverb
This snippet begins where the last example ended, and adds an environmental reverb.
As with the proceeding examples, run it with python -i
.
reverb = libaudioverse.FdnReverbNode(s) send = e.add_effect_send(channels = 4, is_reverb = True, connect_by_default = True) e.connect(send, reverb, 0) reverb.connect(0, s)
This example sets up an effect send, an additional output on the environment which is intended to be routed through effects. Sources also pan a copy of their audio through the effect sends, using any strategy but HRTF as determined implicitly by the channel count of the send To be more specific: 1 channel is mono, 2 is stereo, 4 is 4.0, 6 is 5.1, and 8 is 7.1. All other values are disallowed.
In this example we specify that all sources created and any created in future should be connected to the effect send, that it is for reverb, and that it has 4 channels. Any attempt to create an effect send for reverb without using 4 channels will error. Unlike non-reverb sends, effect sends for reverb pan their audio differently, such that the reverb fades in with distance.
create_effect_send
returns the index of the newly created output, which we then feed through an FDN reverb and then to the server.
In C, this function is [function-Lav_environmentNodeCreateEffectSend].
FDN reverbs are very simple reverberators.
The two most important properties are density
and t60
.
Density
ranges from 0 to 1, specifying how close together the reflections are.
T60
is the time it will take for the reverb to decay by 60 decibals, assuming that you play and then stop some input.
You can think of t60
as roughly analogous to the reverb’s duration.
FDN reverbs also contain configurable lowpass filters, and the ability to modulate the delay lines. See the documentation for more.
Note
|
While FDN reverbs support delay line modulation, this does not currently work well and will be fixed post-0.9. |
You have as many effect sends as you want, limited only by computation capacity. Sources have functions to connect and disconnect themselves from effect sends in a fully configurable manner, and you can feel free to make your own custom effects, as well as the ones demonstrated here.
Using Automators
Note
|
The following API needs to either be extended or thrown out. It is not yet clear which will occur. This is not an immediate concern, and the following API will exist in its current form until something better is in place and sufficient notice of any compatibility issues is given in accordance with Libaudioverse’s compatibility policy. |
This sets up a siren-like effect and then turns off the sine node.
import time import libaudioverse libaudioverse.initialize() s=libaudioverse.Server() n=libaudioverse.SineNode(s) n.frequency = 300 n.frequency.linear_ramp_to_value(1.0, 600) n.frequency.linear_ramp_to_value(2.0, 300) n.frequency.linear_ramp_to_value(3.0, 600) n.frequency.linear_ramp_to_value(4.0, 300) n.frequency.linear_ramp_to_value(5.0, 600) n.mul.set(5.1, 1.0) n.mul.linear_ramp_to_value(5.2, 0.0) n.connect(0, s) s.set_output_device("default") time.sleep(8.0) libaudioverse.shutdown()
The above example demonstrates automators. Libaudioverse processes audio in blocks, submitting each block to the sound card before beginning the next. During the processing of a block, no API call can have effect. The problem with this setup is that there is no way to allow user code to be called more rapidly than once per block. Worse yet, being called exactly once per block requires extra work and degrades performance. Automators exist to allow smoothe property modifications despite this limitation.
The linear ramp is an automator which begins moving the value of the property to the specified value. The first argument is the time at which the property must reach the target value erelative to the current time, and the second the value which must be reached. Set is a similar function, but instead moves the value instantaneously at the specified time. Note that all times are specified relative to now, and that it is not possible to schedule automators in the past.
What we do in the above example, therefore, is schedule a triangular sweep of the frequency between 300 HZ and 600 HZ. Then we schedule a fade-out using the set and linear ramp.
There are three notable points about automators worth specifically pointing out, though the first may or may not be obvious.
First, the linear ramp and many other automators use the "previous" value of the property. To that end, it is necessary to set the property to the starting point before automating it. If you don’t, then it will start from wherever it was last set; this may or not be a problem, depending on application structure.
Second, setting a property cancels all pending automators. This is to avoid strange conditions and make validation of inputs possible.
Finally, the setup with mul is a bit strange. Since linear ramps start immediately, it is often necessary to schedule another automator before them. Since we don’t want mul to start ramping until a bit after 5 seconds, we use the set automator. This makes the linear ramp’s previous value the endpoint of the set automator, such that it only takes effect afterwords. If that line is commented out, the sine node will get progressively quieter for the entire example rather than rapidly fading out at the end.
Properties come in two variations, a-rate and k-rate. Most properties are k-rate properties, and their value is computed once per block. Some are processed as much as every sample, such as the sine node’s frequency and the mul propperty on all nodes. These are referred to as the a-rate properties.
The biggest advantage of automators is that they are computed per-sample on a-rate properties.
Since both mul
and frequency
are a-rate, the above example will not become choppy, even should the block size be set absurdly high.
Connecting Nodes to Properties
Note
|
the above notice about the automation API needing a redesign does not apply to this section. The following functionality will always be available. |
This example sets up ring modulation. As with other examples, you will want to run it interactively; this one is worth experimenting with.
import libaudioverse import time libaudioverse.initialize() s = libaudioverse.Server() n1, n2 = libaudioverse.SineNode(s), libaudioverse.SineNode(s) n2.mul = 0.0 n1.frequency = 100 n2.frequency=400 n1.connect(0, n2.mul) n2.connect(0, s) s.set_output_device("default") time.sleep(10.0)
The above example shows how to connect the output of a node to a property, the third type of connection supported by Libaudioverse. In C, this is mapped to Lav_nodeConnectProperty. This works only with float and double properties. Attempting to do it to any other property type will produce an error.
As with automators, this type of control can be sample-perfect on a-rate properties. Unlike automators, connected nodes act as offsets to whatever the property would be without the node. It is common, therefore, to first set the target property to 0.
You can connect multiple outputs to the property. They function identically to 1-channel inputs, including downmixing logic.
While Libaudioverse already has a ringmod node which is admittedly much more efficient, this is the simplest example to demonstrate it with. A similar technique can be used to set up FM synthesis or continuous filter sweeping, as well as a wide variety of other interesting effects.
Technical Description Of Libaudioverse
This section of the manual describes Libaudioverse from a high-level perspective and provides technical details required to optimize and troubleshoot your application. For a gentler and much more hands-on introduction, see the overview.
Introduction
Libaudioverse is composed primarily of three object types: the server, buffers, and nodes.
The server is the main entry point, and is required for creating any other Libaudioverse object. All objects save for servers are themselves associated with servers. Attempts to combine objects from different servers are always errors.
Buffers represent chunks of decoded audio data, and can be loaded from a variety of sources. Buffers commonly hold data from files and are usually combined with a buffer node for playback.
Finally, nodes represent audio production, analysis, and transformation. They are by far the most complex and interesting object type in Libaudioverse.
Initialization
Before using Libaudioverse, call Lav_initialize. Failure to do so will result in crashes. When done using the library, call Lav_shutdown. Failure to do so may lead to crashes, depending on what is or is not created. It is not safe to assume that Libaudioverse will properly clean itself up at process exit without a call to Lav_shutdown, though failing to do so is common in exploratory situations for languages which provide a REPL.
You may initialize the library more than once: subsequent initializations do nothing. You must deinitialize the library exactly as many times as it has been initialized, no more.
Pointer Ownership and Object Lifetime
A Note for Users of Languages with Automatic Memory Management
The following sections are very complicated, but languages whichcan be integrated with Libaudioverse’s freeing logic handle all of it for you. Unless you are in C or another language where you must manually manage memory, all you need to know is that the following are strong references:
-
Given some node
a
and some other nodeb
, the calla.connect(some_output, b, some_input)
creates a strong reference fromb
toa
. The connection remains alive untilb
is collected or you explicitly kill it. -
Connecting to properties creates a strong reference in the same manner as above. So does connecting to the server.
-
The server is alive as long as something created from it is alive.
Finally, deinitialization of the library kills all the objects on the library’s side. You should never use anything after deinitializing the library.
Everything related to pointer ownership and keeping pointers alive is handled deep inside the bindings to such languages. You need not concern yourself with it. Any language with concerns along these lines will clearly mention them in the documentation for that language.
Pointer Ownership
When Libaudioverse returns a buffer of memory, it almost always allocates a copy. Exceptions to this rule will be clearly documented.
The calling application is responsible for freeing this buffer, always through Lav_free.
Use of free
from the standard library on these pointers will cause memory leaks at best.
When Lav_shutdown is called, all pointers that libaudioverse allocated are immediately freed. Calling this function after the library is deinitialized does nothing.
Object Lifetime
Libaudioverse objects ar publicly exposed through reference-counted handles. There are three functions dealing with handle management: Lav_handleIncRef, Lav_handleDecRef, and Lav_handleGetAndClearFirstAccess. As above, calling these functions after library shutdown does nothing.
In order to be as fast as possible and to block as little as possible, Libaudioverse defers deletions to the end of the current block. This means that any pending callbacks for a deleted handle may still fire, depending on when and how they were called. Even if you think a handle should no longer exist, you should be prepared to see it again.
In order to be sane and avoid crashes, Libaudioverse creates strong references internally. Examples include connections (from the input of the target to the output of the source) and setting buffer properties. The rest of this section explains how this logic works.
A handle is either external or internal. Handles are external if and only if their reference count is greater than or equal to 1. The most common method of getting an external handle is to create an object. When a handle first transitions from the internal to external state, its reference count is always set to one. The function Lav_handleGetAndClearFirstAccess indicates whether a handle has just transitioned from the internal to external states, clearing an internal flag. This function exists primarily to assist bindings in knowing when they need to increment the handle’s reference count. When a handle’s reference count goes to 0, it is not immediately deleted but instead becomes internal once more.
Relationships between Libaudioverse objects will also keep handles alive by forming invisible and internal strong references. The following are the common cases in which this occurs:
-
A server is alive so long as any object created using the server is still alive.
-
A node is alive so long as it has an output connected to another node that is also still alive.
-
Buffers are alive as long as they are assigned to a buffer property, or otherwise in use.
In order to detect the death of a handle, Libaudioverse provides the Lav_setHandleDestroyedCallback function. Handle values are not reused unless the application manages to overflow a 32-bit signed integer. Most bindings therefore use the proxy pattern: the objects that user code deals with are thin proxies containing the handle and a pointer to global state. When the handle destroyed callback is called, the global state is then destroyed. This allows for keeping callback objects and other such resources alive in languages with garbage collectors, as not to invalidate pointers held by Libaudioverse. The handle destroyed callback must do its best to not block whenever possible, as it may be called from any thread.
The Server
The server is the main entry point to Libaudioverse.
The two most crutial pieces of information needed for the server are the block size and sample rate. The latter is self-explanatory. The block size is the number of samples to process at once, and must be a multiple of 4. Servers are created with Lav_createServer. The strongly suggested defaults for these parameters are 1024 and 44100 respectively. These are sufficient and performant for most applications.
By default, Libaudioverse will use one thread per core on the current system for audio mixing. This may be changed via Lav_serverSetThreads.
Servers handle audio output and hold state, provided via dependency injection to created objects. All Libaudioverse objects are associated with exactly one server in a permanent manner. Any attempt to use a pair of objjects from different servers together will error.
Audio Output
Servers are the final destination for audio, and output may be retrieved in 3 ways. In all cases, Libaudioverse applies the audio upmixing and downmixing algorithms as specified here to reach the required channel count. None of the following three methods of receiving audio should be mixed; doing so results in undefined behavior.
Lav_serverGetBlock fills a buffer allocated by the calling application with a block of audio data.
Lav_serverWriteFile drives the server for the specified duration, synthesizing as fast as possible and writing to the specified file. The file format is determined from the extension of the provided path. The supported file formats are not currently documented as this is in flux, but you are guaranteed to have at least .wav and .ogg.
The final option is to call Lav_serverSetOutputDevice. This links the server to a specific audio device.
Libaudioverse represents specific audio devices with string identifiers. These strings should be considered opaque. They should never be stored. In future, Libaudioverse will make a best effort to allow you to put them in configuration files, but this functionality is not currently implemented. The format of these strings is subject to change.
The default audio device is the string "default". Where it can, Libaudioverse will attempt to follow any changes in the default audio device.
Multiple calls to Lav_serverSetOutputDevice are allowed, though playback may not be gapless.
Important
|
Audio stacks are limited. There is no reliable way to properly detect channel counts for all setups. For this reason, your application should assume that it is running on a set of stereo speakers (2 channels, don’t apply HRTFs) until the user specifies otherwise. If you use the wrong channel count, Libaudioverse will apply the remixing algorithms but the experience will be sub-par. Always trust the user; if it is important for your application to know if it is running on surround sound, ask or direct users to an options menu before choosing on their behalf. |
Atomicity and Batching Calls
Libaudioverse outputs audio in blocks. When outputting to an audio device, any operation which may be completed with one function call will either be completely audible or not audible on the next block. If the operation in question can be done in one function call, hearing partial results is not possible.
There are three ways to ensure that operations which take more than one function call are only audible when finished:
-
Perform the operations on a set of disconnected nodes before connecting them.
-
use Lav_serverLock and Lav_serverUnlock. Note that, as these function names imply, servers function as mutexes; lock inversion and other concerns can apply in multithreaded scenarios.
-
Set a per-block callback which Libaudioverse will call just before mixing every block. This can be done with Lav_serverSetBlockCallback.
Most applications will want to use Lav_serverLock before beginning their per-frame audio update, and Lav_serverUnlock afterwords. Failure to call Lav_serverUnlock in a timely manner will cause audio glitching; failure to call it at all will cause silence and freeze Libaudioverse’s background threads.
The per-block callback is for advanced synthesis applications which need a stronger guarantee: not only is the operation happening completely before the next block, it is running every block. Using the per-block callback for a game’s frame updates will lead to massively degraded performance. You should only use it when controlling nodes exactly every block is important.
Buffers
Buffers store un-encoded float32 audio data at the sampling rate of the server. They can be loaded from files or arrays, and will resample the data exactly once when loaded. Buffers are most commonly used with buffer nodes.
Save for the contained audio data, buffers are stateless; using them requires coupling them with a node. Since buffers are quite large, using a cache is recommended. Buffers may safely be used in more than one place at a time. Modifying a buffer’s audio data while it is in use will result in an error.
Nodes
Nodes represent audio transformation, genneration, and analysis. This section discusses nodes generally, including the audio conversion algorithms, properties, and connection logic,. To see what kinds of specific nodes are on offer, see the Nodes reference.
Connections and Automatic Audio Channel Count Conversion
Nodes have 0 or more inputs and 0 or more outputs. Outputs are connected to inputs in a many-to-many relationship, such that each input acts as a mixer. Libaudioverse makes the opinionated decision that connections are made from outputs to inputs and broken in the same manner.
The two functions relevant to node-to-node connections are Lav_nodeConnect and Lav_nodeDisconnect.
Connecting nodes to the server is accomplished with Lav_nodeConnectServer.
Lav_nodeConnectProperty will be discussed later.
In languages with function overloading or sufficient flexibility to fake it, these three functions are often combined into one.
Any connection that would cause a cycle (i.e. a.connect(0, b, 0)
and b.connect(0, a, 0)
in Python) will error.
All inputs and outputs have a documented channel count. Libaudioverse has intrinsic understanding of the following channel counts, and can freely and automatically convert between them:
Count |
Name |
Order |
1 |
Mono |
Mono |
2 |
Stereo |
Left, Right |
4 |
4.0 Surround (quad) |
front left, front right, back left, back right |
6 |
5.1 surround |
front left, front right, center, lfe, back left, back right |
8 |
7.1 Surround |
front left, front right, center, lfe, back left, back right, side left, side right |
Where applicable, libaudioverse prefers to copy WebAudio’s conversion algorithms. This is used for everything save conversions involving 7.1. Regretfully, the WebAudio specification does not specify what to do in this case. To that end, Libaudioverse uses a custom algorithm that is subject to change.
If an input or an output has a channel count not found in the above table, then one of three things happens:
-
If the output is mono, then the mono output fills all channels of the input.
-
If the output has less channels than the input, additional channels are filled with zero.
-
If the output has more channels than the input, additional channels are dropped.
Conceptually, nodes have a time that is specific to each node. This time does not actually exist and cannot be queried, but makes a good metaphorical mechanism for understanding how nodes advance. You can observe it somewhat directly by looking at the position property on a buffer node.
If the node’s state is paused, time does not advance for it under any circumstance, and it simply always outputs zero. Time advances for a node if one of the following two conditions is true:
-
You can grab one or more of the node’s outputs and somehow follow them via any path whatsoever through nodes which are playing or always playing to the server.
-
The node’s state is always playing.
If some node a
has a connection to some node b
from an output of a
to an input of b
then a
will always execute before b
.
In addition, any callbacks that happen in the audio thread on a
will happen before any such on b
.
Properties
Properties control aspects of nodes in the manner that their name suggests. They are managed through a variety of functions depending on the property type, i.e. Lav_nodeSetIntProperty.
The full list of property management functions is too long to be listed here, but they all follow a similar naming pattern.
Lav_nodeSetTypeProperty
and Lav_nodeGetTypeProperty
, where Type
is the property’s type, are the most important.
Properties are always of one of the following types: int (32-bit signed integer), float, double, float3, float6, string, array of int, array of float, or buffer.
Boolean properties are int properties with the range 0 to 1, and are used as int properties in the C bindings. They exist for bindings generation and documentation clarity.
Some int properties must take their values from an enum. When this is the case, which enum is documented with the property.
Float3 and float6 properties are packed vectors primarily used for the 3D components. The purpose of float3 and float6 properties are to provide a fast path for orientations and positions, and to reduce need for Lav_serverLock and Lav_serverUnlock with the 3D components of this library.
There are three standard properties on all nodes. They are as follows, with more complete documentation here:
-
State
. An int. This property takes its value from the Lav_NODE_STATES enumeration. Nodes which are playing are used as-needed. Nodes which are paused act as though they are always outputting zeros. Nodes which are always playing always process, even if no one needs their output. The default is playing. -
Mul
. A float. This is a multiplier (naively volume) which is applied to the node’s outputs beforeadd
. -
Add
. A float. This is an additional additive factor (DC offset) applied to the outputs of the node after the application ofmul
.
Automation and Property Connections
While all other types of properties are exactly the value they are currently set to, float and double properties have two additional features which allow for fine-grained control. The value of a float or double property is actually a sum of all of the following:
-
The set value, if no automators are currently effecting the property.
-
The automation value, computed by looking at the automation timeline.
-
The value of the property’s input.
These will be discussed here.
First is the set value. This is fairly self-explanatory: call Lav_nodeSetFloatProperty
.
Second is the automation timeline. Automators include such things as Lav_automationLinearRampToValue and Lav_automationEnvelope. When in use, the automation timeline takes the place of the set value; note that setting the property explicitly will cancel all automators.
Only one automator can be in effect at any given time. They have both a duration and a starting point. Automators such as the envelope have a non-zero duration, and will move the value of the property appropriately as described by the provided array. Other automators such as linear ramps have a duration of zero and affect the property starting when the previous automator ends.
Attempting to schedule an automator during the duration of another automator (or such that they start at the same exact time for those automators which have a duration of zero) is an error.
Finally, every float and double property can be treated as a mono input via the function Lav_nodeConnectProperty. The value of all connected nodes is converted and summed, and then acts as an additional additive factor.
Proper use of these features includes understanding k-rate versus a-rate properties, terms borrowed from csound. A k-rate property has it’s value read at the beginning of every block, while an a-rate property has it’s value read more often. Usually a-rate properties are read every sample, but this is not a guarantee; if an a-rate property is read less often, this will be documented in the description.
Callbacks
Some nodes have callbacks, which work exactly as the name suggests.
What needs to be mentioned about callbacks that makes them deserve a section is this: they can be called in two places, and which place will always be documented.
Any callback which does not explicitly specify that it is called outside the audio thread is allowed to run in the audio thread. These callbacks should consequently not have the Libaudioverse API used from it. If the Libaudioverse API can be used from such a callback, then the specific parts of the API that should be used will be outlined. Using the Libaudioverse API in an incorrect manner from a callback which is called inside the audio thread will lead to undefined behavior. Said undefined behavior will be well down the road to outright crashing.
The other place that callbacks can be called is on a background thread owned by the server.
This will be clearly documented.
This thread is created even if you opt to use Lav_serverGetBlock
.
In this case, using the Libaudioverse API is safe.
Blocking in a callback is usually a bad idea. If the callback is running in the audio threads, blocking will decrease performance and cause Libaudioverse to begin adjusting the latency upward. In extreme cases, blocking in the audio threads will cause glitching. Blocking inside callbacks which are not in the audio threads will stop further callbacks from executing, but will otherwise not degrade performance immediately. It should be noted that Libaudioverse sometimes uses the thread on which these callbacks run internally, and that blocking the callback queue may cause resources to build up over time.
No guarantee is made that only one callback will execute at a time. All callbacks should be fully threadsafe.
The Libaudioverse C API
This section of the Libaudioverse documentation documents the low-level C API.
Functions By Category
The following is a complete listing of non-node-specific Libaudioverse functions. If you do not see a function here, it is documented with its node.
Each function lists a description, the full C prototype, and information on all involved typedefs.
The LavError
and LavHandle
typedefs are intensionally omitted: both typedef to int.
All functions return error codes which should be checked. Error conditions are not documented at this time; see the enum section of this documentation for specific information on possible error return values. Most error conditions are indicative of programmer error.
Core Functions
The following functions are the most important functions of Libaudioverse. Writing an app without them is impossible.
Lav_errorGetFile
Prototype: LavError Lav_errorGetFile(const char** destination)
Get the Libaudioverse cpp file where the most recent error on this thread occured. The pointer returned is valid until another error occurs on this thread. This function is mainly for debugging and bindings.
Type |
Name |
Description |
|
destination |
Holds the result of a call to this function. |
Lav_errorGetLine
Prototype: LavError Lav_errorGetLine(int* destination)
Return the source line for the last error that occured on this thread. This function is mainly for debugging and bindings.
Type |
Name |
Description |
|
destination |
Holds the result of a call to this function. |
Lav_errorGetMessage
Prototype: LavError Lav_errorGetMessage(const char** destination)
Get the message corresponding to the last error that happened on this thread. The returned pointer is valid until another error occurs. The main purpose of this function is debugging and bindings.
Type |
Name |
Description |
|
destination |
Holds the result of a call to this function. |
Lav_free
Prototype: LavError Lav_free(void* ptr)
Frees pointers that Libaudioverse gives you. In order to free pointers from Libaudioverse, be sure to use this function rather than the normal system free.
This function is no-op after shutdown, but should not be used before initialization. This behavior simplifies writing garbage-collected bindings to Libaudioverse, and should not be relied on in C code.
Type |
Name |
Description |
|
ptr |
The pointer to free. |
Lav_getLoggingCallback
Prototype: LavError Lav_getLoggingCallback(LavLoggingCallback* destination)
Get the logging callback.
Type |
Name |
Description |
|
destination |
The pointer to the logging callback if set, otherwise NULL. |
Name |
Actual Type |
LavLoggingCallback |
|
Lav_getLoggingLevel
Prototype: LavError Lav_getLoggingLevel(int* destination)
Get the current logging level
Type |
Name |
Description |
|
destination |
Holds the result of a call to this function. |
Lav_handleDecRef
Prototype: LavError Lav_handleDecRef(LavHandle handle)
Decrement the reference count of a Libaudioverse handle. This function is the equivalent to Lav_free for objects. Note that this is only a decrement. If you call it in the middle of a block or in a variety of other situations, you may see the same handle again via a callback.
This function is no-op after shutdown, but should not be used before initialization. This behavior simplifies writing garbage-collected bindings to Libaudioverse, and should not be relied on directly by C programs.
Type |
Name |
Description |
|
handle |
The handle whose reference count we are decrementing. |
Lav_handleGetAndClearFirstAccess
Prototype: LavError Lav_handleGetAndClearFirstAccess(LavHandle handle, int* destination)
Checks the handle’s first access flag and clears it. This is an atomic operation, used by bindings to automatically increment and decrement handle reference counts appropriately.
Type |
Name |
Description |
|
handle |
The handle to check. |
|
destination |
1 if the first access flag is set, otherwise 0. |
Lav_handleGetRefCount
Prototype: LavError Lav_handleGetRefCount(LavHandle handle, int* destination)
For debugging. Allows obtaining the current reference count of the handle. This function is not guaranteed to be reliable; do not assume that it is correct or change application behavior based off it.
Type |
Name |
Description |
|
handle |
The handle to obtain the reference count of |
|
destination |
After a call to this function, contains the reference count of the handle. |
Lav_handleGetType
Prototype: LavError Lav_handleGetType(LavHandle handle, int* destination)
Returns the type of the handle.
Type |
Name |
Description |
|
handle |
The handle to obtain the type of. |
|
destination |
A |
Lav_handleIncRef
Prototype: LavError Lav_handleIncRef(LavHandle handle)
Newly allocated Libaudioverse handles have a reference count of 1. This function allows incrementing this reference count. If you are working in C, this function is not very helpful. It is used primarily by the various programming language bindings in order to make the garbage collector play nice.
Type |
Name |
Description |
|
handle |
The handle whose reference count is to be incremented. |
Lav_initialize
Prototype: LavError Lav_initialize()
This function initializes Libaudioverse. You must call it before calling any other functions.
Lav_isInitialized
Prototype: LavError Lav_isInitialized(int* destination)
Indicates whether Libaudioverse is initialized.
Type |
Name |
Description |
|
destination |
Holds the result of a call to this function. |
Lav_setHandleDestroyedCallback
Prototype: LavError Lav_setHandleDestroyedCallback(LavHandleDestroyedCallback cb)
Set the callback to be called when a Libaudioverse handle is permanently destroyed. Libaudioverse guarantees that handle values will not be recycled. When this callback is called, it is the last time your program can see the specific handle in question, and further use of that handle will cause crashes.
Type |
Name |
Description |
|
cb |
The callback to be called when handles are destroyed. |
Name |
Actual Type |
LavHandleDestroyedCallback |
|
Lav_setLoggingCallback
Prototype: LavError Lav_setLoggingCallback(LavLoggingCallback cb)
Configure a callback to receive logging messages. Note that this function can be called before Libaudioverse initialization.
The callback will receive 3 parameters: level, message, and is_final. Level is the logging level. Message is the message to log. is_final is always 0, save when the message is the last message the logging callback will receive, ever. Use is_final to determine when to deinitialize your Libaudioverse logging.
Type |
Name |
Description |
|
cb |
The callback to use for logging. |
Name |
Actual Type |
LavLoggingCallback |
|
Lav_setLoggingLevel
Prototype: LavError Lav_setLoggingLevel(int level)
Set the logging level. You will receive messages via the logging callback for all levels greater than the logging level.
Type |
Name |
Description |
|
level |
The new logging level. |
Lav_shutdown
Prototype: LavError Lav_shutdown()
Shuts down Libaudioverse. You must call this function at the end of your application. Failure to do so may cause crashes. Once this function has been called, all pointers and handles from Libaudioverse are invalid. Libaudioverse cannot be safely reinitialized.
Server Functions
The following functions relate to and control the server.
Lav_createServer
Prototype: LavError Lav_createServer(unsigned int sr, unsigned int blockSize, LavHandle* destination)
Creates a server.
The new server has no associated audio device.
To make it output, use Lav_serverSetOutputDevice
.
Type |
Name |
Description |
|
sr |
The sampling rate of the new server. |
|
blockSize |
The block size of the new server. |
|
destination |
Holds the result of a call to this function. |
Lav_serverCallIn
Prototype: LavError Lav_serverCallIn(LavHandle serverHandle, double when, int inAudioThread, LavTimeCallback cb, void* userdata)
Schedule a function to run in the future.
This function is either called inside the audio thread or outside the audio thread. If called inside the audio thread, it must exit quickly and not call the Libaudioverse API. If called outside the audio thread, it can call the Libaudioverse API and will not block audio. This is the same as node callbacks.
Time advances for servers if and only if they are processing audio for some purpose; this callback is called in audio time, as it were. The precision of the callback is limited by the block size. Smaller block sizes will call callbacks more precisely.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
when |
The number of seconds from the current time to call the callback. |
|
inAudioThread |
If nonzero, call the callback in the audio thread. |
|
cb |
The callback to call. |
|
userdata |
An extra parameter that will be passed to the callback. |
Name |
Actual Type |
LavTimeCallback |
|
Lav_serverClearOutputDevice
Prototype: LavError Lav_serverClearOutputDevice(LavHandle serverHandle)
Clear a server’s output device.
This is no-op if no output device has been set.
After a call to this function, it is again safe to use Lav_serverGetBlock
.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
Lav_serverGetBlock
Prototype: LavError Lav_serverGetBlock(LavHandle serverHandle, unsigned int channels, int mayApplyMixingMatrix, float* buffer)
Gets a block of audio from the server and advances its time. You must allocate enough space to hold exactly one block of audio: the server’s block size times the number of channels requested floating point values. Note that mixing this function with other output methods invokes undefined behavior.
Type |
Name |
Description |
|
serverHandle |
The handle of the server to read a block from. |
|
channels |
The number of channels we want. The servers' output will be upmixed or downmixed as appropriate. |
|
mayApplyMixingMatrix |
If 0, drop any additional channels in the server’s output and set any missing channels in the server’s output to 0. Otherwise, if we can, apply a mixing matrix. |
|
buffer |
The memory to which to write the result. |
Lav_serverGetBlockSize
Prototype: LavError Lav_serverGetBlockSize(LavHandle serverHandle, int* destination)
Query the block size of the specified server.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_serverGetSr
Prototype: LavError Lav_serverGetSr(LavHandle serverHandle, int* destination)
Query the server’s sampling rate.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_serverGetThreads
Prototype: LavError Lav_serverGetThreads(LavHandle serverHandle, int* destination)
Get the number of threads that the server is currently using.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_serverLock
Prototype: LavError Lav_serverLock(LavHandle serverHandle)
All operations between a call to this function and a call to Lav_serverUnlock will happen together, with no blocks mixed between them. This is equivalent to assuming that the server is a lock, with all of the required caution that implies. No other thread will be able to access this server or objects created from it until Lav_serverUnlock is called. If you do not call Lav_serverUnlock in a timely manner, then audio will stop until you do.
Pairs of Lav_serverLock and Lav_serverUnlock nest safely.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
Lav_serverSetBlockCallback
Prototype: LavError Lav_serverSetBlockCallback(LavHandle serverHandle, LavTimeCallback callback, void* userdata)
Set a callback to be called just before every block and in the audio thread. This callback can and should access the Libaudioverse API: the point of it is that you can use it to perform tasks where missing even one block would be problematic, i.e. very precise scheduling of events.
This callback can even block, though this will slow down audio mixing and may cause glitchy audio. The one thing you should never do in this callback is access anything belonging to another server, as this can cause deadlock.
The callback receives two parameters: the server to which it is associated and the time in server time that corresponds to the beginning of the block about to be mixed.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
callback |
The callback to use. |
|
userdata |
An extra parameter that will be passed to the callback. |
Name |
Actual Type |
LavTimeCallback |
|
Lav_serverSetOutputDevice
Prototype: LavError Lav_serverSetOutputDevice(LavHandle serverHandle, const char* device, int channels, int mixahead)
Set the output device of the server. Use the literal string "default" for the default audio device.
Note that it is possible to change the output device of a server even after it has been set.
After the output device has been set, calls to Lav_serverGetBlock
will error.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
device |
The output device the server is to play on. |
|
channels |
The number of channels we wish to output. |
|
mixahead |
The number of audio blocks to prepare ahead of the audio device. Must be at least 1. |
Lav_serverSetThreads
Prototype: LavError Lav_serverSetThreads(LavHandle serverHandle, int threads)
Set the number of threads that the server is allowed to use.
The value of the threads parameter may be from 1 to infinity. When set to 1, processing happens in the thread who calls Lav_serverGetBlock. All other values sleep the thread calling Lav_serverGetBlock and perform processing in background threads.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
threads |
The number of threads to use for processing. Must be at least 1. Typical values include 1 and 1 less than the available cores. |
Lav_serverUnlock
Prototype: LavError Lav_serverUnlock(LavHandle serverHandle)
Release the internal lock of a server, allowing normal operation to resume. This is to be used after a call to Lav_serverLock and on the same thread as that call; calling it in any other circumstance or on any other thread invokes undefined behavior.
Pairs of Lav_serverLock and Lav_serverUnlock nest safely.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
Lav_serverWriteFile
Prototype: LavError Lav_serverWriteFile(LavHandle serverHandle, const char* path, int channels, double duration, int mayApplyMixingMatrix)
Write the server’s output to the specified file.
This function advances the server as though Lav_serverGetBlock were called multiple times, the number of times determined by duration. As a consequence, it is not possible to use this function while the server is outputting.
The file format is determined from the path. Recognized extensions include ".wav" and ".ogg", which are guaranteed to work on all systems. In all cases, reasonable defaults are used for those settings which are specific to the encoder.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
path |
The path to the audio file to be written. |
|
channels |
The number of channels in the resulting file. |
|
duration |
Duration of the resulting file, in seconds. |
|
mayApplyMixingMatrix |
1 if applying a mixing matrix should be attempted, 0 if extra channels should be treated as 0 or dropped. This is the same behavior as with Lav_serverGetBlock. |
Device Enumeration
The following functions are for queryng informationa bout audio devices.
Note that channel counts are not reliable, and that you should probably use stereo unless the user explicitly says otherwise.
Lav_deviceGetChannels
Prototype: LavError Lav_deviceGetChannels(unsigned int index, unsigned int* destination)
Query the maximum number of channels for this device before downmixing occurs. You should query the user as to the type of audio they want rather than relying on this function. Some operating systems and backends will perform their own downmixing and happily claim 8-channel audio on stereo headphones. Furthermore, some hardware and device drivers will do the same. It is not possible for Libaudioverse to detect this case.
Type |
Name |
Description |
|
index |
The index of the audio device. |
|
destination |
Holds the result of a call to this function. |
Lav_deviceGetCount
Prototype: LavError Lav_deviceGetCount(unsigned int* destination)
Get the number of audio devices on the system.
Type |
Name |
Description |
|
destination |
Holds the result of a call to this function. |
Lav_deviceGetName
Prototype: LavError Lav_deviceGetName(unsigned int index, char** destination)
Returns a human-readable name for the specified audio device.
The string that this function outputs is encoded in UTF8.
Type |
Name |
Description |
|
index |
The index of the audio device. |
|
destination |
Contains a pointer to a string allocated by Libaudioverse containing the name. Use Lav_free on this string when done with it. |
Node Functions
The following functions work on all Libaudioverse nodes.
Lav_nodeConnect
Prototype: LavError Lav_nodeConnect(LavHandle nodeHandle, int output, LavHandle destHandle, int input)
Connect the specified output of the specified node to the specified input of the specified node.
it is an error if this would cause a cycle in the graph of nodes.
Type |
Name |
Description |
|
nodeHandle |
The node whose output we are going to connect. |
|
output |
The index of the output to connect. |
|
destHandle |
The node to whose input we are connecting. |
|
input |
The input to which to connect. |
Lav_nodeConnectProperty
Prototype: LavError Lav_nodeConnectProperty(LavHandle nodeHandle, int output, LavHandle otherHandle, int slot)
Connect a node’s output to an automatable property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
output |
The output to connect. |
|
otherHandle |
The node to which we are connecting. |
|
slot |
The index of the property to which to connect. |
Lav_nodeConnectServer
Prototype: LavError Lav_nodeConnectServer(LavHandle nodeHandle, int output)
Connect the specified output of the specified node to the server’s input.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
output |
The index of the output to connect. |
Lav_nodeDisconnect
Prototype: LavError Lav_nodeDisconnect(LavHandle nodeHandle, int output, LavHandle otherHandle, int input)
Disconnect the output of the specified node.
If otherHandle is 0, disconnect from all inputs.
If otherHandle is nonzero, disconnect from the specific node and input combination.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
output |
The output to disconnect. |
|
otherHandle |
The node from which to disconnect. |
|
input |
The input of the other node from which to disconnect. |
Lav_nodeGetArrayPropertyLengthRange
Prototype: LavError Lav_nodeGetArrayPropertyLengthRange(LavHandle nodeHandle, int propertyIndex, unsigned int* destinationMin, unsigned int* destinationMax)
Get the allowed range for the length of an array in an array property. This works on both int and float properties.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destinationMin |
After a call to this function, contains the minimum allowed length. |
|
destinationMax |
After a call to this function, contains the maximum allowed length. |
Lav_nodeGetBufferProperty
Prototype: LavError Lav_nodeGetBufferProperty(LavHandle nodeHandle, int propertyIndex, LavHandle* destination)
Gets the value of a specified buffer property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetDoubleProperty
Prototype: LavError Lav_nodeGetDoubleProperty(LavHandle nodeHandle, int propertyIndex, double* destination)
Get the specified double property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetDoublePropertyRange
Prototype: LavError Lav_nodeGetDoublePropertyRange(LavHandle nodeHandle, int propertyIndex, double* destinationMin, double* destinationMax)
Query the range of a double property. Note that ranges are meaningless for read-only properties.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destinationMin |
After a call to this function, holds the range’s minimum. |
|
destinationMax |
After a call to this function, holds the range’s maximum. |
Lav_nodeGetFloatArrayPropertyLength
Prototype: LavError Lav_nodeGetFloatArrayPropertyLength(LavHandle nodeHandle, int propertyIndex, unsigned int* destination)
Get the length of the specified float array property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetFloatProperty
Prototype: LavError Lav_nodeGetFloatProperty(LavHandle nodeHandle, int propertyIndex, float* destination)
Get the specified float property’s value.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetFloatPropertyRange
Prototype: LavError Lav_nodeGetFloatPropertyRange(LavHandle nodeHandle, int propertyIndex, float* destinationMin, float* destinationMax)
Get the range of a float property. Note that ranges are meaningless for read-only properties.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destinationMin |
After a call to this function, holds the range’s minimum. |
|
destinationMax |
After a call to this function, holds the range’s maximum. |
Lav_nodeGetInputConnectionCount
Prototype: LavError Lav_nodeGetInputConnectionCount(LavHandle nodeHandle, unsigned int* destination)
Get the number of inputs this node has.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetIntArrayPropertyLength
Prototype: LavError Lav_nodeGetIntArrayPropertyLength(LavHandle nodeHandle, int propertyIndex, int* destination)
Get the length of the specified int array property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetIntProperty
Prototype: LavError Lav_nodeGetIntProperty(LavHandle nodeHandle, int propertyIndex, int* destination)
Get the value of the specified int property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetIntPropertyRange
Prototype: LavError Lav_nodeGetIntPropertyRange(LavHandle nodeHandle, int propertyIndex, int* destinationMin, int* destinationMax)
Get the range of an int property. Note that ranges are meaningless for read-only properties.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destinationMin |
After a call to this function, holds the range’s minimum. |
|
destinationMax |
After a call to this function, holds the range’s maximum. |
Lav_nodeGetOutputConnectionCount
Prototype: LavError Lav_nodeGetOutputConnectionCount(LavHandle nodeHandle, unsigned int* destination)
Get the number of outputs this node has.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetPropertyHasDynamicRange
Prototype: LavError Lav_nodeGetPropertyHasDynamicRange(LavHandle nodeHandle, int propertyIndex, int* destination)
Find out whether or not a property has a dynamic range. Properties with dynamic ranges change their ranges at specified times, as documented by the documentation for the property of interest.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
After a call to this function, contains 1 if the property has a dynamic range, otherwise 0. |
Lav_nodeGetPropertyName
Prototype: LavError Lav_nodeGetPropertyName(LavHandle nodeHandle, int propertyIndex, char** destination)
Get the name of a property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
After a call to this function, contains a newly allocated string that should be freed with Lav_free. The string is the name of this property. |
Lav_nodeGetPropertyType
Prototype: LavError Lav_nodeGetPropertyType(LavHandle nodeHandle, int propertyIndex, int* destination)
Get the type of a property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetServer
Prototype: LavError Lav_nodeGetServer(LavHandle nodeHandle, LavHandle* destination)
Get the server that a node belongs to.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeGetStringProperty
Prototype: LavError Lav_nodeGetStringProperty(LavHandle nodeHandle, int propertyIndex, const char** destination)
Get the specified string property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
destination |
After a call to this function, contains a pointer to a newly allocated string that is a copy of the value of the property. Free this string with Lav_free. |
Lav_nodeIsolate
Prototype: LavError Lav_nodeIsolate(LavHandle nodeHandle)
Equivalent to disconnecting all of the outputs of this node. After a call to isolate, this node will no longer be affecting audio in any way.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
Lav_nodeReadFloatArrayProperty
Prototype: LavError Lav_nodeReadFloatArrayProperty(LavHandle nodeHandle, int propertyIndex, unsigned int index, float* destination)
Read the float array property at a specified index.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
index |
The index at which to read. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeReadIntArrayProperty
Prototype: LavError Lav_nodeReadIntArrayProperty(LavHandle nodeHandle, int propertyIndex, unsigned int index, int* destination)
Read the int array property at a specified index.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
index |
The index at which to read. |
|
destination |
Holds the result of a call to this function. |
Lav_nodeReplaceFloatArrayProperty
Prototype: LavError Lav_nodeReplaceFloatArrayProperty(LavHandle nodeHandle, int propertyIndex, unsigned int length, float* values)
Replace the array contained by a float array property with a new array. Note that, as usual, memory is copied, not shared.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
length |
The length of the new array. |
|
values |
The array itself. |
Lav_nodeReplaceIntArrayProperty
Prototype: LavError Lav_nodeReplaceIntArrayProperty(LavHandle nodeHandle, int propertyIndex, unsigned int length, int* values)
Replace the array contained by an int array property with a new array. Note that, as usual, memory is copied, not shared.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
length |
The length of the new array. |
|
values |
The array itself. |
Lav_nodeReset
Prototype: LavError Lav_nodeReset(LavHandle nodeHandle)
Reset a node. What this means depends on the node in question. Properties are not touched by node resetting.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
Lav_nodeResetProperty
Prototype: LavError Lav_nodeResetProperty(LavHandle nodeHandle, int propertyIndex)
Reset a property to its default.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
Lav_nodeSetBufferProperty
Prototype: LavError Lav_nodeSetBufferProperty(LavHandle nodeHandle, int propertyIndex, LavHandle value)
Set a buffer property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
value |
The buffer to set the property to. 0 means none. |
Lav_nodeSetDoubleProperty
Prototype: LavError Lav_nodeSetDoubleProperty(LavHandle nodeHandle, int propertyIndex, double value)
Set the specified double property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
value |
the new value of the property. |
Lav_nodeSetFloat3Property
Prototype: LavError Lav_nodeSetFloat3Property(LavHandle nodeHandle, int propertyIndex, float v1, float v2, float v3)
Set the specified float3 property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
v1 |
The first component of the float3. |
|
v2 |
The second component of the float3. |
|
v3 |
The third component of the float3. |
Lav_nodeSetFloat6Property
Prototype: LavError Lav_nodeSetFloat6Property(LavHandle nodeHandle, int propertyIndex, float v1, float v2, float v3, float v4, float v5, float v6)
Set the specified float6 property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
v1 |
The first component of the float6. |
|
v2 |
The second component of the float6. |
|
v3 |
The third component of the float6. |
|
v4 |
The fourth component of the float6. |
|
v5 |
The fifth component of the float6. |
|
v6 |
The 6th component of the float6. |
Lav_nodeSetFloatProperty
Prototype: LavError Lav_nodeSetFloatProperty(LavHandle nodeHandle, int propertyIndex, float value)
Set the specified float property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
value |
the new value of the property. |
Lav_nodeSetIntProperty
Prototype: LavError Lav_nodeSetIntProperty(LavHandle nodeHandle, int propertyIndex, int value)
Set an int property. Note that this function also applies to boolean properties, as these are actually int properties with the range [0, 1].
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
value |
The new value of the property. |
Lav_nodeSetStringProperty
Prototype: LavError Lav_nodeSetStringProperty(LavHandle nodeHandle, int propertyIndex, char* value)
Set the specified string property.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
value |
the new value of the property. Note that the specified string is copied and the memory may be freed. |
Lav_nodeWriteFloatArrayProperty
Prototype: LavError Lav_nodeWriteFloatArrayProperty(LavHandle nodeHandle, int propertyIndex, unsigned int start, unsigned int stop, float* values)
Write a range of values into the specified float array property, without changing its length.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
start |
The starting index of the range to replace. Must be less than the length of the property. |
|
stop |
One past the end of the region to be replaced. Must be no more than the length of the property. |
|
values |
the data with which to replace the range. Must have length stop-start. |
Lav_nodeWriteIntArrayProperty
Prototype: LavError Lav_nodeWriteIntArrayProperty(LavHandle nodeHandle, int propertyIndex, unsigned int start, unsigned int stop, int* values)
Write a range of values into the specified int array property, without changing its length.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
start |
The starting index of the range to replace. Must be less than the length of the property. |
|
stop |
One past the end of the region to be replaced. Must be no more than the length of the property. |
|
values |
the data with which to replace the range. Must have length stop-start. |
Automator Functions
The following functions manipulate automatable properties.
Lav_automationCancelAutomators
Prototype: LavError Lav_automationCancelAutomators(LavHandle nodeHandle, int propertyIndex, double time)
Cancel all automators that are scheduled to begin running after the specified time.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
propertyIndex |
The property to manipulate. |
|
time |
The time after which to cancel automation. This is relative to the node. |
Lav_automationEnvelope
Prototype: LavError Lav_automationEnvelope(LavHandle nodeHandle, int slot, double time, double duration, int valuesLength, double* values)
An automator that performs an envelope.
The specified points are stretched to fit the specified duration.
At the scheduled time of this automator, the envelope will begin being performed, finishing at time+duration
.
As described in the basics section, it is an error to schedule an automator during the range (time, time+duration)
.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
slot |
The index of the property to automate. |
|
time |
The time at which the envelope should begin. |
|
duration |
The duration of the envelope. |
|
valuesLength |
The length of the values array. |
|
values |
The points of the envelope, sampled every |
Lav_automationLinearRampToValue
Prototype: LavError Lav_automationLinearRampToValue(LavHandle nodeHandle, int slot, double time, double value)
Sets up a linear ramp.
The value of a linear ramp begins at the end of the last automator and linearly increases to the start time of this automator, after which the property holds steady unless more automators are scheduled.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
slot |
The slot of the property to automate. |
|
time |
The time at which we must be at the specified value. |
|
value |
The value we must arrive at by the specified time. |
Lav_automationSet
Prototype: LavError Lav_automationSet(LavHandle nodeHandle, int slot, double time, double value)
An automator that sets the property’s value to a specific value at a specific time.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
slot |
The slot of the property to automate. |
|
time |
The time at which to set the value. |
|
value |
The value to set the property to at the specified time. |
Buffer Functions
The following functions manipulate buffers.
Lav_bufferGetDuration
Prototype: LavError Lav_bufferGetDuration(LavHandle bufferHandle, float* destination)
Get the duration of the buffer in seconds.
Type |
Name |
Description |
|
bufferHandle |
The buffer to retrieve the duration for. |
|
destination |
Holds the result of a call to this function. |
Lav_bufferGetLengthInSamples
Prototype: LavError Lav_bufferGetLengthInSamples(LavHandle bufferHandle, int* destination)
Get the length of the specified buffer in samples.
The sample rate of a buffer is the sample rate of the server for which that buffer was created. This function is primarily useful for estimating ram usage in caching structures.
Type |
Name |
Description |
|
bufferHandle |
The buffer whose length is to be queried. |
|
destination |
Holds the result of a call to this function. |
Lav_bufferGetServer
Prototype: LavError Lav_bufferGetServer(LavHandle bufferHandle, LavHandle* destination)
Get the handle of the server used to create this buffer.
Type |
Name |
Description |
|
bufferHandle |
The handle of the buffer. |
|
destination |
Holds the result of a call to this function. |
Lav_bufferLoadFromArray
Prototype: LavError Lav_bufferLoadFromArray(LavHandle bufferHandle, int sr, int channels, int frames, float* data)
Load data into the specified buffer from the specified array of floating point audio data.
Type |
Name |
Description |
|
bufferHandle |
The buffer to load data into. |
|
sr |
The sampling rate of the data in the array. |
|
channels |
The number of audio channels in the data; frames*channels is the total length of the array in samples. |
|
frames |
The number of frames of audio data; frames*channels is the length of the array in samples. |
|
data |
A pointer to the beginning of the array to load from. |
Lav_bufferLoadFromFile
Prototype: LavError Lav_bufferLoadFromFile(LavHandle bufferHandle, const char* path)
Loads data into this buffer from a file. The file will be resampled to the sampling rate of the server. This will happen synchronously.
Type |
Name |
Description |
|
bufferHandle |
The buffer into which to load data. |
|
path |
The path to the file to load data from. |
Lav_bufferNormalize
Prototype: LavError Lav_bufferNormalize(LavHandle bufferHandle)
Normalize the buffer. This function divides by the sample whose absolute value is greatest. The effect is to make sounds as loud as possible without clipping or otherwise distorting the sound.
Type |
Name |
Description |
|
bufferHandle |
The buffer to normalize. |
Lav_createBuffer
Prototype: LavError Lav_createBuffer(LavHandle serverHandle, LavHandle* destination)
Create an empty buffer.
Type |
Name |
Description |
|
serverHandle |
The simulation to manipulate. |
|
destination |
Holds the result of a call to this function. |
Libaudioverse Node Reference
This section is an overview of all Libaudioverse nodes.
For binding-specific references, see the bindings themselves. Python uses docstrings, for example.
Usually, the names of nodes can be inferred by mentally stripping the Lav_OBJTYPE_
prefix from the identifying constant and looking for suffix_object
or SuffixObject
depending on the conventions of your language.
Any function not described in the C API section is a "extra function", a function which breaks the usual property model. Extra functions do any number of things and are documented with the node that they manipulate.
To determine the number of inputs and outputs a node has, as well as their channel counts, check the general description of the node and the description of its constructor in that order. No node’s output or input count can change after the node is created. A few nodes change the input and output channel counts depending on properties. The most notable node of this type is the amplitude panner.
Generic Node
C Type Identifier: Lav_OBJTYPE_GENERIC_NODE
The properties and functionality described here are available on every Libaudioverse node without exception.
While an enumeration value is reserved for the generic node, it should not be possible to receive one publicly. This identifier is only used internally.
Properties
add
C Enumeration Value: Lav_NODE_ADD
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: a
After mul is applied, we add the value to which this property is set to the node’s result.
channel_interpretation
C Enumeration Value: Lav_NODE_CHANNEL_INTERPRETATION
Type: int
Range: A value from the Lav_CHANNEL_INTERPRETATIONS enumeration.
Default Value: Lav_CHANNEL_INTERPRETATION_SPEAKERS
Rate: k
How to treat channel count mismatches. The default is to apply mixing matrices when possible.
If set to Lav_CHANNEL_INTERPRETATION_SPEAKERS
, mixing matrices are applied to inputs.
Otherwise, when set to Lav_CHANNEL_INTERPRETATION_DISCRETE
, they are not.
This property is almost never needed.
mul
C Enumeration Value: Lav_NODE_MUL
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 1.0
Rate: a
After this node processes, the value to which mul is set is used as a multiplier on the result. The most notable effect of this is to change the node’s volume. A variety of other uses exist, however, especially as regards to nodes which are connected to properties. Mul is applied before add.
state
C Enumeration Value: Lav_NODE_STATE
Type: int
Range: A value from the Lav_NODE_STATES enumeration.
Default Value: Lav_NODESTATE_PLAYING
Rate: k
The node’s state. See the basics section in the Libaudioverse manual for details. The default is usually what you want.
Additive Saw Node
C Type Identifier: Lav_OBJTYPE_ADDITIVE_SAW_NODE
Constructor: LavError Lav_createAdditiveSawNode(LavHandle serverHandle, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
1 |
A saw wave. |
The most accurate, least featureful, and slowest saw oscillator.
This oscillator uses additive synthesis to produce saw waves. The efficiency therefore depends on the frequency. Sweeping this oscillator will perform poorly if you do not set the harmonics to a nonzero value.
This oscillator is slightly under the range -1 to 1. Of the additive oscillators, the sawtooth wave is the worst in this respect. For this reason, it is probably not suitable as a control signal. This is not fixable using additive synthesis and is a frequency dependent effect.
Properties
frequency
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY
Type: float
Range: [0, 'INFINITY']
Default Value: 440.0
Rate: a
The frequency of the saw wave, in hertz.
frequency_multiplier
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY_MULTIPLIER
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 1.0
Rate: a
An additional multiplicative factor applied to the frequency of the oscillator.
This is useful for creating instruments, as the notes of the standard musical scale fall on frequency multiples of a reference pitch, rather than a linear increase.
phase
C Enumeration Value: Lav_OSCILLATOR_PHASE
Type: float
Range: [0.0, 1.0]
Default Value: 0.0
Rate: k
The phase of the saw wave. This is measured in periods, not in radians.
harmonics
C Enumeration Value: Lav_SAW_HARMONICS
Type: int
Range: [0, 'MAX_INT']
Default Value: 0
Rate: k
The number of harmonics. 0 requests automatic adjustment. Use a nonzero value if you intend to sweep the saw wave.
While this property has no max value, any combination of frequency and harmonics that leads to aliasing will alias.
To avoid this, make sure that frequency*harmonics
never goes over half your chosen sampling rate.
Additive Square Node
C Type Identifier: Lav_OBJTYPE_ADDITIVE_SQUARE_NODE
Constructor: LavError Lav_createAdditiveSquareNode(LavHandle serverHandle, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
1 |
A square wave. |
The most accurate, least featureful, and slowest square oscillator.
This oscillator uses additive synthesis to produce square waves. The efficiency therefore depends on the frequency. Sweeping this oscillator will perform poorly if you do not set the harmonics to a nonzero value.
This oscillator is slightly under the range -1 to 1. For this reason, it is probably not suitable as a control signal. This is not fixable using additive synthesis and is a frequency dependent effect.
Properties
frequency
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY
Type: float
Range: [0, 'INFINITY']
Default Value: 440.0
Rate: k
The frequency of the square wave, in hertz.
frequency_multiplier
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY_MULTIPLIER
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 1.0
Rate: a
An additional multiplicative factor applied to the frequency of the oscillator.
This is useful for creating instruments, as the notes of the standard musical scale fall on frequency multiples of a reference pitch, rather than a linear increase.
phase
C Enumeration Value: Lav_OSCILLATOR_PHASE
Type: float
Range: [0.0, 1.0]
Default Value: 0.0
Rate: k
The phase of the square wave. This is measured in periods, not in radians.
harmonics
C Enumeration Value: Lav_SQUARE_HARMONICS
Type: int
Range: [0, 'MAX_INT']
Default Value: 0
Rate: k
The number of harmonics. 0 requests automatic adjustment. Use a nonzero value if you intend to sweep the square wave.
While this property has no max value, any combination of frequency and harmonics that leads to aliasing will alias.
To avoid this, make sure that 2*frequency*(2*harmonics-1)
never goes over half your chosen sampling rate.
Additive Triangle Node
C Type Identifier: Lav_OBJTYPE_ADDITIVE_TRIANGLE_NODE
Constructor: LavError Lav_createAdditiveTriangleNode(LavHandle serverHandle, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
1 |
A triangle wave. |
The most accurate, least featureful, and slowest triangle oscillator.
This oscillator uses additive synthesis to produce triangle waves. The efficiency therefore depends on the frequency. Sweeping this oscillator will perform poorly if you do not set the harmonics to a nonzero value.
This oscillator is slightly under the range -1 to 1. Calibration scripts show that the worst case is -0.9 to 0.9, with the error increasing as frequency increases. For this reason, it is probably not suitable as a control signal. This is not fixable using additive synthesis and is a frequency dependent effect.
Properties
frequency
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY
Type: float
Range: [0, 'INFINITY']
Default Value: 440.0
Rate: k
The frequency of the triangle wave, in hertz.
frequency_multiplier
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY_MULTIPLIER
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 1.0
Rate: a
An additional multiplicative factor applied to the frequency of the oscillator.
This is useful for creating instruments, as the notes of the standard musical scale fall on frequency multiples of a reference pitch, rather than a linear increase.
phase
C Enumeration Value: Lav_OSCILLATOR_PHASE
Type: float
Range: [0.0, 1.0]
Default Value: 0.0
Rate: k
The phase of the triangle wave. This is measured in periods, not in radians.
harmonics
C Enumeration Value: Lav_TRIANGLE_HARMONICS
Type: int
Range: [0, 'MAX_INT']
Default Value: 0
Rate: k
The number of harmonics. 0 requests automatic adjustment. Use a nonzero value if you intend to sweep the triangle wave.
While this property has no max value, any combination of frequency and harmonics that leads to aliasing will alias.
To avoid this, make sure that 2*frequency*(2*harmonics-1)
never goes over half your chosen sampling rate.
Allpass Node
C Type Identifier: Lav_OBJTYPE_ALLPASS_NODE
Constructor: LavError Lav_createAllpassNode(LavHandle serverHandle, int channels, int maxDelay, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to filter. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The filtered signal. |
Implements a first-order allpass filter whose transfer function is \(\frac{c+Z^{-d} }{1 + cZ^{-d} }\) where c
is the coefficient and d
the delay in samples.
This filter is useful in various reverb designs.
Properties
coefficient
C Enumeration Value: Lav_ALLPASS_COEFFICIENT
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: See below
Rate: k
The coefficient of the allpass filter’s transfer function.
For those not familiar with digital signal processing, this controls how quickly the repeating echoes created by this filter decay.
delay_samples
C Enumeration Value: Lav_ALLPASS_DELAY_SAMPLES
Type: int
Range: dynamic
Default Value: 1
Rate: k
The delay of the delay line in samples. The range of this property depends on the maxDelay parameter to the constructor.
Note that values less than 1 sample still introduce delay.
delay_max
C Enumeration Value: Lav_ALLPASS_DELAY_SAMPLES_MAX
Type: int
This property is read-only.
The max delay as set at the node’s creation time.
interpolation_time
C Enumeration Value: Lav_ALLPASS_INTERPOLATION_TIME
Type: float
Range: [0.001, 'INFINITY']
Default Value: 0.001
Rate: k
When the delay_samples property is changed, the delay line crossfades between the old position and the new one. Essentially, this property sets how long it will take the allpass filter to settle after a delay change. Note that for this node, it is impossible to get rid of the crossfade completely.
Amplitude Panner Node
C Type Identifier: Lav_OBJTYPE_AMPLITUDE_PANNER_NODE
Constructor: LavError Lav_createAmplitudePannerNode(LavHandle serverHandle, LavHandle* destination)
Index |
Channels |
Description |
0 |
1 |
The signal to pan |
Index |
Channels |
Description |
0 |
Depends on a number of properties on this node. |
The result of panning the signal. |
This panner pans for a set of regular speakers without any additional effects applied. Additionally, it understands surround sound speaker layouts and allows for the assignment of custom speaker mappings. The default configuration provides a stereo panner that can be used without any additional steps. The additional function Lav_amplitudePannerNodeConfigureStandardChannelMap can set the panner to output for a variety of standard configurations, so be sure to see its documentation.
Properties
azimuth
C Enumeration Value: Lav_PANNER_AZIMUTH
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The horizontal angle of the panner in degrees. 0 is directly ahead, and positive values are clockwise.
channel_map
C Enumeration Value: Lav_PANNER_CHANNEL_MAP
Type: float_array
Default Value: [-90, 90]
Rate: k
The angles of the speakers in the order in which they are to be mapped to channels. The first speaker will be mapped to the first channel, the second to the second, etc. These channels are then combined and produced as the single output of the panner.
You can use floating point infinity to indicate a channel should be skipped. This functionality is used by all of the standard channel maps to skip the center and LFE channels.
elevation
C Enumeration Value: Lav_PANNER_ELEVATION
Type: float
Range: [-90.0, 90.0]
Default Value: 0.0
Rate: k
The vertical angle of the panner in degrees. 0 is horizontal and positive values are upwards. Note that, for amplitude panners, this has no effect and exists only to allow swapping with the HRTF panner without changing code.
should_crossfade
C Enumeration Value: Lav_PANNER_SHOULD_CROSSFADE
Type: boolean
Default Value: 1
Rate: k
Whether or not to instantly move to the new position. If crossfading is disabled, large movements of the panner will cause audible clicks. Disabling crossfading can aid performance under heavy workloads, especially with the HRTF panner. If crossfading is enabled, moving the panner will slowly fade it to the new position over the next block.
Extra Functions
configure_standard_map
Prototype: LavError Lav_amplitudePannerNodeConfigureStandardMap(LavHandle nodeHandle, unsigned int channels)
Sets the channel map and other properties on this node to match a standard configuration. The possible standard configurations are found in the Lav_PANNING_STRATEGIES enumeration.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
channels |
A value from the Lav_PANNING_STRATEGIES enumeration. |
Biquad Filter Node
C Type Identifier: Lav_OBJTYPE_BIQUAD_NODE
Constructor: LavError Lav_createBiquadNode(LavHandle serverHandle, unsigned int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to process. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The result of processing the audio via the filter. |
Implementation of a biquad filter section, as defined by the Audio EQ Cookbook by Robert Bristo-Johnson. This node is capable of implementing almost every filter needed for basic audio effects, including equalizers. For the specific equations used, see the Audio EQ Cookbook. It may be found at: http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
Properties
dbgain
C Enumeration Value: Lav_BIQUAD_DBGAIN
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
This property is a the gain in decibals to be used with the peaking and shelving filters. It measures the gain that these filters apply to the part of the signal they boost.
filter_type
C Enumeration Value: Lav_BIQUAD_FILTER_TYPE
Type: int
Range: A value from the Lav_BIQUAD_TYPES enumeration.
Default Value: Lav_BIQUAD_TYPE_LOWPASS
Rate: k
The type of the filter. This determines the interpretations of the other properties on this node.
frequency
C Enumeration Value: Lav_BIQUAD_FREQUENCY
Type: float
Range: [0, 'INFINITY']
Default Value: 2000.0
Rate: k
This is the frequency of interest. What specifically this means depends on the selected filter type; for example, it is the cutoff frequency for lowpass and highpass.
q
C Enumeration Value: Lav_BIQUAD_Q
Type: float
Range: [0.001, 'INFINITY']
Default Value: 0.5
Rate: k
Q is a mathematically complex parameter, a full description of which is beyond the scope of this manual.
Naively, Q can be interpreted as a measure of resonation.
For Q⇐0.5
, the filter is said to be damped:
it will cut frequencies.
For Q>0.5, however, some frequencies are likely to be boosted.
Q controls the bandwidth for the bandpass and peaking filter types For everything except the peaking filter, this property follows the normal definition of Q in the electrical engineering literature. For more specifics, see the Audio EQ Cookbook. It is found here: http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
Blit Node
C Type Identifier: Lav_OBJTYPE_BLIT_NODE
Constructor: LavError Lav_createBlitNode(LavHandle serverHandle, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
1 |
A bandlimited impulse train. |
Generates bandlimited impulse trains. These sound like a buzz, but have important applications in the alias-free synthesis of analog waveforms.
Properties
harmonics
C Enumeration Value: Lav_BLIT_HARMONICS
Type: int
Range: [0, 'MAX_INT']
Default Value: 0
Rate: k
The number of harmonics to include. 0 requests automatic adjustment. When 0, the algorithm this node represents will include as many harmonics as it can without aliasing.
should_normalize
C Enumeration Value: Lav_BLIT_SHOULD_NORMALIZE
Type: boolean
Default Value: 1
Rate: k
If false, the produced BLIT will have an integral of 1 over every period. If true, the produced blit will be normalized to be between 1 and -1, and suitable for audio. The default is true.
frequency
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY
Type: float
Range: [0, 'INFINITY']
Default Value: 440.0
Rate: a
The frequency of the impulse train in HZ.
frequency_multiplier
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY_MULTIPLIER
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 1.0
Rate: a
An additional multiplicative factor applied to the frequency of the oscillator.
This is useful for creating instruments, as the notes of the standard musical scale fall on frequency multiples of a reference pitch, rather than a linear increase.
phase
C Enumeration Value: Lav_OSCILLATOR_PHASE
Type: float
Range: [0.0, 1.0]
Default Value: 0.0
Rate: k
The phase of the impulse train. This is measured in periods, not in radians.
Buffer Node
C Type Identifier: Lav_OBJTYPE_BUFFER_NODE
Constructor: LavError Lav_createBufferNode(LavHandle serverHandle, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
Depends on the currently playing buffer. |
The output from the buffer being played. |
This node plays a buffer. The output of this node will have as many channels as the buffer does, so connecting it directly to the server will have the desired effect.
Properties
buffer
C Enumeration Value: Lav_BUFFER_BUFFER
Type: buffer
Default Value: See below
Rate: k
The currently playing buffer. Setting this property will reset position.
ended_count
C Enumeration Value: Lav_BUFFER_ENDED_COUNT
Type: int
Range: [0, 'MAX_INT']
Default Value: 0
Rate: k
Increments every time the buffer reaches it’s end. If the buffer is not looping, this can be used to determine when the buffer is ended, without using the callback. if the buffer is configured to loop, the counter will count up every time the end of a loop is reached. You can write to this property to reset it.
looping
C Enumeration Value: Lav_BUFFER_LOOPING
Type: boolean
Default Value: 0
Rate: k
If true, this node continues playing the same buffer from the beginning after it reaches the end.
position
C Enumeration Value: Lav_BUFFER_POSITION
Type: double
Range: dynamic
Default Value: 0.0
Rate: k
The position of playback, in seconds. The range of this property corresponds to the total duration of the buffer.
rate
C Enumeration Value: Lav_BUFFER_RATE
Type: double
Range: [0, 'INFINITY']
Default Value: 1.0
Rate: k
A multiplier that applies to playback rate. 1.0 is identity. Values less than 1.0 cause a decrease in pitch and values greater than 1.0 cause an increase in pitch.
Callbacks
end
Setter: LavError Lav_bufferNodeSetEndCallback(LavHandle nodeHandle, LavParameterlessCallback callback, void* userdata)
Callback Prototype: void (LavHandle nodeHandle, void* userdata)
Type |
Name |
Description |
|
nodeHandle |
The node which called this callback. |
|
userdata |
The userdata parameter as passed to the setter for this callback. |
Called outside the audio threads every time the buffer reaches the end of the audio data.
Buffer Timeline Node
C Type Identifier: Lav_OBJTYPE_BUFFER_TIMELINE_NODE
Constructor: LavError Lav_createBufferTimelineNode(LavHandle serverHandle, int channels, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The sum of all playing buffers. |
Represents timelines of buffers.
This node provides the ability to schedule buffers to play at any specific time in the future. This node supports pitch bending scheduled buffers. There is no limit to the number of buffers which may be scheduled at any given time, and polyphony is supported.
Extra Functions
schedule_buffer
Prototype: LavError Lav_bufferTimelineNodeScheduleBuffer(LavHandle nodeHandle, LavHandle bufferHandle, double time, float pitchBend)
Schedule a buffer, optionally with pitch bend. The time is relative to now.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
bufferHandle |
The buffer to schedule. |
|
time |
The time to play the buffer. |
|
pitchBend |
The pitch bend, which must be positive. Use 1.0 to disable. |
Channel Merger Node
C Type Identifier: Lav_OBJTYPE_CHANNEL_MERGER_NODE
Constructor: LavError Lav_createChannelMergerNode(LavHandle serverHandle, int channels, LavHandle* destination)
The number of inputs to this node depends on parameters to its constructor.
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The result of merging the input channels. |
Libaudioverse inputs and outputs transport multiple channels of audio, which is usually the desired behavior. This node, coupled with the channel splitter node , allows advanced applications to manipulate the individual audio channels directly. The usual workflow is as follows: feed the output of a node through a channel splitter node, modify the channels individually, and then merge them with this node.
Channel Splitter Node
C Type Identifier: Lav_OBJTYPE_CHANNEL_SPLITTER_NODE
Constructor: LavError Lav_createChannelSplitterNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to split into component channels. |
The number of outputs from this node depends on parameters to its constructor.
Libaudioverse inputs and outputs transport multiple channels of audio, which is usually the desired behavior. This node, coupled with the channel merger node, allows advanced applications to manipulate the individual audio channels directly. The usual workflow is as follows: feed the output of a node through this node, modify the channels individually, and then merge them with a channel merger node.
Convolver Node
C Type Identifier: Lav_OBJTYPE_CONVOLVER_NODE
Constructor: LavError Lav_createConvolverNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to be convolved. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The convolved signal. |
A simple convolver.
This implements convolution directly, without use of the FFT.
Properties
impulse_response
C Enumeration Value: Lav_CONVOLVER_IMPULSE_RESPONSE
Type: float_array
Default Value: [1.0]
Rate: k
The impulse response to convolve the input with.
Crossfader Node
C Type Identifier: Lav_OBJTYPE_CROSSFADER_NODE
Constructor: LavError Lav_createCrossfaderNode(LavHandle serverHandle, int channels, int inputs, LavHandle* destination)
The number of inputs to this node depends on parameters to its constructor.
Index |
Channels |
Description |
0 |
Depends on the channel count given to the constructor. |
The output of the crossfade. |
A crossfader is a node which allows for selection of exactly one input. The selection can be changed by crossfading, a technique whereby the currently selected input is slowly faded out and the new one faded in.
By using crossfades of no duration, this node can also be made to function as a switch or selector, selecting an input from among the connected nodes.
This particular case is optimized, and special support is implemented via allowing you to write directly to the current_input
property.
This crossfader has a configurable number of inputs. All inputs and the single output have the same channel count. These are both configurable via parameters to the constructor.
Properties
current_input
C Enumeration Value: Lav_CROSSFADER_CURRENT_INPUT
Type: int
Range: dynamic
Default Value: 0
Rate: k
The currently active input.
Writing to this property is equivalent to crossfading with a time of 0. Note that the output is a combination of the current and target inputs while crossfading.
is_crossfading
C Enumeration Value: Lav_CROSSFADER_IS_CROSSFADING
Type: boolean
Default Value: 0
Rate: k
True if we are crossfading, otherwise false.
target_input
C Enumeration Value: Lav_CROSSFADER_TARGET_INPUT
Type: int
This property is read-only.
The input which the current crossfade is headed for.
When not crossfading, this property is meaningless.
Callbacks
finished
Setter: LavError Lav_crossfaderNodeSetFinishedCallback(LavHandle nodeHandle, LavParameterlessCallback callback, void* userdata)
Callback Prototype: void (LavHandle nodeHandle, void* userdata)
Type |
Name |
Description |
|
nodeHandle |
The node which called this callback. |
|
userdata |
The userdata parameter as passed to the setter for this callback. |
Called outside the audio thread when the currently scheduled crossfade finishes.
Extra Functions
crossfade
Prototype: LavError Lav_crossfaderNodeCrossfade(LavHandle nodeHandle, float duration, int input)
Begin a crossfade.
if a crossfade is currently inn progress, it finishes immediately and fires the event.
Using a duration of 0 is an instantaneous crossfade, equivalent to writing directly to the current_input property. Crossfades of duration 0 do not fire the finished event.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
duration |
The duration of the crossfade. |
|
input |
The input to crossfade to. |
Crossfading Delay Line Node
C Type Identifier: Lav_OBJTYPE_CROSSFADING_DELAY_NODE
Constructor: LavError Lav_createCrossfadingDelayNode(LavHandle serverHandle, float maxDelay, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to delay. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The delayed signal. |
Implements a crossfading delay line. Delay lines have uses in echo and reverb, as well as many more esoteric effects.
Properties
delay
C Enumeration Value: Lav_DELAY_DELAY
Type: float
Range: dynamic
Default Value: 0.0
Rate: k
The delay of the delay line in seconds. The range of this property depends on the maxDelay parameter to the constructor.
Note that values less than 1 sample still introduce delay.
delay_max
C Enumeration Value: Lav_DELAY_DELAY_MAX
Type: float
This property is read-only.
The max delay as set at the node’s creation time.
feedback
C Enumeration Value: Lav_DELAY_FEEDBACK
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The feedback coefficient. The output of the delay line is fed back into the delay line, multiplied by this coefficient. Setting feedback to small values can make echoes, comb filters, and a variety of other effects.
interpolation_time
C Enumeration Value: Lav_DELAY_INTERPOLATION_TIME
Type: float
Range: [0.001, 'INFINITY']
Default Value: 0.001
Rate: k
When the delay property is changed, the delay line crossfades between the old position and the new one. This property sets how long this crossfade will take. Note that for this node, it is impossible to get rid of the crossfade completely.
Dc Blocker Node
C Type Identifier: Lav_OBJTYPE_DC_BLOCKER_NODE
Constructor: LavError Lav_createDcBlockerNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
A signal with some DC. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The same signal with DC cut using a first-order filter. |
A DC blocker. This is a first-order filter, the best possible within numerical limits. It consists of a zero at DC, and a pole as close to DC as we can put it. For any sampling rate, this node is the best first-order section for DC removal possible.
Dopplering Delay Line Node
C Type Identifier: Lav_OBJTYPE_DOPPLERING_DELAY_NODE
Constructor: LavError Lav_createDoppleringDelayNode(LavHandle serverHandle, float maxDelay, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to delay. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The delayed signal. |
Implements a dopplering delay line, an interpolated delay line that intensionally bends pitch when the delay changes. Delay lines have uses in echo and reverb, as well as many more esoteric effects.
Properties
delay
C Enumeration Value: Lav_DELAY_DELAY
Type: float
Range: dynamic
Default Value: 0.0
Rate: k
The delay of the delay line in seconds. The range of this property depends on the maxDelay parameter to the constructor.
Note that values less than 1 sample still introduce delay.
delay_max
C Enumeration Value: Lav_DELAY_DELAY_MAX
Type: float
This property is read-only.
The max delay as set at the node’s creation time.
interpolation_time
C Enumeration Value: Lav_DELAY_INTERPOLATION_TIME
Type: float
Range: [0.001, 'INFINITY']
Default Value: 0.01
Rate: k
When the delay property is changed, the delay line moves the delay to the new position. This property sets how long this will take. Note that for this node, it is impossible to get rid of the crossfade completely.
On this delay line, the interpolation time is the total duration of a pitch bend caused by moving the delay.
Environment Node
C Type Identifier: Lav_OBJTYPE_ENVIRONMENT_NODE
Constructor: LavError Lav_createEnvironmentNode(LavHandle serverHandle, const char* hrtfPath, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
Depends on the output_channels property. |
The output of the 3D environment. |
This is the entry point to the 3D simulation capabilities. Environment nodes hold the information needed to pan sources, as well as acting as an aggregate output for all sources that use this environment.
Note that the various properties for default values do not affect already created sources. It is best to configure these first. Any functionality to change a property on all sources needs to be implemented by the app, and is not offered by Libaudioverse.
Properties
default_size
C Enumeration Value: Lav_ENVIRONMENT_DEFAULT_SIZE
Type: float
Range: [0.0, 'INFINITY']
Default Value: 0.0
Rate: k
The default size for new sources. Sources aare approximated as spheres, with 0 being the special case of a point source. Size is used to determine the listener’s distance from a source.
distance_model
C Enumeration Value: Lav_ENVIRONMENT_DISTANCE_MODEL
Type: int
Range: A value from the Lav_DISTANCE_MODELS enumeration.
Default Value: Lav_DISTANCE_MODEL_LINEAR
Rate: k
Distance models control how quickly sources get quieter as they move away from the listener.
By default, sources are configured to delegate to the environment when looking for values to use for the distance model parameters.
This behavior may be changed by setting Lav_SOURCE_CONTROL_DISTANCE_MODEL
to true.
max_distance
C Enumeration Value: Lav_ENVIRONMENT_MAX_DISTANCE
Type: float
Range: [0.0, 'INFINITY']
Default Value: 150.0
Rate: k
The maximum distance at which a source is audible. Consider this property to be in meters.
By default, sources are configured to delegate to the environment when looking for values to use for the distance model parameters.
This behavior may be changed by setting Lav_SOURCE_CONTROL_DISTANCE_MODEL
to true.
max_reverb_level
C Enumeration Value: Lav_ENVIRONMENT_MAX_REVERB_LEVEL
Type: float
Range: [0.0, 1.0]
Default Value: 0.6
Rate: k
The maximum amount of audio to be diverted to reverb sends, if any.
Behavior is undefined if this property is ever less than Lav_ENVIRONMENT_MIN_REVERB_LEVEL.
By default, sources look to their environmlent for the value of this property.
If you wish to set it on a per-source basis, set Lav_SOURCE_CONTROL_REVERB
to true on the source.
min_reverb_level
C Enumeration Value: Lav_ENVIRONMENT_MIN_REVERB_LEVEL
Type: float
Range: [0.0, 1.0]
Default Value: 0.15
Rate: k
The minimum reverb level allowed.
if a send is configured to be a reverb send, this is the minimum amount of audio that will be diverted to it.
Behavior is undefined if this property is ever greater than the value of Lav_ENVIRONMENT_MAX_REVERB_LEVEL.
By default, sources look to their environmlent for the value of this property.
If you wish to set it on a per-source basis, set Lav_SOURCE_CONTROL_REVERB
to true on the source.
orientation
C Enumeration Value: Lav_ENVIRONMENT_ORIENTATION
Type: float6
Default Value: [0.0, 0.0, -1.0, 0.0, 1.0, 0.0]
Rate: k
The orientation of the listener. The first three elements are a vector representing the direction in which the listener is looking and the second 3 a vector representing the direction in which a rod pointing out of the top of the listener’s head would be pointing
This property packs these vectors because they must never be modified separately. Additionally, they should both be unit vectors and must also be orthoganal.
the default situates the listener such that positive x is right, positive y is up, and positive z is behind the listener. The setting (0, 1, 0, 0, 0, 1) will situate the listener such that positive x is right and positive y is forward. For those not familiar with trigonometry and who wish to consider positive x east and positivve y north, the following formula will turn the listener to face a scertain direction specified in radians clockwise of north: (sin(theta), cos(theta), 0, 0, 0, 1). As usual, note that radians=degrees*PI/180.
output_channels
C Enumeration Value: Lav_ENVIRONMENT_OUTPUT_CHANNELS
Type: int
Range: [0, 8]
Default Value: 2
Rate: k
Environments are not smart enough to determine the number of channels their output needs to have. If you are using something greater than stereo, i.e. 5.1, you need to change this property. The specific issue solved by this property is the case in which one source is set to something different than all others, or where the app changes the panning strategies of sources after creation.
Values besides 2, 4, 6, or 8 do not usually have much meaning.
panning_strategy
C Enumeration Value: Lav_ENVIRONMENT_PANNING_STRATEGY
Type: int
Range: A value from the Lav_PANNING_STRATEGIES enumeration.
Default Value: Lav_PANNING_STRATEGY_STEREO
Rate: k
The panning strategy for any source configured to delegate to the environment. All new sources delegate to the environment by default.
If you want to change this property for a specific source, set Lav_SOURCE_CONTROL_PANNING
on the source to true.
position
C Enumeration Value: Lav_ENVIRONMENT_POSITION
Type: float3
Default Value: [0.0, 0.0, 0.0]
Rate: k
The position of the listener, in world coordinates.
default_reverb_distance
C Enumeration Value: Lav_ENVIRONMENT_REVERB_DISTANCE
Type: float
Range: [0.0, 'INFINITY']
Default Value: 75.0
Rate: k
The distance at which a source will be heard only in the reverb.
See documentation on the source node node for a specific explanation.
By default, sources get the value of this property from the environment.
To control this property on a per-source basis, set Lav_SOURCE_CONTROL_REVERB
to true on the source.
Extra Functions
add_effect_send
Prototype: LavError Lav_environmentNodeAddEffectSend(LavHandle nodeHandle, int channels, int isReverb, int connectByDefault, int* destination)
Add an effect send.
Effect sends are aggregates of all sources configured to make use of them. This function’s return value is the index of the newly created effecct send.
The world gains an additional output for every added effect send. This output aggregates all audio of sources configured to send to it, including the panning effects on those sources. The returned index is the number of the newly created output.
Two special cases are worth noting.
First, a mono effect send includes all sources with only attenuation applied.
Second, if the effect send has 4 channels, it may be configured to be a reverb effect send with the isReverb parameter. Reverb effect sends are treated differently in terms of attenuation: as sources move away from the listener, their dry path becomes less but the audio sent to the reverb effect send becomes greater.
No effect send can include occlusion effects.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
channels |
The number of channels the effect send is to have. Must be 1, 2, 4, 6, or 8. |
|
isReverb |
nonzero if this is a reverb effect send. |
|
connectByDefault |
If nonzero, all existing and newly created sources will send to this effect send unless disabled. |
|
destination |
Holds the result of a call to this function. |
play_async
Prototype: LavError Lav_environmentNodePlayAsync(LavHandle nodeHandle, LavHandle bufferHandle, float x, float y, float z, int isDry)
Play a buffer, using the specified position and the currently set defaults on the world for distance model and panning strategy. This is the same as creating a buffer and a source, but Libaudioverse retains control of these objects. When the buffer finishes playing, the source is automatically disposed of.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
bufferHandle |
The buffer to play. |
|
x |
The x-component of the position. |
|
y |
The y-component of the position. |
|
z |
The z-component of the position. |
|
isDry |
If true, we avoid sending to the effect sends configured as defaults. |
Fdn Reverb Node
C Type Identifier: Lav_OBJTYPE_FDN_REVERB_NODE
Constructor: LavError Lav_createFdnReverbNode(LavHandle serverHandle, LavHandle* destination)
Index |
Channels |
Description |
0 |
4 |
The signal to apply reverb to. |
Index |
Channels |
Description |
0 |
4 |
The signal with reverb applied. |
An 8 delay line FDN reverberator, based off a householder reflection.
This reverb takes as its input and outputs ats its output quadraphonic audio. Panning effects will still be observed at the output with some bias. If a stereo signal is fed into the reverb and the reverb is likewise connected to a stereo output, the input signal’s volume will effectively be halved.
Properties
cutoff_frequency
C Enumeration Value: Lav_FDN_REVERB_CUTOFF_FREQUENCY
Type: float
Range: dynamic
Default Value: 5000
Rate: k
Controls the frequencies of lowpass filters on the feedback path of the reverb. Lowering this property leads to softer and less harsh reverb.
delay_modulation_depth
C Enumeration Value: Lav_FDN_REVERB_DELAY_MODULATION_DEPTH
Type: float
Range: [0.0, 1.0]
Default Value: 0.0
Rate: k
Controls how deep the modulation of the delay lines is. Increasing this property slightly makes the late reverb sound less metallic, while extremely high values add chorus-like effects. This property acts as a multiplier, and the correspondance between it and physical units is intentionally left unspecified.
delay_modulation_frequency
C Enumeration Value: Lav_FDN_REVERB_DELAY_MODULATION_FREQUENCY
Type: float
Range: [0.0, 500.0]
Default Value: 10.0
Rate: k
Controls how fast the internal delay lines modulate.
density
C Enumeration Value: Lav_FDN_REVERB_DENSITY
Type: float
Range: [0.0, 1.0]
Default Value: 0.5
Rate: k
Controls the density of the reverb. Extremely low values sound "grainy"; extremely high values tend to resonate.
t60
C Enumeration Value: Lav_FDN_REVERB_T60
Type: float
Range: [0.0, 'INFINITY']
Default Value: 1.0
Rate: k
The t60
is the time it takes the reverb to decay by 60 decibals.
Feedback Delay Network Node
C Type Identifier: Lav_OBJTYPE_FEEDBACK_DELAY_NETWORK_NODE
Constructor: LavError Lav_createFeedbackDelayNetworkNode(LavHandle serverHandle, float maxDelay, int channels, LavHandle* destination)
The inputs of this node are described below.
The outputs of this node are described below.
Implements a feedback delay network. This is possibly the single-most complicated node in Libaudioverse, and full documentation of it goes well beyond the manual. Unless you know what a feedback delay network is and have a specific reason for using one, this node will probably not help you.
This node has n
inputs and outputs, where n
is the lines
parameter to the constructor.
Each input and output pair represent the input and output of a specific delay line, respectively.
Properties
delays
C Enumeration Value: Lav_FDN_DELAYS
Type: float_array
Default Value: See below
Rate: k
The lengths of the delay lines in seconds.
This array must be channels
long.
All values must be positive and no more than the maximum delay specified to the constructor.
filter_frequencies
C Enumeration Value: Lav_FDN_FILTER_FREQUENCIES
Type: float_array
Default Value: See below
Rate: k
The frequencies of the filters. The range of this property is 0 to Nyquist, or half the sampling rate.
filter_types
C Enumeration Value: Lav_FDN_FILTER_TYPES
Type: int_array
Default Value: See below
Rate: k
Allows insertion of filters in the feedback paths. These filters can be individually enabled and disabled; the default is disabled.
matrix
C Enumeration Value: Lav_FDN_MATRIX
Type: float_array
Default Value: See below
Rate: k
The feedback matrix.
A column vector is formed by reading all delay lines. This vector is multiplied by this matrix, and then fed back into the delay lines.
The matrix is stored in row-major order. The supplied array must have a length equal to the square of the channels specified to the constructor.
max_delay
C Enumeration Value: Lav_FDN_MAX_DELAY
Type: float
This property is read-only.
The maximum delay any of the internal delay lines may be set to.
output_gains
C Enumeration Value: Lav_FDN_OUTPUT_GAINS
Type: float_array
Default Value: See below
Rate: k
Allows control of the individual gains of the output.
These gains do not apply to the feedback path and are only for controlling relative output levels.
The array for this property allows any floating point values, and must be exactly channels
long.
Fft Convolver Node
C Type Identifier: Lav_OBJTYPE_FFT_CONVOLVER_NODE
Constructor: LavError Lav_createFftConvolverNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to be convolved. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The convolved signal. |
A convolver for long impulse responses.
This convolver uses the overlap-add convolution algorithm. It is slower than the convolver node for small impulse responses.
The difference between this node and the convolver node is the complexity of the algorithm. This node is capable of handling impulses longer than a second, a case for which the convolver node will fail to run in realtime.
Furthermore, as the most common operation for this node is reverb, it is possible to set each channel’s response separately.
Extra Functions
set_response
Prototype: LavError Lav_fftConvolverNodeSetResponse(LavHandle nodeHandle, int channel, int length, float* response)
Set the response for a specific channel.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
channel |
The channel to set the response for. |
|
length |
The length of the response in samples. |
|
response |
The new response. |
set_response_from_file
Prototype: LavError Lav_fftConvolverNodeSetResponseFromFile(LavHandle nodeHandle, const char* path, int fileChannel, int convolverChannel)
Set the impulse response for a specific channel of this node from a file.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
path |
The path to the file. |
|
fileChannel |
The channel of the file to use as the response. |
|
convolverChannel |
The channel for which the response is to be set. |
File Streamer Node
C Type Identifier: Lav_OBJTYPE_FILE_STREAMER_NODE
Constructor: LavError Lav_createFileStreamerNode(LavHandle serverHandle, const char* path, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
Depends on the file. |
The output of the stream. |
Streams a file, which must be specified to the constructor and cannot be changed thereafter.
This node is a stopgap solution, and should be considered temporary. It will likely remain for backward compatibility. Libaudioverse plans to eventually offer a more generic streaming node that also supports web addresses; such a node will have a completely different, less buffer-like interface.
In order to stream a file, it must be passed through a resampler. Consequentlty, the position property is slightly inaccurate and the ended property and callback are slightly delayed.
Properties
ended
C Enumeration Value: Lav_FILE_STREAMER_ENDED
Type: boolean
This property is read-only.
Switches from false to true once the stream has ended completely and gone silent. This property will never go true unless looping is false.
looping
C Enumeration Value: Lav_FILE_STREAMER_LOOPING
Type: boolean
Default Value: 0
Rate: k
If true, this node repeats the file from the beginning once it reaches the end. Note that setting looping means that ended will never go true. If ended is already true, it may take until the end of the next processing block for ended to properly go false once more.
position
C Enumeration Value: Lav_FILE_STREAMER_POSITION
Type: double
Range: dynamic
Default Value: 0.0
Rate: k
The position of playback, in seconds. The range of this property corresponds to the total duration of the file. Note that this property may be slightly inaccurate because this node has to pass data through a resampler.
Callbacks
end
Setter: LavError Lav_fileStreamerNodeSetEndCallback(LavHandle nodeHandle, LavParameterlessCallback callback, void* userdata)
Callback Prototype: void (LavHandle nodeHandle, void* userdata)
Type |
Name |
Description |
|
nodeHandle |
The node which called this callback. |
|
userdata |
The userdata parameter as passed to the setter for this callback. |
Called outside the audio threads after the stream has both reached its end and gone silent. When called, ended will be set to true,.
Filtered Delay Node
C Type Identifier: Lav_OBJTYPE_FILTERED_DELAY_NODE
Constructor: LavError Lav_createFilteredDelayNode(LavHandle serverHandle, float maxDelay, unsigned int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to process. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The result of processing the audio via the filter and delay line. |
This node consists of a delay line with a biquad filter attached. The output of the delay line is filtered. The difference between this node and a delay line and filter pair is that this node will use the filtered output for the feedback.
This node is equivalent to the delay line in the Karplus-strong algorithm.
Properties
dbgain
C Enumeration Value: Lav_FILTERED_DELAY_DBGAIN
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
This property is a the gain in decibals to be used with the peaking and shelving filters. It measures the gain that these filters apply to the part of the signal they boost.
delay
C Enumeration Value: Lav_FILTERED_DELAY_DELAY
Type: float
Range: dynamic
Default Value: 0.0
Rate: k
The delay of the delay line in seconds. The range of this property depends on the maxDelay parameter to the constructor.
delay_max
C Enumeration Value: Lav_FILTERED_DELAY_DELAY_MAX
Type: float
This property is read-only.
The max delay as set at the node’s creation time.
feedback
C Enumeration Value: Lav_FILTERED_DELAY_FEEDBACK
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The feedback coefficient. The output of the filter is fed back into the delay line, multiplied by this coefficient.
filter_type
C Enumeration Value: Lav_FILTERED_DELAY_FILTER_TYPE
Type: int
Range: A value from the Lav_BIQUAD_TYPES enumeration.
Default Value: Lav_BIQUAD_TYPE_LOWPASS
Rate: k
The type of the filter. This determines the interpretations of the other properties on this node.
frequency
C Enumeration Value: Lav_FILTERED_DELAY_FREQUENCY
Type: float
Range: [0, 'INFINITY']
Default Value: 2000.0
Rate: k
This is the frequency of interest. What specifically this means depends on the selected filter type; for example, it is the cutoff frequency for lowpass and highpass.
interpolation_time
C Enumeration Value: Lav_FILTERED_DELAY_INTERPOLATION_TIME
Type: float
Range: [0.001, 'INFINITY']
Default Value: 0.001
Rate: k
When the delay property is changed, the delay line crossfades between the old position and the new one. This property sets how long this crossfade will take. Note that for this node, it is impossible to get rid of the crossfade completely.
q
C Enumeration Value: Lav_FILTERED_DELAY_Q
Type: float
Range: [0.001, 'INFINITY']
Default Value: 0.5
Rate: k
Q is a mathematically complex parameter, a full description of which is beyond the scope of this manual. For lowpass, bandpass, and high pass filters, Q can be interpreted as a measure of resonation. For Q⇐0.5, the filter is said to be damped: it will cut frequencies. For Q>0.5, however, some frequencies are likely to be boosted.
Q controls the bandwidth for the bandpass and peaking filter types as well as the slope for the shelving EQ.
For everything except the peaking filter, this property follows the normal definition of Q in the electrical engineering literature. For more specifics, see the Audio EQ Cookbook. It is found here: http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
First Order Filter Node
C Type Identifier: Lav_OBJTYPE_FIRST_ORDER_FILTER_NODE
Constructor: LavError Lav_createFirstOrderFilterNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to filter. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The filtered signal. |
A first order filter section, implementing the transfer function \(H(Z) = \frac{B_0 + B_1 Z^{-1} }{1+A_0 Z^{-1} }\)
This filter is not your friend unless you know DSP or have a specific goal in mind. Most applications will want a biquad filter node or a One-Pole Filter node instead.
This filter is not controlled through frequency specifications. Instead, the position of the pole and the zero on the real axis are individually controllable with a-rate properties. Some helper functions exist to position them for common configurations, but other filter types do most of it better. The major advantage for this filter type is that it is incredibly inexpensive as compared to the IIR filter node and supports automation of the pole and zero’s position.
Properties
pole
C Enumeration Value: Lav_FIRST_ORDER_FILTER_POLE
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: a
The position of the pole on the real axis.
The pole may be positioned anywhere, but stable filters usually keep all poles inside the unit circle. For a stable filter, the value of this property should usually between -1 and 1.
zero
C Enumeration Value: Lav_FIRST_ORDER_FILTER_ZERO
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: a
The position of the zero on the real axis.
Extra Functions
configure_allpass
Prototype: LavError Lav_firstOrderFilterNodeConfigureAllpass(LavHandle nodeHandle, float frequency)
Configure this node as an allpass. You specify the \(\frac{\pi}{2}\) frequency. You get a filter with a phase of \(\pi\) at DC and 0 at Nyquist.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
frequency |
The frequency at which the filter has a phase of \(\frac{\pi}{2}\). Must be between 0 and Nyquist. |
configure_highpass
Prototype: LavError Lav_firstOrderFilterNodeConfigureHighpass(LavHandle nodeHandle, float frequency)
Configure the filter as a highpass with a roll-off of 6 DB
per octave.
This is identical to the One-Pole Filter node highpass configuration.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
frequency |
The |
configure_lowpass
Prototype: LavError Lav_firstOrderFilterNodeConfigureLowpass(LavHandle nodeHandle, float frequency)
Configure the filter as a first-order Butterworth lowpass. This is equivalent to the One-Pole Filter node lowpass configuration.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
frequency |
The |
Gain Node
C Type Identifier: Lav_OBJTYPE_GAIN_NODE
Constructor: LavError Lav_createGainNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal whose gain is to be changed. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The signal with its gain changed. |
This node is essentially in instantiated generic node, offering only the functionality therein. Its purpose is to allow changing the gain or adding offset to a large collection of nodes. One possible use is as a simple mixer: point all the nodes to be mixed at the input, set mul, and then point the output at the destination for the mixed audio.
Graph Listener Node
C Type Identifier: Lav_OBJTYPE_GRAPH_LISTENER_NODE
Constructor: LavError Lav_createGraphListenerNode(LavHandle serverHandle, unsigned int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The audio which will be passed to the associated callback. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The same audio as connected to the input without modification. |
This node defines a callback which is called every block. The callback is passed pointers to the audio data passing through this node for the current block. The effect is that this node allows observing audio passing through any location in the audio graph.
Callbacks
listening
Setter: LavError Lav_graphListenerNodeSetListeningCallback(LavHandle nodeHandle, LavGraphListenerNodeListeningCallback callback, void* userdata)
Callback Prototype: void (LavHandle nodeHandle, unsigned int frames, unsigned int channels, float* buffer, void* userdata)
Type |
Name |
Description |
|
nodeHandle |
The node which called this callback. |
|
frames |
The number of frames of audio being made available to client code. This should always be the same as the server’s block size. |
|
channels |
The number of channels of audio being made available to client code. |
|
buffer |
The data, stored in interleaved format. The length of this buffer is |
|
userdata |
The userdata parameter as passed to the setter for this callback. |
When set, audio is passed to this callback every block. This callback is called inside the audio threads; do not block.
Hard Limiter Node
C Type Identifier: Lav_OBJTYPE_HARD_LIMITER_NODE
Constructor: LavError Lav_createHardLimiterNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to limit |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The limited signal: no sample shall have an absolute value greater than 1.0. |
The input to this node is hard limited: values less than -1.0 are set to -1.0 and values above 1.0 are set to 1.0. Use the hard limiter in order to prevent oddities with audio hardware; it should usually be the last piece in your pipeline before the server. Note that the 3D API handles hard limiting appropriately, and you do not need to worry about this there.
Hrtf Node
C Type Identifier: Lav_OBJTYPE_HRTF_NODE
Constructor: LavError Lav_createHrtfNode(LavHandle serverHandle, const char* hrtfPath, LavHandle* destination)
Index |
Channels |
Description |
0 |
1 |
The signal to pan. |
Index |
Channels |
Description |
0 |
2 |
The signal with the HRTF applied. |
This node implements an HRTF panner. You can use either Libaudioverse’s internal HRTF (The Diffuse MIT Kemar Dataset) by passing "default" as the HRTf file name, or an HRTF of your own.
Properties
azimuth
C Enumeration Value: Lav_PANNER_AZIMUTH
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The horizontal angle of the panner in degrees. 0 is straight ahead and positive values are clockwise.
elevation
C Enumeration Value: Lav_PANNER_ELEVATION
Type: float
Range: [-90.0, 90.0]
Default Value: 0.0
Rate: k
The vertical angle of the panner in degrees. 0 is horizontal and positive values move upward.
should_crossfade
C Enumeration Value: Lav_PANNER_SHOULD_CROSSFADE
Type: boolean
Default Value: 1
Rate: k
By default, panners crossfade their output. This property allows such functionality to be disabled. Note that for HRTF nodes, crossfading is more important than for other panner types. Unlike other panner types, the audio artifacts produced by disabling crossfading are noticeable, even for updates of only a few degrees.
Iir Filter Node
C Type Identifier: Lav_OBJTYPE_IIR_NODE
Constructor: LavError Lav_createIirNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to filter. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The signal with the IIR filter applied. |
Implements arbetrary IIR filters. The only restriction on the filter is that the first element of the denominator must be nonzero. To configure this node, use the function Lav_iirNodeSetCoefficients.
Extra Functions
set_coefficients
Prototype: LavError Lav_iirNodeSetCoefficients(LavHandle nodeHandle, int numeratorLength, double* numerator, int denominatorLength, double* denominator, int shouldClearHistory)
Configure the coefficients of the IIR filter.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
numeratorLength |
The number of coefficients in the numerator of the filter’s transfer function. |
|
numerator |
The numerator of the transfer function. |
|
denominatorLength |
The number of coefficients in the denominator of the transfer function. Must be at least 1. |
|
denominator |
The denominator of the transfer function. The first coefficient must be nonzero. |
|
shouldClearHistory |
1 if we should reset the internal histories, otherwise 0. |
Leaky Integrator Node
C Type Identifier: Lav_OBJTYPE_LEAKY_INTEGRATOR_NODE
Constructor: LavError Lav_createLeakyIntegratorNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
A signal to integrate. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The integral of the signal. |
A leaky integrator. Leaky integrators integrate their input signals, while leaking over time. Introducing the leak allows for avoiding DC offset problems. If you feed this node a signal that is zero, it will slowly decrease the output in accordance with the Lav_LEAKY_INTEGRATOR_LEAKYNESS property.
Properties
leakyness
C Enumeration Value: Lav_LEAKY_INTEGRATOR_LEAKYNESS
Type: double
Range: [0.0, 1.0]
Default Value: 1.0
Rate: k
The leakyness (or time constant) of the integrator.
If you feed the leaky integrator a constant signal of 0, then this property’s value is the percent decrease as observed after 1 second.
Multipanner Node
C Type Identifier: Lav_OBJTYPE_MULTIPANNER_NODE
Constructor: LavError Lav_createMultipannerNode(LavHandle serverHandle, char* hrtfPath, LavHandle* destination)
Index |
Channels |
Description |
0 |
1 |
The signal to pan. |
Index |
Channels |
Description |
0 |
Depends on the currently set panning strategy. |
The signal, panned according to the configured panning strategy. |
A panner which can have the algorithm it uses changed at runtime. The use for multipanners is for applications in which we may wish to change the speaker configuration at runtime. Capabilities include switching from HRTF to stereo and back, a useful property for games wherein the user might or might not be using headphones.
Properties
azimuth
C Enumeration Value: Lav_PANNER_AZIMUTH
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The horizontal angle of the panner, in degrees. 0 is straight ahead and positive values are clockwise.
elevation
C Enumeration Value: Lav_PANNER_ELEVATION
Type: float
Range: [-90.0, 90.0]
Default Value: 0.0
Rate: k
The vertical angle of the panner, in degrees. 0 is horizontal and positive values are upward.
should_crossfade
C Enumeration Value: Lav_PANNER_SHOULD_CROSSFADE
Type: boolean
Default Value: 1
Rate: k
Whether or not this panner should crossfade. Lack of crossfading introduces audible artifacts when the panner is moved. You usually want this on.
strategy
C Enumeration Value: Lav_PANNER_STRATEGY
Type: int
Range: A value from the Lav_PANNING_STRATEGIES enumeration.
Default Value: Lav_PANNING_STRATEGY_STEREO
Rate: k
What type of panning to use. Possibilities include HRTF, stereo, 5.1, and 7.1 speaker configurations. For something more nontraditional, use an amplitude panner.
Noise Generator Node
C Type Identifier: Lav_OBJTYPE_NOISE_NODE
Constructor: LavError Lav_createNoiseNode(LavHandle serverHandle, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
1 |
The noise generated by this node. |
Generates any of a variety of types of noise.
Properties
noise_type
C Enumeration Value: Lav_NOISE_NOISE_TYPE
Type: int
Range: A value from the Lav_NOISE_TYPES enumeration.
Default Value: Lav_NOISE_TYPE_WHITE
Rate: k
The type of noise to generate.
should_normalize
C Enumeration Value: Lav_NOISE_SHOULD_NORMALIZE
Type: boolean
Default Value: 0
Rate: k
Whether or not to normalize the output. Some types of noise are quieter without this enabled. Turning it on is sometimes helpful and sometimes not.
One-Pole Filter Node
C Type Identifier: Lav_OBJTYPE_ONE_POLE_FILTER_NODE
Constructor: LavError Lav_createOnePoleFilterNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to filter. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The filtered signal. |
A one-pole filter section, implementing the transfer function \(H(Z) = rac{1}{1+A_0 Z^{-1} }\)
This filter is capable of implementing either a lowpass or highpass filter and is extremmely cheep. The produced filter rolls off at about 6 DB per octave.
The default filter configuration is a lowpass at 500 HZ.
The type of the filter is controlled via the is_highpass
property.
If said property is true, the filter becomes a highpass.
Note that this filter can be swept with a-rate accuracy.
Properties
frequency
C Enumeration Value: Lav_ONE_POLE_FILTER_FREQUENCY
Type: float
Range: dynamic
Default Value: 500.0
Rate: a
The -3 DB frequency of the filter.
The range of this property is from 0 to half the sampling rate.
is_highpass
C Enumeration Value: Lav_ONE_POLE_FILTER_IS_HIGHPASS
Type: boolean
Default Value: 0
Rate: k
True if the filter is a highpass.
If this property is false, the filter is a lowpass.
Pull Node
C Type Identifier: Lav_OBJTYPE_PULL_NODE
Constructor: LavError Lav_createPullNode(LavHandle serverHandle, unsigned int sr, unsigned int channels, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The result of the configured callback. |
This node calls the audio callback whenever it needs more audio. The purpose of this node is to inject audio from an external source that Libaudioverse does not support, for example a custom network protocol.
Callbacks
audio
Setter: LavError Lav_pullNodeSetAudioCallback(LavHandle nodeHandle, LavPullNodeAudioCallback callback, void* userdata)
Callback Prototype: void (LavHandle nodeHandle, int frames, int channels, float* buffer, void* userdata)
Type |
Name |
Description |
|
nodeHandle |
The node which called this callback. |
|
frames |
The number of frames of audio needed. This is not guaranteed to be the same on every call. |
|
channels |
The number of channels as set when the pull node is created. |
|
buffer |
The destination to which audio should be written. This is a buffer that is |
|
userdata |
The userdata parameter as passed to the setter for this callback. |
Called when the node needs more audio.
Push Node
C Type Identifier: Lav_OBJTYPE_PUSH_NODE
Constructor: LavError Lav_createPushNode(LavHandle serverHandle, unsigned int sr, unsigned int channels, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
Either audio from the internal queue or zero. |
The purpose of this node is the same as the pull node, but it is used in situations wherein we do not know when we are going to get audio. Audio is queued as it is pushed to this node and then played as fast as possible. This node can be used to avoid writing a queue of audio yourself, as it essentially implements said functionality. If you need low latency audio or the ability to run something like the Opus encoder’s ability to cover for missing frames, you need a pull node.
Properties
threshold
C Enumeration Value: Lav_PUSH_THRESHOLD
Type: float
Range: [0.0, 'INFINITY']
Default Value: 0.03
Rate: k
When the remaining audio in the push node has a duration less than this property, the low callback is called.
Callbacks
low
Setter: LavError Lav_pushNodeSetLowCallback(LavHandle nodeHandle, LavParameterlessCallback callback, void* userdata)
Callback Prototype: void (LavHandle nodeHandle, void* userdata)
Type |
Name |
Description |
|
nodeHandle |
The node which called this callback. |
|
userdata |
The userdata parameter as passed to the setter for this callback. |
Called once per block and outside the audio thread when there is less than the specified threshold audio remaining.
underrun
Setter: LavError Lav_pushNodeSetUnderrunCallback(LavHandle nodeHandle, LavParameterlessCallback callback, void* userdata)
Callback Prototype: void (LavHandle nodeHandle, void* userdata)
Type |
Name |
Description |
|
nodeHandle |
The node which called this callback. |
|
userdata |
The userdata parameter as passed to the setter for this callback. |
Called exactly once and outside the audio thread when the node runs out of audio completely.
Extra Functions
feed
Prototype: LavError Lav_pushNodeFeed(LavHandle nodeHandle, unsigned int length, float* frames)
Feed more audio data into the internal queue.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
length |
The length of the buffer, in samples. |
|
frames |
The buffer to feed into the node. This memory is copied. |
Recorder Node
C Type Identifier: Lav_OBJTYPE_RECORDER_NODE
Constructor: LavError Lav_createRecorderNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to record. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The same as the input signal. |
Records audio to files.
The usage pattern for this node is simple: connect something to the input, call Lav_recorderNodeStartRecording, and ensure that the node is processed. In order to avoid potential problems with blocks of silence at the beginning of the recording, this node’s default state is playing. You should connect the output to something that will demand the recorder node’s audio or change the state to always playing, usually after a call to Lav_recorderNodeStartRecording. If you don’t, no recording will take place.
Unlike most other nodes in Libaudioverse, it is important that you call Lav_recorderNodeStopRecording when done recording. Failure to do so may lead to any of a number of surprising results.
Extra Functions
start_recording
Prototype: LavError Lav_recorderNodeStartRecording(LavHandle nodeHandle, const char* path)
Begin recording to the specified files. The sample rate is the same as that of the server. The channel count is the same as this node was initialized with. The format of the file is determined from the extension: this function recognizes ".wav" and ".ogg" on all platforms.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
path |
The path of the file to record to. |
stop_recording
Prototype: LavError Lav_recorderNodeStopRecording(LavHandle nodeHandle)
Stops recording.
Be sure to call this function. Failure to do so may lead to any of a number of undesirable problems.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
Ring Modulator Node
C Type Identifier: Lav_OBJTYPE_RINGMOD_NODE
Constructor: LavError Lav_createRingmodNode(LavHandle serverHandle, LavHandle* destination)
Index |
Channels |
Description |
0 |
1 |
The first signal. |
1 |
1 |
The second signal. |
Index |
Channels |
Description |
0 |
1 |
The result of multiplying the two input signals together. |
This node has two inputs and one output. The two inputs will be converted to mono and then multiplied, before being sent to the output.
Sine Node
C Type Identifier: Lav_OBJTYPE_SINE_NODE
Constructor: LavError Lav_createSineNode(LavHandle serverHandle, LavHandle* destination)
This node has no inputs.
Index |
Channels |
Description |
0 |
1 |
A sine wave. |
A simple sine oscillator.
Properties
frequency
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY
Type: float
Range: [0, 'INFINITY']
Default Value: 440.0
Rate: a
The frequency of the sine wave in HZ.
frequency_multiplier
C Enumeration Value: Lav_OSCILLATOR_FREQUENCY_MULTIPLIER
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 1.0
Rate: a
An additional multiplicative factor applied to the frequency of the oscillator.
This is useful for creating instruments, as the notes of the standard musical scale fall on frequency multiples of a reference pitch, rather than a linear increase.
phase
C Enumeration Value: Lav_OSCILLATOR_PHASE
Type: float
Range: [0.0, 1.0]
Default Value: 0.0
Rate: k
The phase of the sine node. This is measured in periods, not in radians.
Source Node
C Type Identifier: Lav_OBJTYPE_SOURCE_NODE
Constructor: LavError Lav_createSourceNode(LavHandle serverHandle, LavHandle environmentHandle, LavHandle* destination)
Index |
Channels |
Description |
0 |
1 |
The audio to enter the 3D environment. |
This node has no outputs.
The source node allows the spatialization of sound that passes through it. Sources have one input which is mono, to which a node should be connected. The audio from the input is spatialized according both to the source’s properties and those on its environment, and passed directly to the environment. Sources have no outputs. To hear a source, you must connect its environment to something instead.
Since the source communicates with the environment through a nonstandard mechanism, environments do not keep their sources alive. If you are in a garbage collected language, failure to hold on to the source nodes will cause them to go silent.
Properties
control_distance_model
C Enumeration Value: Lav_SOURCE_CONTROL_DISTANCE_MODEL
Type: boolean
Default Value: 0
Rate: k
In order to make working with sources easier for simple applications, some properties of source objects are ignored in favor of values on the environment. This property is used to disable this behavior for properties related to the distance model.
control_panning
C Enumeration Value: Lav_SOURCE_CONTROL_PANNING
Type: boolean
Default Value: 0
Rate: k
In order to make working with sources easier for simple applications, some properties of source objects are ignored in favor of values on the environment. This property is used to disable this behavior for properties related to panning.
control_reverb
C Enumeration Value: Lav_SOURCE_CONTROL_REVERB
Type: boolean
Default Value: 0
Rate: k
In order to make working with sources easier for simple applications, some properties of source objects are ignored in favor of values on the environment. This property is used to disable this behavior for properties related to reverb.
distance_model
C Enumeration Value: Lav_SOURCE_DISTANCE_MODEL
Type: int
Range: A value from the Lav_DISTANCE_MODELS enumeration.
Default Value: Lav_DISTANCE_MODEL_LINEAR
Rate: k
The distance model determines how quickly sources get quieter as they move away from the listener. The default value of this property is set from the corresponding property on the environment at source creation. By default, sources ignore this property in favor of the value provided by their environment. Set Lav_SOURCE_CONTROL_DISTANCE_MODEL to true to control it yourself.
head_relative
C Enumeration Value: Lav_SOURCE_HEAD_RELATIVE
Type: boolean
Default Value: 0
Rate: k
Whether or not to consider this source’s position to always be relative to the listener.
Sources which are head relative interpret their positions in the default coordinate system, relative to the listener. Positive x is right, positive y is up, and positive z is behind the listener. The orientation and position properties of an environment do not affect head relative sources, making them ideal for such things as footsteps and/or HUD effects that should be panned.
max_distance
C Enumeration Value: Lav_SOURCE_MAX_DISTANCE
Type: float
Range: [0.0, 'INFINITY']
Default Value: 150.0
Rate: k
The maximum distance from the listener at which the source will be audible. The default value of this property is set from the corresponding property on the environment at source creation. By default, sources do not respect this property and use the corresponding value from their environment. Set Lav_SOURCE_CONTROL_DISTANCE_MODEL to true to control it yourself.
max_reverb_level
C Enumeration Value: Lav_SOURCE_MAX_REVERB_LEVEL
Type: float
Range: [0.0, 1.0]
Default Value: 0.6
Rate: k
The maximum amount of audio to be diverted to reverb sends, if any.
Behavior is undefined if this property is ever less than Lav_SOURCE_MIN_REVERB_LEVEL.
The default value of this property is set from the corresponding property on the environment at source creation. By default, this property is ignored in favor of the value provided by this source’s environment. Set Lav_SOURCE_CONTROL_REVERB to true to control it yourself.
min_reverb_level
C Enumeration Value: Lav_SOURCE_MIN_REVERB_LEVEL
Type: float
Range: [0.0, 1.0]
Default Value: 0.15
Rate: k
The minimum reverb level allowed.
if a send is configured to be a reverb send, this is the minimum amount of audio that will be diverted to it.
Behavior is undefined if this property is ever greater than the value you give to Lav_SOURCE_MAX_REVERB_LEVEL.
The default value of this property is set from the corresponding property on the environment at source creation. By default, this property is ignored in favor of the value provided by this source’s environment. Set Lav_SOURCE_CONTROL_REVERB to true to control it yourself.
occlusion
C Enumeration Value: Lav_SOURCE_OCCLUSION
Type: float
Range: [0.0, 1.0]
Default Value: 0.0
Rate: k
A scalar representing how occluded this source is.
This property controls internal filters of the source that make occluded objects sound muffled. A value of 1.0 is a fully occluded source, which will be all but silent; a value of 0.0 has no effect.
It is extremely difficult to map occlusion to a physical quantity. As a consequence, this property is unitless.
orientation
C Enumeration Value: Lav_SOURCE_ORIENTATION
Type: float6
Default Value: [0.0, 0.0, -1.0, 0.0, 1.0, 0.0]
Rate: k
The orientation of the source. This is not currently used. In future, it will be used for sound cones and filters on sources facing away. The interpretation is the same as that for the listener: the first 3 values are the direction of the front and the second 3 the direction of the top. Note that these must both be unit vectors and that they must be orthoganal. They are packed because, also like the listener, they must never be modified separately.
panning_strategy
C Enumeration Value: Lav_SOURCE_PANNING_STRATEGY
Type: int
Range: A value from the Lav_PANNING_STRATEGIES enumeration.
Default Value: Lav_PANNING_STRATEGY_STEREO
Rate: k
The strategy for the internal multipanner. The default value of this property is set from the corresponding property on the environment at source creation. By default, this property is ignored and sources use the value provided by their environment. Set Lav_SOURCE_CONTROL_PANNING to true to control it yourself.
position
C Enumeration Value: Lav_SOURCE_POSITION
Type: float3
Default Value: [0.0, 0.0, 0.0]
Rate: k
The position of the source in world coordinates.
reverb_distance
C Enumeration Value: Lav_SOURCE_REVERB_DISTANCE
Type: float
Range: [0.0, 'INFINITY']
Default Value: 75.0
Rate: k
The distance at which the source will only be heard through the reverb effect sends.
If this source is not feeding any effect sends configured as reverbs, this property has no effect.
For values greater than Lav_SOURCE_MAX_DISTANCE, the source will always be heard at least somewhat in the dry path. Lav_SOURCE_DISTANCE_MODEL controls how this crossfading takes place.
The default value of this property is set from the corresponding property on the environment at source creation. By default, sources ignore this property in favor of the value provided by their environment. Set Lav_SOURCE_CONTROL_REVERB to true to control it yourself.
size
C Enumeration Value: Lav_SOURCE_SIZE
Type: float
Range: [0.0, 'INFINITY']
Default Value: 0.0
Rate: k
The size of the source. Sources are approximated as spheres. The size is used to determine the closest point on the source to the listener, and is the radius of this sphere. Size currently has no other effect.
The default value of this property is set from the corresponding property on the environment at source creation.
Extra Functions
feed_effect
Prototype: LavError Lav_sourceNodeFeedEffect(LavHandle nodeHandle, int effect)
Begin feeding the specified effect send.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
effect |
The index of the effect send to feed. |
set_properties_from_environment
Prototype: LavError Lav_sourceNodeSetPropertiesFromEnvironment(LavHandle nodeHandle)
A convenience function for working with properties on sources. When called, this function sets the values of all properties which have corresponding properties on the environment to the values from the environment.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
stop_feeding_effect
Prototype: LavError Lav_sourceNodeStopFeedingEffect(LavHandle nodeHandle, int effect)
Stop feeding an effect send.
Type |
Name |
Description |
|
nodeHandle |
The node to manipulate. |
|
effect |
The send to stop feeding. |
Three Band Eq Node
C Type Identifier: Lav_OBJTYPE_THREE_BAND_EQ_NODE
Constructor: LavError Lav_createThreeBandEqNode(LavHandle serverHandle, int channels, LavHandle* destination)
Index |
Channels |
Description |
0 |
The number of channels for this input depends on parameters to this node’s constructor. |
The signal to equalize. |
Index |
Channels |
Description |
0 |
The number of channels for this output depends on parameters to this node’s constructor. |
The equalized signal. |
A three band equalizer.
This node consists of a peaking filter and a highshelf filter in series, such that the frequency spectrum may be equalized in three, configurable bands.
The lowest of these bands begins at lowband_frequency
and continues down to 0 hz
.
The highest is from highband_frequency
and continues until nyquist.
The middle is the remaining space between the low and high band.
If the high band begins below the low band, behavior is undefined, but will almost certainly not do what you want.
Libaudioverse does not check for this case.
The slopes that this node institutes are not perfect and cannot increase effectively beyond a certain point. This is the least expensive of the Libaudioverse equalizers, and is sufficient for many simpler applications.
Properties
highband_dbgain
C Enumeration Value: Lav_THREE_BAND_EQ_HIGHBAND_DBGAIN
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The gain to apply to the highest frequency band as decibals.
highband_frequency
C Enumeration Value: Lav_THREE_BAND_EQ_HIGHBAND_FREQUENCY
Type: float
Range: dynamic
Default Value: 1000.0
Rate: k
The frequency that divides the middle band from the high band.
lowband_dbgain
C Enumeration Value: Lav_THREE_BAND_EQ_LOWBAND_DBGAIN
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The gain of the lowest frequency band as decibals.
lowband_frequency
C Enumeration Value: Lav_THREE_BAND_EQ_LOWBAND_FREQUENCY
Type: float
Range: dynamic
Default Value: 300.0
Rate: k
The frequency that divides the low and middle bands.
This ranges from 0 to nyquist.
midband_dbgain
C Enumeration Value: Lav_THREE_BAND_EQ_MIDBAND_DBGAIN
Type: float
Range: ['-INFINITY', 'INFINITY']
Default Value: 0.0
Rate: k
The gain to apply to the middle band of the equalizer.
Enumerations
The following section lists some of Libaudioverse’s enumerations. This section concerns itself only with those enumerations that are important by themselves.
Lav_BIQUAD_TYPES
Indicates a biquad filter type, used with the biquad filter node and in a few other places.
Member |
Description |
Lav_BIQUAD_TYPE_ALLPASS |
Indicates an allpass filter. |
Lav_BIQUAD_TYPE_BANDPASS |
Indicates a bandpass filter. |
Lav_BIQUAD_TYPE_HIGHPASS |
Indicates a highpass filter. |
Lav_BIQUAD_TYPE_HIGHSHELF |
Indicates a highshelf filter. |
Lav_BIQUAD_TYPE_IDENTITY |
This filter does nothing. |
Lav_BIQUAD_TYPE_LOWPASS |
Indicates a lowpass filter. |
Lav_BIQUAD_TYPE_LOWSHELF |
Indicates a lowshelf filter. |
Lav_BIQUAD_TYPE_NOTCH |
Indicates a notch filter. |
Lav_BIQUAD_TYPE_PEAKING |
Indicates a peaking filter. |
Lav_CHANNEL_INTERPRETATIONS
Specifies how to treat inputs to this node for upmixing and downmixing.
Member |
Description |
Lav_CHANNEL_INTERPRETATION_DISCRETE |
If channel counts mismatch, don’t apply mixing matrices. Either drop or fill with zeros as appropriate. |
Lav_CHANNEL_INTERPRETATION_SPEAKERS |
Apply mixing matrices if needed. |
Lav_DISTANCE_MODELS
used in the 3D components of this library. Indicates how sound should become quieter as objects move away from the listener.
Libaudioverse computes the distance from the center of the source to the listener, then subtracts the size.
In the following, distance
refers to this distance.
Libaudioverse also computes a second value called distancePercent
; specifically, distancePercent = distance/maxDistance
.
Member |
Description |
Lav_DISTANCE_MODEL_INVERSE |
Sounds fall off as |
Lav_DISTANCE_MODEL_INVERSE_SQUARE |
Sounds fall off as |
Lav_DISTANCE_MODEL_LINEAR |
Sound falls off as |
Lav_ERRORS
All functions in this library return one of the following enum values, indicating their error condition.
Member |
Description |
Lav_ERROR_BUFFER_IN_USE |
Indicates an attempt to modify a buffer while something is reading its data. |
Lav_ERROR_CANNOT_CONNECT_TO_PROPERTY |
Attempt to connect a node to a property which cannot be automated. |
Lav_ERROR_CANNOT_CROSS_SERVERS |
An attempt was made to relate two objects from different servers. This could be assigning to buffer properties, connecting nodes, or any other such condition. |
Lav_ERROR_CANNOT_INIT_AUDIO |
The audio subsystem could not be initialized. |
Lav_ERROR_CAUSES_CYCLE |
The requested operation would cause a cycle in the graph of nodes that need processing. |
Lav_ERROR_FILE |
Represents a miscelaneous file error. |
Lav_ERROR_FILE_NOT_FOUND |
Libaudioverse could not find a specified file. |
Lav_ERROR_HRTF_INVALID |
An attempt to use an invalid HRTF database. |
Lav_ERROR_INTERNAL |
If you see this error, it’s a bug. |
Lav_ERROR_INVALID_HANDLE |
A value passed in as a handle is not currently a handle which is valid. |
Lav_ERROR_INVALID_POINTER |
Attempt to free a pointer that Libaudioverse doesn’t know about. |
Lav_ERROR_INVALID_PROPERTY |
An attempt to access a property which does not exist on the specified node. |
Lav_ERROR_MEMORY |
Libaudioverse triedd to allocate a pointer, but could not. |
Lav_ERROR_NO_SUCH_DEVICE |
Attempt to use an I/O device that doesn’t exist. In addition to being caused by your code, this can happen if the user unplugs the device. |
Lav_ERROR_NONE |
No error occured. |
Lav_ERROR_NOT_INITIALIZED |
Failure to call |
Lav_ERROR_NULL_POINTER |
You passed a null pointer into Libaudioverse in a context where null pointers are not allowed. |
Lav_ERROR_OVERLAPPING_AUTOMATORS |
An attempt to schedule an automator within the duration of another. |
Lav_ERROR_PROPERTY_IS_READ_ONLY |
Attempt to set a read-only property. |
Lav_ERROR_RANGE |
A function parameter is not within a valid range. This could be setting property values outside their range, accessing inputs and outputs that do not exist, or any of a variety of other range error conditions. |
Lav_ERROR_TYPE_MISMATCH |
Indicates an attempt to manipulate a property through a function that does not work with that property’s type. |
Lav_ERROR_UNKNOWN |
Something went wrong. This error indicates that we couldn’t figure out what. |
Lav_FDN_FILTER_TYPES
Possible filter types for a feedback delay network’s feedback path.
Member |
Description |
Lav_FDN_FILTER_TYPE_DISABLED |
Don’t insert filters on the feedback path. |
Lav_FDN_FILTER_TYPE_HIGHPASS |
Insert highpass filters on the FDN’s feedback path. |
Lav_FDN_FILTER_TYPE_LOWPASS |
Insert lowpass filters on the FDN’s feedback path. |
Lav_LOGGING_LEVELS
Possible levels for logging.
Member |
Description |
Lav_LOGGING_LEVEL_CRITICAL |
Logs critical messages such as failures to initialize and error conditions. |
Lav_LOGGING_LEVEL_DEBUG |
Logs everything possible. |
Lav_LOGGING_LEVEL_INFO |
Logs informative messages. |
Lav_LOGGING_LEVEL_OFF |
No log messages will be generated. |
Lav_NODE_STATES
used to indicate the state of a node. This is the value of the node’s state property and determins how the node is processed.
Member |
Description |
Lav_NODESTATE_ALWAYS_PLAYING |
This node advances always. |
Lav_NODESTATE_PAUSED |
This node is paused. |
Lav_NODESTATE_PLAYING |
This node advances if other nodes need audio from it. |
Lav_NOISE_TYPES
Specifies types of noise.
Member |
Description |
Lav_NOISE_TYPE_BROWN |
Brown noise. Brown noise decreases at 6 DB per octave. |
Lav_NOISE_TYPE_PINK |
Pink noise. Pink noise falls off at 3 DB per octave. |
Lav_NOISE_TYPE_WHITE |
gaussian white noise. |
Lav_PANNING_STRATEGIES
Indicates a strategy to use for panning. This is mostly for the multipanner node and the 3D components of this library.
Member |
Description |
Lav_PANNING_STRATEGY_HRTF |
Indicates HRTF panning. |
Lav_PANNING_STRATEGY_STEREO |
Indicates stereo panning. |
Lav_PANNING_STRATEGY_SURROUND40 |
Indicates 4.0 surround sound (quadraphonic) panning. |
Lav_PANNING_STRATEGY_SURROUND51 |
Indicates 5.1 surround sound panning. |
Lav_PANNING_STRATEGY_SURROUND71 |
Indicates 7.1 surround sound panning. |
Lav_PROPERTY_TYPES
Indicates the type of a property.
Member |
Description |
Lav_PROPERTYTYPE_BUFFER |
Property holds a handle to a buffer. |
Lav_PROPERTYTYPE_DOUBLE |
Property holds a 64-bit double. |
Lav_PROPERTYTYPE_FLOAT |
Property holds a 32-bit floating point value. |
Lav_PROPERTYTYPE_FLOAT3 |
Property holds a float3, a vector of 3 floats. |
Lav_PROPERTYTYPE_FLOAT6 |
Property holds a float6, a vector of 6 floats. |
Lav_PROPERTYTYPE_FLOAT_ARRAY |
Property is an array of floats. |
Lav_PROPERTYTYPE_INT |
Property holds a 32-bit integer. |
Lav_PROPERTYTYPE_INT_ARRAY |
Property is an array of ints. |
Lav_PROPERTYTYPE_STRING |
Property holds a string. |