/*
* Copyright (c) 2007 - 2008 by Damien Di Fede <ddf@compartmental.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package ddf.minim;
/**
* <code>MAudioBuffer</code> encapsulates a sample buffer of floats. All Minim
* classes that give you access to audio samples do so with an
* <code>MAudioBuffer</code>. The underlying array is not immutable and this
* class has a number of methods for reading and writing to that array. It is
* even possible to be given a direct handle on the array to process it as you
* wish.
*
* @author Damien Di Fede
*
*/
final class MAudioBuffer implements AudioBuffer
{
private float[] samples;
/**
* Constructs and MAudioBuffer that is <code>bufferSize</code> samples long.
*
* @param bufferSize
* the size of the buffer
*/
MAudioBuffer(int bufferSize)
{
samples = new float[bufferSize];
}
public synchronized int size()
{
return samples.length;
}
public synchronized float get(int i)
{
return samples[i];
}
public synchronized float get(float i)
{
int lowSamp = (int)i;
int hiSamp = lowSamp + 1;
if ( hiSamp == samples.length )
{
return samples[lowSamp];
}
float lerp = i - lowSamp;
return samples[lowSamp] + lerp*(samples[hiSamp] - samples[lowSamp]);
}
public synchronized void set(float[] buffer)
{
if (buffer.length != samples.length)
Minim
.error("MAudioBuffer.set: passed array (" + buffer.length + ") " +
"must be the same length (" + samples.length + ") as this MAudioBuffer.");
else
samples = buffer;
}
/**
* Mixes the two float arrays and puts the result in this buffer. The
* passed arrays must be the same length as this buffer. If they are not, an
* error will be reported and nothing will be done. The mixing function is:
* <p>
* <code>samples[i] = (b1[i] + b2[i]) / 2</code>
*
* @param b1
* the first buffer
* @param b2
* the second buffer
*/
public synchronized void mix(float[] b1, float[] b2)
{
if ((b1.length != b2.length)
|| (b1.length != samples.length || b2.length != samples.length))
{
Minim.error("MAudioBuffer.mix: The two passed buffers must be the same size as this MAudioBuffer.");
}
else
{
for (int i = 0; i < samples.length; i++)
{
samples[i] = (b1[i] + b2[i]) / 2;
}
}
}
/**
* Sets all of the values in this buffer to zero.
*/
public synchronized void clear()
{
samples = new float[samples.length];
}
public synchronized float level()
{
float level = 0;
for (int i = 0; i < samples.length; i++)
{
level += (samples[i] * samples[i]);
}
level /= samples.length;
level = (float) Math.sqrt(level);
return level;
}
public synchronized float[] toArray()
{
float[] ret = new float[samples.length];
System.arraycopy(samples, 0, ret, 0, samples.length);
return ret;
}
}