Hi,
Today I’ve been trying to make a simpler version of this music player by Misaki Nakano.
Out of the different options available, one has caught my eyes:
- the cubic (or Catmull-Rom spline) interpolation mode.
I believe the easiest way to achive that effect in Processing is to use the curveVertex()
function which is an actual implementation of Catmull-Rom splines.
However, when simply replacing vertex()
by curveVertex()
in the script below (without forgeting to remove QUAD_STRIPS
from beginShape()
) my sketch goes from this:
… to this:
Do you know what I’m missing here ?
Also, I notice the animation in Misaki’s player is smooth and “bouncy” while my version is somewhat brisk and jerky. Do you have an idea of what I could improve to get a smoother animation ?
There are other smaller issues I have but I prefer to stop here for now.
Any suggestion would be helpful. Thank you.
add_library('minim')
add_library('peasycam')
cylindrical, isPlaying, isMute = False, False, False
pts, radius, latheRadius, segments = 20, 1, 300, 128
vertices, vertices2 = [[PVector() for e in range(pts+1)] for e in range(2)]
def setup():
global song, fftLin, fftLog, cam
size(1200, 800, P3D)
frameRate(1000)
smooth(8)
cam = PeasyCam(this, 600)
cam.setMaximumDistance(600)
cam.rotateX(-PI/2.4)
perspective(60 * DEG_TO_RAD, width/float(height), 2, 6000)
minim = Minim(this)
song = minim.loadFile("tm1.mp3")
fftLin, fftLog = [FFT(song.bufferSize(), song.sampleRate()) for e in range(2)]
fftLin.linAverages(30), fftLog.logAverages(22, 3)
def draw():
background(225, 250, 255)
lights()
ambientLight(255,153,39)
directionalLight(255,43,192, 1, 0, 0)
pointLight(255,215,60, width, height/2, 0)
rotateZ(frameCount*PI/560)
fill(255,82,139)
noStroke()
song.play() if isPlaying else song.pause()
song.mute() if isMute else song.unmute()
fftLin.forward(song.mix)
fftLog.forward(song.mix)
latheAngle = 0
for s in range(segments):
angle = 0
beginShape(QUAD_STRIP)
for i, v in enumerate(vertices2):
division = 1 if s%2 == 0 else 6
step = s*2 # select 1 freq every 2 freq (up to 256 out of 512)
c_step = (s*2)+((s%2)*2) # select 1 freq every 4 freq (up to 256 freq out of 512)
if cylindrical: sscale = map(fftLin.getBand(c_step)*((s+10)/10), 0, 35, .8, 35)
else: sscale = map(fftLin.getBand(step)*((s+10)/10), 0, 30, .8, 24)
sscale = constrain(sscale, 0, 50)
vertices[i].x = latheRadius + sin(radians(angle)) * radius * sscale
vertices[i].z = cos(radians(angle)) * radius * sscale
angle+=360.0/pts
vertex(v.x, v.y, v.z)
v.x = cos(radians(latheAngle)) * vertices[i].x
v.y = sin(radians(latheAngle)) * vertices[i].x
v.z = vertices[i].z
vertex(v.x, v.y, v.z)
latheAngle += (360.0+260)/(segments*6/division) if cylindrical else 360.0/segments
endShape()
cam.beginHUD()
text("'p' = PLAY/PAUSE", 20, 30)
text("'r' = REPLAY", 20, 50)
text("'m' = MUTE", 20, 70)
text("'c' = MODE", 20, 90)
cam.endHUD()
def keyPressed():
global isPlaying, cylindrical, isMute
if key == 'p': isPlaying = not isPlaying
if key == 'm': isMute = not isMute
if key == 'c': cylindrical = not cylindrical
if key == 'r': song.rewind()