GUI.pde 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. import controlP5.*;
  2. import netP5.*;
  3. ControlP5 cp5;
  4. // === EQ bands (fixed centers/Q, draggable gains in dB) ===
  5. float band1Gain = 0;
  6. float band2Gain = 0;
  7. final float band1Center = 0.3;
  8. final float band2Center = 0.7;
  9. final float bandQ = 10;
  10. boolean draggingBand1 = false;
  11. boolean draggingBand2 = false;
  12. // === Other effect parameters ===
  13. float delayTime = 0.5;
  14. float delayFeedback = 0.4;
  15. float distortionAmount= 0.5;
  16. float distortionMix = 0.5;
  17. float chorusAmount = 0.5;
  18. float chorusDryWet = 0.5;
  19. void setup() {
  20. size(1680, 780, P3D);
  21. // Use orthographic projection to render a perfect cube without perspective distortion
  22. ortho(0, width, height, 0, -1000, 1000);
  23. frameRate(125);
  24. background(21,21,30);
  25. noStroke();
  26. surface.setResizable(false);
  27. surface.setLocation(100, 100);
  28. cp5 = new ControlP5(this);
  29. // Envelope knobs
  30. cp5.addKnob("AmpAttack").setLabel("Attack").setRange(0,1).setValue(0.4)
  31. .setPosition(85,350).setRadius(45).setViewStyle(Knob.ARC)
  32. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  33. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  34. cp5.addKnob("AmpRelease").setLabel("Release").setRange(0,1).setValue(0.4)
  35. .setPosition(215,350).setRadius(45).setViewStyle(Knob.ARC)
  36. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  37. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  38. cp5.addKnob("FilterAttack").setLabel("Attack").setRange(0,1).setValue(0.4)
  39. .setPosition(405,350).setRadius(45).setViewStyle(Knob.ARC)
  40. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  41. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  42. cp5.addKnob("FilterRelease").setLabel("Release").setRange(0,1).setValue(0.4)
  43. .setPosition(535,350).setRadius(45).setViewStyle(Knob.ARC)
  44. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  45. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  46. cp5.addKnob("PitchAttack").setLabel("Attack").setRange(0,1).setValue(0.4)
  47. .setPosition(725,350).setRadius(45).setViewStyle(Knob.ARC)
  48. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  49. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  50. cp5.addKnob("PitchRelease").setLabel("Release").setRange(0,1).setValue(0.4)
  51. .setPosition(855,350).setRadius(45).setViewStyle(Knob.ARC)
  52. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  53. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  54. // Distortion knobs
  55. cp5.addKnob("distortionAmount").setLabel("Amount").setRange(0,1).setValue(distortionAmount)
  56. .setPosition(405,550).setRadius(45).setViewStyle(Knob.ARC)
  57. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  58. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  59. cp5.addKnob("distortionMix").setLabel("Mix").setRange(0,1).setValue(distortionMix)
  60. .setPosition(535,550).setRadius(45).setViewStyle(Knob.ARC)
  61. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  62. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  63. // Chorus knobs
  64. cp5.addKnob("chorusAmount").setLabel("Amount").setRange(0,1).setValue(chorusAmount)
  65. .setPosition(725,550).setRadius(45).setViewStyle(Knob.ARC)
  66. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  67. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  68. cp5.addKnob("chorusDryWet").setLabel("Dry/Wet").setRange(0,1).setValue(chorusDryWet)
  69. .setPosition(855,550).setRadius(45).setViewStyle(Knob.ARC)
  70. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  71. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  72. // Delay knobs
  73. cp5.addKnob("delayTime").setLabel("Time").setRange(0,1).setValue(delayTime)
  74. .setPosition(1045,550).setRadius(45).setViewStyle(Knob.ARC)
  75. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  76. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  77. cp5.addKnob("delayFeedback").setLabel("Feedback").setRange(0,1).setValue(delayFeedback)
  78. .setPosition(1175,550).setRadius(45).setViewStyle(Knob.ARC)
  79. .setColorBackground(color(21,21,30)).setColorForeground(color(255,178,44))
  80. .setColorActive(color(250,170,40)).setFont(createFont("Futura",15));
  81. }
  82. void draw() {
  83. background(21,21,30);
  84. // Panels grid
  85. stroke(64); fill(12);
  86. rect(50,100,300,180,8);
  87. rect(370,100,300,180,8);
  88. rect(690,100,300,180,8);
  89. rect(1010,100,300,180,8);
  90. rect(1330,100,300,180,8);
  91. rect(50,300,300,180,8);
  92. rect(370,300,300,180,8);
  93. rect(690,300,300,180,8);
  94. rect(50,500,300,180,8);
  95. rect(370,500,300,180,8);
  96. rect(690,500,300,180,8);
  97. rect(1010,500,300,180,8);
  98. rect(1330,500,300,180,8);
  99. // Labels
  100. textAlign(CENTER, TOP);
  101. fill(255); textSize(18);
  102. text("Oscillator #1", 200, 110);
  103. text("Oscillator #2", 520, 110);
  104. text("Oscillator #3", 840, 110);
  105. text("Filter", 1160,110);
  106. text("LFO", 1480,110);
  107. text("Amp Env", 200, 330);
  108. text("Filter Env", 520, 330);
  109. text("Pitch Env", 840, 330);
  110. text("EQ", 200, 530);
  111. text("Distortion", 520, 530);
  112. text("Chorus", 840, 530);
  113. text("Delay", 1160, 530);
  114. text("Reverb", 1480, 530);
  115. // Waveforms & graphs
  116. SinWave();
  117. SawtoothWave();
  118. TriangleWave();
  119. drawFilterGraph();
  120. drawLFOWaveform();
  121. drawEQGraph();
  122. // --- Reverb: smaller wireframe cube ---
  123. pushMatrix();
  124. translate(1480, 590, 0);
  125. rotateX(frameCount * 0.01f);
  126. rotateY(frameCount * 0.013f);
  127. rotateZ(frameCount * 0.007f);
  128. noFill();
  129. stroke(255, 178, 44);
  130. strokeWeight(2);
  131. float s = 20; // half-edge length = 20 → full cube = 40
  132. // front face (z = +s)
  133. line(-s,-s, s, s,-s, s);
  134. line( s,-s, s, s, s, s);
  135. line( s, s, s, -s, s, s);
  136. line(-s, s, s, -s,-s, s);
  137. // back face (z = -s)
  138. line(-s,-s,-s, s,-s,-s);
  139. line( s,-s,-s, s, s,-s);
  140. line( s, s,-s, -s, s,-s);
  141. line(-s, s,-s, -s,-s,-s);
  142. // side edges
  143. line(-s,-s, s, -s,-s,-s);
  144. line( s,-s, s, s,-s,-s);
  145. line( s, s, s, s, s,-s);
  146. line(-s, s, s, -s, s,-s);
  147. popMatrix();
  148. }
  149. void drawEQGraph() {
  150. int x0=50, y0=500, w=300, h=180;
  151. int midY = y0 + h/2;
  152. stroke(64); fill(12);
  153. rect(x0,y0,w,h,8);
  154. stroke(80); fill(255);
  155. textSize(12); textAlign(RIGHT, CENTER);
  156. for(int i=0; i<=4; i++){
  157. float db = map(i, 0, 4, +20, -60);
  158. float yy = y0 + i*(h/4);
  159. line(x0-5, yy, x0, yy);
  160. text(nf(db,1,0)+" dB", x0-8, yy);
  161. }
  162. fill(255,178,44); textSize(14);
  163. textAlign(LEFT, BOTTOM);
  164. text("Low Band: "+nf(band1Gain,1,1)+" dB", x0+8, y0+h-8);
  165. textAlign(RIGHT, BOTTOM);
  166. text("High Band: "+nf(band2Gain,1,1)+" dB", x0+w-8, y0+h-8);
  167. noFill(); stroke(255,178,44);
  168. beginShape();
  169. float g1n = map(band1Gain, -60, 20, -1, 1);
  170. float g2n = map(band2Gain, -60, 20, -1, 1);
  171. for(int i=0; i<=w; i++){
  172. float norm = i/(float)w;
  173. float d1 = g1n * exp(-sq((norm-band1Center)*bandQ));
  174. float d2 = g2n * exp(-sq((norm-band2Center)*bandQ));
  175. float y = midY - (d1 + d2)*(h/2);
  176. vertex(x0+i, y);
  177. }
  178. endShape();
  179. noStroke(); fill(255,178,44);
  180. float hx1 = x0 + band1Center*w;
  181. float hy1 = midY - map(band1Gain,-60,20,-1,1)*(h/2);
  182. ellipse(hx1, hy1, 12, 12);
  183. float hx2 = x0 + band2Center*w;
  184. float hy2 = midY - map(band2Gain,-60,20,-1,1)*(h/2);
  185. ellipse(hx2, hy2, 12, 12);
  186. }
  187. void mousePressed() {
  188. int x0=50, y0=500, w=300, h=180;
  189. float hy1 = map(band1Gain, 20, -60, y0, y0+h);
  190. float hy2 = map(band2Gain, 20, -60, y0, y0+h);
  191. if (dist(mouseX, mouseY, x0+band1Center*w, hy1) < 10) draggingBand1 = true;
  192. else if (dist(mouseX, mouseY, x0+band2Center*w, hy2) < 10) draggingBand2 = true;
  193. }
  194. void mouseDragged() {
  195. int y0=500, h=180;
  196. if (draggingBand1) {
  197. float cy = constrain(mouseY, y0, y0+h);
  198. band1Gain = map(cy, y0+h, y0, -60, 20);
  199. }
  200. if (draggingBand2) {
  201. float cy = constrain(mouseY, y0, y0+h);
  202. band2Gain = map(cy, y0+h, y0, -60, 20);
  203. }
  204. }
  205. void mouseReleased() {
  206. draggingBand1 = draggingBand2 = false;
  207. }
  208. // ControlP5 callbacks (no-op)
  209. void AmpAttack(float v) {}
  210. void AmpRelease(float v) {}
  211. void FilterAttack(float v) {}
  212. void FilterRelease(float v) {}
  213. void PitchAttack(float v) {}
  214. void PitchRelease(float v) {}
  215. void distortionAmount(float v){ distortionAmount = v; }
  216. void distortionMix(float v) { distortionMix = v; }
  217. void chorusAmount(float v) { chorusAmount = v; }
  218. void chorusDryWet(float v) { chorusDryWet = v; }
  219. void delayTime(float v) { delayTime = v; }
  220. void delayFeedback(float v) { delayFeedback = v; }
  221. // Waveform & helpers
  222. void SinWave() {
  223. stroke(255,178,44); noFill();
  224. float phase = frameCount * 0.025f;
  225. int yBase=210, amp=60, x0=70, x1=330;
  226. beginShape();
  227. for(int x=x0; x<=x1; x++){
  228. float t = map(x,x0,x1,0,TWO_PI*2);
  229. vertex(x,yBase+sin(t+phase)*amp);
  230. }
  231. endShape();
  232. }
  233. void SawtoothWave() {
  234. stroke(255,178,44); noFill();
  235. float phase=frameCount*0.025f; int yBase=210, x0=390, x1=650;
  236. beginShape();
  237. for(int x=x0; x<=x1; x++){
  238. float t=map(x,x0,x1,0,2)+phase, p=t-floor(t), v=-1+p*2;
  239. vertex(x,yBase+v*60);
  240. }
  241. endShape();
  242. }
  243. void TriangleWave() {
  244. stroke(255,178,44); noFill();
  245. float phase=frameCount*0.04f; int yBase=210, amp=60, x0=710, x1=970;
  246. beginShape();
  247. for(int x=x0; x<=x1; x++){
  248. float t=map(x,x0,x1,0,4)+phase; int s=floor(t); float f=t-s;
  249. float v=(s%2==0)?-1+f*2:1-f*2;
  250. vertex(x,yBase+v*amp);
  251. }
  252. endShape();
  253. }
  254. void drawFilterGraph() {
  255. stroke(255,178,44); noFill();
  256. int x0=1030, y0=140, w=260, h=180;
  257. beginShape();
  258. for(int i=0;i<=w;i++){
  259. float n=i/(float)w, m=1/sqrt(1+pow(n/0.5f,2));
  260. vertex(x0+i, y0+(1-m)*h);
  261. }
  262. endShape();
  263. }
  264. void drawLFOWaveform() {
  265. stroke(255,178,44); noFill();
  266. int x0=1330, y0=100, w=260, h=180, m=20;
  267. float phase=frameCount*0.02f;
  268. beginShape();
  269. for(int i=0;i<=w;i++){
  270. float a=map(i,0,w,0,TWO_PI);
  271. vertex(x0+m+i, y0+h/2+sin(a)*(h/2-10));
  272. }
  273. endShape();
  274. float p=(phase%TWO_PI)/TWO_PI;
  275. noStroke(); fill(255,178,44);
  276. ellipse(x0+m+p*w, y0+h/2+sin(phase)*(h/2-10), 12,12);
  277. }