Initial commit.
This commit is contained in:
BIN
src/dk/itu/mario/engine/sonar/.DS_Store
vendored
Normal file
BIN
src/dk/itu/mario/engine/sonar/.DS_Store
vendored
Normal file
Binary file not shown.
38
src/dk/itu/mario/engine/sonar/FakeSoundEngine.java
Normal file
38
src/dk/itu/mario/engine/sonar/FakeSoundEngine.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package dk.itu.mario.engine.sonar;
|
||||
|
||||
|
||||
|
||||
import dk.itu.mario.engine.sonar.sample.SonarSample;
|
||||
|
||||
|
||||
public class FakeSoundEngine extends SonarSoundEngine
|
||||
{
|
||||
public void setListener(SoundListener soundListener)
|
||||
{
|
||||
}
|
||||
|
||||
public void shutDown()
|
||||
{
|
||||
}
|
||||
|
||||
public SonarSample loadSample(String resourceName)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void play(SonarSample sample, SoundSource soundSource, float volume, float priority, float rate)
|
||||
{
|
||||
}
|
||||
|
||||
public void clientTick(float alpha)
|
||||
{
|
||||
}
|
||||
|
||||
public void tick()
|
||||
{
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
}
|
||||
}
|
||||
33
src/dk/itu/mario/engine/sonar/FixedSoundSource.java
Normal file
33
src/dk/itu/mario/engine/sonar/FixedSoundSource.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package dk.itu.mario.engine.sonar;
|
||||
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public class FixedSoundSource implements SoundSource
|
||||
{
|
||||
private float x;
|
||||
private float y;
|
||||
|
||||
public FixedSoundSource(float x, float y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public FixedSoundSource(SoundSource soundSource)
|
||||
{
|
||||
this.x = soundSource.getX(1);
|
||||
this.y = soundSource.getY(1);
|
||||
}
|
||||
|
||||
public float getX(float alpha)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY(float alpha)
|
||||
{
|
||||
return y;
|
||||
}
|
||||
}
|
||||
145
src/dk/itu/mario/engine/sonar/SonarSoundEngine.java
Normal file
145
src/dk/itu/mario/engine/sonar/SonarSoundEngine.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package dk.itu.mario.engine.sonar;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import javax.sound.sampled.*;
|
||||
|
||||
|
||||
import dk.itu.mario.engine.sonar.mixer.ListenerMixer;
|
||||
|
||||
import dk.itu.mario.engine.sonar.sample.SamplePlayer;
|
||||
import dk.itu.mario.engine.sonar.sample.SonarSample;
|
||||
import dk.itu.mario.engine.sonar.sample.SampleLoader;
|
||||
|
||||
|
||||
|
||||
public class SonarSoundEngine implements Runnable
|
||||
{
|
||||
private SonarSample silentSample;
|
||||
private SourceDataLine sdl;
|
||||
private int rate = 44100;
|
||||
private ListenerMixer listenerMixer;
|
||||
private int bufferSize = rate / 100; // 10 ms
|
||||
private ByteBuffer soundBuffer = ByteBuffer.allocate(bufferSize * 4);
|
||||
private float[] leftBuf, rightBuf;
|
||||
private float amplitude = 1;
|
||||
private float targetAmplitude = 1;
|
||||
private boolean alive = true;
|
||||
|
||||
protected SonarSoundEngine()
|
||||
{
|
||||
}
|
||||
|
||||
public SonarSoundEngine(int maxChannels) throws LineUnavailableException
|
||||
{
|
||||
silentSample = new SonarSample(new float[] {0}, 44100);
|
||||
Mixer mixer = AudioSystem.getMixer(null);
|
||||
|
||||
sdl = (SourceDataLine) mixer.getLine(new Line.Info(SourceDataLine.class));
|
||||
sdl.open(new AudioFormat(rate, 16, 2, true, false), bufferSize * 2 * 2 * 2 * 2 * 2);
|
||||
soundBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
sdl.start();
|
||||
|
||||
try
|
||||
{
|
||||
/* FloatControl volumeControl = (FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN);
|
||||
volumeControl.setValue(volumeControl.getMaximum());*/
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
System.out.println("Failed to set the sound volume");
|
||||
}
|
||||
|
||||
listenerMixer = new ListenerMixer(maxChannels);
|
||||
|
||||
leftBuf = new float[bufferSize];
|
||||
rightBuf = new float[bufferSize];
|
||||
|
||||
Thread thread = new Thread(this);
|
||||
thread.setDaemon(true);
|
||||
thread.setPriority(10);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void setListener(SoundListener soundListener)
|
||||
{
|
||||
listenerMixer.setSoundListener(soundListener);
|
||||
}
|
||||
|
||||
public void shutDown()
|
||||
{
|
||||
alive = false;
|
||||
}
|
||||
|
||||
public SonarSample loadSample(String resourceName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SampleLoader.loadSample(resourceName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println("Failed to load sample " + resourceName + ". Using silent sample");
|
||||
e.printStackTrace();
|
||||
return silentSample;
|
||||
}
|
||||
}
|
||||
|
||||
public void play(SonarSample sample, SoundSource soundSource, float volume, float priority, float rate)
|
||||
{
|
||||
synchronized (listenerMixer)
|
||||
{
|
||||
if(!dk.itu.mario.engine.Art.mute)
|
||||
listenerMixer.addSoundProducer(new SamplePlayer((SonarSample) sample, rate), soundSource, volume, priority);
|
||||
}
|
||||
}
|
||||
|
||||
public void clientTick(float alpha)
|
||||
{
|
||||
synchronized (listenerMixer)
|
||||
{
|
||||
listenerMixer.update(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick()
|
||||
{
|
||||
soundBuffer.clear();
|
||||
|
||||
// targetAmplitude = (targetAmplitude - 1) * 0.9f + 1;
|
||||
// targetAmplitude = (targetAmplitude - 1) * 0.9f + 1;
|
||||
synchronized (listenerMixer)
|
||||
{
|
||||
float maxAmplitude = listenerMixer.read(leftBuf, rightBuf, rate);
|
||||
// if (maxAmplitude > targetAmplitude) targetAmplitude = maxAmplitude;
|
||||
}
|
||||
|
||||
soundBuffer.clear();
|
||||
float gain = 32000;
|
||||
for (int i = 0; i < bufferSize; i++)
|
||||
{
|
||||
// amplitude += (targetAmplitude - amplitude) / rate;
|
||||
// amplitude = 1;
|
||||
// float gain = 30000;
|
||||
int l = (int) (leftBuf[i] * gain);
|
||||
int r = (int) (rightBuf[i] * gain);
|
||||
if (l > 32767) l = 32767;
|
||||
if (r > 32767) r = 32767;
|
||||
if (l < -32767) l = -32767;
|
||||
if (r < -32767) r = -32767;
|
||||
soundBuffer.putShort((short)l);
|
||||
soundBuffer.putShort((short)r);
|
||||
}
|
||||
|
||||
sdl.write(soundBuffer.array(), 0, bufferSize * 2 * 2);
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
while (alive)
|
||||
{
|
||||
tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
6
src/dk/itu/mario/engine/sonar/SoundListener.java
Normal file
6
src/dk/itu/mario/engine/sonar/SoundListener.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package dk.itu.mario.engine.sonar;
|
||||
|
||||
|
||||
public interface SoundListener extends SoundSource
|
||||
{
|
||||
}
|
||||
8
src/dk/itu/mario/engine/sonar/SoundProducer.java
Normal file
8
src/dk/itu/mario/engine/sonar/SoundProducer.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package dk.itu.mario.engine.sonar;
|
||||
|
||||
public interface SoundProducer
|
||||
{
|
||||
public float read(float[] buf, int readRate);
|
||||
public void skip(int samplesToSkip, int readRate);
|
||||
public boolean isLive();
|
||||
}
|
||||
7
src/dk/itu/mario/engine/sonar/SoundSource.java
Normal file
7
src/dk/itu/mario/engine/sonar/SoundSource.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package dk.itu.mario.engine.sonar;
|
||||
|
||||
public interface SoundSource
|
||||
{
|
||||
public float getX(float alpha);
|
||||
public float getY(float alpha);
|
||||
}
|
||||
7
src/dk/itu/mario/engine/sonar/StereoSoundProducer.java
Normal file
7
src/dk/itu/mario/engine/sonar/StereoSoundProducer.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package dk.itu.mario.engine.sonar;
|
||||
|
||||
public interface StereoSoundProducer
|
||||
{
|
||||
public float read(float[] leftBuf, float[] rightBuf, int readRate);
|
||||
public void skip(int samplesToSkip, int readRate);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
BIN
src/dk/itu/mario/engine/sonar/sample/.DS_Store
vendored
Normal file
BIN
src/dk/itu/mario/engine/sonar/sample/.DS_Store
vendored
Normal file
Binary file not shown.
114
src/dk/itu/mario/engine/sonar/sample/SampleLoader.java
Normal file
114
src/dk/itu/mario/engine/sonar/sample/SampleLoader.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package dk.itu.mario.engine.sonar.sample;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
public class SampleLoader
|
||||
{
|
||||
/**
|
||||
* Loads a sample from an url
|
||||
*/
|
||||
public static SonarSample loadSample(String resourceName) throws UnsupportedAudioFileException, IOException
|
||||
{
|
||||
// Hack to prevent "mark/reset not supported" on some systems
|
||||
InputStream in=SampleLoader.class.getResourceAsStream(resourceName);
|
||||
byte[] d = rip(in);
|
||||
AudioInputStream ais = AudioSystem.getAudioInputStream(new ByteArrayInputStream(d));
|
||||
return buildSample(rip(ais), ais.getFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Rips the entire contents of an inputstream into a byte array
|
||||
*/
|
||||
private static byte[] rip(InputStream in) throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
byte[] b = new byte[4096];
|
||||
|
||||
int read = 0;
|
||||
while ((read = in.read(b)) > 0)
|
||||
{
|
||||
bos.write(b, 0, read);
|
||||
}
|
||||
|
||||
bos.close();
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorganizes audio sample data into the intenal sonar format
|
||||
*/
|
||||
private static SonarSample buildSample(byte[] b, AudioFormat af) throws UnsupportedAudioFileException
|
||||
{
|
||||
// Rip audioformat data
|
||||
int channels = af.getChannels();
|
||||
int sampleSize = af.getSampleSizeInBits();
|
||||
float rate = af.getFrameRate();
|
||||
boolean signed = af.getEncoding() == AudioFormat.Encoding.PCM_SIGNED;
|
||||
|
||||
// Sanity checking
|
||||
if (channels != 1) throw new UnsupportedAudioFileException("Only mono samples are supported");
|
||||
if (!(sampleSize == 8 || sampleSize == 16 || sampleSize == 32)) throw new UnsupportedAudioFileException("Unsupported sample size");
|
||||
if (!(af.getEncoding() == AudioFormat.Encoding.PCM_UNSIGNED || af.getEncoding() == AudioFormat.Encoding.PCM_SIGNED)) throw new UnsupportedAudioFileException("Unsupported encoding");
|
||||
|
||||
// Wrap the data into a bytebuffer, and set up the byte order
|
||||
ByteBuffer bb = ByteBuffer.wrap(b);
|
||||
bb.order(af.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
int s = b.length / (sampleSize / 8);
|
||||
float[] buf = new float[s];
|
||||
// Six different cases for reordering the data. Can this be improved without slowing it down?
|
||||
if (sampleSize == 8)
|
||||
{
|
||||
if (signed)
|
||||
{
|
||||
for (int i = 0; i < s; i++)
|
||||
buf[i] = bb.get() / (float)0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < s; i++)
|
||||
buf[i] = ((bb.get()&0xFF)-0x80) / (float)0x80;
|
||||
}
|
||||
}
|
||||
else if (sampleSize == 16)
|
||||
{
|
||||
if (signed)
|
||||
{
|
||||
for (int i = 0; i < s; i++)
|
||||
buf[i] = bb.getShort() / (float)0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < s; i++)
|
||||
buf[i] = ((bb.getShort()&0xFFFF)-0x8000) / (float)0x8000;
|
||||
}
|
||||
}
|
||||
else if (sampleSize == 32)
|
||||
{
|
||||
if (signed)
|
||||
{
|
||||
for (int i = 0; i < s; i++)
|
||||
buf[i] = bb.getInt() / (float)0x80000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nasty.. check this.
|
||||
for (int i = 0; i < s; i++)
|
||||
buf[i] = ((bb.getInt()&0xFFFFFFFFl)-0x80000000l) / (float)0x80000000;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the completed sample
|
||||
return new SonarSample(buf, rate);
|
||||
}
|
||||
}
|
||||
57
src/dk/itu/mario/engine/sonar/sample/SamplePlayer.java
Normal file
57
src/dk/itu/mario/engine/sonar/sample/SamplePlayer.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package dk.itu.mario.engine.sonar.sample;
|
||||
|
||||
|
||||
|
||||
import dk.itu.mario.engine.sonar.SoundProducer;
|
||||
|
||||
|
||||
public class SamplePlayer implements SoundProducer
|
||||
{
|
||||
private SonarSample sample;
|
||||
private float pos = 0;
|
||||
public boolean alive = true;
|
||||
private float rate;
|
||||
|
||||
public SamplePlayer(SonarSample sample, float rate)
|
||||
{
|
||||
this.rate = rate;
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
public float read(float[] buf, int readRate)
|
||||
{
|
||||
float step = (sample.rate*rate)/readRate;
|
||||
|
||||
for (int i=0; i<buf.length; i++)
|
||||
{
|
||||
if (pos>=sample.buf.length)
|
||||
{
|
||||
buf[i] = 0;
|
||||
alive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[i]=sample.buf[(int)(pos)];
|
||||
}
|
||||
pos+=step;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void skip(int samplesToSkip, int readRate)
|
||||
{
|
||||
float step = sample.rate/readRate;
|
||||
pos+=step*samplesToSkip;
|
||||
|
||||
if (pos>=sample.buf.length)
|
||||
{
|
||||
alive = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLive()
|
||||
{
|
||||
return alive;
|
||||
}
|
||||
}
|
||||
13
src/dk/itu/mario/engine/sonar/sample/SonarSample.java
Normal file
13
src/dk/itu/mario/engine/sonar/sample/SonarSample.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package dk.itu.mario.engine.sonar.sample;
|
||||
|
||||
public class SonarSample
|
||||
{
|
||||
public final float[] buf;
|
||||
public final float rate;
|
||||
|
||||
public SonarSample(float[] buf, float rate)
|
||||
{
|
||||
this.buf = buf;
|
||||
this.rate = rate;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user