annotate projects/samples/render.cpp @ 24:ad5cd8dd99b3 bbb_network

UDP communication in place, pre-alpha
author Giulio Moro <giuliomoro@yahoo.it>
date Fri, 08 May 2015 11:12:13 +0100
parents 06f93bef7dd2
children a6d223473ea2
rev   line source
victor@1 1 /*
victor@1 2 * render.cpp
victor@1 3 *
victor@1 4 * Created on: Oct 24, 2014
victor@1 5 * Author: Andrew McPherson and Victor Zappi
victor@1 6 */
victor@1 7
victor@1 8
victor@1 9 #include "../../include/render.h"
victor@1 10 #include "../../include/RTAudio.h" // to schedule lower prio parallel process
victor@1 11 #include <rtdk.h>
victor@1 12 #include <cmath>
victor@1 13 #include <stdio.h>
victor@1 14 #include "SampleData.h"
victor@1 15
victor@1 16 SampleData gSampleData; // User defined structure to get complex data from main
victor@1 17 int gReadPtr; // Position of last read sample from file
victor@1 18
victor@1 19 // Task for handling the update of the frequencies using the matrix
victor@1 20 AuxiliaryTask gTriggerSamplesTask;
victor@1 21
victor@1 22 bool initialise_trigger();
victor@1 23 void trigger_samples();
victor@1 24
victor@1 25 // initialise_render() is called once before the audio rendering starts.
victor@1 26 // Use it to perform any initialisation and allocation which is dependent
victor@1 27 // on the period size or sample rate.
victor@1 28 //
victor@1 29 // userData holds an opaque pointer to a data structure that was passed
victor@1 30 // in from the call to initAudio().
victor@1 31 //
victor@1 32 // Return true on success; returning false halts the program.
victor@1 33
andrewm@14 34 bool initialise_render(int numMatrixChannels, int numAudioChannels,
andrewm@14 35 int numMatrixFramesPerPeriod,
andrewm@14 36 int numAudioFramesPerPeriod,
andrewm@14 37 float matrixSampleRate, float audioSampleRate,
andrewm@14 38 void *userData)
victor@1 39 {
victor@1 40
victor@1 41 // Retrieve a parameter passed in from the initAudio() call
victor@1 42 gSampleData = *(SampleData *)userData;
victor@1 43
victor@1 44 gReadPtr = -1;
victor@1 45
victor@1 46 // Initialise auxiliary tasks
victor@1 47 if(!initialise_trigger())
victor@1 48 return false;
victor@1 49
victor@1 50 return true;
victor@1 51 }
victor@1 52
victor@1 53 // render() is called regularly at the highest priority by the audio engine.
victor@1 54 // Input and output are given from the audio hardware and the other
victor@1 55 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
victor@1 56 // will be 0.
victor@1 57
victor@1 58 void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut,
victor@1 59 uint16_t *matrixIn, uint16_t *matrixOut)
victor@1 60 {
victor@1 61 for(int n = 0; n < numAudioFrames; n++) {
victor@1 62 float out = 0;
victor@1 63
victor@1 64 // If triggered...
victor@1 65 if(gReadPtr != -1)
victor@1 66 out += gSampleData.samples[gReadPtr++]; // ...read each sample...
victor@1 67
victor@1 68 if(gReadPtr >= gSampleData.sampleLen)
victor@1 69 gReadPtr = -1;
victor@1 70
andrewm@14 71 for(int channel = 0; channel < gNumAudioChannels; channel++)
andrewm@14 72 audioOut[n * gNumAudioChannels + channel] = out; // ...and put it in both left and right channel
victor@1 73 }
victor@1 74
victor@1 75 // Request that the lower-priority task run at next opportunity
victor@1 76 scheduleAuxiliaryTask(gTriggerSamplesTask);
victor@1 77 }
victor@1 78
victor@1 79 // Initialise the auxiliary task
victor@1 80 // and print info
victor@1 81
victor@1 82 bool initialise_trigger()
victor@1 83 {
victor@1 84 if((gTriggerSamplesTask = createAuxiliaryTaskLoop(&trigger_samples, 50, "beaglert-trigger-samples")) == 0)
victor@1 85 return false;
victor@1 86
victor@1 87 rt_printf("Press 'a' to trigger sample, 's' to stop\n");
victor@1 88 rt_printf("Press 'q' to quit\n");
victor@1 89
victor@1 90 return true;
victor@1 91 }
victor@1 92
victor@1 93 // This is a lower-priority call to periodically read keyboard input
victor@1 94 // and trigger samples. By placing it at a lower priority,
victor@1 95 // it has minimal effect on the audio performance but it will take longer to
victor@1 96 // complete if the system is under heavy audio load.
victor@1 97
victor@1 98 void trigger_samples()
victor@1 99 {
victor@1 100 // This is not a real-time task!
victor@1 101 // Cos getchar is a system call, not handled by Xenomai.
victor@1 102 // This task will be automatically down graded.
victor@1 103
victor@1 104 char keyStroke = '.';
victor@1 105
victor@1 106 keyStroke = getchar();
victor@1 107 while(getchar()!='\n'); // to read the first stroke
victor@1 108
victor@1 109 switch (keyStroke)
victor@1 110 {
victor@1 111 case 'a':
victor@1 112 gReadPtr = 0;
victor@1 113 break;
victor@1 114 case 's':
victor@1 115 gReadPtr = -1;
victor@1 116 break;
victor@1 117 case 'q':
victor@1 118 gShouldStop = true;
victor@1 119 break;
victor@1 120 default:
victor@1 121 break;
victor@1 122 }
victor@1 123 }
victor@1 124
victor@1 125
victor@1 126
victor@1 127 // cleanup_render() is called once at the end, after the audio has stopped.
victor@1 128 // Release any resources that were allocated in initialise_render().
victor@1 129
victor@1 130 void cleanup_render()
victor@1 131 {
victor@1 132 delete[] gSampleData.samples;
victor@1 133 }