In this Discussion

Minim/Tuio combination

I tried the setVolume or setGain instances both didn't change anything. I am trying to start with no sound till tuioCursorList.size is bigger than 0 and when it is, sound can fade in with a simple for loop but all my attempts on changing the volume failed so couldn't implement it to the code.

I got part of the code from Minim > Synthesis > realtimeControlExample and some stuff are out of my reach. In the code below. The out.PlayNote takes 3 parameter I got the idea of them first is the start point, second is the duration and thirds is the note which will be played. How can I set so that the note plays not just for defined time but as long as program is running?

And the I tried calling out.playNote in draw and didn't work, works only when its called setup which makes it harder for me to change the parameters.

// import everything necessary to make sound.
import ddf.minim.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;
import TUIO.*;
TuioProcessing tuioClient = new TuioProcessing(this);
ArrayList<TuioCursor> tuioCursorList = new ArrayList<TuioCursor>();
Minim minim;
AudioOutput out;
NoiseInstrument myNoise;
float x = 0;
float y = 0;
float xPos;
float yPos;
void setup()
{
size( 500, 500, P2D );
minim = new Minim( this );
out = minim.getLineOut( Minim.MONO, 512 );
myNoise = new NoiseInstrument( 1.0, out );
out.playNote( 0, 100.0, myNoise );
}
void draw()
{
background( 0 );
tuioCursorList = tuioClient.getTuioCursorList();
for (int i=0; i<tuioCursorList.size(); i++) {
TuioCursor tc = tuioCursorList.get(i);
xPos = tc.getScreenX(width);
yPos = tc.getScreenY(height);
if ( tuioCursorList.size() > 0) {
float freq = map( yPos, 0, height, 200, 120 );
float q = map( xPos, 0, width, 15, 25 );
myNoise.setFilterCF( freq );
myNoise.setFilterQ( q );
println(tuioCursorList.size());
}
}
}
// Every instrument must implement the Instrument interface so
// playNote() can call the instrument's methods.
// This noise instrument uses white noise and two bandpass filters
// to make a "whistling wind" sound. By changing using the methods which
// change the frequency and the bandwidth of the filters, the sound changes.
class NoiseInstrument implements Instrument
{
// create all variables that must be used throughout the class
Noise myNoise;
Multiplier multiply;
AudioOutput out;
BandPass filt1, filt2;
Summer sum;
float freq1, freq2, freq3;
float bandWidth1, bandWidth2;
float filterFactor;
// constructors for this intsrument
NoiseInstrument( float amplitude, AudioOutput output )
{
// equate class variables to constructor variables as necessary
out = output;
// give some initial values to the realtime control variables
freq1 = 150.0;
bandWidth1 = 10.0;
filterFactor = 1.7;
// create new instances of any UGen objects
myNoise = new Noise( amplitude, Noise.Tint.WHITE );
multiply = new Multiplier( 0 );
filt1 = new BandPass( freq1, bandWidth1, out.sampleRate() );
filt2 = new BandPass( freq2(), bandWidth2(), out.sampleRate() );
sum = new Summer();
// patch everything (including the out this time)
myNoise.patch( filt1 ).patch( sum );
myNoise.patch( filt2 ).patch( sum );
sum.patch( multiply );
}
// every instrument must have a noteOn( float ) method
void noteOn( float dur )
{
// set the multiply to 1 to turn on the note
multiply.setValue( 1 );
multiply.patch( out );
}
// every instrument must have a noteOff() method
void noteOff()
{
// set the multiply to 0 to turn off the note
multiply.setValue( 0 );
multiply.unpatch( out );
}
// this is a helper method only used internally to find the second filter
float freq2()
{
// calculate the second frequency based on the first
return filterFactor*freq1;
}
// this is a helper method only used internally
// to find the bandwidth of the second filter
float bandWidth2()
{
// calculate the second bandwidth based on the first
return filterFactor*bandWidth1;
}
// this is a method to set the center frequencies
// of the two filters based on the CF of the first
void setFilterCF( float cf )
{
freq1 = cf;
filt1.setFreq( freq1 );
filt2.setFreq( freq2() );
}
// this is a method to set the bandwidths
// of the two filters based on the BW of the first
void setFilterBW( float bw )
{
bandWidth1 = bw;
filt1.setBandWidth( bandWidth1 );
filt2.setBandWidth( bandWidth2() );
}
// this is a method to set the Q (inverse of bandwidth)
// of the two filters based on the
void setFilterQ( float q )
{
setFilterBW( freq1/q );
}
}
// called when a cursor is added to the scene
void addTuioCursor(TuioCursor tcur) {
}
// called when a cursor is moved
void updateTuioCursor (TuioCursor tcur) {
}
// called when a cursor is removed from the scene
void removeTuioCursor(TuioCursor tcur) {
}
// --------------------------------------------------------------
// these callback methods are called whenever a TUIO event occurs
// there are three callbacks for add/set/del events for each object/cursor/blob type
// the final refresh callback marks the end of each TUIO frame
// called when an object is added to the scene
void addTuioObject(TuioObject tobj) {
}
// called when an object is moved
void updateTuioObject (TuioObject tobj) {
}
// called when an object is removed from the scene
void removeTuioObject(TuioObject tobj) {
}
// --------------------------------------------------------------
// called when a blob is added to the scene
void addTuioBlob(TuioBlob tblb) {
}
// called when a blob is moved
void updateTuioBlob (TuioBlob tblb) {
}
// called when a blob is removed from the scene
void removeTuioBlob(TuioBlob tblb) {
}
// --------------------------------------------------------------
// called at the end of each TUIO frame
void refresh(TuioTime frameTime) {
}

Right, okay. So here's the example that demonstrates changing the gain.

/**
* This sketch demonstrates how to use the <code>getGain</code> and <code>setGain</code> methods of a
* <code>Controller</code> object. The class used here is an <code>AudioOutput</code> but you can also
* get and set the gain of <code>AudioSample</code>, <code>AudioSnippet</code>, <code>AudioInput</code>,
* and <code>AudioPlayer</code> objects. <code>getGain</code> and <code>setGain</code> will get and set
* the gain of the <code>DataLine</code> that is being used for input or output, but only if that line has
* a gain control. A <code>DataLine</code> is a low-level JavaSound class that is used for sending audio to,
* or receiving audio from, the audio system. You will notice in this sketch that you will hear the gain
* changing (if it's available) but you will not see any difference in the waveform being drawn. The reason for this
* is that what you see in the output's sample buffers is what it sends to the audio system. The system makes the
* gain change after receiving the samples.
*/
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) )
{
// map the mouse position to the audible range of the gain
float val = map(mouseX, 0, width, 6, -48);
// if a gain control is not available, this will do nothing
out.setGain(val);
// if a gain control is not available this will report zero
text("The current gain is " + out.getGain() + ".", 5, 15);
}
else
{
text("The output doesn't have a gain control.", 5, 15);
}
}

When you run this, do you get changing gain based on the mouse Position?