본문 바로가기
  • Let's go grab a data
Development/Processing

p5.js sound library, FFT 이용한 sound visualization

by pub-lican-ai 2017. 3. 14.
반응형

p5.js sound library, FFT 이용한 sound visualization


[다운로드]

http://p5js.org/download/   (p5.js, p5.min.js)

https://github.com/processing/p5.js-sound/tree/master/lib  (p5.sound.js, p5.sound.min.js)


[음원파일]

C:\Users\Public\Music\Sample Music\Kalimba.mp3

C:\Users\Public\Music\Sample Music\Sleep Away.mp3

두 개의 파일을 html 프로젝트 내 public 폴더의 audio 폴더로 옮겨놓음.


[app.js]

app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);


[index.html]

<!DOCTYPE html>

<html>

  <head>

    <script src="/javascripts/p5.js"></script>

    <script src="/javascripts/p5.sound.js"></script>

    <script src="/javascripts/sketch.js"></script>

  </head>

  <body>


  </body>

</html>


[sketch.js]

js파일을 하나 만들어 아래 코드 삽입 후 테스트

var defaultText = "click to play";

var nameText = "' Kalimba.mp3 '";


function preload() {

    sound = loadSound('/audio/Kalimba.mp3');

    sound1 = loadSound('/audio/Hair.mp3');

}


function setup() {

    var cnv = createCanvas(800, 600);


    /*colorMode(HSB);*/

    angleMode(DEGREES);

    cnv.mouseClicked(togglePlay);


    fft = new p5.FFT(0.9,256);   //(smoothing, bins)


    sound.amp(0.2);

    sound1.amp(0.2);


    sound.addCue(0.50, changeText, "hello" );

    sound.addCue(1.00, changeText, "p5" );

    sound.addCue(2.00, changeText, "what" );

    sound.addCue(2.50, changeText, "do" );

    sound.addCue(3.00, changeText, "you" );

    sound.addCue(3.50, changeText, "want" );

    sound.addCue(4.00, changeText, "to" );

    sound.addCue(5.00, changeText, "make?" );

    sound.addCue(10.00, changeText, "" );

}


function draw() {

    background(255);


    fill(0);


    var spectrum = fft.analyze();

    noStroke();

    for (var i = 0; i< spectrum.length; i++){

        var x = map(i, 0, spectrum.length, 0, width);

        var h = -height + map(spectrum[i], 0, 255, height, 0);

        fill(i,100,100);

        rect(x, height, width / spectrum.length, h )

    }


    text(nameText, 50, 10);

    textAlign(CENTER);

    text(defaultText, width/2, height/2);


    var waveform = fft.waveform();

    noFill();


    beginShape();

    stroke(255,0,0); // waveform is red

    strokeWeight(1);

    for (var i = 0; i< waveform.length; i++){

        var x = map(i, 0, waveform.length, 0, width);

        var y = map( waveform[i], -1, 1, 0, height/2);

        vertex(x,y);

    }

    endShape();


    translate(width/2,height/2);

    for (var i = 0; i< 170; i++){   //음원이 high frequency를 사용하지 않아 spectrum.length를 사용하지 않고 임의 지정

        /*var angle = map(i,0,spectrum.length,0,360);*/

        var angle = map(i,0,170,0,360);

        var amp = spectrum[i];

        var r = map(amp, 0, 256, 40, 200);

        var r1 = map(0, 0, 256, 40, 200);

        var x = r1 * cos(angle);

        var y = r1 * sin(angle);

        var x1 = r * cos(angle);

        var y1 = r * sin(angle);

        /*stroke(i,256,256);*/

        line(x,y,x1,y1);

    }

}


function togglePlay() {

    sound.amp(0.2);

    sound1.amp(0.2);

    if (sound.isPlaying()) {

        sound.stop();

        sound1.loop();

        nameText =  "' Hair.mp3 '"

    } else {

        sound.loop();

        sound1.stop();

        nameText =  "' Kalimba.mp3 '"

    }

}


function changeText(val) {

    defaultText = val;

}


반응형