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