Mercurial > hg > beaglert
changeset 5:09f03ac40fcc
API improvements and cleanups. Now all common audio command-line options can be parsed automatically.
author | andrewm |
---|---|
date | Sat, 08 Nov 2014 16:16:55 +0100 |
parents | f34c63568523 |
children | ab396a08e962 49f22e1246b2 |
files | .cproject core/RTAudio.cpp core/RTAudioCommandLine.cpp include/RTAudio.h include/Utilities.h projects/audio_in_FFT/main.cpp projects/audio_in_FFT/render.cpp projects/basic/main.cpp projects/basic_analog_output/main.cpp projects/basic_analog_output/render.cpp projects/basic_sensor/main.cpp projects/basic_sensor/render.cpp projects/d-box/main.cpp projects/filter_FIR/main.cpp projects/filter_FIR/render.cpp projects/filter_IIR/main.cpp projects/oscillator_bank/main.cpp projects/samples/main.cpp |
diffstat | 18 files changed, 580 insertions(+), 399 deletions(-) [+] |
line wrap: on
line diff
--- a/.cproject Thu Nov 06 19:02:48 2014 +0000 +++ b/.cproject Sat Nov 08 16:16:55 2014 +0100 @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<?fileVersion 4.0.0?> - -<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> +<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> <storageModule moduleId="org.eclipse.cdt.core.settings"> <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.528876549"> <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.528876549" moduleId="org.eclipse.cdt.core.settings" name="Debug"> @@ -82,9 +80,9 @@ </toolChain> </folderInfo> <sourceEntries> + <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> - <entry excluding="filter_IIR|filter_FIR|oscillator_bank|samples|basic_sensor|d-box|basic_analog_output|basic" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects"/> + <entry excluding="basic_sensor|d-box|audio_in_FFT|filter_IIR|filter_FIR|samples|oscillator_bank|basic" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects"/> </sourceEntries> </configuration> </storageModule> @@ -136,6 +134,7 @@ </option> <option id="gnu.cpp.link.option.libs.1930118082" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"> <listOptionValue builtIn="false" value="rt"/> + <listOptionValue builtIn="false" value="sndfile"/> <listOptionValue builtIn="false" value="native"/> <listOptionValue builtIn="false" value="xenomai"/> </option> @@ -155,9 +154,9 @@ </toolChain> </folderInfo> <sourceEntries> + <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> - <entry excluding="filter_IIR|filter_FIR|oscillator_bank|samples|basic_sensor|d-box|basic_analog_output|basic" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects"/> + <entry excluding="basic_sensor|d-box|audio_in_FFT|filter_IIR|filter_FIR|samples|oscillator_bank|basic" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects"/> </sourceEntries> </configuration> </storageModule>
--- a/core/RTAudio.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/core/RTAudio.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -44,8 +44,6 @@ } InternalAuxiliaryTask; const char gRTAudioThreadName[] = "beaglert-audio"; -const char gRTCalculationThreadNameMedium[] = "dbox-calculation-medium"; -const char gRTCalculationThreadNameLow[] = "dbox-calculation-low"; // Real-time tasks and objects RT_TASK gRTAudioThread; @@ -61,6 +59,7 @@ int gRTAudioVerbose = 0; // Verbosity level for debugging char gPRUFilename[256] = "pru_rtaudio.bin"; // path to PRU binary file int gAmplifierMutePin = -1; +int gAmplifierShouldBeginMuted = 0; // initAudio() prepares the infrastructure for running PRU-based real-time @@ -74,31 +73,41 @@ // // Returns 0 on success. -int initAudio(int periodSize, int useMatrix, - void *userData, - int codecI2CAddress, int ampMutePin) +int BeagleRT_initAudio(RTAudioSettings *settings, void *userData) { rt_print_auto_init(1); + setVerboseLevel(settings->verbose); + if(gRTAudioVerbose == 1) rt_printf("Running with Xenomai\n"); - if(gRTAudioVerbose == 1) - cout << "---------------->Init Audio Thread" << endl; + if(gRTAudioVerbose) { + cout << "Starting with period size " << settings->periodSize << "; "; + if(settings->useMatrix) + cout << "matrix enabled\n"; + else + cout << "matrix disabled\n"; + cout << "DAC level " << settings->dacLevel << "dB; ADC level " << settings->adcLevel; + cout << "dB; headphone level " << settings->headphoneLevel << "dB\n"; + if(settings->beginMuted) + cout << "Beginning with speaker muted\n"; + } // Prepare GPIO pins for amplifier mute and status LED - if(ampMutePin >= 0) { - gAmplifierMutePin = ampMutePin; + if(settings->ampMutePin >= 0) { + gAmplifierMutePin = settings->ampMutePin; + gAmplifierShouldBeginMuted = settings->beginMuted; - if(gpio_export(ampMutePin)) { + if(gpio_export(settings->ampMutePin)) { if(gRTAudioVerbose) cout << "Warning: couldn't export amplifier mute pin\n"; } - if(gpio_set_dir(ampMutePin, OUTPUT_PIN)) { + if(gpio_set_dir(settings->ampMutePin, OUTPUT_PIN)) { if(gRTAudioVerbose) cout << "Couldn't set direction on amplifier mute pin\n"; return -1; } - if(gpio_set_value(ampMutePin, LOW)) { + if(gpio_set_value(settings->ampMutePin, LOW)) { if(gRTAudioVerbose) cout << "Couldn't set value on amplifier mute pin\n"; return -1; @@ -109,15 +118,15 @@ gPRU = new PRU(); gAudioCodec = new I2c_Codec(); - if(gPRU->prepareGPIO(useMatrix, 1, 1)) { + if(gPRU->prepareGPIO(settings->useMatrix, 1, 1)) { cout << "Error: unable to prepare GPIO for PRU audio\n"; return 1; } - if(gPRU->initialise(0, periodSize, true)) { + if(gPRU->initialise(0, settings->periodSize, true)) { cout << "Error: unable to initialise PRU\n"; return 1; } - if(gAudioCodec->initI2C_RW(2, codecI2CAddress, -1)) { + if(gAudioCodec->initI2C_RW(2, settings->codecI2CAddress, -1)) { cout << "Unable to open codec I2C\n"; return 1; } @@ -125,11 +134,13 @@ cout << "Error: unable to initialise audio codec\n"; return 1; } - gAudioCodec->setDACVolume(0); // Set the DAC volume to full-scale - gAudioCodec->setHPVolume(-12); // Headphones 6dB down - gAudioCodec->setADCVolume(-12); // Set the ADC volume to 6dB down - if(!initialise_render(2, useMatrix ? periodSize : 0, periodSize * 2, 22050.0, 44100.0, userData)) { + // Set default volume levels + BeagleRT_setDACLevel(settings->dacLevel); + BeagleRT_setADCLevel(settings->adcLevel); + BeagleRT_setHeadphoneLevel(settings->headphoneLevel); + + if(!initialise_render(2, settings->useMatrix ? settings->periodSize : 0, settings->periodSize * 2, 22050.0, 44100.0, userData)) { cout << "Couldn't initialise audio rendering\n"; return 1; } @@ -161,10 +172,13 @@ } else { // All systems go. Run the loop; it will end when gShouldStop is set to 1 - // First unmute the amplifier - if(gpio_set_value(gAmplifierMutePin, HIGH)) { - if(gRTAudioVerbose) - rt_printf("Warning: couldn't set value (high) on amplifier mute pin\n"); + + if(!gAmplifierShouldBeginMuted) { + // First unmute the amplifier + if(BeagleRT_muteSpeakers(0)) { + if(gRTAudioVerbose) + rt_printf("Warning: couldn't set value (high) on amplifier mute pin\n"); + } } gPRU->loop(); @@ -242,7 +256,7 @@ // It launches the real-time Xenomai task which runs the audio loop. Returns 0 // on success. -int startAudio() +int BeagleRT_startAudio() { // Create audio thread with the highest priority if(rt_task_create(&gRTAudioThread, gRTAudioThreadName, 0, 99, T_JOINABLE | T_FPU)) { @@ -273,11 +287,14 @@ // Stop the PRU-based audio from running and wait // for the tasks to complete before returning. -void stopAudio() +void BeagleRT_stopAudio() { // Tell audio thread to stop (if this hasn't been done already) gShouldStop = true; + if(gRTAudioVerbose) + cout << "Stopping audio...\n"; + // Now wait for threads to respond and actually stop... rt_task_join(&gRTAudioThread); @@ -293,7 +310,7 @@ } // Free any resources associated with PRU real-time audio -void cleanupAudio() +void BeagleRT_cleanupAudio() { cleanup_render(); @@ -318,6 +335,48 @@ gAmplifierMutePin = -1; } +// 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) +{ + if(gAudioCodec == 0) + return -1; + return gAudioCodec->setDACVolume((int)floorf(decibels * 2.0 + 0.5)); +} + +// Set the level of the ADC +// 0dB is the maximum, -12dB is the minimum; 1.5dB steps +int BeagleRT_setADCLevel(float decibels) +{ + if(gAudioCodec == 0) + return -1; + return gAudioCodec->setADCVolume((int)floorf(decibels * 2.0 + 0.5)); +} + +// 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) +{ + if(gAudioCodec == 0) + return -1; + return gAudioCodec->setHPVolume((int)floorf(decibels * 2.0 + 0.5)); +} + +// Mute or unmute the onboard speaker amplifiers +// mute == 0 means unmute; otherwise mute +// Returns 0 on success +int BeagleRT_muteSpeakers(int mute) +{ + int pinValue = mute ? LOW : HIGH; + + // Check that we have an enabled pin for controlling the mute + if(gAmplifierMutePin < 0) + return -1; + + return gpio_set_value(gAmplifierMutePin, pinValue); +} + // Set the verbosity level void setVerboseLevel(int level) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/RTAudioCommandLine.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -0,0 +1,156 @@ +/* + * RTAudioCommandLine.cpp + * + * Created on: Nov 8, 2014 + * Author: parallels + */ + +#include <iostream> +#include <cstdlib> +#include <cstring> +#include <getopt.h> + +#include "../include/RTAudio.h" + +// Default command-line options for RTAudio +struct option gDefaultLongOptions[] = +{ + {"period", 1, NULL, 'p'}, + {"verbose", 0, NULL, 'v'}, + {"use-matrix", 1, NULL, 'm'}, + {"mute-speaker", 1, NULL, 'M'}, + {"dac-level", 1, NULL, 'D'}, + {"adc-level", 1, NULL, 'A'}, + {"hp-level", 1, NULL, 'H'}, + {NULL, 0, NULL, 0} +}; + +const char gDefaultShortOptions[] = "p:vm:M:D:A:H:"; + +// This function sets the default settings for the RTAudioSettings structure +void BeagleRT_defaultSettings(RTAudioSettings *settings) +{ + // Set default values for settings + settings->periodSize = 8; + settings->beginMuted = 0; + settings->dacLevel = DEFAULT_DAC_LEVEL; + settings->adcLevel = DEFAULT_ADC_LEVEL; + settings->headphoneLevel = DEFAULT_HP_LEVEL; + settings->useMatrix = 1; + settings->verbose = 0; + settings->codecI2CAddress = CODEC_I2C_ADDRESS; + settings->ampMutePin = kAmplifierMutePin; +} + +// This function drops in place of getopt() in the main() function +// and handles the initialisation of the RTAudio settings using +// standard command-line arguments. System default arguments will +// be stored in settings, otherwise arguments will be returned +// as getopt() normally does. + +int BeagleRT_getopt_long(int argc, char *argv[], const char *customShortOptions, const struct option *customLongOptions, RTAudioSettings *settings) +{ + static int firstRun = 1; + static char totalShortOptions[256]; + static struct option totalLongOptions[256]; + + int c; + + // Prep total option string the first time this is + // run. As a getopt() substitute, it will be called repeatedly working its + // way through argc and argv. + if(firstRun) { + firstRun = 0; + + // Copy short options into one string + strcpy(totalShortOptions, gDefaultShortOptions); + strncat(totalShortOptions, customShortOptions, 256 - strlen(gDefaultShortOptions) - 1); + + // Copy long options into one array + int n = 0; + while(1) { + if(gDefaultLongOptions[n].name == NULL) + break; + totalLongOptions[n].name = gDefaultLongOptions[n].name; + totalLongOptions[n].has_arg = gDefaultLongOptions[n].has_arg; + totalLongOptions[n].flag = gDefaultLongOptions[n].flag; + totalLongOptions[n].val = gDefaultLongOptions[n].val; + n++; + } + + // Copy custom options into the array, if present + if(customLongOptions == 0) { + // Terminate the array + totalLongOptions[n].name = NULL; + totalLongOptions[n].has_arg = 0; + totalLongOptions[n].flag = NULL; + totalLongOptions[n].val = 0; + } + else { + int customIndex = 0; + while(n < 256) { + if(customLongOptions[customIndex].name == NULL) + break; + totalLongOptions[n].name = customLongOptions[customIndex].name; + totalLongOptions[n].has_arg = customLongOptions[customIndex].has_arg; + totalLongOptions[n].flag = customLongOptions[customIndex].flag; + totalLongOptions[n].val = customLongOptions[customIndex].val; + n++; + customIndex++; + } + + // Terminate the array + totalLongOptions[n].name = NULL; + totalLongOptions[n].has_arg = 0; + totalLongOptions[n].flag = NULL; + totalLongOptions[n].val = 0; + } + } + + while(1) { + if ((c = getopt_long(argc, argv, totalShortOptions, totalLongOptions, NULL)) < 0) + return c; + + switch (c) { + case 'p': + settings->periodSize = atoi(optarg); + if(settings->periodSize < 1) + settings->periodSize = 1; + break; + case 'v': + settings->verbose = 1; + break; + case 'm': + settings->useMatrix = atoi(optarg); + break; + case 'M': + settings->beginMuted = atoi(optarg); + break; + case 'D': + settings->dacLevel = atof(optarg); + break; + case 'A': + settings->adcLevel = atof(optarg); + break; + case 'H': + settings->headphoneLevel = atof(optarg); + break; + case '?': + default: + return c; + } + } +} + +// This function prints standard usage information for default arguments +// Call from within your own usage function +void BeagleRT_usage() +{ + std::cerr << " --period [-p] period: Set the hardware period (buffer) size in matrix samples\n"; + std::cerr << " --dac-level [-D] dBs: Set the DAC output level (0dB max; -63.5dB min)\n"; + std::cerr << " --adc-level [-A] dBs: Set the ADC input level (0dB max; -12dB min)\n"; + std::cerr << " --hp-level [-H] dBs: Set the headphone output level (0dB max; -63.5dB min)\n"; + std::cerr << " --mute-speaker [-M] val: Set whether to mute the speaker initially (default: no)\n"; + std::cerr << " --use-matrix [-m] val: Set whether to use ADC/DAC matrix\n"; + std::cerr << " --verbose [-v]: Enable verbose logging information\n"; +}
--- a/include/RTAudio.h Thu Nov 06 19:02:48 2014 +0000 +++ b/include/RTAudio.h Sat Nov 08 16:16:55 2014 +0100 @@ -25,22 +25,73 @@ #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 }; +// 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 (matrix) 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 useMatrix; // Whether to enable the ADC and DAC + int verbose; // Whether to use verbose logging + + // 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 +} RTAudioSettings; + 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; -int initAudio(int periodSize, int useMatrix, void *userData, - int codecI2CAddress = CODEC_I2C_ADDRESS, int ampMutePin = kAmplifierMutePin); -int startAudio(); -void stopAudio(); -void cleanupAudio(); +// 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);
--- a/include/Utilities.h Thu Nov 06 19:02:48 2014 +0000 +++ b/include/Utilities.h Sat Nov 08 16:16:55 2014 +0100 @@ -8,6 +8,13 @@ #ifndef UTILITIES_H_ #define UTILITIES_H_ +// Macros for accessing the matrix values: usable _only_ within render() + +// Read an analog input from input pin p at frame f +#define analogRead(p, f) (matrixIn[(f)*8 + (p)]) +// Write an analog output frame at output pin p, frame f, to value v +#define analogWrite(p, f, v) (matrixOut[(f)*8 + (p)] = (uint16_t)(v)) + float map(float x, float in_min, float in_max, float out_min, float out_max); float constrain(float x, float min_val, float max_val);
--- a/projects/audio_in_FFT/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/audio_in_FFT/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -9,6 +9,7 @@ #include <cstdlib> #include <libgen.h> #include <signal.h> +#include <getopt.h> #include "../../include/RTAudio.h" using namespace std; @@ -22,44 +23,43 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f frequency]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -s fftsize: Set the fSize of the FFT, in samples\n"; - cerr << " -m: Enable the matrix (ADC and DAC) as well as audio\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --fftsize [-s] size: Set the fSize of the FFT, in samples\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int periodSize = 8; // Period size in sensor frames - int verbose = 0; // Verbose printing level + RTAudioSettings settings; // Standard audio settings int fftSize = 64; // Size of the FFT, in samples - int useMatrix = 0; // Whether to use the matrix or just audio + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"fftsize", 1, NULL, 's'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + + settings.useMatrix = 0; // No matrix usage by default // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vf:m")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hs:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - periodSize = atoi(optarg); - if(periodSize < 1) - periodSize = 1; - break; - case 'v': - verbose = 1; - break; case 's': fftSize = atof(optarg); break; - case 'm': - useMatrix = 1; - break; case '?': default: usage(basename(argv[0])); @@ -67,26 +67,14 @@ } } - - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << periodSize << " and FFT size " << fftSize << endl; - if(useMatrix) - cout << "Matrix enabled\n"; - else - cout << "Matrix disabled\n"; - } - // Initialise the PRU audio device - if(initAudio(periodSize, useMatrix, &fftSize) != 0) { + if(BeagleRT_initAudio(&settings, &fftSize) != 0) { cout << "Error: unable to initialise audio" << endl; return -1; } // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -100,15 +88,12 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0; } +
--- a/projects/audio_in_FFT/render.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/audio_in_FFT/render.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -11,14 +11,16 @@ #include <NE10.h> // neon library #include <cmath> -int gFftSize; +int gFFTSize; +float gFFTScaleFactor = 0; int gNumChannels; int gReadPointer = 0; int gWritePointer = 0; // FFT vars -ne10_fft_cpx_float32_t* timeDomain; +ne10_fft_cpx_float32_t* timeDomainIn; +ne10_fft_cpx_float32_t* timeDomainOut; ne10_fft_cpx_float32_t* frequencyDomain; ne10_fft_cfg_float32_t cfg; @@ -36,14 +38,16 @@ float audioSampleRate, void *userData) { // Retrieve a parameter passed in from the initAudio() call - gFftSize = *(int *)userData; + gFFTSize = *(int *)userData; + gFFTScaleFactor = 1.0f / (float)gFFTSize; gNumChannels = numChannels; - //memset(outSamples, gFftSize, 0.0); // set all to 0 + timeDomainIn = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); + timeDomainOut = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); + frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFFTSize * sizeof (ne10_fft_cpx_float32_t)); + cfg = ne10_fft_alloc_c2c_float32 (gFFTSize); - timeDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFftSize * sizeof (ne10_fft_cpx_float32_t)); - frequencyDomain = (ne10_fft_cpx_float32_t*) NE10_MALLOC (gFftSize * sizeof (ne10_fft_cpx_float32_t)); - cfg = ne10_fft_alloc_c2c_float32 (gFftSize); + memset(timeDomainOut, 0, gFFTSize * sizeof (ne10_fft_cpx_float32_t)); return true; } @@ -57,28 +61,26 @@ uint16_t *matrixIn, uint16_t *matrixOut) { for(int n = 0; n < numAudioFrames; n++) { - timeDomain[gReadPointer].r = (ne10_float32_t) ((audioIn[n*gNumChannels] + audioIn[n*gNumChannels+1])/2); - timeDomain[gReadPointer].i = 0; - gReadPointer++; - } + timeDomainIn[gReadPointer].r = (ne10_float32_t) ((audioIn[n*gNumChannels] + audioIn[n*gNumChannels+1]) * 0.5); + timeDomainIn[gReadPointer].i = 0; - if(gReadPointer>=gFftSize) - { - //FFT - ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomain, cfg->twiddles, cfg->factors, gFftSize, 0); + if(++gReadPointer >= gFFTSize) + { + //FFT + ne10_fft_c2c_1d_float32_neon (frequencyDomain, timeDomainIn, cfg->twiddles, cfg->factors, gFFTSize, 0); - //Do frequency domain stuff + //Do frequency domain stuff - //IFFT - ne10_fft_c2c_1d_float32_neon (timeDomain, frequencyDomain, cfg->twiddles, cfg->factors, gFftSize, 1); + //IFFT + ne10_fft_c2c_1d_float32_neon (timeDomainOut, frequencyDomain, cfg->twiddles, cfg->factors, gFFTSize, 1); - gReadPointer = 0; - gWritePointer = 0; - } + gReadPointer = 0; + gWritePointer = 0; + } - for(int n = 0; n < numAudioFrames; n++) { for(int channel = 0; channel < gNumChannels; channel++) - audioOut[n * gNumChannels + channel] = (float) timeDomain[gWritePointer++].r/gFftSize; + audioOut[n * gNumChannels + channel] = (float) timeDomainOut[gWritePointer].r * gFFTScaleFactor; + gWritePointer++; } } @@ -87,7 +89,8 @@ void cleanup_render() { - NE10_FREE(timeDomain); + NE10_FREE(timeDomainIn); + NE10_FREE(timeDomainOut); NE10_FREE(frequencyDomain); NE10_FREE(cfg); }
--- a/projects/basic/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/basic/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -9,6 +9,7 @@ #include <cstdlib> #include <libgen.h> #include <signal.h> +#include <getopt.h> #include "../../include/RTAudio.h" using namespace std; @@ -22,44 +23,41 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f frequency]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -f frequency: Set the frequency of the oscillator\n"; - cerr << " -m: Enable the matrix (ADC and DAC) as well as audio\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --frequency [-f] frequency: Set the frequency of the oscillator\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int periodSize = 8; // Period size in sensor frames - int verbose = 0; // Verbose printing level + RTAudioSettings settings; // Standard audio settings float frequency = 440.0; // Frequency of oscillator - int useMatrix = 0; // Whether to use the matrix or just audio + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"frequency", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vf:m")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - periodSize = atoi(optarg); - if(periodSize < 1) - periodSize = 1; - break; - case 'v': - verbose = 1; - break; case 'f': frequency = atof(optarg); break; - case 'm': - useMatrix = 1; - break; case '?': default: usage(basename(argv[0])); @@ -67,26 +65,14 @@ } } - - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << periodSize << " and frequency " << frequency << endl; - if(useMatrix) - cout << "Matrix enabled\n"; - else - cout << "Matrix disabled\n"; - } - // Initialise the PRU audio device - if(initAudio(periodSize, useMatrix, &frequency) != 0) { + if(BeagleRT_initAudio(&settings, &frequency) != 0) { cout << "Error: unable to initialise audio" << endl; return -1; } // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -100,14 +86,10 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0;
--- a/projects/basic_analog_output/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/basic_analog_output/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -9,6 +9,7 @@ #include <cstdlib> #include <libgen.h> #include <signal.h> +#include <getopt.h> #include "../../include/RTAudio.h" using namespace std; @@ -22,36 +23,41 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f input] [-a input]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -f frequency: Set frequency of LED fade (default: 1.0)\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --frequency [-f] frequency: Set the frequency of the LED fade (default: 1.0)\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int periodSize = 8; // Period size in sensor frames - int verbose = 0; // Verbose printing level - float frequency = 1.0; // Frequency of LED fades + RTAudioSettings settings; // Standard audio settings + float frequency = 1.0; // Frequency of LED fades + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"frequency", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + + // In this example, audio isn't used so might as well leave speaker muted + settings.beginMuted = 1; // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vf:")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - periodSize = atoi(optarg); - if(periodSize < 1) - periodSize = 1; - break; - case 'v': - verbose = 1; - break; case 'f': frequency = atof(optarg); if(frequency < 0) @@ -66,22 +72,14 @@ } } - - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << periodSize << " and frequency " << frequency << endl; - } - // Initialise the PRU audio device - if(initAudio(periodSize, 1, &frequency) != 0) { + if(BeagleRT_initAudio(&settings, &frequency) != 0) { cout << "Error: unable to initialise audio" << endl; return -1; } // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -95,14 +93,10 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0;
--- a/projects/basic_analog_output/render.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/basic_analog_output/render.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -62,7 +62,7 @@ if(out > MATRIX_MAX) out = MATRIX_MAX; - matrixOut[n * 8 + channel] = (uint16_t)out; + analogWrite(channel, n, out); // Advance by pi/4 (1/8 of a full rotation) for each channel relativePhase += M_PI * 0.25;
--- a/projects/basic_sensor/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/basic_sensor/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -9,6 +9,7 @@ #include <cstdlib> #include <libgen.h> #include <signal.h> +#include <getopt.h> #include "../../include/RTAudio.h" using namespace std; @@ -25,36 +26,39 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f input] [-a input]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -f input: Choose the analog input controlling frequency (0-7; default 0)\n"; - cerr << " -a input: Choose the analog input controlling amplitude (0-7; default 1)\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --frequency [-f] input: Choose the analog input controlling frequency (0-7; default 0)\n"; + cerr << " --amplitude [-a] input: Choose the analog input controlling amplitude (0-7; default 1)\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int periodSize = 8; // Period size in sensor frames - int verbose = 0; // Verbose printing level + RTAudioSettings settings; // Standard audio settings + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"frequency", 1, NULL, 'f'}, + {"amplitude", 1, NULL, 'a'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vf:a:")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hf:a:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - periodSize = atoi(optarg); - if(periodSize < 1) - periodSize = 1; - break; - case 'v': - verbose = 1; - break; case 'f': gSensorInputFrequency = atoi(optarg); if(gSensorInputFrequency < 0 || gSensorInputFrequency > 7) { @@ -76,24 +80,19 @@ } } + // Initialise the PRU audio device + if(BeagleRT_initAudio(&settings, 0) != 0) { + cout << "Error: unable to initialise audio" << endl; + return -1; + } - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << periodSize << endl; + if(settings.verbose) { cout << "--> Frequency on input " << gSensorInputFrequency << endl; cout << "--> Amplitude on input " << gSensorInputAmplitude << endl; } - // Initialise the PRU audio device - if(initAudio(periodSize, 1, 0) != 0) { - cout << "Error: unable to initialise audio" << endl; - return -1; - } - // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -107,14 +106,10 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0;
--- a/projects/basic_sensor/render.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/basic_sensor/render.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -64,8 +64,8 @@ for(int n = 0; n < numAudioFrames; n++) { if(!(n % 2)) { // Even audio samples: update frequency and amplitude from the matrix - frequency = map((float)matrixIn[gSensorInputFrequency], 0, MATRIX_MAX, 100, 1000); - amplitude = (float)matrixIn[gSensorInputAmplitude] / MATRIX_MAX; + frequency = map((float)analogRead(gSensorInputFrequency, n/2), 0, MATRIX_MAX, 100, 1000); + amplitude = (float)analogRead(gSensorInputAmplitude, n/2) / MATRIX_MAX; } float out = amplitude * sinf(gPhase);
--- a/projects/d-box/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/d-box/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -262,7 +262,7 @@ } -void parseArguments(arg_data args) +void parseArguments(arg_data args, RTAudioSettings *settings) { // Default filename; gPartialFilename = strdup("D-Box_sound_250_60_40_h88_2.txt"); @@ -271,12 +271,10 @@ struct option long_option[] = { {"help", 0, NULL, 'h'}, - {"period", 1, NULL, 'p'}, - {"verbose", 1, NULL, 'v'}, {"audioin", 1, NULL, 'i'}, {"file", 1, NULL, 'f'}, {"keyboard", 1, NULL, 'k'}, - {"audio-test", 0, NULL, 'A'}, + {"audio-test", 0, NULL, 'T'}, {"new-sensors", 0, NULL, 'S'}, {"sensor0", 1, NULL, 'Q'}, {"sensor1", 1, NULL, 'R'}, @@ -290,22 +288,18 @@ int morehelp = 0; int tmp = -1; + BeagleRT_defaultSettings(settings); + while (1) { int c; - if ((c = getopt_long(args.argc, args.argv, "hp:vf:ki:sAQ:R:Sl:u:o:n:g:", long_option, NULL)) < 0) + if ((c = BeagleRT_getopt_long(args.argc, args.argv, "hf:ki:sTQ:R:Sl:u:o:n:g:", long_option, settings)) < 0) break; switch (c) { case 'h': morehelp++; break; - case 'p': - gPeriodSize = atoi(optarg); - break; - case 'v': - gVerbose = 1; - break; case 'f': free(gPartialFilename); gPartialFilename = strdup(optarg); @@ -319,7 +313,7 @@ case 's': forceSensors = true; break; - case 'A': + case 'T': useAudioTest = true; break; case 'S': @@ -360,10 +354,14 @@ break; } } + + gPeriodSize = settings->periodSize; + gVerbose = settings->verbose; } int main(int argc, char *argv[]) { + RTAudioSettings settings; // Standard audio settings RT_TASK rtSensorThread; const char rtSensorThreadName[] = "dbox-sensor"; int oscBankHopSize; @@ -371,7 +369,7 @@ // Parse command-line arguments args.argc = argc; args.argv = argv; - parseArguments(args); + parseArguments(args, &settings); setVerboseLevel(gVerbose); if(gVerbose == 1 && useAudioTest) @@ -384,7 +382,7 @@ oscBankHopSize = gOscBanks[gCurrentOscBank]->getHopSize()/gOscBanks[gCurrentOscBank]->getMinSpeed(); // Initialise the audio device - if(initAudio(gPeriodSize, 1, &oscBankHopSize) != 0) + if(BeagleRT_initAudio(&settings, &oscBankHopSize) != 0) return -1; // Initialise the status LED @@ -405,7 +403,7 @@ if(gVerbose == 1) cout << "main() : creating audio thread" << endl; - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -465,12 +463,12 @@ usleep(100000); } - stopAudio(); + BeagleRT_stopAudio(); if(!useAudioTest) rt_task_join(&rtSensorThread); - cleanupAudio(); + BeagleRT_cleanupAudio(); pthread_join( keyboardThread, NULL); pthread_join( logThread, NULL);
--- a/projects/filter_FIR/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/filter_FIR/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -10,14 +10,13 @@ #include <libgen.h> #include <signal.h> #include <string> +#include <getopt.h> #include <sndfile.h> // to load audio files #include "../../include/RTAudio.h" #include "SampleData.h" using namespace std; -int gPeriodSize = 8; // Period size in sensor frames - // Load samples from file int initFile(string file, SampleData *smp)//float *& smp) { @@ -81,44 +80,43 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f frequency]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -m: Enable the matrix (ADC and DAC) as well as audio\n"; - cerr << " -f filename: Name of the file to load (default is \"sample.wav\")\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --file [-f] filename: Name of the file to load (default is \"longsample.wav\")\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int verbose = 0; // Verbose printing level - int useMatrix = 0; // Whether to use the matrix or just audio + RTAudioSettings settings; // Standard audio settings string fileName; // Name of the sample to load SampleData sampleData; // User define structure to pass data retrieved from file to render function sampleData.samples = 0; sampleData.sampleLen = -1; + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"file", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vms:")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - gPeriodSize = atoi(optarg); - if(gPeriodSize < 1) - gPeriodSize = 1; - break; - case 'v': - verbose = 1; - break; - case 'm': - useMatrix = 1; - break; case 'f': fileName = string((char *)optarg); break; @@ -130,18 +128,10 @@ } if(fileName.empty()){ - fileName = "filter/longsample.wav"; + fileName = "longsample.wav"; } - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << gPeriodSize << endl; - if(useMatrix) - cout << "Matrix enabled\n"; - else - cout << "Matrix disabled\n"; + if(settings.verbose) { cout << "Loading file " << fileName << endl; } @@ -152,17 +142,18 @@ return -1; } - if(verbose) + if(settings.verbose) cout << "File contains " << sampleData.sampleLen << " samples" << endl; + // Initialise the PRU audio device - if(initAudio(gPeriodSize, useMatrix, &sampleData) != 0) { + if(BeagleRT_initAudio(&settings, &sampleData) != 0) { cout << "Error: unable to initialise audio" << endl; return -1; } // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -176,15 +167,12 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0; } +
--- a/projects/filter_FIR/render.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/filter_FIR/render.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -36,7 +36,7 @@ bool initialise_trigger(); void trigger_samples(); -extern int gPeriodSize; // Period size in sensor frames +int gPeriodSize; // Period size in sensor frames // initialise_render() is called once before the audio rendering starts. @@ -58,6 +58,7 @@ gReadPtr = -1; gNumChannels = numChannels; + gPeriodSize = numMatrixFramesPerPeriod; initialise_filter();
--- a/projects/filter_IIR/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/filter_IIR/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -10,6 +10,7 @@ #include <libgen.h> #include <signal.h> #include <string> +#include <getopt.h> #include <sndfile.h> // to load audio files #include "../../include/RTAudio.h" #include "SampleData.h" @@ -70,7 +71,6 @@ return 0; } - // Handle Ctrl-C by requesting that the audio rendering stop void interrupt_handler(int var) { @@ -81,46 +81,45 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f frequency]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -m: Enable the matrix (ADC and DAC) as well as audio\n"; - cerr << " -f filename: Name of the file to load (default is \"sample.wav\")\n"; - cerr << " -c freq: Set the cut off frequency of the filter in Hz\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --file [-f] filename: Name of the file to load (default is \"longsample.wav\")\n"; + cerr << " --cutfreq [-c] freq: Set the cut off frequency of the filter in Hz\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int verbose = 0; // Verbose printing level - int periodSize = 8; // Period size in sensor frames - int useMatrix = 0; // Whether to use the matrix or just audio + RTAudioSettings settings; // Standard audio settings string fileName; // Name of the sample to load SampleData sampleData; // User define structure to pass data retrieved from file to render function sampleData.samples = 0; sampleData.sampleLen = -1; + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"cutfreq", 1, NULL, 'c'}, + {"file", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vms:")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hf:c:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - periodSize = atoi(optarg); - if(periodSize < 1) - periodSize = 1; - break; - case 'v': - verbose = 1; - break; - case 'm': - useMatrix = 1; - break; case 'f': fileName = string((char *)optarg); break; @@ -135,18 +134,10 @@ } if(fileName.empty()){ - fileName = "filter/longsample.wav"; + fileName = "longsample.wav"; } - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << periodSize << " and cut-off frequency" << gCutFreq << endl; - if(useMatrix) - cout << "Matrix enabled\n"; - else - cout << "Matrix disabled\n"; + if(settings.verbose) { cout << "Loading file " << fileName << endl; } @@ -157,17 +148,18 @@ return -1; } - if(verbose) + if(settings.verbose) cout << "File contains " << sampleData.sampleLen << " samples" << endl; + // Initialise the PRU audio device - if(initAudio(periodSize, useMatrix, &sampleData) != 0) { + if(BeagleRT_initAudio(&settings, &sampleData) != 0) { cout << "Error: unable to initialise audio" << endl; return -1; } // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -181,15 +173,12 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0; } +
--- a/projects/oscillator_bank/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/oscillator_bank/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -9,6 +9,7 @@ #include <cstdlib> #include <libgen.h> #include <signal.h> +#include <getopt.h> #include "../../include/RTAudio.h" using namespace std; @@ -16,7 +17,6 @@ int gNumOscillators = 32; int gWavetableLength = 1024; - // Handle Ctrl-C by requesting that the audio rendering stop void interrupt_handler(int var) { @@ -26,38 +26,39 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f input] [-a input]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -n oscs: Set the number of oscillators to use (default: 32)\n"; - cerr << " -w length: Set the wavetable length in samples (default: 1024)\n"; - cerr << " -m: Enable the matrix (ADC and DAC) for controlling parameters\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --num-oscillators [-n] oscs: Set the number of oscillators to use (default: 32)\n"; + cerr << " --wavetable [-w] length: Set the wavetable length in samples (default: 1024)\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int periodSize = 8; // Period size in sensor frames - int verbose = 0; // Verbose printing level - int useMatrix = 0; + RTAudioSettings settings; // Standard audio settings + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"num-oscillators", 1, NULL, 'n'}, + {"wavetable", 1, NULL, 'w'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vn:w:m")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hn:w:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - periodSize = atoi(optarg); - if(periodSize < 1) - periodSize = 1; - break; - case 'v': - verbose = 1; - break; case 'n': gNumOscillators = atoi(optarg); if(gNumOscillators <= 0) { @@ -72,9 +73,6 @@ if(gWavetableLength > 16384) gWavetableLength = 16384; break; - case 'm': - useMatrix = 1; - break; case '?': default: usage(basename(argv[0])); @@ -82,26 +80,18 @@ } } - - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << periodSize << endl; - cout << "--> Using " << gNumOscillators << " oscillators and wavetable of " << gWavetableLength << " samples\n"; - cout << "--> Matrix "; - if(useMatrix) cout << "enabled\n"; - else cout << "disabled\n"; - } - // Initialise the PRU audio device - if(initAudio(periodSize, useMatrix, 0) != 0) { + if(BeagleRT_initAudio(&settings, 0) != 0) { cout << "Error: unable to initialise audio" << endl; return -1; } + if(settings.verbose) { + cout << "--> Using " << gNumOscillators << " oscillators and wavetable of " << gWavetableLength << " samples\n"; + } + // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -115,14 +105,10 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0;
--- a/projects/samples/main.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/projects/samples/main.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -10,6 +10,7 @@ #include <libgen.h> #include <signal.h> #include <string> +#include <getopt.h> #include <sndfile.h> // to load audio files #include "../../include/RTAudio.h" #include "SampleData.h" @@ -79,45 +80,43 @@ // Print usage information void usage(const char * processName) { - cerr << "Usage: " << processName << " [-h] [-v] [-p period] [-f frequency]" << endl; - cerr << " -h: Print this menu\n"; - cerr << " -v: Enable verbose messages\n"; - cerr << " -p period: Set the period (hardware buffer) size in sensor frames\n"; - cerr << " -m: Enable the matrix (ADC and DAC) as well as audio\n"; - cerr << " -f filename: Name of the file to load (default is \"sample.wav\")\n"; + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --file [-f] filename: Name of the file to load (default is \"sample.wav\")\n"; + cerr << " --help [-h]: Print this menu\n"; } int main(int argc, char *argv[]) { - int periodSize = 8; // Period size in sensor frames - int verbose = 0; // Verbose printing level - int useMatrix = 0; // Whether to use the matrix or just audio + RTAudioSettings settings; // Standard audio settings string fileName; // Name of the sample to load SampleData sampleData; // User define structure to pass data retrieved from file to render function sampleData.samples = 0; sampleData.sampleLen = -1; + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"file", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + // Parse command-line arguments while (1) { int c; - if ((c = getopt(argc, argv, "hp:vms:")) < 0) + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) break; switch (c) { case 'h': usage(basename(argv[0])); exit(0); - case 'p': - periodSize = atoi(optarg); - if(periodSize < 1) - periodSize = 1; - break; - case 'v': - verbose = 1; - break; - case 'm': - useMatrix = 1; - break; case 'f': fileName = string((char *)optarg); break; @@ -129,18 +128,10 @@ } if(fileName.empty()){ - fileName = "samples/sample.wav"; + fileName = "sample.wav"; } - // Set verbose logging information (optional by using value > 0; default is 0) - setVerboseLevel(verbose); - - if(verbose) { - cout << "Starting with period size " << periodSize << endl; - if(useMatrix) - cout << "Matrix enabled\n"; - else - cout << "Matrix disabled\n"; + if(settings.verbose) { cout << "Loading file " << fileName << endl; } @@ -151,17 +142,18 @@ return -1; } - if(verbose) + if(settings.verbose) cout << "File contains " << sampleData.sampleLen << " samples" << endl; + // Initialise the PRU audio device - if(initAudio(periodSize, useMatrix, &sampleData) != 0) { + if(BeagleRT_initAudio(&settings, &sampleData) != 0) { cout << "Error: unable to initialise audio" << endl; return -1; } // Start the audio device running - if(startAudio()) { + if(BeagleRT_startAudio()) { cout << "Error: unable to start real-time audio" << endl; return -1; } @@ -175,14 +167,10 @@ } // Stop the audio device - stopAudio(); - - if(verbose) { - cout << "Cleaning up..." << endl; - } + BeagleRT_stopAudio(); // Clean up any resources allocated for audio - cleanupAudio(); + BeagleRT_cleanupAudio(); // All done! return 0;