Mercurial > hg > beaglert
comparison examples/04-Audio/samples/render.cpp @ 464:8fcfbfb32aa0 prerelease
Examples reorder with subdirectories. Added header to each project. Moved Doxygen to bottom of render.cpp.
author | Robert Jack <robert.h.jack@gmail.com> |
---|---|
date | Mon, 20 Jun 2016 16:20:38 +0100 |
parents | |
children | b935f890e512 |
comparison
equal
deleted
inserted
replaced
463:c47709e8b5c9 | 464:8fcfbfb32aa0 |
---|---|
1 /* | |
2 ____ _____ _ _ | |
3 | __ )| ____| | / \ | |
4 | _ \| _| | | / _ \ | |
5 | |_) | |___| |___ / ___ \ | |
6 |____/|_____|_____/_/ \_\ | |
7 | |
8 The platform for ultra-low latency audio and sensor processing | |
9 | |
10 http://bela.io | |
11 | |
12 A project of the Augmented Instruments Laboratory within the | |
13 Centre for Digital Music at Queen Mary University of London. | |
14 http://www.eecs.qmul.ac.uk/~andrewm | |
15 | |
16 (c) 2016 Augmented Instruments Laboratory: Andrew McPherson, | |
17 Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack, | |
18 Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved. | |
19 | |
20 The Bela software is distributed under the GNU Lesser General Public License | |
21 (LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt | |
22 */ | |
23 | |
24 | |
25 #include <Bela.h> | |
26 #include <cmath> | |
27 #include "SampleData.h" | |
28 | |
29 SampleData gSampleData; // User defined structure to get complex data from main | |
30 int gReadPtr; // Position of last read sample from file | |
31 | |
32 // Task for handling the update of the frequencies using the matrix | |
33 AuxiliaryTask gTriggerSamplesTask; | |
34 | |
35 bool initialise_trigger(); | |
36 void trigger_samples(); | |
37 | |
38 bool setup(BelaContext *context, void *userData) | |
39 { | |
40 | |
41 // Retrieve a parameter passed in from the initAudio() call | |
42 gSampleData = *(SampleData *)userData; | |
43 | |
44 gReadPtr = -1; | |
45 | |
46 // Initialise auxiliary tasks | |
47 if(!initialise_trigger()) | |
48 return false; | |
49 | |
50 return true; | |
51 } | |
52 | |
53 void render(BelaContext *context, void *userData) | |
54 { | |
55 for(unsigned int n = 0; n < context->audioFrames; n++) { | |
56 float out = 0; | |
57 | |
58 // If triggered... | |
59 if(gReadPtr != -1) | |
60 out += gSampleData.samples[gReadPtr++]; // ...read each sample... | |
61 | |
62 if(gReadPtr >= gSampleData.sampleLen) | |
63 gReadPtr = -1; | |
64 | |
65 for(unsigned int channel = 0; channel < context->audioChannels; channel++) | |
66 context->audioOut[n * context->audioChannels + channel] = out; // ...and put it in both left and right channel | |
67 } | |
68 | |
69 // Request that the lower-priority task run at next opportunity | |
70 Bela_scheduleAuxiliaryTask(gTriggerSamplesTask); | |
71 } | |
72 | |
73 // Initialise the auxiliary task | |
74 // and print info | |
75 | |
76 bool initialise_trigger() | |
77 { | |
78 if((gTriggerSamplesTask = Bela_createAuxiliaryTask(&trigger_samples, 50, "bela-trigger-samples")) == 0) | |
79 return false; | |
80 | |
81 rt_printf("Press 'a' to trigger sample, 's' to stop\n"); | |
82 rt_printf("Press 'q' to quit\n"); | |
83 | |
84 return true; | |
85 } | |
86 | |
87 // This is a lower-priority call to periodically read keyboard input | |
88 // and trigger samples. By placing it at a lower priority, | |
89 // it has minimal effect on the audio performance but it will take longer to | |
90 // complete if the system is under heavy audio load. | |
91 | |
92 void trigger_samples() | |
93 { | |
94 // This is not a real-time task! | |
95 // Cos getchar is a system call, not handled by Xenomai. | |
96 // This task will be automatically down graded. | |
97 | |
98 char keyStroke = '.'; | |
99 | |
100 keyStroke = getchar(); | |
101 while(getchar()!='\n'); // to read the first stroke | |
102 | |
103 switch (keyStroke) | |
104 { | |
105 case 'a': | |
106 gReadPtr = 0; | |
107 break; | |
108 case 's': | |
109 gReadPtr = -1; | |
110 break; | |
111 case 'q': | |
112 gShouldStop = true; | |
113 break; | |
114 default: | |
115 break; | |
116 } | |
117 } | |
118 | |
119 | |
120 void cleanup(BelaContext *context, void *userData) | |
121 { | |
122 delete[] gSampleData.samples; | |
123 } | |
124 | |
125 /* ------------ Project Explantation ------------ */ | |
126 | |
127 /** | |
128 \example 04-samples | |
129 | |
130 Playback WAV files | |
131 ------------------ | |
132 | |
133 This sketch shows how to playback audio samples from a buffer. | |
134 | |
135 An audio file is loaded into a buffer `SampleData` as `gSampleData`. This is | |
136 accessed with a read pointer that is incremented at audio rate within the render | |
137 function: `out += gSampleData.samples[gReadPtr++]`. | |
138 | |
139 Note that the read pointer is stopped from incrementing past the length of the | |
140 `gSampleData`. This is achieved by comparing the read pointer value against the | |
141 sample length which we can access as follows: `gSampleData.sampleLen`. | |
142 | |
143 The sample is triggered by keyboard input: (a) starts sample playback, (s) | |
144 stops sample playback. The triggering is treated as a lower priority task than | |
145 the audio. You can see this at the bottom of the render function: | |
146 `Bela_scheduleAuxiliaryTask(gTriggerSamplesTask)`; | |
147 */ |