switched back to old system dependent audio method; updated libgdx

framework; added ashley
This commit is contained in:
Harrison Deng 2018-06-30 00:13:39 -05:00
parent 4321a07f66
commit bf94851e06
12 changed files with 18 additions and 920 deletions

View File

@ -42,10 +42,10 @@ project(":desktop") {
dependencies {
implementation project(":core")
implementation "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
implementation "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
compile project(":core")
compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
}
}
@ -56,15 +56,15 @@ project(":android") {
configurations { natives }
dependencies {
implementation project(":core")
implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
compile project(":core")
compile "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
implementation "com.badlogicgames.ashley:ashley:$ashleyVersion"
implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
@ -79,16 +79,12 @@ project(":core") {
dependencies {
implementation "com.badlogicgames.gdx:gdx:$gdxVersion"
implementation "com.badlogicgames.ashley:ashley:$ashleyVersion"
implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
implementation "org.apache.commons:commons-math3:3.2"
implementation "com.github.rwl:jtransforms:2.4.0"
implementation group: 'fr.delthas', name: 'javamp3', version: '1.0.1'
implementation "org:jaudiotagger:2.0.3"
implementation group: 'org.apache.tika', name: 'tika-parsers', version: '1.18'
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
compile "com.github.rwl:jtransforms:2.4.0"
compile "org.apache.commons:commons-math3:3.2"
compile group: 'org.apache.tika', name: 'tika-parsers', version: '1.18'
}
}

View File

@ -1,150 +0,0 @@
package zero1hd.rhythmbullet.audio;
import java.security.InvalidParameterException;
import com.badlogic.gdx.utils.FloatArray;
public class AudioDataPackage {
private FloatArray bassPeaks;
private FloatArray mPeaks;
private FloatArray umPeaks;
private MusicManager musicInfo;
private float bassMaxVal, bassAvg;
private float mMaxVal, mAvg;
private float uMMaxval, uMAvg;
private int PUID;
private float secPerWin;
private float avgSPB;
/**
* Sets the bass data
* @param bassPeaks
* @param bassMaxVal
* @param bassAvg
*/
public void setBassData(FloatArray bassPeaks, float bassMaxVal, float bassAvg) {
if (this.bassPeaks != null) {
throw new InvalidParameterException("The bass peaks of this audio pack has already been set.");
}
this.bassPeaks = bassPeaks;
this.bassMaxVal = bassMaxVal;
this.bassAvg = bassAvg;
}
/**
* Sets the midrange data
* @param mPeaks
* @param mMaxVal
* @param mAvg
*/
public void setmData(FloatArray mPeaks, float mMaxVal, float mAvg) {
if (this.mPeaks != null) {
throw new InvalidParameterException("The midrange peaks of this audio pack has already been set.");
}
this.mPeaks = mPeaks;
this.mMaxVal = mMaxVal;
this.mAvg = mAvg;
}
/**
* Sets the upper-midrange data
* @param umPeaks
* @param uMMaxVal
* @param uMAvg
*/
public void setUmData(FloatArray umPeaks, float uMMaxVal, float uMAvg) {
if (this.umPeaks != null) {
throw new InvalidParameterException("The upper midrange peaks have already been set.");
}
this.umPeaks = umPeaks;
this.uMMaxval = uMMaxVal;
this.uMAvg = uMAvg;
}
public void setMusicInfo(MusicManager musicInfo) {
if (this.musicInfo != null) {
throw new InvalidParameterException("There is already music information in this package.");
}
this.musicInfo = musicInfo;
}
public void setPUID(int pUID) {
PUID = pUID;
}
public void setAvgSPB(float avgSPB) {
this.avgSPB = avgSPB;
}
public void setSecPerWin(float secPerWin) {
this.secPerWin = secPerWin;
}
//All the get methods...
public FloatArray getBassPeaks() {
if (bassPeaks != null) {
return bassPeaks;
} else {
throw new NullPointerException("Bass peaks currently null. This pack hasn't been properly packed!");
}
}
public FloatArray getmPeaks() {
if (mPeaks != null) {
return mPeaks;
} else {
throw new NullPointerException("midrange peaks currently null. This pack hasn't been properly packed!");
}
}
public FloatArray getuMPeaks() {
if (umPeaks != null) {
return umPeaks;
} else {
throw new NullPointerException("Upper midrange peaks currently null. This pack hasn't been properly packed!");
}
}
public MusicManager getMusicInfo() {
if (musicInfo == null) {
throw new NullPointerException("Music info hasn't been baked in...");
}
return musicInfo;
}
public float getBassMaxVal() {
return bassMaxVal;
}
public float getBassAvg() {
return bassAvg;
}
public float getmAvg() {
return mAvg;
}
public float getmMaxVal() {
return mMaxVal;
}
public float getuMMaxval() {
return uMMaxval;
}
public float getuMAvg() {
return uMAvg;
}
public int getPUID() {
return PUID;
}
public float getAvgSPB() {
return avgSPB;
}
public float getSecPerWin() {
return secPerWin;
}
}

View File

@ -1,154 +0,0 @@
package zero1hd.rhythmbullet.audio;
import java.io.IOException;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.audio.wav.WavTag;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.TagException;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.utils.Disposable;
public class MusicInfo implements Disposable {
private long durationInSeconds;
private String songName;
private String author;
private int previousTop;
private int ratedDifficulty;
private boolean invalidMusic;
private boolean containsInfo;
private FileHandle musicFile;
private Preferences musicAnnotation;
public MusicInfo(FileHandle musicFile, Preferences musicAnnotation) {
this.musicFile = musicFile;
this.musicAnnotation = musicAnnotation;
}
/**
* loads the information for this song.
* should be called in non-render thread as is blocking and depends on IO speed.
*/
public void loadInfo() {
if (musicFile.extension().toLowerCase().equals("mp3")) {
MP3File mp3File;
try {
mp3File = new MP3File(musicFile.file());
durationInSeconds = mp3File.getAudioHeader().getTrackLength();
if (mp3File.getTag() != null && mp3File.getTag().getFirstArtwork() != null) {
if (!Gdx.files.external("RhythmBullet/AlbumArt/" + musicFile.name() + ".png").exists()) {
byte[] albumWorkBytes = mp3File.getTag().getFirstArtwork().getBinaryData();
Pixmap pixmap = new Pixmap(albumWorkBytes, 0, albumWorkBytes.length);
PixmapIO.writePNG(Gdx.files.external("RhythmBullet/AlbumArt/" + musicFile.name() + ".png"), pixmap);
pixmap.dispose();
}
}
songName = mp3File.getTag().getFirst(FieldKey.TITLE);
author = mp3File.getTag().getFirst(FieldKey.ARTIST);
} catch (IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
AudioFile audioFile = AudioFileIO.read(musicFile.file());
WavTag wavTag = (WavTag) AudioFileIO.read(musicFile.file()).getTag();
songName = wavTag.getFirst(FieldKey.TITLE);
author = wavTag.getFirst(FieldKey.ARTIST);
durationInSeconds = audioFile.getAudioHeader().getTrackLength();
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException
| InvalidAudioFrameException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (durationInSeconds > 60 * 5) {
invalidMusic = true;
}
if (songName == null || songName.isEmpty()) {
songName = musicFile.nameWithoutExtension();
}
previousTop = musicAnnotation.getInteger(songName + ":previous top", -1);
ratedDifficulty = musicAnnotation.getInteger(songName + ":difficulty", -1);
if (author == null || author.isEmpty()) {
author = "N/A";
}
containsInfo = true;
}
/**
* The album art as a texture.
* Can return null if contains info is false.
* Not automatically disposed.
* @return
*/
public Texture loadTexture() {
Gdx.app.debug("MusicInfo", "Texture loading for music: " + getMusicName());
if (Gdx.files.external("RhythmBullet/AlbumArt/" + musicFile.name() + ".png").exists()) {
return new Texture(Gdx.files.external("RhythmBullet/AlbumArt/" + musicFile.name() + ".png"));
} else {
return null;
}
}
public long getDurationInSeconds() {
return durationInSeconds;
}
public String getMusicName() {
return songName.replace('_', ' ');
}
public String getAuthor() {
return author;
}
public int getPreviousTop() {
return previousTop == -1 ? 0 : previousTop;
}
public int getRatedDifficulty() {
return ratedDifficulty;
}
public boolean isInvalidMusic() {
return invalidMusic;
}
@Override
public void dispose() {
}
/**
* Asks if this contains information.
* @return whether this contains data
*/
public boolean hasInformation() {
return containsInfo;
}
public FileHandle getMusicFile() {
return musicFile;
}
}

View File

@ -1,98 +0,0 @@
package zero1hd.rhythmbullet.audio;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Music.OnCompletionListener;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Disposable;
@Deprecated
public interface MusicManager extends Disposable {
/**
* sets a integer variable to the current window of audio data the playback is at.
* Useful for efficiency because we compute once for that frame then get the values every time it is required instead of calculating every time we get the index.
* @return the playback window index.
*/
public int playbackIndexUpdate();
/**
* Gets the current position in seconds
* @return the current frame of audio.
*/
public int getPlaybackIndexPosition();
/**
* returns the read window size.
* @return
*/
public int getReadWindowSize();
/**
* read in samples and fills the array.
* @param samples the array that should contain said samples
* @return amount read. Will return 0 if end of stream.
*/
public int readSampleFrames(float[] samples);
/**
* returns sample count.
* Can be inaccurate.
* @return
*/
public long getSampleCount();
/**
* returns duration of song in seconds
* @return
*/
public float getDuration();
/**
* returns sample rate
* @return sample rate as float
*/
public float getSampleRate();
public void pause();
public void play();
public boolean isPlaying();
public float getPositionInSeconds();
public void setPosition(float position);
public void setOnCompletionListener(OnCompletionListener listener);
public void setVolume(float percent);
/**
* @return the amount of channels this audio file has.
*/
public int getChannelCount();
/**
* If the the properties of the song are done loading
* @return whether its done loading
*/
public boolean isFinishedLoading();
/**
* Basic song name is the name of the file of the song, meaning we do not check tags for proper song name.
* Thats left up to the song info object.
* @return basic song name
*/
public String getBasicSongName();
/**
* @return the song filehandle.
*/
public FileHandle getMusicFile();
/**
* @return the amount of windows that have been read.
*/
public int framesRead();
public Music getMusic();
}

View File

@ -1,89 +0,0 @@
package zero1hd.rhythmbullet.audio;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.AudioDevice;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Music.OnCompletionListener;
import zero1hd.rhythmbullet.audio.processor.PCMProcessor;
public class RhythmBulletAudioThread extends Thread {
private AudioDevice ad;
private PCMProcessor sp;
private Music music;
private volatile OnCompletionListener ocl;
private short[] pcm;
private volatile boolean terminated;
private volatile boolean playing;
private volatile long framesPlayed;
private volatile float framesToSkip;
public RhythmBulletAudioThread(int windowSize, VisualizableMusic vm) {
music = vm;
this.sp = vm.getSampleProcessor();
pcm = new short[(sp.isStereo() ? 2 : 1)*windowSize];
setName("RhythmBullet-AudioPlayback-Thread");
play();
start();
}
@Override
public void run() {
sp.initiate();
this.ad = Gdx.audio.newAudioDevice(sp.getSampleRate(), !sp.isStereo());
while (!terminated && sp.readSamples(pcm, this) > 0) {
ad.writeSamples(pcm, 0, pcm.length);
}
if (ocl != null) {
ocl.onCompletion(music);
}
super.run();
}
public synchronized void play() {
playing = true;
notify();
}
public synchronized void pause() {
playing = false;
while (!playing) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized short[] getPcm() {
return pcm;
}
public void terminate() {
terminated = true;
}
public boolean isTerminated() {
return terminated;
}
public boolean isPlaying() {
return playing;
}
public void setOnCompletionListener(OnCompletionListener ocl) {
this.ocl = ocl;
}
public void jumpToFrame(long frame) {
if (framesPlayed > frame) {
}
}
}

View File

@ -1,117 +0,0 @@
package zero1hd.rhythmbullet.audio;
import java.io.IOException;
import java.nio.file.Paths;
import javax.sound.sampled.UnsupportedAudioFileException;
import com.badlogic.gdx.audio.Music;
import zero1hd.rhythmbullet.audio.processor.MP3PCMProcessor;
import zero1hd.rhythmbullet.audio.processor.PCMProcessor;
import zero1hd.rhythmbullet.audio.processor.WAVPCMProcessor;
public class VisualizableMusic implements Music {
private int windowSize = 1024;
private OnCompletionListener ocl;
private boolean looping;
private RhythmBulletAudioThread rat;
private String fileLoc;
private PCMProcessor sampleProcessor;
public VisualizableMusic(String fileLoc) {
this.fileLoc = fileLoc;
if (fileLoc.toLowerCase().endsWith("wav")) {
try {
sampleProcessor = new WAVPCMProcessor(Paths.get(fileLoc), windowSize);
} catch (IOException | UnsupportedAudioFileException e) {
e.printStackTrace();
}
} else if (fileLoc.toLowerCase().endsWith("mp3")) {
sampleProcessor = new MP3PCMProcessor(Paths.get(fileLoc), windowSize);
}
}
@Override
public void play() {
if (rat == null) {
rat = new RhythmBulletAudioThread(windowSize, this);
rat.setOnCompletionListener(ocl);
rat.start();
} else {
rat.play();
}
}
@Override
public void pause() {
rat.pause();
}
@Override
public void stop() {
rat.terminate();
rat = null;
}
@Override
public boolean isPlaying() {
return rat.isPlaying();
}
@Override
public void setLooping(boolean isLooping) {
looping = isLooping;
}
@Override
public boolean isLooping() {
return looping;
}
@Override
public void setVolume(float volume) {
sampleProcessor.setVolume(volume);
}
@Override
public float getVolume() {
return sampleProcessor.getVolume();
}
@Override
public void setPan(float pan, float volume) {
sampleProcessor.setPan(pan);
sampleProcessor.setVolume(volume);
}
@Override
public void setPosition(float position) {
// TODO Auto-generated method stub
}
@Override
public float getPosition() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
@Override
public void setOnCompletionListener(OnCompletionListener listener) {
this.ocl = listener;
if (rat != null) {
rat.setOnCompletionListener(listener);
}
}
protected PCMProcessor getSampleProcessor() {
return sampleProcessor;
}
}

View File

@ -0,0 +1,4 @@
package zero1hd.rhythmbullet.audio.processor;
public interface AudioProcessor {
}

View File

@ -1,107 +0,0 @@
package zero1hd.rhythmbullet.audio.processor;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import fr.delthas.javamp3.Sound;
public class MP3PCMProcessor implements PCMProcessor {
private boolean stereo;
private int sampleRate;
private volatile float volume, pan;
private boolean initiated;
private Sound audioInputStream;
private Path path;
private byte[] buffer;
public MP3PCMProcessor(Path path, int windowSize) {
try(Sound sound = new Sound(new BufferedInputStream(Files.newInputStream(path)))) {
sampleRate = sound.getSamplingFrequency();
stereo = sound.isStereo();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void initiate() {
try {
audioInputStream = new Sound(new BufferedInputStream(Files.newInputStream(path)));
} catch (IOException e) {
e.printStackTrace();
}
buffer = new byte[audioInputStream.getAudioFormat().getFrameSize()];
initiated = true;
}
@Override
public boolean isStereo() {
return stereo;
}
@Override
public int getSampleRate() {
return sampleRate;
}
@Override
public int readSamples(short[] pcm, Object syncObj) {
if (initiated) {
synchronized (syncObj) {
int framesRead = 0;
for (int sampleID = 0; sampleID < pcm.length; sampleID++) {
try {
if (audioInputStream.read(buffer) > 0) {
pcm[sampleID] = (short) ((buffer[1] << 8) + (buffer[0] & 0x00ff));
pcm[sampleID] *= volume * (Math.min(1-pan, 1));
if (stereo) {
short secondChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff));
secondChan *= volume * (Math.min(1+pan, 1));
sampleID++;
pcm[sampleID] = secondChan;
}
framesRead++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return framesRead;
}
} else {
throw new IllegalStateException("Stream has not been initialized.");
}
}
@Override
public void setVolume(float volume) {
this.volume = volume;
}
@Override
public float getVolume() {
return volume;
}
@Override
public void setPan(float pan) {
this.pan = pan;
}
@Override
public float getPan() {
return pan;
}
@Override
public void dispose() {
try {
audioInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,75 +0,0 @@
package zero1hd.rhythmbullet.audio.processor;
import com.badlogic.gdx.utils.Disposable;
public interface PCMProcessor extends Disposable {
/**
* Called once, contains the initiation to the stream, only called when play-back begins.
* Not thread safe as it should be the first thing to be called during read process.
*/
public void initiate();
/**
* @return number of channels
*/
public boolean isStereo();
/**
* @return sample rate
*/
public int getSampleRate();
/**
* <b>Thread safe</b>
* Reads samples (NOT FRAMES) with interwoven data for stereo.
* stored in 16 bit format (first 8 are the first byte of data while the second 8 are the second byte of data that composes a short value)
* @param pcm the array the samples should fill
* @param syncObj the object that this object should use to synchronize multiple threads.
* @return the amount of samples read.
*/
public int readSamples(short[] pcm, Object syncObj);
/**
* <b>Thread safe</b>
* ranges from 0 to 1.
* @param volume the volume to set
*/
public void setVolume(float volume);
/**
* <b>Thread safe</b>
* @return the volume ranging from 0 to 1
*/
public float getVolume();
/**
* <b>Thread safe</b>
* sets the pan from the left channel to the right.
* ranges from -1 to 1.
* Default is 0, -1 is left, 1 is right.
* @param pan
*/
public void setPan(float pan);
/**
* <b>Thread safe</b>
* Returns the pan value from -1 to 1.
* see {@link #setPan(float)} for more information.
* @return the pan value.
*/
public float getPan();
/**
* resets the current input stream to the beginning.
* Not thread safe and should be called in the same thread as the one doing the playback.
*/
public void resetStream();
/**
* Skip this amount of frames.
* Not thread safe since this should be called in the same thread as the one doing the playback.
* @param framesToSkip
*/
public void skipFrames(long framesToSkip);
}

View File

@ -1,105 +0,0 @@
package zero1hd.rhythmbullet.audio.processor;
import java.io.IOException;
import java.nio.file.Path;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
public class WAVPCMProcessor implements PCMProcessor {
private boolean stereo;
private int sampleRate;
private byte[] buffer;
private Path path;
private AudioInputStream audioInputStream;
private volatile float volume, pan;
private boolean initiated;
public WAVPCMProcessor(Path path, int windowSize) throws IOException, UnsupportedAudioFileException {
this.path = path;
AudioFormat format = AudioSystem.getAudioFileFormat(path.toFile()).getFormat();
stereo = format.getChannels() > 1 ? true : false;
sampleRate = (int) format.getSampleRate();
volume = 1f;
}
@Override
public void initiate() {
try {
audioInputStream = AudioSystem.getAudioInputStream(path.toFile());
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
buffer = new byte[audioInputStream.getFormat().getFrameSize()];
initiated = true;
}
public boolean isStereo() {
return stereo;
}
public int getSampleRate() {
return sampleRate;
}
@Override
public int readSamples(short[] pcm, Object syncObj) {
if (initiated) {
synchronized (syncObj) {
int framesRead = 0;
for (int sampleID = 0; sampleID < pcm.length; sampleID++) {
try {
if (audioInputStream.read(buffer) > 0) {
pcm[sampleID] = (short) ((buffer[1] << 8) + (buffer[0] & 0x00ff));
pcm[sampleID] *= volume * (Math.min(1-pan, 1));
if (stereo) {
short secondChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff));
secondChan *= volume * (Math.min(1+pan, 1));
sampleID++;
pcm[sampleID] = secondChan;
}
framesRead++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return framesRead;
}
} else {
throw new IllegalStateException("Stream has not been initialized.");
}
}
@Override
public void setVolume(float volume) {
this.volume = volume;
}
@Override
public float getVolume() {
return volume;
}
@Override
public void setPan(float pan) {
this.pan = pan;
}
@Override
public float getPan() {
return pan;
}
@Override
public void dispose() {
try {
audioInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -7,8 +7,6 @@ import com.badlogic.gdx.utils.Disposable;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
import zero1hd.rhythmbullet.audio.MusicManager;
@Deprecated
public class MusicManagerFFT implements Disposable {
protected MusicManager mm;
private FloatFFT_1D fft;

View File

@ -1,5 +1,3 @@
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: "java"
sourceCompatibility = 1.6
@ -14,9 +12,6 @@ task run(dependsOn: classes, type: JavaExec) {
standardInput = System.in
workingDir = project.assetsDir
ignoreExitValue = true
if(Os.isFamily(Os.FAMILY_MAC))
jvmArgs += "-XstartOnFirstThread"
}
task debug(dependsOn: classes, type: JavaExec) {