robert@372
|
1 /*
|
robert@372
|
2 ____ _____ _ _
|
robert@372
|
3 | __ )| ____| | / \
|
robert@372
|
4 | _ \| _| | | / _ \
|
robert@372
|
5 | |_) | |___| |___ / ___ \
|
robert@372
|
6 |____/|_____|_____/_/ \_\.io
|
robert@372
|
7
|
robert@372
|
8 */
|
robert@372
|
9
|
robert@372
|
10 /**
|
robert@372
|
11 \example 1_scope_basic
|
robert@372
|
12
|
robert@372
|
13 Oscilloscope in-browser
|
robert@372
|
14 -----------------------
|
robert@372
|
15
|
robert@372
|
16 This example demonstrates the scope feature of the IDE.
|
robert@372
|
17
|
robert@372
|
18 The scope is instantiated at the top of the file via `Scope scope;`
|
robert@372
|
19
|
robert@372
|
20 In `setup()` we define how many channels the scope should have and the sample
|
robert@372
|
21 rate that it should run at via `scope.setup(3, context->audioSampleRate)`.
|
robert@372
|
22
|
robert@372
|
23 In `render()` we choose what the scope log via `scope.log(out, out2, out3)`.
|
robert@372
|
24 In this example the scope is logging three sine waves with different phases. To see
|
robert@372
|
25 the output click on the <b>Open Scope</b> button.
|
robert@372
|
26
|
robert@372
|
27 An additional option is to set the trigger of the oscilloscope from within `render()`.
|
robert@372
|
28 In this example we are triggering the scope when oscillator 1 becomes less than
|
robert@372
|
29 oscillator 2 via `scope.trigger()`. Note that this functionality only takes effect
|
robert@372
|
30 when the triggering mode is set to custom in the scope UI.
|
robert@372
|
31 */
|
robert@372
|
32
|
giuliomoro@301
|
33 #include <Bela.h>
|
l@273
|
34 #include <Scope.h>
|
l@273
|
35 #include <cmath>
|
l@273
|
36
|
l@273
|
37 // set the frequency of the oscillators
|
l@273
|
38 float gFrequency = 110.0;
|
l@273
|
39 float gPhase;
|
l@273
|
40 float gInverseSampleRate;
|
l@273
|
41
|
l@273
|
42 // instantiate the scope
|
l@273
|
43 Scope scope;
|
l@273
|
44
|
giuliomoro@301
|
45 bool setup(BelaContext *context, void *userData)
|
l@273
|
46 {
|
l@273
|
47 // tell the scope how many channels and the sample rate
|
l@273
|
48 scope.setup(3, context->audioSampleRate);
|
l@273
|
49
|
l@273
|
50 gPhase = 0;
|
l@273
|
51 gInverseSampleRate = 1.0f/context->audioSampleRate;
|
l@273
|
52
|
l@273
|
53 return true;
|
l@273
|
54 }
|
l@273
|
55
|
l@273
|
56 float lastOut = 0.0;
|
l@273
|
57 float lastOut2 = 0.0;
|
giuliomoro@301
|
58 void render(BelaContext *context, void *userData)
|
l@273
|
59 {
|
l@273
|
60 // iterate over the audio frames and create three oscillators, seperated in phase by PI/2
|
l@273
|
61 for (unsigned int n=0; n<context->audioFrames; n++){
|
l@273
|
62 float out = 0.8f * sinf(gPhase);
|
l@273
|
63 float out2 = 0.8f * sinf(gPhase - M_PI/2);
|
l@273
|
64 float out3 = 0.8f * sinf(gPhase + M_PI/2);
|
l@273
|
65 gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
|
l@273
|
66 if(gPhase > 2.0 * M_PI)
|
l@273
|
67 gPhase -= 2.0 * M_PI;
|
l@273
|
68
|
l@273
|
69 // log the three oscillators to the scope
|
l@273
|
70 scope.log(out, out2, out3);
|
l@273
|
71
|
l@273
|
72 // optional - tell the scope to trigger when oscillator 1 becomes less than oscillator 2
|
l@273
|
73 // note this has no effect unless trigger mode is set to custom in the scope UI
|
l@273
|
74 if (lastOut >= lastOut2 && out < out2){
|
l@273
|
75 scope.trigger();
|
l@273
|
76 }
|
l@273
|
77
|
l@273
|
78 lastOut = out;
|
l@273
|
79 lastOut2 = out2;
|
l@273
|
80 }
|
l@273
|
81 }
|
l@273
|
82
|
giuliomoro@301
|
83 void cleanup(BelaContext *context, void *userData)
|
l@273
|
84 {
|
l@273
|
85
|
l@273
|
86 }
|