This is a part of the Kinetiszer project.
flange.c@1:8ae4ab73ca6a, 2014-10-28 (annotated)
- Committer:
- Clemo
- Date:
- Tue Oct 28 20:09:12 2014 +0000
- Revision:
- 1:8ae4ab73ca6a
- Parent:
- 0:cb80470434eb
First publication (untested)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Clemo | 0:cb80470434eb | 1 | /* |
Clemo | 0:cb80470434eb | 2 | Copyright 2013 Paul Soulsby www.soulsbysynths.com |
Clemo | 0:cb80470434eb | 3 | This file is part of Atmegatron. |
Clemo | 0:cb80470434eb | 4 | |
Clemo | 0:cb80470434eb | 5 | Atmegatron is free software: you can redistribute it and/or modify |
Clemo | 0:cb80470434eb | 6 | it under the terms of the GNU General Public License as published by |
Clemo | 0:cb80470434eb | 7 | the Free Software Foundation, either version 3 of the License, or |
Clemo | 0:cb80470434eb | 8 | (at your option) any later version. |
Clemo | 0:cb80470434eb | 9 | |
Clemo | 0:cb80470434eb | 10 | Atmegatron is distributed in the hope that it will be useful, |
Clemo | 0:cb80470434eb | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
Clemo | 0:cb80470434eb | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Clemo | 0:cb80470434eb | 13 | GNU General Public License for more details. |
Clemo | 0:cb80470434eb | 14 | |
Clemo | 0:cb80470434eb | 15 | You should have received a copy of the GNU General Public License |
Clemo | 0:cb80470434eb | 16 | along with Atmegatron. If not, see <http://www.gnu.org/licenses/>. |
Clemo | 0:cb80470434eb | 17 | */ |
Clemo | 0:cb80470434eb | 18 | |
Clemo | 0:cb80470434eb | 19 | //*******PHASER - referred to as Flanger in code*************** |
Clemo | 0:cb80470434eb | 20 | //Adds delayed copy of waveform to output + feedback |
Clemo | 0:cb80470434eb | 21 | |
Clemo | 0:cb80470434eb | 22 | #include "atmegatron.h" |
Clemo | 0:cb80470434eb | 23 | |
Clemo | 0:cb80470434eb | 24 | |
Clemo | 0:cb80470434eb | 25 | byte flange_lfoamt = 0; //set maximum wave offset (0-31) |
Clemo | 0:cb80470434eb | 26 | //signed char flange_store[WAVE_LEN*2]; //buffer to store 2x waveform + feedback. need 2x waveform when delay = max (31) |
Clemo | 0:cb80470434eb | 27 | sample_t flange_store[WAVE_LEN*2]; //buffer to store 2x waveform + feedback. need 2x waveform when delay = max (31) |
Clemo | 0:cb80470434eb | 28 | sample_t flange_store_ch2[WAVE_LEN*2]; //buffer to store 2x waveform + feedback. need 2x waveform when delay = max (31) |
Clemo | 0:cb80470434eb | 29 | |
Clemo | 0:cb80470434eb | 30 | //lets and gets |
Clemo | 0:cb80470434eb | 31 | void Flange_Let_LFOAmt(byte newamt) |
Clemo | 0:cb80470434eb | 32 | { |
Clemo | 0:cb80470434eb | 33 | if (newamt!=flange_lfoamt) //if new value different to current |
Clemo | 0:cb80470434eb | 34 | { |
Clemo | 0:cb80470434eb | 35 | if (flange_lfoamt==0) //if new value is off: |
Clemo | 0:cb80470434eb | 36 | { |
Clemo | 0:cb80470434eb | 37 | Flange_ClearBuffer(); //clear flange buffer. |
Clemo | 0:cb80470434eb | 38 | } |
Clemo | 0:cb80470434eb | 39 | flange_lfoamt = newamt; |
Clemo | 0:cb80470434eb | 40 | } |
Clemo | 0:cb80470434eb | 41 | } |
Clemo | 0:cb80470434eb | 42 | |
Clemo | 0:cb80470434eb | 43 | |
Clemo | 0:cb80470434eb | 44 | byte Flange_Get_LFOAmt(void) |
Clemo | 0:cb80470434eb | 45 | { |
Clemo | 0:cb80470434eb | 46 | return flange_lfoamt; |
Clemo | 0:cb80470434eb | 47 | } |
Clemo | 0:cb80470434eb | 48 | |
Clemo | 0:cb80470434eb | 49 | |
Clemo | 0:cb80470434eb | 50 | //Flanger meat |
Clemo | 0:cb80470434eb | 51 | void Flange_Process(void) |
Clemo | 0:cb80470434eb | 52 | { |
Clemo | 0:cb80470434eb | 53 | byte i; |
Clemo | 0:cb80470434eb | 54 | sample_t s, o; |
Clemo | 0:cb80470434eb | 55 | long curindex, maxindex; |
Clemo | 0:cb80470434eb | 56 | //if flanger (phaser) on: |
Clemo | 0:cb80470434eb | 57 | if (flange_lfoamt > 0) |
Clemo | 0:cb80470434eb | 58 | { |
Clemo | 0:cb80470434eb | 59 | maxindex = (WAVE_LEN - flange_lfoamt); //intermediate value (don't -1 from maxindex, so min flangestore offset is 1 (not 0) i.e. always offset by some amount) |
Clemo | 0:cb80470434eb | 60 | curindex = ((127 - LFO_Get_Level()) * (long)flange_lfoamt * 8225 >> 21) + maxindex; //calculate delay length of delayed waveform (8225 >> 21 is way of doing / 255, without using slow divide) |
Clemo | 0:cb80470434eb | 61 | //****METHOD WITH FEEDBACK |
Clemo | 0:cb80470434eb | 62 | //cycle through wave form |
Clemo | 0:cb80470434eb | 63 | for (i=0; i<WAVE_LEN; i++) |
Clemo | 0:cb80470434eb | 64 | { |
Clemo | 0:cb80470434eb | 65 | s = Wave_Get_Process(i); //get sample |
Clemo | 0:cb80470434eb | 66 | o = (s >> 1) + (flange_store[i+curindex] >> 1); //divide amp of sample / 2. Then add offset sample from flange_store / 2. (both samples divided / 2 to prevent output clipping when zero offset) |
Clemo | 0:cb80470434eb | 67 | Wave_Let_Process(i, o); //write back to wave table |
Clemo | 0:cb80470434eb | 68 | } |
Clemo | 0:cb80470434eb | 69 | //now waveform processed, cycle through waveform again writing to flange_store |
Clemo | 0:cb80470434eb | 70 | for (i=0; i<WAVE_LEN; i++) |
Clemo | 0:cb80470434eb | 71 | { |
Clemo | 0:cb80470434eb | 72 | flange_store[i] = Wave_Get_Process(i); |
Clemo | 0:cb80470434eb | 73 | flange_store[i+WAVE_LEN] = flange_store[i]; |
Clemo | 0:cb80470434eb | 74 | } |
Clemo | 0:cb80470434eb | 75 | //******METHOD WITHOUT FEEDBACK |
Clemo | 0:cb80470434eb | 76 | // for(i=0;i<WAVE_LEN;i++){ |
Clemo | 0:cb80470434eb | 77 | // flange_store[i] = Wave_Get_Process(i); |
Clemo | 0:cb80470434eb | 78 | // flange_store[i+WAVE_LEN] = flange_store[i]; |
Clemo | 0:cb80470434eb | 79 | // } |
Clemo | 0:cb80470434eb | 80 | // for(i=0;i<WAVE_LEN;i++){ |
Clemo | 0:cb80470434eb | 81 | // o = (flange_store[i] >> 1) + (flange_store[i+curindex] >> 1); |
Clemo | 0:cb80470434eb | 82 | // Wave_Let_Process(i, o); |
Clemo | 0:cb80470434eb | 83 | // } |
Clemo | 0:cb80470434eb | 84 | } |
Clemo | 0:cb80470434eb | 85 | } |
Clemo | 0:cb80470434eb | 86 | |
Clemo | 0:cb80470434eb | 87 | |
Clemo | 0:cb80470434eb | 88 | void Flange_ClearBuffer(void) |
Clemo | 0:cb80470434eb | 89 | { |
Clemo | 0:cb80470434eb | 90 | // Clear buffer. Used to stop feedback making sound when key released |
Clemo | 0:cb80470434eb | 91 | // (this was a problem when flange was combined with distortion). |
Clemo | 0:cb80470434eb | 92 | memset(flange_store,0,sizeof(flange_store)); //quicker than loop |
Clemo | 0:cb80470434eb | 93 | // CPV addition. |
Clemo | 0:cb80470434eb | 94 | memset(flange_store_ch2,0,sizeof(flange_store_ch2)); //quicker than loop |
Clemo | 0:cb80470434eb | 95 | } |
Clemo | 0:cb80470434eb | 96 | |
Clemo | 0:cb80470434eb | 97 | |
Clemo | 0:cb80470434eb | 98 | // CPV addition. |
Clemo | 0:cb80470434eb | 99 | void Flange_Process_Channel2(void) |
Clemo | 0:cb80470434eb | 100 | { |
Clemo | 0:cb80470434eb | 101 | long curindex; |
Clemo | 0:cb80470434eb | 102 | //long maxindex; |
Clemo | 0:cb80470434eb | 103 | //if flanger (phaser) on: |
Clemo | 0:cb80470434eb | 104 | //if (flange_lfoamt>0) |
Clemo | 0:cb80470434eb | 105 | { |
Clemo | 0:cb80470434eb | 106 | //intermediate value (don't -1 from maxindex, so min flangestore offset is 1 (not 0) i.e. always offset by some amount) |
Clemo | 0:cb80470434eb | 107 | // maxindex = (WAVE_LEN - flange_lfoamt); |
Clemo | 0:cb80470434eb | 108 | //calculate delay length of delayed waveform (8225 >> 21 is way of doing / 255, without using slow divide) |
Clemo | 0:cb80470434eb | 109 | // curindex = ((127 - LFO_Get_Level()) * (long)flange_lfoamt * 8225 >> 21) + maxindex; |
Clemo | 0:cb80470434eb | 110 | curindex = 15; //((uint8_t)(127-LFO_Get_Level())) >> 4; |
Clemo | 0:cb80470434eb | 111 | memcpy(wave_process_ch2,flange_store_ch2+curindex,WAVE_LEN*sizeof(sample_t)); |
Clemo | 0:cb80470434eb | 112 | memcpy(flange_store_ch2,wave_process,WAVE_LEN*sizeof(sample_t)); |
Clemo | 0:cb80470434eb | 113 | memcpy(flange_store_ch2+WAVE_LEN,wave_process,WAVE_LEN*sizeof(sample_t)); |
Clemo | 0:cb80470434eb | 114 | } |
Clemo | 0:cb80470434eb | 115 | } |