Minim:控制器

[ javadoc | 范例 ]

像之前的章节里提到的,JavaSound使用Line在你的系统和程序间传递音频。每条线路都可以通过它进行声相、平衡、增益和音量调节。优点是你无须在你的合成类里执行以上的控制,但缺点是在回放音频时,只有当你的软件接到采样后这些控制才会起作用。这意味着你在播放一个立体声音频时,即使将平衡调至极右,你也不会在你的采样中看到任何差别。换句话说,当你以为左声道的值为0的时候,它仍将保存原始音频文件左声道内的一起实际存在的东西。另外,在监听音频输入的时候,设置一个控制将被反映入采样缓冲器中,因为它将在你的软件收到音频之前起效。

打印控制

并非所有控制在所有线路上都可用。你可以使用方法printControls打印出一个控制器上可用的控制,同时包括那些控制的范围。

示范代码在线范例

import ddf.minim.*;

Minim minim;
AudioOutput out;

void setup()
{
  size(512, 200);
  minim = new Minim(this);
  out = minim.getLineOut();
  out.printControls();
}

void draw()
{
  background(0);
}

void stop()
{
  // 日完记得关闭Minim音频类
  out.close();
  minim.stop();

  super.stop();
}

询问控制

Controller提供方法hasControl,这样你可以在尝试使用一个控制前测定它是否存在。hasControl的引数为Control.Type。控制器包括三个静态成员(member),他们是BALANCE, GAIN, PAN, MUTE, SAMPLE_RATE和VOLUME。

示范代码在线范例

import ddf.minim.*;

Minim minim;
AudioOutput out;

void setup()
{
  size(512, 200);
  minim = new Minim(this);
  out = minim.getLineOut();

  textFont(createFont("Arial", 12));
}

void draw()
{
  background(0);

  if ( out.hasControl(Controller.PAN) )
  {
    text("The output has a pan control.", 5, 15);
  }
  else
  {
    text("The output doesn't have a pan control.", 5, 15);
  }

  if ( out.hasControl(Controller.VOLUME) )
  {
    text("The output has a volume control.", 5, 30);
  }
  else
  {
    text("The output doesn't have a volume control.", 5, 30);
  }

  if ( out.hasControl(Controller.SAMPLE_RATE) )
  {
    text("The output has a sample rate control.", 5, 45);
  }
  else
  {
    text("The output doesn't have a sample rate control.", 5, 45);
  }

  if ( out.hasControl(Controller.BALANCE) )
  {
    text("The output has a balance control.", 5, 60);
  }
  else
  {
    text("The output doesn't have a balance control.", 5, 60);
  }

  if ( out.hasControl(Controller.MUTE) )
  {
    text("The output has a mute control.", 5, 75);
  }
  else
  {
    text("The output doesn't have a mute control.", 5, 75);
  }

  if ( out.hasControl(Controller.GAIN) )
  {
    text("The output has a gain control.", 5, 90);
  }
  else
  {
    text("The output doesn't have a gain control.", 5, 105);
  }
}

void stop()
{
  // 日完记得XXXXXX
  out.close();
  minim.stop();

  super.stop();
}

获取和设置控制器

当你知道了你可以使用什么控制后,你可以使用适当的方法get(获取)和set(设置)操作它们。

setBalance(float value)
getBalance()
setGain(float value)
getGain()
setPan(float value)
getPan()
setVolume(float value)
getVolume()

平衡的范围是-1~1,增益常从-80~6,声相也是从-1~1,音量的范围作者说他自己也不知道。。。从所有的使用上,增益基本上等同于音量。以下是操作一个输出的增益的例子。其他控制的例子可以在这里找到。

示范代码在线范例

import ddf.minim.*;
import ddf.minim.signals.*;

Minim minim;
AudioOutput out;
Oscillator  osc;
WaveformRenderer waveform;

void setup()
{
  size(512, 200);
  minim = new Minim(this);
  out = minim.getLineOut();

  // see the example AudioOutput >> SawWaveSignal for more about this class
  osc = new SawWave(100, 0.2, out.sampleRate());
  // see the example Polyphonic >> addSignal for more about this
  out.addSignal(osc);

  waveform = new WaveformRenderer();
  // see the example Recordable >> addListener for more about this
  out.addListener(waveform);

  textFont(createFont("Arial", 12));
}

void draw()
{
  background(0);
  // see waveform.pde for more about this
  waveform.draw();

  if ( out.hasControl(Controller.GAIN) )
  {
    // 将鼠标位置映射到可听到的增益范围内
    float val = map(mouseX, 0, width, 6, -48);
    // 如果一个增益控制不可用,这里将什么都不做
    out.setGain(val);
    // 如果一个增益控制不可用,这里将输出0
    text("The current gain is " + out.getGain() + ".", 5, 15);
  }
  else
  {
    text("The output doesn't have a gain control.", 5, 15);
  }
}

void stop()
{
  // 日完记得XXXXX
  out.close();
  minim.stop();

  super.stop();
}

变化控制

因为反映的是一系列连续值的范围,所以所有这些控制都被称为浮点控制。Controller为持续改变这些控制之一的值提供方法。这被称为变化(shifting)。shifting的方法如下:

shiftBalance(float from, float to, int ms)
shiftGain(float from, float to, int ms)
shiftPan(float from, float to, int ms)
shiftVolume(float from, float to, int ms)

很明显的,from是一个值开始的点,to是目标值,ms是以毫秒计的shift作用时间。

示范代码在线范例

import ddf.minim.*;
import ddf.minim.signals.*;

Minim minim;
AudioOutput out;
WaveformRenderer waveform;
SawWave saw;

