view include/BeagleRT.h @ 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
children 643cbee74eda
line wrap: on
line source
/*
 *  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_ */