Manual: Controller

[ javadoc | examples ]

As mentioned in the previous section, JavaSound uses Lines to transfer audio between your program and the system. Each line has controls associated with it that let you change things like panning, balance, gain, and volume. The advantage is that you needn’t worry about implementing these types of controls in your own audio synthesis classes, but the disadvantage is that when playing back audio the controls take effect after your application receives the samples. This means that you could be playing some stereo file with the balance set to hard right and you will not see any difference in the samples that you can access. In other words, while you may expect that the left channel will contain all zeros, it will still contain what actually exists in the left channel of the file. On the other hand, when monitoring the audio input, setting a control will be reflected in the sample buffers because it will take effect before your application receives the audio.

Printing Controls

Not all controls are available on all lines. You can use the printControls method to print a list of the controls available to a controller, as well as the ranges of those controls, in the console of the PDE.

Code Sample (view online)

[snip code_sample]http://code.compartmental.net/minim/examples/Controller/printControls/PrintControls.pde[/snip]

Querying For Controls

Printing the available controls to the console is informative if you are just beginning development, but the reality is that different controls may be available on different computers (this is a problem I hope to address in a future release). To cope with this, Controller provides the hasControl method, so that you can determine if a control exists before you try to use it. The argument to the hasControl method is a Control.Type, which is a class defined by the JavaSound API. Controller has six static members of this type, which correspond to commonly found controls. They are BALANCE, GAIN, PAN, MUTE, SAMPLE_RATE, and VOLUME.

Code Sample (view online)

[snip code_sample]http://code.compartmental.net/minim/examples/Controller/hasControl/hasControl.pde[/snip]

Getting and Setting Controls

Once you know what controls are available you can use the appropriate set and get methods to manipulate them. The getters and setters are:

[snip java]
setBalance(float value)
getBalance()
setGain(float value)
getGain()
setPan(float value)
getPan()
setVolume(float value)
getVolume()
[/snip]

The range for balance is from -1 to 1, for gain it is usually from -80 to 6, for pan it is from -1 to 1, and for volume I don’t know the range because I’ve yet to use a line that it was available on. For all intents and purposes, gain is basically the same as volume. Below is an example that manipulates the gain of an output. Examples for the other controls can be found here.

Code Sample (view online)

[snip code_sample]http://code.compartmental.net/minim/examples/Controller/getSetGain/getSetGain.pde[/snip]

Shifting Controls

All of these controls are so-called float controls because they represent a continuous range of values. Controller provides methods to change the value of one of these controls over time. This is called shifting. The shifting methods are as follows:

[snip java]
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)
[/snip]

As is probably obvious, from is the value to start at, to is the target value, and ms is how long the shift should take in milliseconds.

In the event that you try to get, set, or shift a control that is not available, Minim will print an error message in the console of the PDE, but your application will not crash. The following code sample demonstrates how you can use each of the shift methods.

Code Sample (view online)

[snip code_sample]http://code.compartmental.net/minim/examples/Controller/shifting/shifting.pde[/snip]

Muting

Finally, muting is often available as a control on a line. The muting methods are as follows, their names should be pretty self-explanatory:

[snip java]
isMuted()
mute()
unmute()
[/snip]

Once again, if muting is not an available control, muting and unmuting will do nothing and an error will be printed in the console informing you that muting is not available.

Code Sample (view online)

[snip code_sample]http://code.compartmental.net/minim/examples/Controller/muting/muting.pde[/snip]

Using A Control Directly

All of the methods described so far are actually convenience methods that access the appropriate Controls of a Line and call the appropriate methods. However, it is possible for you to directly access these JavaSound controls and manipulate them yourself. The first way to do this is to use the getControls method of Controller. This method returns an array of Control objects which you will then need to cast to the appropriate class (either FloatControl or BooleanControl). You can determine the control’s type by calling its getType method and then comparing the returned Control.Type to one of the static members of Controller mentioned above. You might also use instanceof to simply determine which class it is before casting it.

Code Sample (view online)

[snip code_sample]http://code.compartmental.net/minim/examples/Controller/getControls/getControls.pde[/snip]

Each of these methods returns the appropriate FloatControl. They do not check availablity before trying to get the control from the Line and will throw an IllegalArgumentException if the control is not available. You can avoid this situation by checking for a control’s availability with hasControl before calling one of these methods. Here’s an example of using pan() to access the pan control, rather than using the setPan method.

Code Sample (online example)

[snip code_sample]http://code.compartmental.net/minim/examples/Controller/FloatControl/getSetValue/getSetValue.pde[/snip]

Detailing all of the methods of a FloatControl here would be a bit much, so instead I recommend you take a look at the Javadoc for the class or check out my online examples for the class.

7 thoughts on “Manual: Controller

  1. hi there!

    is there anyway to control the sample rate, thus changing playback speed of an audioplayer file while playing??
    tried lots of stuff, but nothing works.

    the code handling sampling rate looks like this so far:

    if (player.isPlaying()) {
    if (player.hasControl(Controller.SAMPLE_RATE)) {
    float val = map(mouseX, 0, width, 0.0, 44100.0);
    println(player.sampleRate().setValue(val));
    }
    }

    i get “Cannot invoke setValue(float) on the primitive type float”

    any help is very much appreciated!

    cheers.

  2. The sampleRate() method you are calling returns a float value that is the current sample rate of the player. It’s not like the pan() method, which returns a FloatControl that you can use to change the pan value. A sample rate control is typically not available, but if it is, you can get it by using player.getControl(Controller.SAMPLE_RATE). If there is no sample rate control available, this method will return null, so be sure you check for that or your program will crash when you try to use the return value.

  3. hi. i’ve been working through your tutorial which i’ve found to be quite enjoyable!

    on the examples above:

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

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

    i get a “Cannot find a class or type named “WaveformRenderer” error.

    i’m using processing 1.0.9 with minim 2.0.2

    any ideas about this?

    thanks!

  4. okay! i finally figured out what is going on!
    it was just that missing piece of code defining the WaveformRenderer class…

    this is really cool! thanks again!

    jasper

  5. when I try to call this method on my audioplayer object:

    audioPlayerObject.hasControl(Controller.VOLUME)

    it tells me that the function does not exist. How do you change volume or gain on an audioplayer object???

  6. Loads of thanks for your impressive work.

    I’m wondering if there is any way of changing the playback speed of recorded audio. ..or if you have any advice for me where to start looking if I want to create a class (within or without Minim) which can do this.