switched back to old system dependent audio method; updated libgdx
framework; added ashley
This commit is contained in:
		
							
								
								
									
										32
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								build.gradle
									
									
									
									
									
								
							@@ -42,10 +42,10 @@ project(":desktop") {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dependencies {
 | 
					    dependencies {
 | 
				
			||||||
        implementation project(":core")
 | 
					        compile project(":core")
 | 
				
			||||||
        implementation "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
 | 
					        compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
 | 
				
			||||||
        implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
 | 
					        compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
 | 
				
			||||||
        implementation "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
 | 
					        compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -56,15 +56,15 @@ project(":android") {
 | 
				
			|||||||
    configurations { natives }
 | 
					    configurations { natives }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dependencies {
 | 
					    dependencies {
 | 
				
			||||||
        implementation project(":core")
 | 
					        compile project(":core")
 | 
				
			||||||
        implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
 | 
					        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"
 | 
				
			||||||
        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
 | 
					        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-arm64-v8a"
 | 
				
			||||||
        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
 | 
					        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
 | 
				
			||||||
        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
 | 
					        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
 | 
				
			||||||
        implementation "com.badlogicgames.ashley:ashley:$ashleyVersion"
 | 
					        compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
 | 
				
			||||||
        implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
 | 
					        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"
 | 
				
			||||||
        natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
 | 
					        natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
 | 
				
			||||||
        natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
 | 
					        natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
 | 
				
			||||||
@@ -79,16 +79,12 @@ project(":core") {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dependencies {
 | 
					    dependencies {
 | 
				
			||||||
        implementation "com.badlogicgames.gdx:gdx:$gdxVersion"
 | 
					        compile "com.badlogicgames.gdx:gdx:$gdxVersion"
 | 
				
			||||||
        implementation "com.badlogicgames.ashley:ashley:$ashleyVersion"
 | 
					        compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
 | 
				
			||||||
        implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
 | 
					        compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
 | 
				
			||||||
 | 
					        compile "com.github.rwl:jtransforms:2.4.0"
 | 
				
			||||||
        implementation "org.apache.commons:commons-math3:3.2"
 | 
					        compile "org.apache.commons:commons-math3:3.2"
 | 
				
			||||||
        implementation "com.github.rwl:jtransforms:2.4.0"
 | 
					        compile group: 'org.apache.tika', name: 'tika-parsers', version: '1.18'
 | 
				
			||||||
        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'
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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) {
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										4
									
								
								core/src/zero1hd/rhythmbullet/audio/processor/AudioProcessor.java
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								core/src/zero1hd/rhythmbullet/audio/processor/AudioProcessor.java
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					package zero1hd.rhythmbullet.audio.processor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface AudioProcessor {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -7,8 +7,6 @@ import com.badlogic.gdx.utils.Disposable;
 | 
				
			|||||||
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
 | 
					import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
 | 
				
			||||||
import zero1hd.rhythmbullet.audio.MusicManager;
 | 
					import zero1hd.rhythmbullet.audio.MusicManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@Deprecated
 | 
					 | 
				
			||||||
public class MusicManagerFFT implements Disposable {
 | 
					public class MusicManagerFFT implements Disposable {
 | 
				
			||||||
	protected MusicManager mm;
 | 
						protected MusicManager mm;
 | 
				
			||||||
	private FloatFFT_1D fft;
 | 
						private FloatFFT_1D fft;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,3 @@
 | 
				
			|||||||
import org.apache.tools.ant.taskdefs.condition.Os
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
apply plugin: "java"
 | 
					apply plugin: "java"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sourceCompatibility = 1.6
 | 
					sourceCompatibility = 1.6
 | 
				
			||||||
@@ -14,9 +12,6 @@ task run(dependsOn: classes, type: JavaExec) {
 | 
				
			|||||||
    standardInput = System.in
 | 
					    standardInput = System.in
 | 
				
			||||||
    workingDir = project.assetsDir
 | 
					    workingDir = project.assetsDir
 | 
				
			||||||
    ignoreExitValue = true
 | 
					    ignoreExitValue = true
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if(Os.isFamily(Os.FAMILY_MAC))
 | 
					 | 
				
			||||||
        jvmArgs += "-XstartOnFirstThread"
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
task debug(dependsOn: classes, type: JavaExec) {
 | 
					task debug(dependsOn: classes, type: JavaExec) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user