Mercurial > hg > beaglert
changeset 46:eac5d8f40b48 newapi
Fixed file structure to reflect merging include files into BeagleRT.h
author | andrewm |
---|---|
date | Thu, 28 May 2015 14:38:00 -0400 |
parents | 579c86316008 |
children | 643cbee74eda |
files | include/BeagleRT.h include/RTAudio.h include/RTAudioSettings.h include/render.h |
diffstat | 4 files changed, 391 insertions(+), 182 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/BeagleRT.h Thu May 28 14:38:00 2015 -0400 @@ -0,0 +1,391 @@ +/* + * RTAudio.h + * + * Central control code for hard real-time audio on BeagleBone Black + * using PRU and Xenomai Linux extensions. This code began as part + * of the Hackable Instruments project (EPSRC) at Queen Mary University + * of London, 2013-14. + * + * (c) 2014 Victor Zappi and Andrew McPherson + * Queen Mary University of London + */ + + +#ifndef BEAGLERT_H_ +#define BEAGLERT_H_ + +#include <stdint.h> +#include "digital_gpio_mapping.h" + +// Useful constants +#define DBOX_CAPE // New custom cape + +#ifdef DBOX_CAPE +#define CODEC_I2C_ADDRESS 0x18 // Address of TLV320AIC3104 codec +#else +#define CODEC_I2C_ADDRESS 0x1B // Address of TLV320AIC3106 codec +#endif + +// Default volume levels +#define DEFAULT_DAC_LEVEL 0.0 +#define DEFAULT_ADC_LEVEL -6.0 +#define DEFAULT_HP_LEVEL -6.0 + +#define MAX_PRU_FILENAME_LENGTH 256 +#define MAX_SERVERNAME_LENGTH 256 + +// Priority at which BeagleRT audio code runs +// Higher numbers preempt the audio; lower numbers are preempted by it +#define BEAGLERT_AUDIO_PRIORITY 95 + +// Flags for BeagleRTContext data structure +#define BEAGLERT_FLAG_INTERLEAVED (1 << 0) // Set if buffers are interleaved +#define BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST (1 << 1) // Set if analog/digital outputs persist for future buffers + +// Mappings from pin numbers on PCB to actual DAC channels +// This gives the DAC and ADC connectors the same effective pinout + +#define DAC_PIN0 6 +#define DAC_PIN1 4 +#define DAC_PIN2 2 +#define DAC_PIN3 0 +#define DAC_PIN4 1 +#define DAC_PIN5 3 +#define DAC_PIN6 5 +#define DAC_PIN7 7 + +#define ADC_PIN0 0 +#define ADC_PIN1 1 +#define ADC_PIN2 2 +#define ADC_PIN3 3 +#define ADC_PIN4 4 +#define ADC_PIN5 5 +#define ADC_PIN6 6 +#define ADC_PIN7 7 + +// Structure which contains initialisation parameters for the +// real-time audio system +typedef struct { + // These items might be adjusted by the user: + int periodSize; // Number of (analog) frames per period; audio is twice this + int useAnalog; // Whether to use the analog + int useDigital; // Whether to use the 16 programmable GPIOs + int numAnalogChannels; // How many channels for the ADC and DAC + int numDigitalChannels; // How many channels for the GPIOs + + int beginMuted; // Whether to begin with the speakers muted + float dacLevel; // Level for the audio DAC output + float adcLevel; // Level for the audio ADC input + float headphoneLevel; // Level for the headphone output + + char pruFilename[MAX_PRU_FILENAME_LENGTH]; // The external .bin file to load. If empty will use PRU code from pru_rtaudio_bin.h + int verbose; // Whether to use verbose logging + + // These items are application-dependent but should probably be + // determined by the programmer rather than the user + int interleave; // Whether audio/analog data should be interleaved + int analogOutputsPersist; // Whether analog outputs should persist to future frames + // n.b. digital pins always persist, audio never does + + // These items are hardware-dependent and should only be changed + // to run on different hardware + int codecI2CAddress; // Where the codec can be found on the I2C bus + int ampMutePin; // Pin where amplifier mute can be found + int receivePort; // Port where the UDP server will listen + int transmitPort; // Port where the UDP client will transmit + char serverName[MAX_SERVERNAME_LENGTH]; +} BeagleRTInitSettings; + +// BeagleRTContext data structure +// Holds information passed to the render() function and related calls +// Contains the current audio and sensor settings and pointers to the data buffers + +typedef struct { + float *audioIn; + float *audioOut; + float *analogIn; + float *analogOut; + uint32_t *digital; + + uint32_t audioFrames; + uint32_t audioChannels; + float audioSampleRate; + + uint32_t analogFrames; + uint32_t analogChannels; + float analogSampleRate; + + uint32_t digitalFrames; + uint32_t digitalChannels; + float digitalSampleRate; + + uint64_t audioSampleCount; + uint32_t flags; +} BeagleRTContext; + +enum { + kAmplifierMutePin = 61 // P8-26 controls amplifier mute +}; + +typedef void* AuxiliaryTask; // Opaque data type to keep track of aux tasks + +// Flag that indicates when the audio will stop; can be read or +// set by other components which should end at the same time as the audio +extern bool gShouldStop; + +// *** User-defined render functions *** + +/** + * \brief User-defined initialisation function which runs before audio rendering begins. + * + * This function runs once at the beginning of the program, after most of the system + * initialisation has begun but before audio rendering starts. Use it to prepare any + * memory or resources that will be needed in render(). + * + * \param context Data structure holding information on sample rates, numbers of channels, + * frame sizes and other state. Note: the buffers for audio, analog and digital data will + * \b not yet be available to use. Do not attempt to read or write audio or sensor data + * in initialise_render(). + * \param userData An opaque pointer to an optional user-defined data structure. Whatever + * is passed as the second argument to BeagleRT_initAudio() will appear here. + * + * \return true on success, or false if an error occurred. If no initialisation is + * required, initialise_render() should return true. + */ +bool initialise_render(BeagleRTContext *context, void *userData); + +/** + * \brief User-defined callback function to process audio and sensor data. + * + * This function is called regularly by the system every time there is a new block of + * audio and/or sensor data to process. Your code should process the requested samples + * of data, store the results within \c context, and return. + * + * \param context Data structure holding buffers for audio, analog and digital data. The + * structure also holds information on numbers of channels, frame sizes and sample rates, + * which are guaranteed to remain the same throughout the program and to match what was + * passed to initialise_render(). + * \param userData An opaque pointer to an optional user-defined data structure. Will + * be the same as the \c userData parameter passed to initialise_render(). + */ +void render(BeagleRTContext *context, void *userData); + +/** + * \brief User-defined cleanup function which runs when the program finishes. + * + * This function is called by the system once after audio rendering has finished, before the + * program quits. Use it to release any memory allocated in initialise_render() and to perform + * any other required cleanup. If no initialisation is performed in initialise_render(), then + * this function will usually be empty. + * + * \param context Data structure holding information on sample rates, numbers of channels, + * frame sizes and other state. Note: the buffers for audio, analog and digital data will + * no longer be available to use. Do not attempt to read or write audio or sensor data + * in cleanup_render(). + * \param userData An opaque pointer to an optional user-defined data structure. Will + * be the same as the \c userData parameter passed to initialise_render() and render(). + */ +void cleanup_render(BeagleRTContext *context, void *userData); + +// *** Command-line settings *** + +/** + * \brief Initialise the data structure containing settings for BeagleRT. + * + * This function should be called in main() before parsing any command-line arguments. It + * sets default values in the data structure which specifies the BeagleRT settings, including + * frame sizes, numbers of channels, volume levels and other parameters. + * + * \param settings Structure holding initialisation data for BeagleRT. + */ +void BeagleRT_defaultSettings(BeagleRTInitSettings *settings); + +/** + * \brief Get long options from command line argument list, including BeagleRT standard options + * + * This function should be used in main() to process command line options, in place of the + * standard library getopt_long(). Internally, it parses standard BeagleRT command-line options, + * storing the results in the settings data structure. Any options which are not part of the + * BeagleRT standard options will be returned, as they would normally be in getopt_long(). + * + * \param argc Number of command line options, as passed to main(). + * \param argv Array of command line options, as passed to main(). + * \param customShortOptions List of short options to be parsed, analogous to getopt_long(). This + * list should not include any characters already parsed as part of the BeagleRT standard options. + * \param customLongOptions List of long options to parsed, analogous to getopt_long(). This + * list should not include any long options already parsed as part of the BeagleRT standard options. + * \param settings Data structure holding initialisation settings for BeagleRT. Any standard options + * parsed will automatically update this data structure. + * + * \return Value of the next option parsed which is not a BeagleRT standard option, or -1 when the + * argument list has been exhausted. Similar to the return value of getopt_long() except that BeagleRT + * standard options are handled internally and not returned. + */ +int BeagleRT_getopt_long(int argc, char *argv[], const char *customShortOptions, + const struct option *customLongOptions, BeagleRTInitSettings *settings); + +/** + * \brief Print usage information for BeagleRT standard options. + * + * This function should be called from your code wherever you wish to print usage information for the + * user. It will print usage information on BeagleRT standard options, after which you can print usage + * information for your own custom options. + */ +void BeagleRT_usage(); + +/** + * \brief Set level of verbose (debugging) printing. + * + * \param level Verbosity level of the internal BeagleRT system. 0 by default; higher values will + * print more information. Presently all positive numbers produce the same level of printing. + */ +void BeagleRT_setVerboseLevel(int level); + +// *** Audio control functions *** + +/** + * \brief Initialise audio and sensor rendering environment. + * + * This function prepares audio rendering in BeagleRT. It should be called from main() sometime + * after command line option parsing has finished. It will initialise the rendering system, which + * in the process will result in a call to the user-defined initialise_render() function. + * + * \param settings Data structure holding system settings, including numbers of channels, frame sizes, + * volume levels and other information. + * \param userData An opaque pointer to a user-defined data structure which will be passed to + * initialise_render(), render() and cleanup_render(). You can use this to pass custom information + * to the rendering functions, as an alternative to using global variables. + * + * \return 0 on success, or nonzero if an error occurred. + */ +int BeagleRT_initAudio(BeagleRTInitSettings *settings, void *userData); + +/** + * \brief Begin processing audio and sensor data. + * + * This function will start the BeagleRT audio/sensor system. After this function is called, the + * system will make periodic calls to render() until BeagleRT_stopAudio() is called. + * + * \return 0 on success, or nonzero if an error occurred. + */ +int BeagleRT_startAudio(); + +/** + * \brief Stop processing audio and sensor data. + * + * This function will stop the BeagleRT audio/sensor system. After this function returns, no further + * calls to render() will be issued. + */ +void BeagleRT_stopAudio(); + +/** + * \brief Clean up resources from audio and sensor processing. + * + * This function should only be called after BeagleRT_stopAudio(). It will release any + * internal resources for audio and sensor processing. In the process, it will call the + * user-defined cleanup_render() function. + */ +void BeagleRT_cleanupAudio(); + +// Volume/level controls +// These return 0 on success + +// *** Volume and level controls *** + +/** + * \brief Set the level of the audio DAC. + * + * This function sets the level of all audio outputs (headphone, line, speaker). It does + * not affect the level of the (non-audio) analog outputs. + * + * \b Important: do not call this function from within render(), as it does not make + * any guarantees on real-time performance. + * + * \param decibels Level of the DAC output. Valid levels range from -63.5 (lowest) to + * 0 (highest) in steps of 0.5dB. Levels between increments of 0.5 will be rounded down. + * + * \return 0 on success, or nonzero if an error occurred. + */ +int BeagleRT_setDACLevel(float decibels); + +/** + * \brief Set the level of the audio ADC. + * + * This function sets the level of the audio input. It does not affect the level of the + * (non-audio) analog inputs. + * + * \b Important: do not call this function from within render(), as it does not make + * any guarantees on real-time performance. + * + * \param decibels Level of the ADC input. Valid levels range from -12 (lowest) to + * 0 (highest) in steps of 1.5dB. Levels between increments of 1.5 will be rounded down. + * + * \return 0 on success, or nonzero if an error occurred. + */ +int BeagleRT_setADCLevel(float decibels); + +/** + * \brief Set the level of the onboard headphone amplifier. + * + * This function sets the level of the headphone output only (3-pin connector on the BeagleRT + * cape or the output jack on the BeagleBone Audio Cape). It does not affect the level of the + * speakers or the line out pads on the cape. + * + * \b Important: do not call this function from within render(), as it does not make + * any guarantees on real-time performance. + * + * \param decibels Level of the DAC output. Valid levels range from -63.5 (lowest) to + * 0 (highest) in steps of 0.5dB. Levels between increments of 0.5 will be rounded down. + * + * \return 0 on success, or nonzero if an error occurred. + */ +int BeagleRT_setHeadphoneLevel(float decibels); + +/** + * \brief Mute or unmute the onboard speaker amplifiers. + * + * This function mutes or unmutes the amplifiers on the BeagleRT cape. Whether the speakers begin + * muted or unmuted depends on the BeagleRTInitSettings structure passed to BeagleRT_initAudio(). + * + * \b Important: do not call this function from within render(), as it does not make + * any guarantees on real-time performance. + * + * \param mute 0 to enable the speakers, nonzero to mute the speakers. + * + * \return 0 on success, or nonzero if an error occurred. + */ +int BeagleRT_muteSpeakers(int mute); + +// *** Functions for creating auxiliary tasks *** + +/** + * \brief Create a new auxiliary task. + * + * This function creates a new auxiliary task which, when scheduled, runs the function specified + * in the first argument. Note that the task does not run until scheduleAuxiliaryTask() is called. + * Auxiliary tasks should be created in initialise_render() and never in render() itself. + * + * The second argument specifies the real-time priority. Valid values are between 0 + * and 99, and usually should be lower than BEAGLERT_AUDIO_PRIORITY. Tasks with higher priority always + * preempt tasks with lower priority. + * + * \param functionToCall Function which will run each time the auxiliary task is scheduled. + * \param priority Xenomai priority level at which the task should run. + * \param Name for this task, which should be unique system-wide (no other running program should use this name). + */ +AuxiliaryTask createAuxiliaryTaskLoop(void (*functionToCall)(void), int priority, const char *name); + +/** + * \brief Run an auxiliary task which has previously been created. + * + * This function will schedule an auxiliary task to run. When the task runs, the function in the first + * argument of createAuxiliaryTaskLoop() will be called. + * + * scheduleAuxiliaryTask() is typically called from render() to start a lower-priority task. The function + * will not run immediately, but only once any active higher priority tasks have finished. + * + * \param task Task to schedule for running. + */ +void scheduleAuxiliaryTask(AuxiliaryTask task); + +#endif /* BEAGLERT_H_ */
--- a/include/RTAudio.h Thu May 28 14:35:55 2015 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * RTAudio.h - * - * Central control code for hard real-time audio on BeagleBone Black - * using PRU and Xenomai Linux extensions. This code began as part - * of the Hackable Instruments project (EPSRC) at Queen Mary University - * of London, 2013-14. - * - * (c) 2014 Victor Zappi and Andrew McPherson - * Queen Mary University of London - */ - - -#ifndef RTAUDIO_H_ -#define RTAUDIO_H_ -#include "RTAudioSettings.h" -#include "render.h" - -// Useful constants -#define DBOX_CAPE // New custom cape - -#ifdef DBOX_CAPE -#define CODEC_I2C_ADDRESS 0x18 // Address of TLV320AIC3104 codec -#else -#define CODEC_I2C_ADDRESS 0x1B // Address of TLV320AIC3106 codec -#endif - -// Default volume levels -#define DEFAULT_DAC_LEVEL 0.0 -#define DEFAULT_ADC_LEVEL -6.0 -#define DEFAULT_HP_LEVEL -6.0 - -enum { - kAmplifierMutePin = 61 // P8-26 controls amplifier mute -}; - -typedef void* AuxiliaryTask; // Opaque data type to keep track of aux tasks - -// Flag that indicates when the audio will stop; can be read or -// set by other components which should end at the same time as the audio -extern bool gShouldStop; - -// Command-line settings -void BeagleRT_defaultSettings(RTAudioSettings *settings); -int BeagleRT_getopt_long(int argc, char *argv[], const char *customShortOptions, - const struct option *customLongOptions, RTAudioSettings *settings); -void BeagleRT_usage(); - -// Basic audio control functions: init, start, stop and clean up -int BeagleRT_initAudio(RTAudioSettings *settings, void *userData); -int BeagleRT_startAudio(); -void BeagleRT_stopAudio(); -void BeagleRT_cleanupAudio(); - -// Volume/level controls -// These return 0 on success - -// Set the level of the DAC; affects all outputs (headphone, line, speaker) -// 0dB is the maximum, -63.5dB is the minimum; 0.5dB steps -int BeagleRT_setDACLevel(float decibels); - -// Set the level of the ADC -// 0dB is the maximum, -12dB is the minimum; 1.5dB steps -int BeagleRT_setADCLevel(float decibels); - -// Set the level of the onboard headphone amplifier; affects headphone -// output only (not line out or speaker) -// 0dB is the maximum, -63.5dB is the minimum; 0.5dB steps -int BeagleRT_setHeadphoneLevel(float decibels); - -// Mute or unmute the onboard speaker amplifiers -// mute == 0 means unmute; otherwise mute -// Returns 0 on success -int BeagleRT_muteSpeakers(int mute); - -// Functions for creating auxiliary tasks -AuxiliaryTask createAuxiliaryTaskLoop(void (*functionToCall)(void), int priority, const char *name); -void scheduleAuxiliaryTask(AuxiliaryTask task); - -void setVerboseLevel(int level); - -#endif /* RTAUDIO_H_ */
--- a/include/RTAudioSettings.h Thu May 28 14:35:55 2015 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * RTaudioSettings.h - * - * Created on: 6 May 2015 - * Author: unmanaged - */ - -#ifndef RTAUDIOSETTINGS_H_ -#define RTAUDIOSETTINGS_H_ - -#define MAX_PRU_FILENAME_LENGTH 256 -#define MAX_SERVERNAME_LENGTH 256 -// Structure which contains initialisation parameters for the -// real-time audio system -typedef struct { - // These items might be adjusted by the user: - int periodSize; // Number of (analog) frames per period; audio is twice this - int beginMuted; // Whether to begin with the speakers muted - float dacLevel; // Level for the audio DAC output - float adcLevel; // Level for the audio ADC input - float headphoneLevel; // Level for the headphone output - int useAnalog; // Whether to use the analog - int useDigital; // Whether to use the 16 programmable GPIOs - int numAnalogChannels; // How many channels for the ADC and DAC - int numDigitalChannels; // How many channels for the GPIOs - int verbose; // Whether to use verbose logging - char pruFilename[MAX_PRU_FILENAME_LENGTH]; //the external .bin file to load. If empty will use PRU code from pru_rtaudio_bin.h - // These items are hardware-dependent and should only be changed - // to run on different hardware - int codecI2CAddress; // Where the codec can be found on the I2C bus - int ampMutePin; // Pin where amplifier mute can be found - int receivePort; //port where the UDP server will listen - int transmitPort; //port where the UDP client will transmit - char serverName[MAX_SERVERNAME_LENGTH]; -} RTAudioSettings; - - - - -#endif /* RTAUDIOSETTINGS_H_ */
--- a/include/render.h Thu May 28 14:35:55 2015 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * render.h - * - * Created on: May 28, 2014 - * Author: Victor Zappi - */ - -#ifndef RENDER_H_ -#define RENDER_H_ - -// uint types -#include <stdint.h> -#include "Utilities.h" -#include "digital_gpio_mapping.h" -#include "RTAudioSettings.h" - -// Mappings from pin numbers on PCB to actual DAC channels -// This gives the DAC and ADC connectors the same effective pinout -#define DAC_PIN0 6 -#define DAC_PIN1 4 -#define DAC_PIN2 2 -#define DAC_PIN3 0 -#define DAC_PIN4 1 -#define DAC_PIN5 3 -#define DAC_PIN6 5 -#define DAC_PIN7 7 - -#define ADC_PIN0 0 -#define ADC_PIN1 1 -#define ADC_PIN2 2 -#define ADC_PIN3 3 -#define ADC_PIN4 4 -#define ADC_PIN5 5 -#define ADC_PIN6 6 -#define ADC_PIN7 7 - -#define ANALOG_MAX 65535.0 - -extern int gNumAudioChannels; // How many audio channels are present -extern int gNumAnalogChannels; // How many analog channels are present -extern int gNumDigitalChannels; -bool initialise_render(int numAnalogChannels, int numDigitalChannels, int numAudioChannels, - int numAnalogFramesPerPeriod, - int numAudioFramesPerPeriod, - float analogSampleRate, float audioSampleRate, - void *userData, RTAudioSettings *settings); - -void render(int numAnalogFrames, int numAudioFrames, int numDigitalFrames, float *audioIn, float *audioOut, - float *analogIn, float *analogOut, uint32_t *digital); - -void render_medium_prio(); -void render_low_prio(); - -void schedule_render_medium_prio(); -void schedule_render_low_prio(); - - -void cleanup_render(); - -#endif /* RENDER_H_ */