# HG changeset patch # User Giulio Moro # Date 1430406167 -3600 # Node ID 31503d9de1019a34e8413a173712d112e837f319 # Parent 85e8b08a7471ee75a27b7bb1a8f645080582f12a - digitalWrite and analogWrite macros are now persistent: they write a value on the given channel from the current frame to the end of the buffer. When this is not needed you can use digitalWriteFrame and analogWriteFrame instead. - included the matrix_gpio_demo code - the Eclipe project is somehow broken diff -r 85e8b08a7471 -r 31503d9de101 .cproject --- a/.cproject Mon Apr 27 18:27:04 2015 +0100 +++ b/.cproject Thu Apr 30 16:02:47 2015 +0100 @@ -5,16 +5,16 @@ - + - + @@ -29,7 +29,9 @@ @@ -83,12 +93,12 @@ - + diff -r 85e8b08a7471 -r 31503d9de101 include/Utilities.h --- a/include/Utilities.h Mon Apr 27 18:27:04 2015 +0100 +++ b/include/Utilities.h Thu Apr 30 16:02:47 2015 +0100 @@ -16,18 +16,31 @@ // Read an analog input from input pin p at frame f #define analogRead(p, f) (matrixIn[(f)*gNumMatrixChannels + (p)]) // Write an analog output frame at output pin p, frame f, to value v -#define analogWrite(p, f, v) (matrixOut[(f)*gNumMatrixChannels + (p)] = (uint16_t)(v)) +#define analogWriteFrame(p, f, v) (matrixOut[(f)*gNumMatrixChannels + (p)] = (v)) +#define analogWrite(pin, frame, value) \ +(({do {\ + for (int _privateI=(frame); _privateI>(bit))&1) #define changeBit(word,bit,value) ((clearBit((word),(bit))) | ((value)<<(bit))) //matrixGpio API: -#define setDigitalDirection(pin,frame,direction) matrixGpio[(frame)]=changeBit(matrixGpio[(frame)],(pin),(direction)) +#define setDigitalDirectionFrame(pin,frame,direction) matrixGpio[(frame)]=changeBit(matrixGpio[(frame)],(pin),(direction)) +#define setDigitalDirection(pin,frame,direction) (for(int _privateI=(frame);_privateI +#include +#include +#include +#include +#include "../include/RTAudio.h" +#include +#include +#include + +using namespace std; + +// Handle Ctrl-C by requesting that the audio rendering stop +void interrupt_handler(int var) +{ + gShouldStop = true; +} + +// Print usage information +void usage(const char * processName) +{ + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --help [-h]: Print this menu\n"; +} + +int main(int argc, char *argv[]) +{ + RTAudioSettings settings; // Standard audio settings + float frequency = 1000.0; // Frequency of crossover + + 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 = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) + break; + switch (c) { + case 'h': + usage(basename(argv[0])); + exit(0); + case 'f': + frequency = atof(optarg); + if(frequency < 20.0) + frequency = 20.0; + if(frequency > 5000.0) + frequency = 5000.0; + break; + case '?': + default: + usage(basename(argv[0])); + exit(1); + } + } + + // Initialise the PRU audio device + if(BeagleRT_initAudio(&settings, &frequency) != 0) { + cout << "Error: unable to initialise audio" << endl; + return -1; + } + + // Start the audio device running + if(BeagleRT_startAudio()) { + cout << "Error: unable to start real-time audio" << endl; + return -1; + } + + // Set up interrupt handler to catch Control-C + signal(SIGINT, interrupt_handler); + signal(SIGTERM, interrupt_handler); + + // Run until told to stop + while(!gShouldStop) { + usleep(100000); + } + + // Stop the audio device + BeagleRT_stopAudio(); + + // Clean up any resources allocated for audio + BeagleRT_cleanupAudio(); + + // All done! + return 0; +} diff -r 85e8b08a7471 -r 31503d9de101 projects/matrix_gpio_demo/render.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/matrix_gpio_demo/render.cpp Thu Apr 30 16:02:47 2015 +0100 @@ -0,0 +1,81 @@ +/* + * + * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover + * using the BeagleBone Black. + * + * Andrew McPherson and Victor Zappi + * Queen Mary, University of London + */ + +#include "../include/render.h" +#include +#include + +/* TASK: declare any global variables you need here */ + +// initialise_render() is called once before the audio rendering starts. +// Use it to perform any initialisation and allocation which is dependent +// on the period size or sample rate. +// +// userData holds an opaque pointer to a data structure that was passed +// in from the call to initAudio(). +// +// Return true on success; returning false halts the program. +int gNumMatrixGpioFrames=0; +bool initialise_render(int numMatrixChannels, int numMatrixGpioChannels, int numAudioChannels, + int numMatrixFramesPerPeriod, + int numAudioFramesPerPeriod, + float matrixSampleRate, float audioSampleRate, + void *userData) +{ + gNumMatrixChannels=numMatrixChannels; + return true; +} + +// render() is called regularly at the highest priority by the audio engine. +// Input and output are given from the audio hardware and the other +// ADCs and DACs (if available). If only audio is available, numMatrixFrames +// will be 0. + +long int gCountFrames=0; +void render(int numMatrixFrames, int numMatrixGpioFrames, int numAudioFrames, float *audioIn, float *audioOut, + float *matrixIn, float *matrixOut, uint32_t *matrixGpio) +/* + * Hey, expect buffer underruns to happen here, as we are doing lots of printfs + * */ +{ + gNumMatrixGpioFrames=numMatrixGpioFrames; + if(gCountFrames==0){ //this will be executed only on the first call to render(), but the bits will go through this cycle for every subsequent buffer + // that is, P8_29 will pulse at the beginning of each buffer + } + for(int i=1; i