Initial commit.
This commit is contained in:
BIN
src/dk/itu/mario/engine/sonar/mixer/.DS_Store
vendored
Normal file
BIN
src/dk/itu/mario/engine/sonar/mixer/.DS_Store
vendored
Normal file
Binary file not shown.
93
src/dk/itu/mario/engine/sonar/mixer/ListenerMixer.java
Normal file
93
src/dk/itu/mario/engine/sonar/mixer/ListenerMixer.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package dk.itu.mario.engine.sonar.mixer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
|
||||
import dk.itu.mario.engine.sonar.SoundListener;
|
||||
import dk.itu.mario.engine.sonar.SoundProducer;
|
||||
import dk.itu.mario.engine.sonar.SoundSource;
|
||||
import dk.itu.mario.engine.sonar.StereoSoundProducer;
|
||||
|
||||
public class ListenerMixer implements StereoSoundProducer
|
||||
{
|
||||
private List<Sound> sounds = new ArrayList<Sound>();
|
||||
private float[] buf = new float[0];
|
||||
private int maxChannels;
|
||||
private SoundListener soundListener;
|
||||
|
||||
public ListenerMixer(int maxChannels)
|
||||
{
|
||||
this.maxChannels = maxChannels;
|
||||
}
|
||||
|
||||
public void setSoundListener(SoundListener soundListener)
|
||||
{
|
||||
this.soundListener = soundListener;
|
||||
}
|
||||
|
||||
public void addSoundProducer(SoundProducer producer, SoundSource soundSource, float volume, float priority)
|
||||
{
|
||||
sounds.add(new Sound(producer, soundSource, volume, priority));
|
||||
}
|
||||
|
||||
public void update(float alpha)
|
||||
{
|
||||
for (Iterator it = sounds.iterator(); it.hasNext();)
|
||||
{
|
||||
Sound sound = (Sound) it.next();
|
||||
sound.update(soundListener, alpha);
|
||||
if (!sound.isLive())
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public float read(float[] leftBuf, float[] rightBuf, int readRate)
|
||||
{
|
||||
if (buf.length != leftBuf.length) buf = new float[leftBuf.length];
|
||||
|
||||
if (sounds.size() > maxChannels)
|
||||
{
|
||||
Collections.sort(sounds);
|
||||
}
|
||||
|
||||
Arrays.fill(leftBuf, 0);
|
||||
Arrays.fill(rightBuf, 0);
|
||||
float maxAmplitude = 0;
|
||||
for (int i = 0; i < sounds.size(); i++)
|
||||
{
|
||||
Sound sound = (Sound) sounds.get(i);
|
||||
if (i < maxChannels)
|
||||
{
|
||||
sound.read(buf, readRate);
|
||||
float rp = (sound.pan<0?1:1-sound.pan)*sound.amplitude;
|
||||
float lp = (sound.pan>0?1:1+sound.pan)*sound.amplitude;
|
||||
for (int j = 0; j < leftBuf.length; j++)
|
||||
{
|
||||
leftBuf[j] += buf[j]*lp;
|
||||
rightBuf[j] += buf[j]*rp;
|
||||
if (leftBuf[j]>maxAmplitude) maxAmplitude = leftBuf[j];
|
||||
if (rightBuf[j]>maxAmplitude) maxAmplitude = rightBuf[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sound.skip(leftBuf.length, readRate);
|
||||
}
|
||||
}
|
||||
|
||||
return maxAmplitude;
|
||||
}
|
||||
|
||||
public void skip(int samplesToSkip, int readRate)
|
||||
{
|
||||
for (int i = 0; i < sounds.size(); i++)
|
||||
{
|
||||
Sound sound = (Sound) sounds.get(i);
|
||||
sound.skip(samplesToSkip, readRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/dk/itu/mario/engine/sonar/mixer/Sound.java
Normal file
84
src/dk/itu/mario/engine/sonar/mixer/Sound.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package dk.itu.mario.engine.sonar.mixer;
|
||||
|
||||
|
||||
|
||||
import dk.itu.mario.engine.sonar.SoundListener;
|
||||
import dk.itu.mario.engine.sonar.SoundProducer;
|
||||
import dk.itu.mario.engine.sonar.SoundSource;
|
||||
|
||||
|
||||
public class Sound implements Comparable
|
||||
{
|
||||
private static final double l10 = Math.log(10);
|
||||
|
||||
private SoundProducer producer;
|
||||
private SoundSource source;
|
||||
private float volume;
|
||||
private float priority;
|
||||
|
||||
private float x, y, z;
|
||||
private float score = 0;
|
||||
|
||||
public float pan;
|
||||
public float amplitude;
|
||||
|
||||
public Sound(SoundProducer producer, SoundSource source, float volume, float priority)
|
||||
{
|
||||
this.producer = producer;
|
||||
this.source = source;
|
||||
this.volume = volume;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public void update(SoundListener listener, float alpha)
|
||||
{
|
||||
x = source.getX(alpha)-listener.getX(alpha);
|
||||
y = source.getY(alpha)-listener.getY(alpha);
|
||||
|
||||
float distSqr = x*x+y*y+z*z;
|
||||
float dist = (float)Math.sqrt(distSqr);
|
||||
|
||||
float REFERENCE_DISTANCE = 1;
|
||||
float ROLLOFF_FACTOR = 2;
|
||||
|
||||
// float dB = (float)(volume + (20 * (Math.log(1.0 / distSqr) / l10)));
|
||||
float dB = (float)(volume - 20*Math.log(1 + ROLLOFF_FACTOR*(dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE )/ l10);
|
||||
dB = Math.min(dB, +6);
|
||||
// dB = Math.max(dB, MIN_GAIN);
|
||||
|
||||
score = dB*priority;
|
||||
|
||||
// double angle = WMath.atan2(y, x);
|
||||
|
||||
float p = -x/320.0f;
|
||||
if (p<-1) p = -1;
|
||||
if (p>1) p = 1;
|
||||
float dd = distSqr/16;
|
||||
if (dd>1) dd = 1;
|
||||
pan =(p*dd);
|
||||
amplitude = volume*1f;
|
||||
}
|
||||
|
||||
public void read(float[] buf, int readRate)
|
||||
{
|
||||
producer.read(buf, readRate);
|
||||
}
|
||||
|
||||
public void skip(int samplesToSkip, int readRate)
|
||||
{
|
||||
producer.skip(samplesToSkip, readRate);
|
||||
}
|
||||
|
||||
public boolean isLive()
|
||||
{
|
||||
return producer.isLive();
|
||||
}
|
||||
|
||||
public int compareTo(Object o)
|
||||
{
|
||||
Sound s = (Sound)o;
|
||||
if (s.score>score) return 1;
|
||||
if (s.score<score) return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user