import ddf.minim.analysis.*; import ddf.minim.*; import processing.opengl.*; Minim minim; AudioPlayer audioPlayer; FFT fft; int iNumAverages = 256; float[] afFreqValues = new float[iNumAverages]; int iMaxCubeSize = 20; int iMinCubeSize = 8; float fRotY = 0; float fRotDY = 0.03; int iNumTrails = 1500; Trail[] aTrails = new Trail[iNumTrails]; int iMaxTrailPoints = 20; float fTrailCalcStep = 0.4; float fTrailDrawStep = 0.4; float fTrailSpeed = 0.4; float fMinTrailLength = -0.2; float fMaxTrailLength = iMaxTrailPoints/2; float fMinStrokeWeight = 0.1; float fMaxStrokeWeight = 4.5; //////////////////////////////////////////////////////////////////////// void setup() { size(720,450, OPENGL); minim = new Minim(this); audioPlayer = minim.loadFile("Breathe.mp3", 1024); audioPlayer.loop(); fft = new FFT(audioPlayer.bufferSize(), audioPlayer.sampleRate()); fft.linAverages(iNumAverages); frameRate(30); for (int i = 0; i < iNumTrails; i++) { aTrails[i] = new Trail((int)random(iMaxCubeSize-iMinCubeSize)+iMinCubeSize); } } //////////////////////////////////////////////////////////////////////// void draw() { fft.forward(audioPlayer.mix); for (int i = 0; i < iNumAverages; i++) { float fNewAlpha = constrain(pow(fft.getAvg(i), 10) * 2, 0, 1); afFreqValues[i] = max(afFreqValues[i] * 0.8 + fNewAlpha * 0.2, fNewAlpha); } float cameraZ = (height/2.0) / tan(PI * 60.0 / 360.0); perspective(-(PI/2), float(width)/float(height), 0.1, 5000); fRotY += fRotDY; camera(cos(fRotY * 0.3) * 2, 0, sin(fRotY * 0.3) * 2, sin(fRotY * 0.3) * 100, -30, cos(fRotY * 0.3) * 100, 0, 1, 0); // camera(0,0,50,0,0,0,0,1,0); background(0,0,0); noFill(); for (int i = 0; i < iNumTrails; i++) { aTrails[i].Draw(); } } //////////////////////////////////////////////////////////////////////// class Trail { Trail(int iCubeSize) { m_iCubeSize = iCubeSize; m_avecPos = new PVector[iMaxTrailPoints]; for (int i = 0; i < iMaxTrailPoints; i++) { m_avecPos[i] = new PVector(0,0,0); } PVector vecPos = new PVector(0,0,0); switch ((int)random(6)) { case 0: vecPos = new PVector((int)random(-m_iCubeSize,m_iCubeSize),(int)random(-m_iCubeSize,m_iCubeSize),-m_iCubeSize); m_iSide = 2; break; case 1: vecPos = new PVector((int)random(-m_iCubeSize,m_iCubeSize),(int)random(-m_iCubeSize,m_iCubeSize),+m_iCubeSize); m_iSide = 2; break; case 2: vecPos = new PVector((int)random(-m_iCubeSize,m_iCubeSize),-m_iCubeSize,(int)random(-m_iCubeSize,m_iCubeSize)); m_iSide = 1; break; case 3: vecPos = new PVector((int)random(-m_iCubeSize,m_iCubeSize),+m_iCubeSize,(int)random(-m_iCubeSize,m_iCubeSize)); m_iSide = 1; break; case 4: vecPos = new PVector(-m_iCubeSize,(int)random(-m_iCubeSize,m_iCubeSize),(int)random(-m_iCubeSize,m_iCubeSize)); m_iSide = 0; break; case 5: vecPos = new PVector(+m_iCubeSize,(int)random(-m_iCubeSize,m_iCubeSize),(int)random(-m_iCubeSize,m_iCubeSize)); m_iSide = 0; break; } for (int i = 0; i < iMaxTrailPoints; i++) { m_avecPos[i] = vecPos.get(); vecPos = GetNewPos(vecPos.get(), false); } m_fPos = iMaxTrailPoints / 2 + random(1); m_iFreq = (int)random(0,iNumAverages); } void Draw() { float fLengthAlpha = afFreqValues[m_iFreq]; float fLength = lerp(fMinTrailLength, fMaxTrailLength, fLengthAlpha); if (fLength > 0.0) { float fCubeSizeAlpha = (float)(m_iCubeSize - iMinCubeSize) / (float)(iMaxCubeSize - iMinCubeSize); if ((m_iFreq & 1) == 0) { stroke(lerp(10, 1, fCubeSizeAlpha),lerp(200, 25, fCubeSizeAlpha),lerp(250, 22, fCubeSizeAlpha)); } else { stroke(lerp(250, 22, fCubeSizeAlpha),lerp(200, 25, fCubeSizeAlpha),lerp(10, 1, fCubeSizeAlpha)); } strokeWeight(lerp(fMinStrokeWeight, fMaxStrokeWeight, 1 - fCubeSizeAlpha)); for (float fPos = 0; fPos < fLength; fPos += fTrailCalcStep) { float fSrcPos = m_fPos - fPos - 1; if (fSrcPos < 0) fSrcPos += iMaxTrailPoints; int iPos11 = (int)((fSrcPos + 0.0) % iMaxTrailPoints); int iPos12 = (int)((fSrcPos + 1.0) % iMaxTrailPoints); float fAlpha1 = (fSrcPos + 0.0) % 1.0; PVector vecSrc1 = m_avecPos[iPos11]; PVector vecDst1 = m_avecPos[iPos12]; PVector vecPos1 = new PVector(lerp(vecSrc1.x, vecDst1.x, fAlpha1), lerp(vecSrc1.y, vecDst1.y, fAlpha1), lerp(vecSrc1.z, vecDst1.z, fAlpha1)); int iPos21 = (int)((fSrcPos + fTrailDrawStep + 0.0) % iMaxTrailPoints); int iPos22 = (int)((fSrcPos + fTrailDrawStep + 1.0) % iMaxTrailPoints); float fAlpha2 = (fSrcPos + fTrailDrawStep) % 1.0; PVector vecSrc2 = m_avecPos[iPos21]; PVector vecDst2 = m_avecPos[iPos22]; PVector vecPos2 = new PVector(lerp(vecSrc2.x, vecDst2.x, fAlpha2), lerp(vecSrc2.y, vecDst2.y, fAlpha2), lerp(vecSrc2.z, vecDst2.z, fAlpha2)); line(vecPos1.x,vecPos1.y,vecPos1.z,vecPos2.x,vecPos2.y,vecPos2.z); } } float fOldPos = m_fPos; m_fPos = (m_fPos + fTrailSpeed * (fLengthAlpha * 0.75 + 0.25)) % iMaxTrailPoints; if ((int)fOldPos != (int)m_fPos) { PVector vecNew = GetNewPos(m_avecPos[(int)(fOldPos+1) % iMaxTrailPoints].get(), fLengthAlpha < 0.1); m_avecPos[(int)(m_fPos+1) % iMaxTrailPoints] = vecNew; } } PVector GetNewPos(PVector vecSrc, boolean bLoud) { PVector vecResult = new PVector(0,0,0); int iChoice; if (bLoud) iChoice = (int)random(4)+4; else iChoice = (int)random(4); vecResult = vecSrc.get(); switch (m_iSide) { case 0: switch (iChoice) { case 0: vecResult.y += +1; break; case 1: vecResult.z += +1; break; case 2: vecResult.y += -1; break; case 3: vecResult.z += -1; break; case 4: vecResult.y += -1; vecResult.z += -1; break; case 5: vecResult.y += +1; vecResult.z += -1; break; case 6: vecResult.y += +1; vecResult.z += +1; break; case 7: vecResult.y += -1; vecResult.z += +1; break; } break; case 1: switch (iChoice) { case 0: vecResult.x += +1; break; case 1: vecResult.z += +1; break; case 2: vecResult.x += -1; break; case 3: vecResult.z += -1; break; case 4: vecResult.x += -1; vecResult.z += -1; break; case 5: vecResult.x += +1; vecResult.z += -1; break; case 6: vecResult.x += +1; vecResult.z += +1; break; case 7: vecResult.x += -1; vecResult.z += +1; break; } break; case 2: switch (iChoice) { case 0: vecResult.x += +1; break; case 1: vecResult.y += +1; break; case 2: vecResult.x += -1; break; case 3: vecResult.y += -1; break; case 4: vecResult.x += -1; vecResult.y += -1; break; case 5: vecResult.x += +1; vecResult.y += -1; break; case 6: vecResult.x += +1; vecResult.y += +1; break; case 7: vecResult.x += -1; vecResult.y += +1; break; } break; } vecResult.x = constrain(vecResult.x, -m_iCubeSize, m_iCubeSize); vecResult.y = constrain(vecResult.y, -m_iCubeSize, m_iCubeSize); vecResult.z = constrain(vecResult.z, -m_iCubeSize, m_iCubeSize); return vecResult; } int m_iCubeSize; PVector[] m_avecPos; int m_iSide; float m_fPos; int m_iFreq; }