annotate projects/analogDigitalDemo/render.cpp @ 45:579c86316008 newapi

Major API overhaul. Moved to a single data structure for handling render functions. Functionally, generally similar except for scheduling within PRU loop function, which now uses interrupts from the PRU rather than polling. This requires an updated kernel.
author andrewm
date Thu, 28 May 2015 14:35:55 -0400
parents 83baffda5786
children a6d223473ea2
rev   line source
giuliomoro@23 1 /*
giuliomoro@19 2 *
giuliomoro@19 3 * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover
giuliomoro@19 4 * using the BeagleBone Black.
giuliomoro@19 5 *
giuliomoro@19 6 * Andrew McPherson and Victor Zappi
giuliomoro@19 7 * Queen Mary, University of London
giuliomoro@19 8 */
giuliomoro@19 9
andrewm@22 10 #include "../../include/render.h"
giuliomoro@19 11 #include <cmath>
giuliomoro@19 12 #include <rtdk.h>
giuliomoro@19 13
giuliomoro@19 14 /* TASK: declare any global variables you need here */
giuliomoro@19 15
giuliomoro@19 16 // initialise_render() is called once before the audio rendering starts.
giuliomoro@19 17 // Use it to perform any initialisation and allocation which is dependent
giuliomoro@19 18 // on the period size or sample rate.
giuliomoro@19 19 //
giuliomoro@19 20 // userData holds an opaque pointer to a data structure that was passed
giuliomoro@19 21 // in from the call to initAudio().
giuliomoro@19 22 //
giuliomoro@19 23 // Return true on success; returning false halts the program.
giuliomoro@20 24 int gNumDigitalFrames=0;
giuliomoro@20 25 bool initialise_render(int numAnalogChannels, int numDigitalChannels, int numAudioChannels,
giuliomoro@20 26 int numAnalogFramesPerPeriod,
giuliomoro@19 27 int numAudioFramesPerPeriod,
giuliomoro@20 28 float analogSampleRate, float audioSampleRate,
giuliomoro@33 29 void *userData, RTAudioSettings* settings)
giuliomoro@19 30 {
giuliomoro@20 31 gNumAnalogChannels=numAnalogChannels;
giuliomoro@23 32 gNumDigitalChannels=numDigitalChannels;
giuliomoro@19 33 return true;
giuliomoro@19 34 }
giuliomoro@19 35
giuliomoro@19 36 // render() is called regularly at the highest priority by the audio engine.
giuliomoro@19 37 // Input and output are given from the audio hardware and the other
giuliomoro@20 38 // ADCs and DACs (if available). If only audio is available, numAnalogFrames
giuliomoro@19 39 // will be 0.
giuliomoro@19 40
giuliomoro@19 41 long int gCountFrames=0;
giuliomoro@20 42 void render(int numAnalogFrames, int numDigitalFrames, int numAudioFrames, float *audioIn, float *audioOut,
giuliomoro@20 43 float *analogIn, float *analogOut, uint32_t *digital)
giuliomoro@19 44 /*
giuliomoro@23 45 we assume that gNumAnalogChannels=8, numAnalogFrames==8 and numDigitalFrames==numAudioFrames
giuliomoro@19 46 * */
giuliomoro@19 47 {
giuliomoro@23 48 if((gCountFrames&31)==0){ //every 32 frames...
giuliomoro@23 49 //ANALOG channels
giuliomoro@23 50 analogWrite(0, 0, analogRead(0,0)); // read the input0 at frame0 and write it to output0 frame0. Using analogWrite will fill the rest of the buffer with the same value
giuliomoro@23 51 // The value at the last frame will persist through the successive buffers until is set again.
giuliomoro@23 52 // This effectively is a pass-through with downsampling by 32 times
giuliomoro@23 53 analogWrite(3, 0, 1.0); // write 1.0 to channel3 from frame0 to the end of the buffer
giuliomoro@23 54 analogWrite(3, 4, 0.1); // write 0.1 to channel3 from frame4 to the end of the buffer
giuliomoro@23 55 analogWriteFrame(3,6,0.2); //write 0.2 to channel3 only on frame 6
giuliomoro@23 56 //this buffer for channel 3 will look like this: 1 1 1 1 0.1 0.1 0.2 0.1
giuliomoro@23 57 //the next buffers for channel 3 will be filled up with 0.1 ....
giuliomoro@23 58 //DIGITAL channels
giuliomoro@23 59 digitalWrite(P8_07,0,GPIO_HIGH); //sets all the frames to HIGH for channel 0
giuliomoro@23 60 digitalWriteFrame(P8_07,4,GPIO_LOW); //only frame 4 will be LOW for channel 0
giuliomoro@23 61 // in this buffer the frames of channel 0 will look like this: 1 1 1 1 0 1 1 1 ...... 1
giuliomoro@23 62 // in the next buffer each frame of channel 0 will be initialized to 1 (the last value of this buffer)
giuliomoro@23 63 digitalWrite(P8_08,0,GPIO_HIGH);
giuliomoro@23 64 digitalWrite(P8_08,2,GPIO_LOW);
giuliomoro@23 65 digitalWrite(P8_08,4,GPIO_HIGH);
giuliomoro@23 66 digitalWrite(P8_08,5,GPIO_LOW);
giuliomoro@33 67 setDigitalDirection(P9_16,0,GPIO_INPUT); // set channel 10 to input
giuliomoro@23 68 // in this buffer the frames of channel 1 will look like this: 1 1 0 0 1 0 0 0 .... 0
giuliomoro@23 69 // in the next buffer each frame of channel 1 will be initialized to 0 (the last value of this buffer)
giuliomoro@19 70 }
giuliomoro@23 71 for(int n=0; n<numAudioFrames; n++){
giuliomoro@23 72 for(int c=0; c<gNumAudioChannels; c++){
giuliomoro@23 73 audioOut[n*gNumAudioChannels + c]=audioIn[n*gNumAudioChannels + c];
giuliomoro@23 74 }
giuliomoro@33 75 //use digital channels 2-8 to create a 7 bit binary counter
giuliomoro@33 76 digital[n]=digital[n] & (~0b111111100); // set to zero (GPIO_OUTPUT) the bits in the lower word
giuliomoro@33 77 digital[n]=digital[n] & ((~0b111111100<<16) | 0xffff ); //initialize to zero the bits in the higher word (output value)
giuliomoro@33 78 digital[n]=digital[n] | ( ((gCountFrames&0b1111111)<<(16+2)) ) ; // set the bits in the higher word to the desired output value, keeping the lower word unchanged
giuliomoro@33 79 digitalWriteFrame(P8_29,n,digitalRead(P8_30,n)); // echo the input from from channel 15 to channel 14
giuliomoro@33 80 digitalWriteFrame(P8_28,n,digitalRead(P9_16,n)); // echo the input from from channel 10 to channel 13
giuliomoro@33 81 setDigitalDirection(P8_30,0,GPIO_INPUT); //set channel 15 to input
giuliomoro@33 82 gCountFrames++;
giuliomoro@19 83 }
giuliomoro@23 84
giuliomoro@23 85 for(int n=0; n<numAnalogFrames; n++){
giuliomoro@23 86 analogWriteFrame(1,n,(gCountFrames&8191)/8192.0); // writes a single frame. channel 1 is a ramp that follows gCountFrames
giuliomoro@23 87 analogWriteFrame(2,n,analogRead(2,n)); // writes a single frame. channel2 is just a passthrough
giuliomoro@23 88 // rt_printf("Analog out frame %d :",n);
giuliomoro@23 89 // for(int c=0; c<gNumAnalogChannels; c++)
giuliomoro@23 90 // rt_printf("%.1f ",analogOut[n*gNumAnalogChannels + c]);
giuliomoro@23 91 // rt_printf("\n");
giuliomoro@19 92 }
giuliomoro@23 93 return;
giuliomoro@23 94
giuliomoro@19 95 }
giuliomoro@19 96 // cleanup_render() is called once at the end, after the audio has stopped.
giuliomoro@19 97 // Release any resources that were allocated in initialise_render().
giuliomoro@19 98
giuliomoro@19 99 void cleanup_render()
giuliomoro@19 100 {
giuliomoro@19 101 /* TASK:
giuliomoro@19 102 * If you allocate any memory, be sure to release it here.
giuliomoro@19 103 * You may or may not need anything in this function, depending
giuliomoro@19 104 * on your implementation.
giuliomoro@19 105 */
giuliomoro@19 106 }