void setup()
{
  size(512, 200);
  minim = new Minim(this);
  out = minim.getLineOut();

  waveform = new WaveformRenderer();
  // see the example Recordable >> addListener for more about this
  out.addListener(waveform);

  // see the example AudioOutput >> SawWaveSignal for more about this
  saw = new SawWave(100, 0.2, out.sampleRate());
  // see the example Polyphonic >> addSignal for more about this
  out.addSignal(saw);

  textFont(createFont("Arial", 12));
}

void draw()
{
  background(0);
  // see waveform.pde for more about this
  waveform.draw();

  if ( out.hasControl(Controller.PAN) )
  {
    text("The current pan value is " + out.getPan() + ".", 5, 15);
  }
  else
  {
    text("The output doesn't have a pan control.", 5, 15);
  }

  if ( out.hasControl(Controller.VOLUME) )
  {
    text("The current volume value is " + out.getVolume() + ".", 5, 30);
  }
  else
  {
    text("The output doesn't have a volume control.", 5, 30);
  }

  if ( out.hasControl(Controller.BALANCE) )
  {
    text("The current balance value is " + out.getBalance() + ".", 5, 45);
  }
  else
  {
    text("The output doesn't have a balance control.", 5, 45);
  }

  if ( out.hasControl(Controller.GAIN) )
  {
    text("The current gain value is " + out.getGain() + ".", 5, 60);
  }
  else
  {
    text("The output doesn't have a gain control.", 5, 60);
  }
}

void keyReleased()
{
  if ( key == 'v' ) out.shiftVolume(0, 1, 2000);
  if ( key == 'g' ) out.shiftGain(-40, 0, 2000);
  if ( key == 'b' ) out.shiftBalance(-1, 1, 2000);
  if ( key == 'p' ) out.shiftPan(1, -1, 2000);
}

void stop()
{
  // always close Minim audio classes when you are finished with them
  out.close();
  minim.stop();

  super.stop();
}

静音

如下

isMuted()
mute()
unmute()

再次,如果静音不是一个可用的控制,静音和非静音将不起任何作用,并会在PDE控制台输出错误信息。

示范代码在线范例

import ddf.minim.*;
import ddf.minim.signals.*;

Minim minim;
AudioOutput out;
WaveformRenderer waveform;
SawWave saw;

void setup()
{
  size(512, 200);
  minim = new Minim(this);
  out = minim.getLineOut();

  waveform = new WaveformRenderer();
  // see the example Recordable >> addListener for more about this
  out.addListener(waveform);

  // see the example AudioOutput >> SawWaveSignal for more about this
  saw = new SawWave(100, 0.2, out.sampleRate());
  // see the example Polyphonic >> addSignal for more about this
  out.addSignal(saw);

  textFont(createFont("Arial", 12));
}

void draw()
{
  background(0);
  // see waveform.pde for more about this
  waveform.draw();

  if ( out.hasControl(Controller.MUTE) )
  {
    if (mousePressed)
    {
      out.mute();
    }
    else
    {
      out.unmute();
    }
    if ( out.isMuted() )
    {
      text("The output is muted.", 5, 15);
    }
    else
    {
      text("The output is not muted.", 5, 15);
    }
  }
  else
  {
    text("The output doesn't have a mute control.", 5, 15);
  }
}

void stop()
{
  // always close Minim audio classes when you are finished with them
  out.close();
  minim.stop();

  super.stop();
}

直接使用一个控制

使用控制更直接的方式是使用Controller的方法getControls。这个方法返回Control对象的数组,你可以使用方法getType测定一个控制的类型。

示范代码在线范例

import ddf.minim.*;
import ddf.minim.signals.*;
import javax.sound.sampled.Control;

Minim minim;
AudioOutput out;
Control[] controls;

void setup()
{
  size(512, 200);
  minim = new Minim(this);
  out = minim.getLineOut();
  controls = out.getControls();

  textFont(createFont("Arial", 12));
}

void draw()
{
  background(0);

  for ( int i = 0; i < controls.length; i++ )
  {
    text("Control " + (i+1) + " is a " + controls[i].toString() + ".", 5, 15 + i*15);
  }
}

void stop()
{
  // always close Minim audio classes when you are finished with them
  out.close();
  minim.stop();

  super.stop();
}

所有这些方法都返回适当的FloatControl。以下是使用pan()而不是setPan进入声相控制的例子:

示范代码在线范例

import ddf.minim.*;
import ddf.minim.signals.*;

Minim minim;
AudioOutput out;
Oscillator  osc;
WaveformRenderer waveform;

void setup()
{
  size(512, 200);
  minim = new Minim(this);
  out = minim.getLineOut();

  // see the example AudioOutput >> SawWaveSignal for more about this class
  osc = new SawWave(100, 0.2, out.sampleRate());
  // see the example Polyphonic >> addSignal for more about this
  out.addSignal(osc);

  waveform = new WaveformRenderer();
  // see the example Recordable >> addListener for more about this
  out.addListener(waveform);

  textFont(createFont("Arial", 12));
}

void draw()
{
  background(0);
  // see waveform.pde for more about this
  waveform.draw();

  if ( out.hasControl(Controller.PAN) )
  {
    // map the mouse position to the range of the pan
    float val = map(mouseX, 0, width, out.pan().getMinimum(), out.pan().getMaximum());
    out.pan().setValue(val);
    text("The current pan is " + out.pan().getValue() + ".", 5, 15);
  }
  else
  {
    text("There is no pan control for this output.", 5, 15);
  }
}

void stop()
{
  // always close Minim audio classes when you are finished with them
  out.close();
  minim.stop();

  super.stop();
}

要细讲FloatControl的所有方法实在太多,所以还是仔细读读javadoc或者研究一下在线范例们吧。

FloatControl
Be Sociable, Share!

《Minim:控制器》有一个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.