mp3 audio processor complete; slow conversion to cleaner system
This commit is contained in:
parent
bf94851e06
commit
8f70d72ed1
@ -1,4 +1,31 @@
|
||||
package zero1hd.rhythmbullet.audio.processor;
|
||||
|
||||
public interface AudioProcessor {
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
public interface AudioProcessor 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);
|
||||
}
|
||||
|
82
core/src/zero1hd/rhythmbullet/audio/processor/WAVAudioProcessor.java
Executable file
82
core/src/zero1hd/rhythmbullet/audio/processor/WAVAudioProcessor.java
Executable file
@ -0,0 +1,82 @@
|
||||
package zero1hd.rhythmbullet.audio.processor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
public class WAVAudioProcessor implements AudioProcessor {
|
||||
private boolean stereo;
|
||||
private int sampleRate;
|
||||
private byte[] buffer;
|
||||
private FileHandle fileHandle;
|
||||
private AudioInputStream audioInputStream;
|
||||
private boolean initiated;
|
||||
|
||||
public WAVAudioProcessor(FileHandle fileHandle, int windowSize) throws IOException, UnsupportedAudioFileException {
|
||||
this.fileHandle = fileHandle;
|
||||
AudioFormat format = AudioSystem.getAudioFileFormat(fileHandle.file()).getFormat();
|
||||
stereo = format.getChannels() > 1 ? true : false;
|
||||
sampleRate = (int) format.getSampleRate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiate() {
|
||||
try {
|
||||
audioInputStream = AudioSystem.getAudioInputStream(fileHandle.file());
|
||||
} 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));
|
||||
if (stereo) {
|
||||
short secondChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff));
|
||||
sampleID++;
|
||||
pcm[sampleID] = secondChan;
|
||||
}
|
||||
framesRead++;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
return framesRead;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Stream has not been initialized.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
audioInputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
142
desktop/src/zero1hd/rhythmbullet/desktop/audio/MP3AudioProcessor.java
Executable file
142
desktop/src/zero1hd/rhythmbullet/desktop/audio/MP3AudioProcessor.java
Executable file
@ -0,0 +1,142 @@
|
||||
package zero1hd.rhythmbullet.desktop.audio;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
|
||||
import javazoom.jl.decoder.Bitstream;
|
||||
import javazoom.jl.decoder.BitstreamException;
|
||||
import javazoom.jl.decoder.DecoderException;
|
||||
import javazoom.jl.decoder.Header;
|
||||
import javazoom.jl.decoder.MP3Decoder;
|
||||
import javazoom.jl.decoder.OutputBuffer;
|
||||
import zero1hd.rhythmbullet.audio.processor.AudioProcessor;
|
||||
|
||||
|
||||
public class MP3AudioProcessor implements AudioProcessor {
|
||||
private boolean stereo;
|
||||
private int sampleRate;
|
||||
private FileHandle fileHandle;
|
||||
private byte[] currentByteSet;
|
||||
private byte[] workset;
|
||||
Bitstream bitstream;
|
||||
MP3Decoder decoder;
|
||||
OutputBuffer sampleBuffer;
|
||||
private int indexHead = -1;
|
||||
|
||||
|
||||
public MP3AudioProcessor(FileHandle fileHandle) {
|
||||
this.fileHandle = fileHandle;
|
||||
|
||||
bitstream = new Bitstream(fileHandle.read());
|
||||
|
||||
try {
|
||||
Header header = bitstream.readFrame();
|
||||
if (header == null) throw new GdxRuntimeException("Empty MP3");
|
||||
stereo = header.mode() == Header.DUAL_CHANNEL;
|
||||
sampleRate = header.getSampleRate();
|
||||
} catch (BitstreamException e) {
|
||||
throw new GdxRuntimeException("error while preloading mp3", e);
|
||||
}
|
||||
|
||||
try {
|
||||
bitstream.close();
|
||||
} catch (BitstreamException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiate() {
|
||||
bitstream = new Bitstream(fileHandle.read());
|
||||
decoder = new MP3Decoder();
|
||||
sampleBuffer = new OutputBuffer(stereo ? 2 : 1, false);
|
||||
decoder.setOutputBuffer(sampleBuffer);
|
||||
workset = new byte[(stereo ? 2 : 1)*2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStereo() {
|
||||
return stereo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSampleRate() {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readSamples(short[] pcm, Object syncObj) {
|
||||
int framesRead = 0;
|
||||
for (int sid = 0; sid < pcm.length; sid++) {
|
||||
for (int wsid = 0; wsid < workset.length; wsid++) {
|
||||
workset[wsid] = nextByte();
|
||||
}
|
||||
if (currentByteSet != null) {
|
||||
pcm[sid] += (workset[1] << 8) + (workset[0] & 0x00ff);
|
||||
if (stereo) {
|
||||
short altChan = (short) ((workset[3] << 8) + (workset[2] & 0x00ff));
|
||||
sid++;
|
||||
pcm[sid] = altChan > pcm[sid] ? altChan : pcm[sid];
|
||||
}
|
||||
framesRead ++;
|
||||
pcm[sid] /= Short.MAX_VALUE+1;
|
||||
}
|
||||
}
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
public byte nextByte() {
|
||||
indexHead++;
|
||||
if (currentByteSet == null || indexHead >= currentByteSet.length) {
|
||||
loadNextBuffer();
|
||||
if (currentByteSet == null) {
|
||||
return 0;
|
||||
}
|
||||
indexHead = 0;
|
||||
}
|
||||
|
||||
return currentByteSet[indexHead];
|
||||
}
|
||||
|
||||
public int loadNextBuffer() {
|
||||
if (bitstream != null) {
|
||||
int bytesRead = 0;
|
||||
try {
|
||||
Header header = bitstream.readFrame();
|
||||
if (header != null) {
|
||||
|
||||
try {
|
||||
decoder.decodeFrame(header, bitstream);
|
||||
} catch (ArrayIndexOutOfBoundsException ae) {
|
||||
Gdx.app.debug("Mp3Manager", "Last buffer reached since array was out of bounds.");
|
||||
} catch (DecoderException de) {
|
||||
Gdx.app.error("MP3 Decoder Error", de.toString());
|
||||
}
|
||||
bitstream.closeFrame();
|
||||
bytesRead = sampleBuffer.reset();
|
||||
currentByteSet = sampleBuffer.getBuffer();
|
||||
} else {
|
||||
currentByteSet = null;
|
||||
}
|
||||
} catch (BitstreamException be) {
|
||||
be.printStackTrace();
|
||||
}
|
||||
return bytesRead;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Gdx.app.debug("MP3Manager", "Disposing...");
|
||||
try {
|
||||
bitstream.close();
|
||||
bitstream = null;
|
||||
} catch (BitstreamException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,277 +0,0 @@
|
||||
package zero1hd.rhythmbullet.desktop.audio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
import org.jaudiotagger.audio.mp3.MP3File;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.audio.Music.OnCompletionListener;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
|
||||
import javazoom.jl.decoder.Bitstream;
|
||||
import javazoom.jl.decoder.BitstreamException;
|
||||
import javazoom.jl.decoder.DecoderException;
|
||||
import javazoom.jl.decoder.Header;
|
||||
import javazoom.jl.decoder.MP3Decoder;
|
||||
import javazoom.jl.decoder.OutputBuffer;
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
|
||||
|
||||
public class Mp3Manager implements MusicManager {
|
||||
private int readWindowSize = 1024;
|
||||
|
||||
private Music playbackMusic;
|
||||
private int playbackIndex, readIndex;
|
||||
|
||||
private int sampleRate;
|
||||
private long sampleCount;
|
||||
private double durationInSeconds;
|
||||
private int channels;
|
||||
Bitstream bitstream;
|
||||
MP3Decoder decoder;
|
||||
OutputBuffer sampleBuffer;
|
||||
private byte[] currentByteSet;
|
||||
private byte[] workset;
|
||||
private int indexHead = -1;
|
||||
|
||||
private FileHandle file;
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private ExecutorService exec;
|
||||
|
||||
private String basicSongName;
|
||||
|
||||
public Mp3Manager(FileHandle audioFile) {
|
||||
this.file = audioFile;
|
||||
lock = new ReentrantLock();
|
||||
this.basicSongName = audioFile.name();
|
||||
exec = Executors.newSingleThreadExecutor();
|
||||
exec.submit(() -> {
|
||||
lock.lock();
|
||||
try {
|
||||
MP3File mp3File = new MP3File(audioFile.file());
|
||||
sampleRate = mp3File.getMP3AudioHeader().getSampleRateAsNumber();
|
||||
durationInSeconds = mp3File.getMP3AudioHeader().getPreciseTrackLength();
|
||||
channels = mp3File.getAudioHeader().getChannels().equals("Mono") ? 1:2;
|
||||
sampleCount = MathUtils.round(Float.valueOf((float) (sampleRate*durationInSeconds))) * channels;
|
||||
|
||||
} catch (IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
lock.unlock();
|
||||
});
|
||||
|
||||
bitstream = new Bitstream(audioFile.read());
|
||||
decoder = new MP3Decoder();
|
||||
|
||||
try {
|
||||
Header header = bitstream.readFrame();
|
||||
if (header == null) throw new GdxRuntimeException("Empty MP3");
|
||||
channels = (byte) (header.mode() == Header.SINGLE_CHANNEL ? 1 : 2);
|
||||
sampleBuffer = new OutputBuffer(channels, false);
|
||||
decoder.setOutputBuffer(sampleBuffer);
|
||||
workset = new byte[channels*2];
|
||||
} catch (BitstreamException e) {
|
||||
throw new GdxRuntimeException("error while preloading mp3", e);
|
||||
}
|
||||
|
||||
playbackMusic = Gdx.audio.newMusic(audioFile);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int playbackIndexUpdate() {
|
||||
playbackIndex = (int) (playbackMusic.getPosition() * sampleRate / readWindowSize);
|
||||
return playbackIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlaybackIndexPosition() {
|
||||
return playbackIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadWindowSize() {
|
||||
return readWindowSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSampleCount() {
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDuration() {
|
||||
return Float.valueOf(String.valueOf(durationInSeconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readSampleFrames(float[] samples) {
|
||||
readIndex++;
|
||||
int framesRead = 0;
|
||||
for (int sid = 0; sid < samples.length; sid++) {
|
||||
for (int wsid = 0; wsid < workset.length; wsid++) {
|
||||
workset[wsid] = nextByte();
|
||||
}
|
||||
if (currentByteSet != null) {
|
||||
samples[sid] += (workset[1] << 8) + (workset[0] & 0x00ff);
|
||||
if (channels > 1) {
|
||||
short altChan = (short) ((workset[3] << 8) + (workset[2] & 0x00ff));
|
||||
|
||||
samples[sid] = altChan > samples[sid] ? altChan : samples[sid];
|
||||
}
|
||||
framesRead ++;
|
||||
samples[sid] /= Short.MAX_VALUE+1;
|
||||
}
|
||||
}
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
public byte nextByte() {
|
||||
indexHead++;
|
||||
if (currentByteSet == null || indexHead >= currentByteSet.length) {
|
||||
loadNextBuffer();
|
||||
if (currentByteSet == null) {
|
||||
return 0;
|
||||
}
|
||||
indexHead = 0;
|
||||
}
|
||||
|
||||
return currentByteSet[indexHead];
|
||||
}
|
||||
|
||||
public int loadNextBuffer() {
|
||||
if (bitstream != null) {
|
||||
int bytesRead = 0;
|
||||
try {
|
||||
Header header = bitstream.readFrame();
|
||||
if (header != null) {
|
||||
|
||||
try {
|
||||
decoder.decodeFrame(header, bitstream);
|
||||
} catch (ArrayIndexOutOfBoundsException ae) {
|
||||
Gdx.app.debug("Mp3Manager", "Last buffer reached since array was out of bounds.");
|
||||
} catch (DecoderException de) {
|
||||
Gdx.app.error("MP3 Decoder Error", de.toString());
|
||||
}
|
||||
bitstream.closeFrame();
|
||||
bytesRead = sampleBuffer.reset();
|
||||
currentByteSet = sampleBuffer.getBuffer();
|
||||
} else {
|
||||
currentByteSet = null;
|
||||
}
|
||||
} catch (BitstreamException be) {
|
||||
be.printStackTrace();
|
||||
}
|
||||
return bytesRead;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSampleRate() {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
playbackMusic.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
playbackMusic.play();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return playbackMusic.isPlaying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPositionInSeconds() {
|
||||
return playbackMusic.getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(float position) {
|
||||
playbackMusic.setPosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnCompletionListener(OnCompletionListener listener) {
|
||||
playbackMusic.setOnCompletionListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVolume(float percent) {
|
||||
playbackMusic.setVolume(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinishedLoading() {
|
||||
if (lock.isHeldByCurrentThread()) {
|
||||
return true;
|
||||
} else {
|
||||
try {
|
||||
if (lock.tryLock(0, TimeUnit.SECONDS)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBasicSongName() {
|
||||
return basicSongName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileHandle getMusicFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Gdx.app.debug("MP3Manager", "Disposing...");
|
||||
playbackMusic.stop();
|
||||
playbackMusic.dispose();
|
||||
exec.shutdown();
|
||||
try {
|
||||
bitstream.close();
|
||||
bitstream = null;
|
||||
} catch (BitstreamException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int framesRead() {
|
||||
return readIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannelCount() {
|
||||
return channels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Music getMusic() {
|
||||
return playbackMusic;
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ public class MusicList extends Observable {
|
||||
if (file.extension().equalsIgnoreCase("wav")) {
|
||||
return new WAVManager(file);
|
||||
} else if (file.extension().equalsIgnoreCase("mp3")) {
|
||||
return new Mp3Manager(file);
|
||||
return new MP3AudioProcessor(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1,155 +0,0 @@
|
||||
package zero1hd.rhythmbullet.desktop.audio;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.audio.Music.OnCompletionListener;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.audio.wavedecoder.WAVSampleReader;
|
||||
|
||||
public class WAVManager implements MusicManager {
|
||||
private int readWindowSize = 1024;
|
||||
private int playbackIndex, readIndex;
|
||||
private Music music;
|
||||
private FileHandle fileHandle;
|
||||
private AudioInputStream ais;
|
||||
private AudioFormat af;
|
||||
private WAVSampleReader d;
|
||||
|
||||
public WAVManager(FileHandle file) {
|
||||
this.fileHandle = file;
|
||||
try {
|
||||
ais = AudioSystem.getAudioInputStream(file.file());
|
||||
d = new WAVSampleReader(ais);
|
||||
af = ais.getFormat();
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
music = Gdx.audio.newMusic(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
music.dispose();
|
||||
try {
|
||||
ais.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int playbackIndexUpdate() {
|
||||
playbackIndex = (int) ((getSampleRate() * getDuration())/getReadWindowSize());
|
||||
return playbackIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlaybackIndexPosition() {
|
||||
return playbackIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadWindowSize() {
|
||||
return readWindowSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readSampleFrames(float[] samples) {
|
||||
try {
|
||||
readIndex++;
|
||||
return d.readSamplesAsFrames(samples);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSampleCount() {
|
||||
return ais.getFrameLength()*d.getChannels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDuration() {
|
||||
return ais.getFrameLength()/af.getFrameRate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSampleRate() {
|
||||
return af.getSampleRate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
music.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
music.play();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return music.isPlaying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPositionInSeconds() {
|
||||
return music.getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(float position) {
|
||||
music.setPosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnCompletionListener(OnCompletionListener listener) {
|
||||
music.setOnCompletionListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVolume(float percent) {
|
||||
music.setVolume(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinishedLoading() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBasicSongName() {
|
||||
return fileHandle.nameWithoutExtension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileHandle getMusicFile() {
|
||||
return fileHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int framesRead() {
|
||||
return readIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannelCount() {
|
||||
return d.getChannels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Music getMusic() {
|
||||
return music;
|
||||
}
|
||||
}
|
@ -14,7 +14,6 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||
import com.badlogic.gdx.utils.reflect.Field;
|
||||
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.audio.visualizer.MusicManagerFFT;
|
||||
import zero1hd.rhythmbullet.audio.visualizer.Visualizer;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user