andrewm@47: /** andrewm@47: * @file giuliomoro@301: * @brief Main Bela public API andrewm@46: * andrewm@46: * Central control code for hard real-time audio on BeagleBone Black andrewm@46: * using PRU and Xenomai Linux extensions. This code began as part andrewm@46: * of the Hackable Instruments project (EPSRC) at Queen Mary University andrewm@46: * of London, 2013-14. andrewm@46: * andrewm@47: * (c) 2014-15 Andrew McPherson, Victor Zappi and Giulio Moro, andrewm@46: * Queen Mary University of London andrewm@46: */ andrewm@46: andrewm@48: /** andrewm@48: * \mainpage andrewm@48: * giuliomoro@301: * Bela is a hard-real-time, ultra-low latency audio and sensor environment for giuliomoro@301: * BeagleBone Black, which works with the BeagleBone Audio Cape or a custom "Bela Cape" andrewm@48: * which incorporates stereo audio with 8x, 16-bit analog inputs and outputs. andrewm@48: * giuliomoro@301: * Bela is based on the Xenomai real-time Linux extensions (http://xenomai.org) and andrewm@48: * uses the BeagleBone %PRU subsystem to address the audio and sensor hardware. andrewm@48: * andrewm@303: * Further information can be found at http://bela.io andrewm@48: */ andrewm@48: andrewm@46: andrewm@303: #ifndef BELA_H_ andrewm@303: #define BELA_H_ andrewm@46: andrewm@46: #include giuliomoro@173: #include andrewm@55: #include andrewm@46: #include "digital_gpio_mapping.h" giuliomoro@237: #include andrewm@46: andrewm@46: // Useful constants andrewm@47: andrewm@47: /** \cond PRIVATE */ andrewm@46: #define DBOX_CAPE // New custom cape andrewm@46: #ifdef DBOX_CAPE andrewm@46: #define CODEC_I2C_ADDRESS 0x18 // Address of TLV320AIC3104 codec andrewm@46: #else andrewm@46: #define CODEC_I2C_ADDRESS 0x1B // Address of TLV320AIC3106 codec andrewm@46: #endif andrewm@46: andrewm@46: #define MAX_PRU_FILENAME_LENGTH 256 andrewm@46: #define MAX_SERVERNAME_LENGTH 256 andrewm@47: /** \endcond */ andrewm@46: andrewm@47: /** andrewm@47: * \ingroup auxtask andrewm@47: * andrewm@47: * Xenomai priority level for audio processing. Maximum possible priority is 99. andrewm@47: * In general, all auxiliary tasks should have a level lower than this unless for\ andrewm@47: * special purposes where the task needs to interrupt audio processing. andrewm@47: */ andrewm@303: #define BELA_AUDIO_PRIORITY 95 andrewm@46: andrewm@47: // Default volume levels andrewm@47: andrewm@47: /** andrewm@47: * \addtogroup levels andrewm@47: * andrewm@47: * @{ andrewm@47: */ andrewm@47: andrewm@47: /** giuliomoro@301: * Default level of the audio DAC in decibels. See Bela_setDACLevel(). andrewm@47: */ andrewm@47: #define DEFAULT_DAC_LEVEL 0.0 andrewm@47: andrewm@47: /** giuliomoro@301: * Default level of the audio ADC in decibels. See Bela_setADCLevel(). andrewm@47: */ andrewm@47: #define DEFAULT_ADC_LEVEL -6.0 andrewm@47: giuliomoro@171: giuliomoro@171: /** giuliomoro@171: * Default level of the Programmable Gain Amplifier in decibels. giuliomoro@171: */ giuliomoro@171: #define DEFAULT_PGA_GAIN 16 giuliomoro@171: andrewm@47: /** giuliomoro@301: * Default level of the headphone output in decibels. See Bela_setHeadphoneLevel(). andrewm@47: */ andrewm@47: #define DEFAULT_HP_LEVEL -6.0 andrewm@47: /** @} */ andrewm@47: andrewm@47: /** giuliomoro@301: * Flag for BelaContext. If set, indicates the audio and analog buffers are interleaved. andrewm@47: */ andrewm@303: #define BELA_FLAG_INTERLEAVED (1 << 0) // Set if buffers are interleaved andrewm@47: /** giuliomoro@301: * Flag for BelaContext. If set, indicates analog outputs persist for future frames. andrewm@47: */ andrewm@303: #define BELA_FLAG_ANALOG_OUTPUTS_PERSIST (1 << 1) // Set if analog/digital outputs persist for future buffers andrewm@46: andrewm@47: /** andrewm@47: * \ingroup control andrewm@47: * \brief Structure containing initialisation parameters for the real-time andrewm@47: * audio control system. andrewm@47: * giuliomoro@301: * This structure is initialised using Bela_defaultSettings(). Its contents andrewm@47: * are used up through the point of calling giuliomoro@301: * Bela_initAudio() at which point it is no longer needed. andrewm@47: */ andrewm@46: typedef struct { andrewm@46: // These items might be adjusted by the user: andrewm@46: andrewm@47: /// \brief Number of (analog) frames per period. andrewm@47: /// andrewm@47: /// Number of audio frames depends on relative sample rates of the two. By default, andrewm@47: /// audio is twice the sample rate, so has twice the period size. andrewm@47: int periodSize; andrewm@47: /// Whether to use the analog input and output andrewm@47: int useAnalog; andrewm@47: /// Whether to use the 16 programmable GPIOs andrewm@47: int useDigital; andrewm@47: /// How many channels for the ADC and DAC andrewm@47: int numAnalogChannels; andrewm@47: /// How many channels for the GPIOs andrewm@47: int numDigitalChannels; andrewm@46: andrewm@47: /// Whether to begin with the speakers muted andrewm@47: int beginMuted; andrewm@47: /// Level for the audio DAC output andrewm@47: float dacLevel; andrewm@47: /// Level for the audio ADC input andrewm@47: float adcLevel; giuliomoro@171: /// Gains for the PGA, left and right channels giuliomoro@171: float pgaGain[2]; andrewm@47: /// Level for the headphone output andrewm@47: float headphoneLevel; andrewm@280: /// How many channels to use on the multiplexer capelet, if enabled andrewm@280: int numMuxChannels; andrewm@47: andrewm@280: /// Which PRU (0 or 1) the code should run on andrewm@280: int pruNumber; andrewm@47: /// The external .bin file to load. If empty will use PRU code from pru_rtaudio_bin.h andrewm@47: char pruFilename[MAX_PRU_FILENAME_LENGTH]; andrewm@47: /// Whether to use verbose logging andrewm@47: int verbose; andrewm@46: andrewm@46: // These items are application-dependent but should probably be andrewm@46: // determined by the programmer rather than the user andrewm@47: andrewm@47: /// Whether audio/analog data should be interleaved andrewm@47: int interleave; andrewm@47: /// \brief Whether analog outputs should persist to future frames. andrewm@47: /// andrewm@47: /// n.b. digital pins always persist, audio never does andrewm@47: int analogOutputsPersist; andrewm@46: andrewm@46: // These items are hardware-dependent and should only be changed andrewm@46: // to run on different hardware andrewm@47: andrewm@47: /// Where the codec can be found on the I2C bus andrewm@47: int codecI2CAddress; andrewm@47: /// Pin where amplifier mute can be found andrewm@47: int ampMutePin; andrewm@47: /// Port where the UDP server will listen andrewm@47: int receivePort; andrewm@47: /// Port where the UDP client will transmit andrewm@47: int transmitPort; andrewm@46: char serverName[MAX_SERVERNAME_LENGTH]; giuliomoro@301: } BelaInitSettings; andrewm@46: andrewm@46: andrewm@47: /** andrewm@47: * \ingroup render andrewm@47: * \brief Structure holding current audio and sensor settings and pointers to data buffers. andrewm@47: * andrewm@56: * This structure is passed to setup(), render() and cleanup(). It is giuliomoro@301: * initialised in Bela_initAudio() based on the contents of the BelaInitSettings andrewm@47: * structure. andrewm@47: */ andrewm@46: typedef struct { andrewm@47: /// \brief Buffer holding audio input samples andrewm@47: /// andrewm@47: /// This buffer may be in either interleaved or non-interleaved format, giuliomoro@301: /// depending on the contents of the BelaInitSettings structure. andrewm@47: /// \b Note: this element is available in render() only. andrewm@307: const float * const audioIn; andrewm@47: andrewm@47: /// \brief Buffer holding audio output samples andrewm@47: /// andrewm@47: /// This buffer may be in either interleaved or non-interleaved format, giuliomoro@301: /// depending on the contents of the BelaInitSettings structure. andrewm@47: /// \b Note: this element is available in render() only. andrewm@307: float * const audioOut; andrewm@47: andrewm@47: /// \brief Buffer holding analog input samples andrewm@47: /// andrewm@47: /// This buffer may be in either interleaved or non-interleaved format, giuliomoro@301: /// depending on the contents of the BelaInitSettings structure. andrewm@47: /// \b Note: this element is available in render() only. andrewm@307: const float * const analogIn; andrewm@47: andrewm@47: /// \brief Buffer holding analog output samples andrewm@47: /// andrewm@47: /// This buffer may be in either interleaved or non-interleaved format, giuliomoro@301: /// depending on the contents of the BelaInitSettings structure. andrewm@47: /// \b Note: this element is available in render() only. andrewm@307: float * const analogOut; andrewm@47: andrewm@47: /// \brief Buffer holding digital input/output samples andrewm@47: /// andrewm@47: /// \b Note: this element is available in render() only. andrewm@307: uint32_t * const digital; andrewm@46: andrewm@47: /// Number of audio frames per period andrewm@307: const uint32_t audioFrames; andrewm@47: /// Number of audio channels (currently always 2) andrewm@307: const uint32_t audioChannels; andrewm@47: /// Audio sample rate in Hz (currently always 44100.0) andrewm@307: const float audioSampleRate; andrewm@46: andrewm@47: /// \brief Number of analog frames per period andrewm@47: /// andrewm@47: /// This will be 0 if analog I/O is disabled. andrewm@307: const uint32_t analogFrames; andrewm@47: andrewm@47: /// \brief Number of analog channels andrewm@47: /// andrewm@47: /// This could take a value of 8, 4 or 2. This will be 0 if analog I/O is disabled. andrewm@307: const uint32_t analogChannels; andrewm@47: andrewm@47: /// \brief Analog sample rate in Hz andrewm@47: /// andrewm@47: /// The analog sample rate depends on the number of analog channels used. If andrewm@47: /// 8 channels are used, the sample rate is 22050. If 4 channels are used, the sample andrewm@47: /// rate is 44100. If 2 channels are used, the sample rate is 88200. If analog I/O andrewm@47: /// is disabled, the sample rate is 0. andrewm@307: const float analogSampleRate; andrewm@46: andrewm@47: /// Number of digital frames per period andrewm@307: const uint32_t digitalFrames; andrewm@47: /// \brief Number of digital channels andrewm@47: /// andrewm@47: /// Currently this will always be 16, unless digital I/O is disabled, in which case it will be 0. andrewm@307: const uint32_t digitalChannels; andrewm@47: /// Digital sample rate in Hz (currently always 44100.0) andrewm@307: const float digitalSampleRate; andrewm@46: andrewm@47: /// \brief Number of elapsed audio samples since the start of rendering. andrewm@47: /// andrewm@47: /// This holds the total number of audio samples as of the beginning of the current period. To andrewm@47: /// find the current number of analog or digital samples elapsed, multiply by the ratio of the andrewm@47: /// sample rates (e.g. half the number of analog samples will have elapsed if the analog sample andrewm@47: /// rate is 22050). andrewm@307: const uint64_t audioSampleCount; andrewm@47: andrewm@47: /// \brief Other audio/sensor settings andrewm@47: /// andrewm@47: /// Binary combination of flags including: andrewm@47: /// andrewm@303: /// BELA_FLAG_INTERLEAVED: indicates the audio and analog buffers are interleaved andrewm@47: /// andrewm@303: /// BELA_FLAG_ANALOG_OUTPUTS_PERSIST: indicates that writes to the analog outputs will andrewm@47: /// persist for future frames. If not set, writes affect one frame only. andrewm@307: const uint32_t flags; giuliomoro@301: } BelaContext; andrewm@46: andrewm@47: /** \ingroup auxtask andrewm@47: * andrewm@47: * Auxiliary task variable. Auxiliary tasks are created using createAuxiliaryTask() and andrewm@56: * automatically cleaned up after cleanup() finishes. andrewm@47: */ andrewm@46: typedef void* AuxiliaryTask; // Opaque data type to keep track of aux tasks andrewm@46: andrewm@47: /** \ingroup render andrewm@47: * andrewm@47: * Flag that indicates when the audio will stop. Threads can poll this variable to indicate when andrewm@47: * they should stop. Additionally, a program can set this to \c true giuliomoro@301: * to indicate that audio processing should terminate. Calling Bela_stopAudio() andrewm@47: * has the effect of setting this to \c true. andrewm@47: */ giuliomoro@233: extern int gShouldStop; andrewm@46: andrewm@46: // *** User-defined render functions *** andrewm@46: andrewm@46: /** andrewm@47: * \defgroup render User-defined render functions andrewm@47: * giuliomoro@301: * These three functions must be implemented by the developer in every Bela program. andrewm@47: * Typically they appear in their own .cpp source file. andrewm@47: * andrewm@47: * @{ andrewm@47: */ andrewm@47: andrewm@47: /** andrewm@46: * \brief User-defined initialisation function which runs before audio rendering begins. andrewm@46: * andrewm@46: * This function runs once at the beginning of the program, after most of the system andrewm@46: * initialisation has begun but before audio rendering starts. Use it to prepare any andrewm@46: * memory or resources that will be needed in render(). andrewm@46: * andrewm@46: * \param context Data structure holding information on sample rates, numbers of channels, andrewm@46: * frame sizes and other state. Note: the buffers for audio, analog and digital data will andrewm@46: * \b not yet be available to use. Do not attempt to read or write audio or sensor data andrewm@56: * in setup(). andrewm@46: * \param userData An opaque pointer to an optional user-defined data structure. Whatever giuliomoro@301: * is passed as the second argument to Bela_initAudio() will appear here. andrewm@46: * andrewm@46: * \return true on success, or false if an error occurred. If no initialisation is andrewm@56: * required, setup() should return true. andrewm@46: */ giuliomoro@301: bool setup(BelaContext *context, void *userData); andrewm@46: andrewm@46: /** andrewm@46: * \brief User-defined callback function to process audio and sensor data. andrewm@46: * andrewm@46: * This function is called regularly by the system every time there is a new block of andrewm@46: * audio and/or sensor data to process. Your code should process the requested samples andrewm@46: * of data, store the results within \c context, and return. andrewm@46: * andrewm@46: * \param context Data structure holding buffers for audio, analog and digital data. The andrewm@46: * structure also holds information on numbers of channels, frame sizes and sample rates, andrewm@46: * which are guaranteed to remain the same throughout the program and to match what was andrewm@56: * passed to setup(). andrewm@46: * \param userData An opaque pointer to an optional user-defined data structure. Will andrewm@56: * be the same as the \c userData parameter passed to setup(). andrewm@46: */ giuliomoro@301: void render(BelaContext *context, void *userData); andrewm@46: andrewm@46: /** andrewm@46: * \brief User-defined cleanup function which runs when the program finishes. andrewm@46: * andrewm@46: * This function is called by the system once after audio rendering has finished, before the andrewm@56: * program quits. Use it to release any memory allocated in setup() and to perform andrewm@56: * any other required cleanup. If no initialisation is performed in setup(), then andrewm@46: * this function will usually be empty. andrewm@46: * andrewm@46: * \param context Data structure holding information on sample rates, numbers of channels, andrewm@46: * frame sizes and other state. Note: the buffers for audio, analog and digital data will andrewm@46: * no longer be available to use. Do not attempt to read or write audio or sensor data andrewm@56: * in cleanup(). andrewm@46: * \param userData An opaque pointer to an optional user-defined data structure. Will andrewm@56: * be the same as the \c userData parameter passed to setup() and render(). andrewm@46: */ giuliomoro@301: void cleanup(BelaContext *context, void *userData); andrewm@46: andrewm@47: /** @} */ andrewm@47: andrewm@47: /** andrewm@47: * \defgroup control Control and command line functions andrewm@47: * giuliomoro@301: * These functions are used to initialise the Bela settings, process arguments andrewm@47: * from the command line, and start/stop the audio and sensor system. andrewm@47: * andrewm@47: * @{ andrewm@47: */ andrewm@47: andrewm@46: // *** Command-line settings *** andrewm@46: andrewm@46: /** giuliomoro@301: * \brief Initialise the data structure containing settings for Bela. andrewm@46: * andrewm@46: * This function should be called in main() before parsing any command-line arguments. It giuliomoro@301: * sets default values in the data structure which specifies the Bela settings, including andrewm@46: * frame sizes, numbers of channels, volume levels and other parameters. andrewm@46: * giuliomoro@301: * \param settings Structure holding initialisation data for Bela. andrewm@46: */ giuliomoro@301: void Bela_defaultSettings(BelaInitSettings *settings); andrewm@46: andrewm@46: /** giuliomoro@301: * \brief Get long options from command line argument list, including Bela standard options andrewm@46: * andrewm@46: * This function should be used in main() to process command line options, in place of the giuliomoro@301: * standard library getopt_long(). Internally, it parses standard Bela command-line options, andrewm@46: * storing the results in the settings data structure. Any options which are not part of the giuliomoro@301: * Bela standard options will be returned, as they would normally be in getopt_long(). andrewm@46: * andrewm@46: * \param argc Number of command line options, as passed to main(). andrewm@46: * \param argv Array of command line options, as passed to main(). andrewm@46: * \param customShortOptions List of short options to be parsed, analogous to getopt_long(). This giuliomoro@301: * list should not include any characters already parsed as part of the Bela standard options. andrewm@46: * \param customLongOptions List of long options to parsed, analogous to getopt_long(). This giuliomoro@301: * list should not include any long options already parsed as part of the Bela standard options. giuliomoro@301: * \param settings Data structure holding initialisation settings for Bela. Any standard options andrewm@46: * parsed will automatically update this data structure. andrewm@46: * giuliomoro@301: * \return Value of the next option parsed which is not a Bela standard option, or -1 when the giuliomoro@301: * argument list has been exhausted. Similar to the return value of getopt_long() except that Bela andrewm@46: * standard options are handled internally and not returned. andrewm@46: */ giuliomoro@301: int Bela_getopt_long(int argc, char *argv[], const char *customShortOptions, giuliomoro@301: const struct option *customLongOptions, BelaInitSettings *settings); andrewm@46: andrewm@46: /** giuliomoro@301: * \brief Print usage information for Bela standard options. andrewm@46: * andrewm@46: * This function should be called from your code wherever you wish to print usage information for the giuliomoro@301: * user. It will print usage information on Bela standard options, after which you can print usage andrewm@46: * information for your own custom options. andrewm@46: */ giuliomoro@301: void Bela_usage(); andrewm@46: andrewm@46: /** andrewm@46: * \brief Set level of verbose (debugging) printing. andrewm@46: * giuliomoro@301: * \param level Verbosity level of the internal Bela system. 0 by default; higher values will andrewm@46: * print more information. Presently all positive numbers produce the same level of printing. andrewm@46: */ giuliomoro@301: void Bela_setVerboseLevel(int level); andrewm@46: andrewm@47: andrewm@46: // *** Audio control functions *** andrewm@46: andrewm@46: /** andrewm@46: * \brief Initialise audio and sensor rendering environment. andrewm@46: * giuliomoro@301: * This function prepares audio rendering in Bela. It should be called from main() sometime andrewm@46: * after command line option parsing has finished. It will initialise the rendering system, which andrewm@56: * in the process will result in a call to the user-defined setup() function. andrewm@46: * andrewm@46: * \param settings Data structure holding system settings, including numbers of channels, frame sizes, andrewm@46: * volume levels and other information. andrewm@46: * \param userData An opaque pointer to a user-defined data structure which will be passed to andrewm@56: * setup(), render() and cleanup(). You can use this to pass custom information andrewm@46: * to the rendering functions, as an alternative to using global variables. andrewm@46: * andrewm@46: * \return 0 on success, or nonzero if an error occurred. andrewm@46: */ giuliomoro@301: int Bela_initAudio(BelaInitSettings *settings, void *userData); andrewm@46: andrewm@46: /** andrewm@46: * \brief Begin processing audio and sensor data. andrewm@46: * giuliomoro@301: * This function will start the Bela audio/sensor system. After this function is called, the giuliomoro@301: * system will make periodic calls to render() until Bela_stopAudio() is called. andrewm@46: * andrewm@46: * \return 0 on success, or nonzero if an error occurred. andrewm@46: */ giuliomoro@301: int Bela_startAudio(); andrewm@46: andrewm@46: /** andrewm@46: * \brief Stop processing audio and sensor data. andrewm@46: * giuliomoro@301: * This function will stop the Bela audio/sensor system. After this function returns, no further andrewm@46: * calls to render() will be issued. andrewm@46: */ giuliomoro@301: int Bela_startAuxiliaryTask(AuxiliaryTask it); giuliomoro@301: void Bela_stopAudio(); andrewm@46: andrewm@46: /** andrewm@46: * \brief Clean up resources from audio and sensor processing. andrewm@46: * giuliomoro@301: * This function should only be called after Bela_stopAudio(). It will release any andrewm@46: * internal resources for audio and sensor processing. In the process, it will call the andrewm@56: * user-defined cleanup() function. andrewm@46: */ giuliomoro@301: void Bela_cleanupAudio(); andrewm@46: andrewm@47: /** @} */ andrewm@47: andrewm@47: /** andrewm@47: * \defgroup levels Audio level controls andrewm@47: * giuliomoro@301: * These functions control the input and output levels for the audio codec. If a Bela program andrewm@47: * does not call these functions, sensible default levels will be used. andrewm@47: * andrewm@47: * @{ andrewm@47: */ andrewm@46: andrewm@46: // *** Volume and level controls *** andrewm@46: andrewm@46: /** andrewm@46: * \brief Set the level of the audio DAC. andrewm@46: * andrewm@46: * This function sets the level of all audio outputs (headphone, line, speaker). It does andrewm@46: * not affect the level of the (non-audio) analog outputs. andrewm@46: * andrewm@46: * \b Important: do not call this function from within render(), as it does not make andrewm@46: * any guarantees on real-time performance. andrewm@46: * andrewm@46: * \param decibels Level of the DAC output. Valid levels range from -63.5 (lowest) to andrewm@46: * 0 (highest) in steps of 0.5dB. Levels between increments of 0.5 will be rounded down. andrewm@46: * andrewm@46: * \return 0 on success, or nonzero if an error occurred. andrewm@46: */ giuliomoro@301: int Bela_setDACLevel(float decibels); andrewm@46: andrewm@46: /** andrewm@46: * \brief Set the level of the audio ADC. andrewm@46: * andrewm@46: * This function sets the level of the audio input. It does not affect the level of the andrewm@46: * (non-audio) analog inputs. andrewm@46: * andrewm@46: * \b Important: do not call this function from within render(), as it does not make andrewm@46: * any guarantees on real-time performance. andrewm@46: * andrewm@46: * \param decibels Level of the ADC input. Valid levels range from -12 (lowest) to andrewm@46: * 0 (highest) in steps of 1.5dB. Levels between increments of 1.5 will be rounded down. andrewm@46: * andrewm@46: * \return 0 on success, or nonzero if an error occurred. andrewm@46: */ giuliomoro@301: int Bela_setADCLevel(float decibels); andrewm@46: giuliomoro@171: giuliomoro@171: /** giuliomoro@171: * \brief Set the gain of the audio preamplifier. giuliomoro@171: * giuliomoro@171: * This function sets the level of the Programmable Gain Amplifier(PGA), which giuliomoro@171: * amplifies the signal before the ADC. giuliomoro@171: * giuliomoro@171: * \b Important: do not call this function from within render(), as it does not make giuliomoro@171: * any guarantees on real-time performance. giuliomoro@171: * giuliomoro@171: * \param decibels Level of the PGA Valid levels range from 0 (lowest) to giuliomoro@171: * 59.5 (highest) in steps of 0.5dB. Levels between increments of 0.5 will be rounded. giuliomoro@171: * \param channel Specifies which channel to apply the gain to. Channel 0 is left, giuliomoro@171: * channel 1 is right giuliomoro@171: * giuliomoro@171: * \return 0 on success, or nonzero if an error occurred. giuliomoro@171: */ giuliomoro@301: int Bela_setPgaGain(float decibels, int channel); giuliomoro@171: andrewm@46: /** andrewm@46: * \brief Set the level of the onboard headphone amplifier. andrewm@46: * giuliomoro@301: * This function sets the level of the headphone output only (3-pin connector on the Bela andrewm@46: * cape or the output jack on the BeagleBone Audio Cape). It does not affect the level of the andrewm@46: * speakers or the line out pads on the cape. andrewm@46: * andrewm@46: * \b Important: do not call this function from within render(), as it does not make andrewm@46: * any guarantees on real-time performance. andrewm@46: * andrewm@46: * \param decibels Level of the DAC output. Valid levels range from -63.5 (lowest) to andrewm@46: * 0 (highest) in steps of 0.5dB. Levels between increments of 0.5 will be rounded down. andrewm@46: * andrewm@46: * \return 0 on success, or nonzero if an error occurred. andrewm@46: */ giuliomoro@301: int Bela_setHeadphoneLevel(float decibels); andrewm@46: andrewm@46: /** andrewm@46: * \brief Mute or unmute the onboard speaker amplifiers. andrewm@46: * giuliomoro@301: * This function mutes or unmutes the amplifiers on the Bela cape. Whether the speakers begin giuliomoro@301: * muted or unmuted depends on the BelaInitSettings structure passed to Bela_initAudio(). andrewm@46: * andrewm@46: * \b Important: do not call this function from within render(), as it does not make andrewm@46: * any guarantees on real-time performance. andrewm@46: * andrewm@46: * \param mute 0 to enable the speakers, nonzero to mute the speakers. andrewm@46: * andrewm@46: * \return 0 on success, or nonzero if an error occurred. andrewm@46: */ giuliomoro@301: int Bela_muteSpeakers(int mute); andrewm@46: andrewm@47: /** @} */ andrewm@47: andrewm@47: /** andrewm@47: * \defgroup auxtask Auxiliary task support andrewm@47: * andrewm@47: * These functions are used to create separate real-time tasks (threads) which run at lower andrewm@47: * priority than the audio processing. They can be used, for example, for large time-consuming andrewm@47: * calculations which would take more than one audio frame length to process, or they could be andrewm@47: * used to communicate with external hardware when that communication might block or be delayed. andrewm@47: * andrewm@56: * All auxiliary tasks used by the program should be created in setup(). The tasks andrewm@47: * can then be scheduled at will within the render() function. andrewm@47: * andrewm@47: * @{ andrewm@47: */ andrewm@47: andrewm@46: // *** Functions for creating auxiliary tasks *** andrewm@46: andrewm@46: /** andrewm@46: * \brief Create a new auxiliary task. andrewm@46: * andrewm@46: * This function creates a new auxiliary task which, when scheduled, runs the function specified andrewm@46: * in the first argument. Note that the task does not run until scheduleAuxiliaryTask() is called. andrewm@56: * Auxiliary tasks should be created in setup() and never in render() itself. andrewm@46: * andrewm@46: * The second argument specifies the real-time priority. Valid values are between 0 andrewm@303: * and 99, and usually should be lower than \ref BELA_AUDIO_PRIORITY. Tasks with higher priority always andrewm@46: * preempt tasks with lower priority. andrewm@46: * andrewm@46: * \param functionToCall Function which will run each time the auxiliary task is scheduled. andrewm@46: * \param priority Xenomai priority level at which the task should run. andrewm@47: * \param name Name for this task, which should be unique system-wide (no other running program should use this name). andrewm@46: */ giuliomoro@301: AuxiliaryTask Bela_createAuxiliaryTask(void (*functionToCall)(void*), int priority, const char *name, void* args, bool autoSchedule = false); giuliomoro@301: AuxiliaryTask Bela_createAuxiliaryTask(void (*functionToCall)(void), int priority, const char *name, bool autoSchedule = false); andrewm@46: andrewm@46: /** giuliomoro@174: * \brief Start an auxiliary task so that it can be run. giuliomoro@174: * giuliomoro@174: * This function will start an auxiliary task but will NOT schedule it. giuliomoro@174: * It will also set a flag in the associate InternalAuxiliaryTask to flag the giuliomoro@174: * task as "started", so that successive calls to the same function for a given AuxiliaryTask giuliomoro@174: * have no effect. giuliomoro@174: * The user should never be required to call this function directly, as it is called giuliomoro@301: * by Bela_scheduleAuxiliaryTask if needed (e.g.: if a task is scheduled in setup() ) giuliomoro@174: * or immediately after starting the audio thread. giuliomoro@174: * giuliomoro@174: * \param task Task to start. giuliomoro@174: */ giuliomoro@174: giuliomoro@301: int Bela_startAuxiliaryTask(AuxiliaryTask task); giuliomoro@174: /** andrewm@46: * \brief Run an auxiliary task which has previously been created. andrewm@46: * andrewm@46: * This function will schedule an auxiliary task to run. When the task runs, the function in the first andrewm@46: * argument of createAuxiliaryTaskLoop() will be called. andrewm@46: * andrewm@46: * scheduleAuxiliaryTask() is typically called from render() to start a lower-priority task. The function andrewm@46: * will not run immediately, but only once any active higher priority tasks have finished. andrewm@46: * andrewm@46: * \param task Task to schedule for running. andrewm@46: */ giuliomoro@301: void Bela_scheduleAuxiliaryTask(AuxiliaryTask task); giuliomoro@301: void Bela_autoScheduleAuxiliaryTasks(); andrewm@47: andrewm@47: /** @} */ giuliomoro@187: #include andrewm@46: andrewm@303: #endif /* BELA_H_ */