Tutorial Sketches - Explanations » History » Version 13

Version 12 (Robert Jack, 2015-07-17 07:29 PM) → Version 13/45 (Astrid Bin, 2015-07-17 07:30 PM)

h1. Tutorial Sketches - Explanations

Find the tutorial sketches in Respository > Projects, or click this link: https://code.soundsoftware.ac.uk/projects/beaglert/repository/show/projects

Below is a list of the sample sketches, and what they do.

h2. Basic sketch structure

A collection of BeagleRT files are called a "project".

h3. The structure of a BeagleRT project

If you open a project folder in the above repository, you'll see that each of these BeagleRT project contains two files: main.cpp and render.cpp (some projects have additional files, but every project has at least these two). The main.cpp file you don't really have to worry about; it contains helper functions and things that run command line arguments. Most work is done in the render.cpp file.

h3. The structure of a render.cpp file

A render.cpp file has three functions: setup(), render() and cleanup().

setup() is a function that runs at the beginning when the project starts.

render() is a function that is regularly called, over and over continuously, at the highest priority by the audio engine.

cleanup() is a function that is called when the program stops, to finish up any processes that might still be running.

Here we will briefly explain each function and the structure of the render.cpp document

h3. Before any functions

At the top of the file, include any libraries you might need.

Additionally, declare any global variables. In these tutorial sketches, all global variables are preceded by a g so we always know which variables are global - gSampleData, for instance. It's not mandatory but is a really good way of keeping track of what's global and what isn't.

Sometimes it's necessary to access a variable from another file, such as main.cpp. In this case, precede this variable with the keyword extern.

h3. Function arguments

setup(), render() and cleanup() each take the same arguments. These are:

BeagleRTContext *context
void *userData

These arguments are pointers to data structures. The main one that's used is context, which is a pointer to a data structure containing lots of information you need.

Take a look at what's in the data structure here: https://code.soundsoftware.ac.uk/projects/beaglert/embedded/structBeagleRTContext.html In that link there is also a

You can access any of those bits of information contained in the data structure like this: context->[item in struct]

For example, context->audioChannels returns the number of audioChannels. context->audioIn[n] would give you the current input sample (assuming that your input is mono - if it's not you will have to account for multiple channels).

Note that every audioIn, audioOut, analogIn, analogOut and digital are buffers.

h2. analogDigitalDemo

h2. audio_in_FFT

This sketch performs an FFT (Fast Fourier Transform) on incoming audio. It uses the NE10 library, included at the top of the file (line 11).

Read the documentation on the NE10 library here: http://projectne10.github.io/Ne10/doc/annotated.html

The variables timeDomainIn, timeDomainOut and frequencyDomain are variables of the struct ne10_fft_cpx_float32_t (http://projectne10.github.io/Ne10/doc/structne10__fft__cpx__float32__t.html). These are declared at the top of the file (line 21), and memory is allocated for them in setup() (line 41).

In render() a for loop performs the FFT is performed on each sample, and the resulting output is placed on each channel.

h2. basic

This sketch produces a sine wave.

The frequency of the sine wave is determined in a global variable, gFrequency (line 12).

h2. basic_analog_input

This sketch produces a sine wave, the frequency and amplitude of which are affected by data received on the analog pins. Before looping through each audio frame, we declare a value for the frequency and amplitude of our sine wave (line 55); we adjust these values by taking in data from analog sensors (for example, a potentiometer).

The important thing to notice is that audio is sampled twice as often as analog data. The audio sampling rate is 44.1kHz (44100 frames per second) and the analog sampling rate is 22.05kHz (22050 frames per second). On line 62 you might notice that we are processing the analog data and updating frequency and amplitude only on every *second* audio sample, since the analog sampling rate is half that of the audio.

Note that the pin numbers are stored in the variables gAnalogInputFrequency and gAnalogInputAmplitude. These are declared in the main.cpp file; if you look in that file you will see that they have the values of 0 and 1. Bear in mind that these are analog input pins which is a specific header!

h2. basic_analog_output

This sketch uses a sine wave to drive the brightness of a series of LEDs connected to the eight analog out pins. Again you can see the nested for loop structure.

Within the first for loop in render we cycle through each frame in the analog output matrix. At each frame we then cycle through the analog output channels with another for loop and set the voltage according to the phase of a sine tone that acts as an LFO.

The output on each pin is set with analogWriteFrame within the for loop that cycles through the analog output channels. This needs to be provided with arguments as follows analogWriteFrame(context, n, channel, out). Channel is where the you give the address of the analog output pin (in this case we cycle through each pin address in the for loop), out is the variable that holds the desired output (set by the sine wave).

Notice that the phase of the brightness cycle for each led is different. This is achieved by updating a variable that stores a relative phase value, this is advanced by pi/4 (1/8 of a full rotation) for each channel giving each of the eight LEDs a different phase.

h2. basic_network



h2. basic_passthru

This sketch demonstrates is possibly the simplest possible case: it of all sketches. It passes audio the input straight through to audio output.

Note
the nested for loop structure. You will see this output, with no processing.

Nothing is done
in all BeagleRT projects. The first for loop cycles through setup(), and in the audio frames, the second through render() file each sample of the audio channels (in this case left 0 and right 1).

We write samples to the audio output buffer with this: context->audioOut[n * context->audioChannels + ch] where n
input is simply put into the current audio frame and ch output. The same is the current channel, both provided by the nested done for loop structure.

We can access samples in
the audio input buffer with this: context->audioIn[n * context->audioChannels + ch]. analog data.

So a simple audio pass through is achieved by: context->audioOut[n * context->audioChannels + ch] = context->audioIn[n * context->audioChannels + ch].

h2. cape_test

h2. d-box

h2. filter_FIR

h2. filter_IIR

h2. oscillator_bank\

h2. samples

h2. tank_wars