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 }