yangfanconan 发表于 2013-7-8 17:37:13

Processing之旅-----【给鱼插上翅膀,Processing基础扩展库2】

下面我们继续学习Processing自带的库---minim ,这是一个音频处理库,怎么说功能十分强大,官网是http://code.compartmental.net/tools/minim/

/**
* This is a relatively simple file player that lets you scrub forward and backward in an audio file.<br />
* It should be noted that it's not *exactly* scrubbing because the playback speed is not changed,
* it's simply that the position in the song is changed by very small increments when fast-forwarding or rewinding.
* But the end result is convincing enough.
* <p>
* The positioning code is inside of the Play, Rewind, and Forward classes, which are in button.pde.
*/

import ddf.minim.*;

Minim minim;
AudioPlayer song;
Play play;
Rewind rewind;
Forward ffwd;

void setup()
{
size(512, 200, P3D);
minim = new Minim(this);
// load a file from the data folder, use a sample buffer of 1024 samples
song = minim.loadFile("fair1939.wav", 512);
// buttons for control
play = new Play(width/2 - 50, 130, 20, 10);
rewind = new Rewind(width/2, 130, 20, 10);
ffwd = new Forward(width/2 + 50, 130, 20, 10);
}

void draw()
{
background(0);
// draw the wave form
// this wav is MONO, so we only need the left channel,
// though we could have used the right channel and gotten the same values
stroke(255);
for (int i = 0; i < song.bufferSize() - 1;i++)
{
    line(i, 50 - song.left.get(i)*50, i+1, 50 - song.left.get(i+1)*10);
}
// draw the position in the song
// the position is in milliseconds,
// to get a meaningful graphic, we need to map the value to the range
float x = map(song.position(), 0, song.length(), 0, width);
stroke(255, 0, 0);
line(x, 50 - 20, x, 50 + 20);
// do the controls
play.update();
play.draw();
rewind.update();
rewind.draw();
ffwd.update();
ffwd.draw();
}

void mousePressed()
{
play.mousePressed();
rewind.mousePressed();
ffwd.mousePressed();
}

void mouseReleased()
{
play.mouseReleased();
rewind.mouseReleased();
ffwd.mouseReleased();
}

abstract class Button
{
int x, y, hw, hh;

Button(int x, int y, int hw, int hh)
{
    this.x = x;
    this.y = y;
    this.hw = hw;
    this.hh = hh;
}

boolean pressed()
{
    return mouseX > x - hw && mouseX < x + hw && mouseY > y - hh && mouseY < y + hh;
}

abstract void mousePressed();
abstract void mouseReleased();
abstract void update();
abstract void draw();
}

class Play extends Button
{
boolean play;
boolean invert;

Play(int x, int y, int hw, int hh)
{
    super(x, y, hw, hh);
    play = true;
}

// code to handle playing and pausing the file
void mousePressed()
{
    if ( pressed() )
    {
      invert = true;
      if ( song.isPlaying() )
      {
      song.pause();
      play = true;
      }
      else
      {
      song.loop();
      play = false;
      }
    }
}

void mouseReleased()
{
    invert = false;
}

// play is a boolean value used to determine what to draw on the button
void update()
{
    if ( song.isPlaying() ) play = false;
    else play = true;
}

void draw()
{
    if ( invert )
    {
      fill(255);
      stroke(0);
    }
    else
    {
      noFill();
      stroke(255);
    }
    rect(x - hw, y - hh, hw*2, hh*2);
    if ( invert )
    {
      fill(0);
      stroke(255);
    }
    else
    {
      fill(255);
      noStroke();
    }
    if ( play )
    {
      triangle(x - hw/3, y - hh/2, x - hw/3, y + hh/2, x + hw/2, y);
    }
    else
    {
      rect(x - hw/3, y - hh/2, hw/4, hh);
      rect(x + hw/8, y - hh/2, hw/4, hh);
    }
}
}

class Rewind extends Button
{
boolean invert;
boolean pressed;

Rewind(int x, int y, int hw, int hh)
{
    super(x, y, hw, hh);
    invert = false;
}

// code used to scrub backward in the file
void update()
{
    // if the rewind button is currently being pressed
    if (pressed)
    {
      // get the current song position
      int pos = song.position();
      // if it greater than 200 milliseconds
      if ( pos > 200 )
      {
      // rewind the song by 200 milliseconds
      song.skip(-200);
      }
      else
      {
      // if the song hasn't played more than 100 milliseconds
      // just rewind to the beginning
      song.rewind();
      }
    }
}

void mousePressed()
{
    pressed = pressed();
    if ( pressed )
    {
      invert = true;
      // if the song isn't currently playing, rewind it to the beginning
      if ( !song.isPlaying() ) song.rewind();      
    }
}

void mouseReleased()
{
    pressed = false;
    invert = false;
}

void draw()
{
    if ( invert )
    {
      fill(255);
      stroke(0);
    }
    else
    {
      noFill();
      stroke(255);
    }
    rect(x - hw, y - hh, hw*2, hh*2);
    if ( invert )
    {
      fill(0);
      stroke(255);
    }
    else
    {
      fill(255);
      noStroke();
    }
    triangle(x - hw/2, y, x, y - hh/2, x, y + hh/2);
    triangle(x, y, x + hw/2, y - hh/2, x + hw/2, y + hh/2);   
}
}

class Forward extends Button
{
boolean invert;
boolean pressed;

Forward(int x, int y, int hw, int hh)
{
    super(x, y, hw, hh);
    invert = false;
}

void update()
{
    // if the forward button is currently being pressed
    if (pressed)
    {
      // get the current position of the song
      int pos = song.position();
      // if the song's position is more than 40 milliseconds from the end of the song
      if ( pos < song.length() - 40 )
      {
      // forward the song by 40 milliseconds
      song.skip(40);
      }
      else
      {
      // otherwise, cue the song at the end of the song
      song.cue( song.length() );
      }
      // start the song playing
      song.play();
    }
}

void mousePressed()
{
    pressed = pressed();
    if ( pressed )
    {
      invert = true;      
    }
}

void mouseReleased()
{
    pressed = false;
    invert = false;
}

void draw()
{
    if ( invert )
    {
      fill(255);
      stroke(0);
    }
    else
    {
      noFill();
      stroke(255);
    }
    rect(x - hw, y - hh, hw*2, hh*2);
    if ( invert )
    {
      fill(0);
      stroke(255);
    }
    else
    {
      fill(255);
      noStroke();
    }
    triangle(x, y, x - hw/2, y - hh/2, x - hw/2, y + hh/2);
    triangle(x, y - hh/2, x, y + hh/2, x + hw/2, y);   
}
}
以上是一个官方的例子,很多minim的功能都要参照其官网的文档。

举一个比较使用的例子
如果游戏中我们想处理一个音效,让它只出现一次,song.loop(0);就可以了。不用搞太复杂。

laozjx 发表于 2016-6-22 16:52:30

谢谢楼主,学习了。
页: [1]
查看完整版本: Processing之旅-----【给鱼插上翅膀,Processing基础扩展库2】