package com.codefixia.drumcloud; import com.codefixia.ui.AnimatedBeatKnob; import com.codefixia.ui.BeatKnob; import com.codefixia.ui.PressZones; import com.codefixia.ui.ToggleButtonsBar; import com.codefixia.utils.AutoMode; import com.codefixia.utils.MainMode; import processing.core.PApplet; public class Automator { private final DrumCloud drumCloud; private boolean stopOnRelease=false; private PressZones kick; private PressZones bass; private PressZones snare; private PressZones hithat; private AnimatedBeatKnob kickKnob; private AnimatedBeatKnob bassKnob; private AnimatedBeatKnob snareKnob; private AnimatedBeatKnob hithatKnob; private AutoMode mode=AutoMode.VOLUME; private int[] offsetsSample={ -1, 0, 1, 2, 3 }; private int[][] offsetsX; private int[][] offsetsY; private ToggleButtonsBar modeSelector,onReleaseSelector,deleteButtons; private int width,height; private float zoneWidth,zoneHeight,zoneOriginX,zoneOriginY,zoneMarginX,zoneMarginY,knobOriginX,knobOriginY; private int kickGrid=0,bassGrid=0,snareGrid=0,hithatGrid=0; Automator(DrumCloud drumCloud) { this.drumCloud = drumCloud; offsetsX=new int[4][4]; offsetsY=new int[4][4]; } public float getContainerOriginX() { return zoneOriginX-width*0.03f; } public float getContainerOriginY() { return drumCloud.padsContainerOriginY; } public float getContainerHeight() { return zoneHeight+((zoneOriginY-getContainerOriginY())*2); } public float getContainerWidth() { return width-2*getContainerOriginX(); } public void setup() { width=drumCloud.width; height=drumCloud.height; zoneWidth=width*0.153f; zoneHeight=height*0.485f; zoneOriginX=width*0.05f; zoneMarginX=width*0.0976f; zoneMarginY=width*0.428f; knobOriginY=height*0.2f; knobOriginX=zoneOriginX+zoneWidth*0.5f; onReleaseSelector=new ToggleButtonsBar(drumCloud.barOriginX, drumCloud.barOriginY+drumCloud.barHeight, drumCloud.barWidth, height*0.05f); String[] modes={ DrumCloud.X.getString(R.string.ON_RELEASE), DrumCloud.X.getString(R.string.HOLD), DrumCloud.X.getString(R.string.STOP) }; onReleaseSelector.setActiveColor(drumCloud.blueColor); onReleaseSelector.setHasLabel(true); onReleaseSelector.setButtons(modes); modeSelector=new ToggleButtonsBar(getContainerOriginX(), DrumCloud.X.padsContainerOriginY-height*0.1f, width-2*getContainerOriginX(), height*0.05f); String[] buttons={ DrumCloud.X.getString(R.string.VOLUME), DrumCloud.X.getString(R.string.SAMPLE), DrumCloud.X.getString(R.string.LOOP), DrumCloud.X.getString(R.string.PITCH) }; modeSelector.setButtons(buttons); deleteButtons=new ToggleButtonsBar(getContainerOriginX(), DrumCloud.X.padsContainerOriginY-height*0.05f, width-2*getContainerOriginX(), height*0.05f); String[] delButtons={ DrumCloud.X.getString(R.string.DELETE), DrumCloud.X.getString(R.string.DELETE), DrumCloud.X.getString(R.string.DELETE), DrumCloud.X.getString(R.string.DELETE) }; deleteButtons.setActiveColor(drumCloud.redColor); deleteButtons.setMomentary(true); deleteButtons.setButtons(delButtons); //deleteButtons.setEnabled(false); if (DrumCloud.isAndroidDevice) { zoneOriginY=height*0.425f; } else { zoneOriginY=height*0.445f; } kick=new PressZones(zoneOriginX,zoneOriginY,zoneWidth,zoneHeight); kick.setFillColor(DrumCloud.X.redColor); bass=new PressZones(zoneOriginX+(zoneWidth+zoneMarginX),zoneOriginY,zoneWidth,zoneHeight); bass.setFillColor(DrumCloud.X.orangeColor); snare=new PressZones(zoneOriginX+2*(zoneWidth+zoneMarginX),zoneOriginY,zoneWidth,zoneHeight); snare.setFillColor(DrumCloud.X.blueColor); hithat=new PressZones(zoneOriginX+3*(zoneWidth+zoneMarginX),zoneOriginY,zoneWidth,zoneHeight); hithat.setFillColor(DrumCloud.X.greenColor); setSubZonesByMode(mode.value()); kickKnob=new AnimatedBeatKnob(knobOriginX,knobOriginY,zoneWidth,zoneWidth,drumCloud); kickKnob.setFillColor(DrumCloud.X.redColor); bassKnob=new AnimatedBeatKnob(knobOriginX+1*(zoneWidth+zoneMarginX),knobOriginY,zoneWidth,zoneWidth,drumCloud); bassKnob.setFillColor(DrumCloud.X.orangeColor); snareKnob=new AnimatedBeatKnob(knobOriginX+2*(zoneWidth+zoneMarginX),knobOriginY,zoneWidth,zoneWidth,drumCloud); snareKnob.setFillColor(DrumCloud.X.blueColor); hithatKnob=new AnimatedBeatKnob(knobOriginX+3*(zoneWidth+zoneMarginX),knobOriginY,zoneWidth,zoneWidth,drumCloud); hithatKnob.setFillColor(DrumCloud.X.greenColor); } public void draw() { onReleaseSelector.draw(); modeSelector.draw(); deleteButtons.draw(); drawLines(); kick.drawState(); bass.drawState(); snare.drawState(); hithat.drawState(); kickKnob.draw(); bassKnob.draw(); snareKnob.draw(); hithatKnob.draw(); } public void drawLines(){ DrumCloud.X.stroke(DrumCloud.X.color(100,128)); DrumCloud.X.strokeWeight(3); for(int i=1;i<4;i++){ for(int j=0;j<4;j++){ float x0=zoneOriginX+(i*zoneWidth)+((i-1)*zoneMarginX); float x1=zoneOriginX+(i*(zoneWidth+zoneMarginX)); float y0=zoneOriginY+(((j+1)*zoneHeight/4.0f)); float y1=zoneOriginY+((j*zoneHeight/4.0f)); DrumCloud.X.line(x0, y0, x1, y1); } } } public void mousePressed(float x, float y) { mousePressed((int)x, (int)y); } public void mousePressed() { mousePressed(drumCloud.mouseX, drumCloud.mouseY); } public void applyModeChanges(PressZones pressZone, int sampleType){ switch (mode) { case VOLUME: DrumCloud.X.controlVolume(pressZone.normalizedValue(), sampleType); break; case SAMPLE: if(pressZone.getLastZoneSelected()!=-1) switch (sampleType) { case 1: drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.KICK]); offsetsSample[DrumCloud.X.KICK]=DrumCloud.X.KICK-1+pressZone.getLastZoneSelected()*4; drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.KICK], kick.getStartGrid(), kickKnob.beatValue()); break; case 2: drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.BASS]); offsetsSample[DrumCloud.X.BASS]=DrumCloud.X.BASS-1+pressZone.getLastZoneSelected()*4; drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.BASS], bass.getStartGrid(), bassKnob.beatValue()); break; case 3: drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.SNARE]); offsetsSample[DrumCloud.X.SNARE]=DrumCloud.X.SNARE-1+pressZone.getLastZoneSelected()*4; drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.SNARE], snare.getStartGrid(), snareKnob.beatValue()); break; case 4: drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.HITHAT]); offsetsSample[DrumCloud.X.HITHAT]=DrumCloud.X.HITHAT-1+pressZone.getLastZoneSelected()*4; drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.HITHAT], hithat.getStartGrid(), hithatKnob.beatValue()); break; } break; case LOOP: if(pressZone.getLastZoneSelected()!=-1) switch (sampleType) { case 1: kickKnob.setBeatValuePosition(5-pressZone.getLastZoneSelected()); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.KICK], kick.getStartGrid(), kickKnob.beatValue()); break; case 2: bassKnob.setBeatValuePosition(5-pressZone.getLastZoneSelected()); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.BASS], bass.getStartGrid(), bassKnob.beatValue()); break; case 3: snareKnob.setBeatValuePosition(5-pressZone.getLastZoneSelected()); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.SNARE], snare.getStartGrid(), snareKnob.beatValue()); break; case 4: hithatKnob.setBeatValuePosition(5-pressZone.getLastZoneSelected()); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.HITHAT], hithat.getStartGrid(), hithatKnob.beatValue()); break; } break; case PITCH: //PApplet.println("Changing pitch:"+pressZone.normalizedValue()*2.0f+" of:"+sampleType); DrumCloud.X.controlPitch(pressZone.normalizedValue()*2.0f, sampleType); break; } } public void mousePressed(int id, int mouseX, int mouseY, float pressure) { //PApplet.println("Press on automator mx:"+drumCloud.mouseX+" my:"+drumCloud.mouseY); if(!stopOnRelease){ kickGrid=kick.getStartGrid(); if(kickGrid==-1)kickGrid=drumCloud.getCurrentGrid(); bassGrid=bass.getStartGrid(); if(bassGrid==-1)bassGrid=drumCloud.getCurrentGrid(); snareGrid=snare.getStartGrid(); if(snareGrid==-1)snareGrid=drumCloud.getCurrentGrid(); hithatGrid=hithat.getStartGrid(); if(hithatGrid==-1)hithatGrid=drumCloud.getCurrentGrid(); } if(kick.isClickStarted(id,mouseX,mouseY,stopOnRelease?drumCloud.getCurrentGrid():kickGrid)){ kickKnob.setStartGrid(kick.getStartGrid()); kickKnob.setAnimating(true); if(stopOnRelease){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.KICK]); drumCloud.addSoundTypeRepeated(offsetsSample[DrumCloud.X.KICK],kick.normalizedValue(),kickKnob.beatValue()); }else{ drumCloud.playSoundType(offsetsSample[DrumCloud.X.KICK],pressure); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.KICK], kickGrid, kickKnob.beatValue()); } applyModeChanges(kick,DrumCloud.X.KICK); } if(bass.isClickStarted(id,mouseX,mouseY,stopOnRelease?drumCloud.getCurrentGrid():bassGrid)){ bassKnob.setStartGrid(bass.getStartGrid()); bassKnob.setAnimating(true); if(stopOnRelease){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.BASS]); drumCloud.addSoundTypeRepeated(offsetsSample[DrumCloud.X.BASS],bass.normalizedValue(),bassKnob.beatValue()); }else{ drumCloud.playSoundType(offsetsSample[DrumCloud.X.BASS],pressure); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.BASS], bassGrid, bassKnob.beatValue()); } applyModeChanges(bass,DrumCloud.X.BASS); } if(snare.isClickStarted(id,mouseX,mouseY,stopOnRelease?drumCloud.getCurrentGrid():snareGrid)){ snareKnob.setStartGrid(snare.getStartGrid()); snareKnob.setAnimating(true); if(stopOnRelease){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.SNARE]); drumCloud.addSoundTypeRepeated(offsetsSample[DrumCloud.X.SNARE],snare.normalizedValue(),snareKnob.beatValue()); }else{ drumCloud.playSoundType(offsetsSample[DrumCloud.X.SNARE],pressure); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.SNARE], snareGrid, snareKnob.beatValue()); } applyModeChanges(snare,DrumCloud.X.SNARE); } if(hithat.isClickStarted(id,mouseX,mouseY,stopOnRelease?drumCloud.getCurrentGrid():hithatGrid)){ hithatKnob.setStartGrid(hithat.getStartGrid()); hithatKnob.setAnimating(true); if(stopOnRelease){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.HITHAT]); drumCloud.addSoundTypeRepeated(offsetsSample[DrumCloud.X.HITHAT],hithat.normalizedValue(),hithatKnob.beatValue()); }else{ drumCloud.playSoundType(offsetsSample[DrumCloud.X.HITHAT],pressure); drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.HITHAT], hithatGrid, hithatKnob.beatValue()); } applyModeChanges(hithat,DrumCloud.X.HITHAT); } if(kickKnob.startDragging(mouseX,mouseY)){ //PApplet.println("Start dragging on click kick knob"); } if(bassKnob.startDragging(mouseX,mouseY)){ } if(snareKnob.startDragging(mouseX,mouseY)){ } if(hithatKnob.startDragging(mouseX,mouseY)){ } int onReleaseSelected=onReleaseSelector.isButtonClicked(mouseX, mouseY); if(onReleaseSelected==2){ stopOnRelease=true; deleteButtons.setEnabled(false); }else if(onReleaseSelected==1){ stopOnRelease=false; deleteButtons.setEnabled(true); } int selected=modeSelector.isButtonClicked(mouseX, mouseY); if(selected!=-1){ setSubZonesByMode(selected); saveOffsetsByMode(mode.value()); mode=AutoMode.fromInt(selected); loadOffsetsByMode(mode.value()); } int delete=deleteButtons.isButtonClicked(mouseX, mouseY); if(delete!=-1){ drumCloud.deleteSoundOfGroup(delete); switch (delete) { case 0: kickKnob.setAnimating(false); kick.resetStartGrid(); break; case 1: bassKnob.setAnimating(false); bass.resetStartGrid(); break; case 2: snareKnob.setAnimating(false); snare.resetStartGrid(); break; case 3: hithatKnob.setAnimating(false); hithat.resetStartGrid(); break; } } } public void setSubZonesByMode(int mode){ switch (mode) { case 0: String[] vSubzones = { "100", "75", "50", "25" }; kick.setSubZoneTexts(vSubzones); bass.setSubZoneTexts(vSubzones); snare.setSubZoneTexts(vSubzones); hithat.setSubZoneTexts(vSubzones); break; case 1: String[] kSubzones = { "K1", "K2", "K3", "K4" }; kick.setSubZoneTexts(kSubzones); String[] bSubzones = { "B1", "B2", "B3", "B4" }; bass.setSubZoneTexts(bSubzones); String[] sSubzones = { "S1", "S2", "S3", "S4" }; snare.setSubZoneTexts(sSubzones); String[] hSubzones = { "H1", "H2", "H3", "H4" }; hithat.setSubZoneTexts(hSubzones); break; case 2: String[] subzones = { "16", "8", "4", "2" }; kick.setSubZoneTexts(subzones); bass.setSubZoneTexts(subzones); snare.setSubZoneTexts(subzones); hithat.setSubZoneTexts(subzones); break; case 3: String[] pSubzones = { "+2", "+1", "-1", "-2" }; kick.setSubZoneTexts(pSubzones); bass.setSubZoneTexts(pSubzones); snare.setSubZoneTexts(pSubzones); hithat.setSubZoneTexts(pSubzones); break; } } public void saveOffsetsByMode(int mode){ for (int zone = 0; zone < 4; zone++) { switch (zone) { case 0: offsetsX[mode][zone]=(int)kick.getOffsetX(); offsetsY[mode][zone]=(int)kick.getOffsetY(); break; case 1: offsetsX[mode][zone]=(int)bass.getOffsetX(); offsetsY[mode][zone]=(int)bass.getOffsetY(); break; case 2: offsetsX[mode][zone]=(int)snare.getOffsetX(); offsetsY[mode][zone]=(int)snare.getOffsetY(); break; case 3: offsetsX[mode][zone]=(int)hithat.getOffsetX(); offsetsY[mode][zone]=(int)hithat.getOffsetY(); break; } } } public void loadOffsetsByMode(int mode){ for (int zone = 0; zone < 4; zone++) { switch (zone) { case 0: kick.setOffsetX(offsetsX[mode][zone]); kick.setOffsetY(offsetsY[mode][zone]); break; case 1: bass.setOffsetX(offsetsX[mode][zone]); bass.setOffsetY(offsetsY[mode][zone]); break; case 2: snare.setOffsetX(offsetsX[mode][zone]); snare.setOffsetY(offsetsY[mode][zone]); break; case 3: hithat.setOffsetX(offsetsX[mode][zone]); hithat.setOffsetY(offsetsY[mode][zone]); break; } } } public void mouseReleased(float x, float y) { mouseReleased((int)x, (int)y); } public void mouseReleased() { mouseReleased(drumCloud.mouseX, drumCloud.mouseY); } public void mouseReleased(int id, int mouseX, int mouseY, float pressure) { //PApplet.println("Release on automator mx:"+drumCloud.mouseX+" my:"+drumCloud.mouseY); if(stopOnRelease){ if(kick.isClickStopped(id)){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.KICK]); kickKnob.setAnimating(false); } if(bass.isClickStopped(id)){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.BASS]); bassKnob.setAnimating(false); } if(snare.isClickStopped(id)){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.SNARE]); snareKnob.setAnimating(false); } if(hithat.isClickStopped(id)){ drumCloud.removeAllSoundsOfType(offsetsSample[DrumCloud.X.HITHAT]); hithatKnob.setAnimating(false); } } if(kickKnob.stopDragging()){ if(kick.isClicked()){ drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.KICK], kick.getStartGrid(), kickKnob.beatValue()); } } if(bassKnob.stopDragging()){ if(bass.isClicked()){ drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.BASS], bass.getStartGrid(), bassKnob.beatValue()); } } if(snareKnob.stopDragging()){ if(snare.isClicked()){ drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.SNARE], snare.getStartGrid(), snareKnob.beatValue()); } } if(hithatKnob.stopDragging()){ if(hithat.isClicked()){ drumCloud.updateSoundTypeRepeated(offsetsSample[DrumCloud.X.HITHAT], hithat.getStartGrid(), hithatKnob.beatValue()); } } deleteButtons.stopClick(); } public void debug() { } public void mouseDragged() { mouseDragged(-1,drumCloud.mouseX, drumCloud.mouseY,1.0f); } public void mouseDragged(int id, int mouseX, int mouseY, float pressure) { //PApplet.println("Drag on automator px:"+drumCloud.pmouseX+" py:"+drumCloud.pmouseY+" mx:"+drumCloud.mouseX+" my:"+drumCloud.mouseY); if(kick.isZoneSelected(id,mouseX,mouseY)!=-1){ applyModeChanges(kick,DrumCloud.X.KICK); } if(bass.isZoneSelected(id,mouseX,mouseY)!=-1){ applyModeChanges(bass,DrumCloud.X.BASS); } if(snare.isZoneSelected(id,mouseX,mouseY)!=-1){ applyModeChanges(snare,DrumCloud.X.SNARE); } if(hithat.isZoneSelected(id,mouseX,mouseY)!=-1){ applyModeChanges(hithat,DrumCloud.X.HITHAT); } //PApplet.println("Setting kick vol:"+kick.normalizedValue()+" y:"+kick.getY()+" my:"+mouseY); kickKnob.dragVertically(mouseY); bassKnob.dragVertically(mouseY); snareKnob.dragVertically(mouseY); hithatKnob.dragVertically(mouseY); } public void mouseMoved() { mouseMoved(drumCloud.mouseX, drumCloud.mouseY); } public void mouseMoved(int mouseX, int mouseY) { //PApplet.println("Moved on automator px:"+drumCloud.pmouseX+" py:"+drumCloud.pmouseY+" mx:"+drumCloud.mouseX+" my:"+drumCloud.mouseY); kickKnob.isOvered(drumCloud.mouseX,drumCloud.mouseY); bassKnob.isOvered(drumCloud.mouseX,drumCloud.mouseY); snareKnob.isOvered(drumCloud.mouseX,drumCloud.mouseY); snareKnob.isOvered(drumCloud.mouseX,drumCloud.mouseY); hithatKnob.isOvered(drumCloud.mouseX,drumCloud.mouseY); } public void updateState() { /*for (int i=0;i<drumCloud.samplesPerBeat.length;i++) { for (int j=1;j<drumCloud.samplesPerBeat[i].length+1;j++) { tracks[i][j].ON=drumCloud.samplesPerBeat[i][j-1]; } }*/ } }