Mercurial > hg > beaglert
comparison projects/bucket_brigade_chorus/render.cpp @ 98:9a413516a1fc
Tweaking the PLL you can obtain a virtual analog Bucket Brigade Device Chorus
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Thu, 23 Jul 2015 02:38:09 +0100 |
parents | |
children | 2bdb48d1fca6 |
comparison
equal
deleted
inserted
replaced
97:c44fa102d02b | 98:9a413516a1fc |
---|---|
1 #include <BeagleRT.h> | |
2 #include <Scope.h> | |
3 #include <cmath> | |
4 #include <Utilities.h> | |
5 | |
6 float gPhase1, gPhase2; | |
7 float gFrequency1, gFrequency2; | |
8 float gInverseSampleRate; | |
9 | |
10 Scope scope; //create a scope object | |
11 | |
12 // initialise_render() is called once before the audio rendering starts. | |
13 // Use it to perform any initialisation and allocation which is dependent | |
14 // on the period size or sample rate. | |
15 // | |
16 // userData holds an opaque pointer to a data structure that was passed | |
17 // in from the call to initAudio(). | |
18 // | |
19 // Return true on success; returning false halts the program. | |
20 #include <I2c_Codec.h> | |
21 #include <PRU.h> | |
22 extern I2c_Codec *gAudioCodec; | |
23 extern PRU *gPRU; | |
24 float D=5264; | |
25 #define delayLength 512 | |
26 float delay[delayLength]; | |
27 int writePointer=0; | |
28 int readPointer=writePointer+1; | |
29 AuxiliaryTask updatePll; | |
30 | |
31 void updatePllFunction(){ | |
32 // rt_printf("now\n"); | |
33 gPRU->setGPIOTestPin(); | |
34 gAudioCodec->setPllD(D); | |
35 gPRU->clearGPIOTestPin(); | |
36 } | |
37 | |
38 bool setup(BeagleRTContext *context, void *userData) | |
39 { | |
40 scope.setup(context->audioSampleRate); //call this once in setup to initialise the scope | |
41 | |
42 gInverseSampleRate = 1.0/context->audioSampleRate; | |
43 | |
44 gPhase1 = 0.0; | |
45 gPhase2 = 0.0; | |
46 | |
47 gFrequency1 = 200.0; | |
48 gFrequency2 = 201.0; | |
49 updatePll=BeagleRT_createAuxiliaryTask(&updatePllFunction, 98, "update PLL"); | |
50 for(int n=0; n<delayLength; n++){ | |
51 delay[n]=0; | |
52 } | |
53 return true; | |
54 } | |
55 | |
56 // render() is called regularly at the highest priority by the audio engine. | |
57 // Input and output are given from the audio hardware and the other | |
58 // ADCs and DACs (if available). If only audio is available, numMatrixFrames | |
59 // will be 0. | |
60 | |
61 void render(BeagleRTContext *context, void *userData) | |
62 { | |
63 static int count=0; | |
64 static float lfoPhase=0; | |
65 static float feedback=0; | |
66 int updateRate=8; | |
67 if((count&(updateRate-1))==0 && digitalReadFrame(context,0,P8_07)==GPIO_HIGH){ | |
68 float amplitude=context->analogIn[0]/0.84*4990; | |
69 float rate=context->analogIn[1]*20+0.1; | |
70 lfoPhase+=rate*2*M_PI*updateRate*context->analogFrames/context->audioSampleRate; | |
71 D=amplitude+amplitude*sinf(lfoPhase); | |
72 BeagleRT_scheduleAuxiliaryTask(updatePll); | |
73 if((count&255)==0){ | |
74 rt_printf("gpio: %d\n",digitalReadFrame(context,0,P8_07)); | |
75 rt_printf("D: %.0f\n", D); | |
76 rt_printf("rate: %f\n", rate/2); | |
77 rt_printf("amplitude: %.3f\n", amplitude); | |
78 rt_printf("feedback: %.3f\n\n", feedback); | |
79 } | |
80 } | |
81 count++; | |
82 | |
83 for(unsigned int n = 0; n < context->audioFrames; n++) { | |
84 feedback=context->analogIn[n/2*context->analogChannels+2]/0.84*1.2; | |
85 if(digitalReadFrame(context,n,P8_08)==GPIO_LOW) | |
86 feedback=0; | |
87 delay[writePointer++]=context->audioIn[n*context->audioChannels+0] + delay[readPointer]*feedback; | |
88 context->audioOut[n*context->audioChannels+0]=context->audioIn[n*context->audioChannels+0]+delay[readPointer++]; | |
89 // context->audioOut[n*context->audioChannels+1]=sinf(gPhase1); | |
90 context->analogOut[n/2*context->analogChannels+0]=D/10000; | |
91 if(writePointer>=delayLength) | |
92 writePointer-=delayLength; | |
93 if(readPointer>=delayLength) | |
94 readPointer-=delayLength; | |
95 | |
96 gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate; | |
97 gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate; | |
98 if(gPhase1 > 2.0 * M_PI) | |
99 gPhase1 -= 2.0 * M_PI; | |
100 if(gPhase2 > 2.0 * M_PI) | |
101 gPhase2 -= 2.0 * M_PI; | |
102 | |
103 } | |
104 } | |
105 | |
106 // cleanup_render() is called once at the end, after the audio has stopped. | |
107 // Release any resources that were allocated in initialise_render(). | |
108 | |
109 void cleanup(BeagleRTContext *context, void *userData) | |
110 { | |
111 | |
112 } |