Began work on music selection UI
This commit is contained in:
parent
fa87f5e8cf
commit
5a472b21e6
@ -47,6 +47,8 @@ project(":desktop") {
|
|||||||
compile "org.apache.commons:commons-math3:3.2"
|
compile "org.apache.commons:commons-math3:3.2"
|
||||||
|
|
||||||
compile "com.github.rwl:jtransforms:2.4.0"
|
compile "com.github.rwl:jtransforms:2.4.0"
|
||||||
|
|
||||||
|
compile "com.mpatric:mp3agic:0.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +77,8 @@ project(":android") {
|
|||||||
compile "org.apache.commons:commons-math3:3.2"
|
compile "org.apache.commons:commons-math3:3.2"
|
||||||
|
|
||||||
compile "com.github.rwl:jtransforms:2.4.0"
|
compile "com.github.rwl:jtransforms:2.4.0"
|
||||||
|
|
||||||
|
compile "com.mpatric:mp3agic:0.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +95,8 @@ project(":core") {
|
|||||||
compile "org.apache.commons:commons-math3:3.2"
|
compile "org.apache.commons:commons-math3:3.2"
|
||||||
|
|
||||||
compile "com.github.rwl:jtransforms:2.4.0"
|
compile "com.github.rwl:jtransforms:2.4.0"
|
||||||
|
|
||||||
|
compile "com.mpatric:mp3agic:0.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package zero1hd.polyjet.audio;
|
package zero1hd.polyjet.audio;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
import javax.sound.sampled.AudioFormat;
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
|
||||||
@ -11,19 +10,19 @@ import com.badlogic.gdx.audio.Music;
|
|||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
import zero1hd.wavedecoder.WavDecoder;
|
import zero1hd.wavedecoder.WavDecoder;
|
||||||
|
import zero1hd.wavedecoder.WavInfo;
|
||||||
|
|
||||||
public class WavAudioData implements AudioData {
|
public class WavAudioData implements AudioData {
|
||||||
private int readWindowSize = 1024;
|
private int readWindowSize = 1024;
|
||||||
private InputStream inStream;
|
|
||||||
private InputStream bufferedAudioIn;
|
|
||||||
private AudioFormat format;
|
private AudioFormat format;
|
||||||
int readIndex;
|
int readIndex;
|
||||||
Music playbackMusic;
|
Music playbackMusic;
|
||||||
WavDecoder decoder;
|
WavDecoder decoder;
|
||||||
|
WavInfo wavinfo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readIndexUpdate() {
|
public void readIndexUpdate() {
|
||||||
readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize);
|
readIndex = (int) (playbackMusic.getPosition() * wavinfo.getSampleRate() / readWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -31,15 +30,21 @@ public class WavAudioData implements AudioData {
|
|||||||
return readIndex;
|
return readIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setInfo(WavInfo wavinfo) {
|
||||||
|
this.wavinfo = wavinfo;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAudioFile(FileHandle audioFileHandler) {
|
public void setAudioFile(FileHandle audioFileHandler) {
|
||||||
reset();
|
reset();
|
||||||
|
try {
|
||||||
inStream = audioFileHandler.read();
|
decoder.setAudioFile(wavinfo);
|
||||||
bufferedAudioIn = new BufferedInputStream(inStream);
|
} catch (InvalidParameterException | IOException e) {
|
||||||
decoder.setAudioFile(audioFileHandler.file());
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
playbackMusic = Gdx.audio.newMusic(audioFileHandler);
|
playbackMusic = Gdx.audio.newMusic(audioFileHandler);
|
||||||
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, (float) decoder.getSampleRate(), 16, decoder.getChannels(), decoder.getChannels()*2, (float)decoder.getSampleRate(), false);
|
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, (float) wavinfo.getSampleRate(), 16, wavinfo.getChannels(), wavinfo.getChannels()*2, (float) wavinfo.getSampleRate(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,16 +54,6 @@ public class WavAudioData implements AudioData {
|
|||||||
playbackMusic.dispose();
|
playbackMusic.dispose();
|
||||||
playbackMusic = null;
|
playbackMusic = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inStream != null) {
|
|
||||||
try {
|
|
||||||
bufferedAudioIn.close();
|
|
||||||
inStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
63
core/src/zero1hd/polyjet/ui/builders/MusicSelectable.java
Normal file → Executable file
63
core/src/zero1hd/polyjet/ui/builders/MusicSelectable.java
Normal file → Executable file
@ -1,16 +1,65 @@
|
|||||||
package zero1hd.polyjet.ui.builders;
|
package zero1hd.polyjet.ui.builders;
|
||||||
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import java.io.IOException;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
|
||||||
|
|
||||||
public class MusicSelectable extends Actor {
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup;
|
||||||
|
import com.mpatric.mp3agic.ID3v2;
|
||||||
|
import com.mpatric.mp3agic.InvalidDataException;
|
||||||
|
import com.mpatric.mp3agic.Mp3File;
|
||||||
|
import com.mpatric.mp3agic.UnsupportedTagException;
|
||||||
|
|
||||||
|
import zero1hd.wavedecoder.WavInfo;
|
||||||
|
|
||||||
|
public class MusicSelectable extends WidgetGroup {
|
||||||
Image imageIcon;
|
Image imageIcon;
|
||||||
FileHandle musicFile;
|
FileHandle musicFile;
|
||||||
|
boolean invalidMusic;
|
||||||
|
long durationInSeconds;
|
||||||
|
String songName;
|
||||||
|
|
||||||
|
WavInfo wavinfo;
|
||||||
|
|
||||||
public MusicSelectable(FileHandle musicFile) {
|
public MusicSelectable(FileHandle musicFile) {
|
||||||
this.musicFile = musicFile;
|
this.musicFile = musicFile;
|
||||||
imageIcon = new Image(new Texture(musicFile));
|
|
||||||
|
if (musicFile.extension().toLowerCase().equals("mp3")) {
|
||||||
|
try {
|
||||||
|
Mp3File mp3File = new Mp3File(musicFile.file());
|
||||||
|
durationInSeconds = mp3File.getLengthInSeconds();
|
||||||
|
|
||||||
|
if (mp3File.hasId3v2Tag()) {
|
||||||
|
ID3v2 id3v2tag = mp3File.getId3v2Tag();
|
||||||
|
byte[] albumWorkBytes = id3v2tag.getAlbumImage();
|
||||||
|
|
||||||
|
Pixmap albumArt = new Pixmap(albumWorkBytes, 0, albumWorkBytes.length);
|
||||||
|
Texture albumArtTexture = new Texture(albumArt);
|
||||||
|
imageIcon = new Image(albumArtTexture);
|
||||||
|
float scale = 0.25f*Gdx.graphics.getHeight()/imageIcon.getHeight();
|
||||||
|
|
||||||
|
imageIcon.setScale(scale);
|
||||||
|
albumArtTexture.dispose();
|
||||||
|
|
||||||
|
songName = id3v2tag.getTitle();
|
||||||
|
}
|
||||||
|
} catch (UnsupportedTagException | InvalidDataException | IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wavinfo = new WavInfo(musicFile.file());
|
||||||
|
durationInSeconds = wavinfo.getDurationInSeconds();
|
||||||
|
}
|
||||||
|
if (durationInSeconds > 60 * 5) {
|
||||||
|
invalidMusic = true;
|
||||||
|
}
|
||||||
|
if (songName == null || songName.isEmpty()) {
|
||||||
|
songName = musicFile.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,96 +1,16 @@
|
|||||||
package zero1hd.wavedecoder;
|
package zero1hd.wavedecoder;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
public class WavDecoder {
|
public class WavDecoder {
|
||||||
DataInputStream readStream;
|
private WavInfo initialData;
|
||||||
private int channels;
|
|
||||||
private double sampleRate;
|
|
||||||
private int dataSize;
|
|
||||||
private int byteRate;
|
|
||||||
|
|
||||||
public void setAudioFile(File file) throws InvalidParameterException {
|
public void setAudioFile(WavInfo info) throws InvalidParameterException, IOException {
|
||||||
try {
|
initialData = info;
|
||||||
FileInputStream audioFile = new FileInputStream(file);
|
initialData.initDataStream();
|
||||||
readStream = new DataInputStream(audioFile);
|
initialData.getHeaderInfo();
|
||||||
|
|
||||||
if (!readBytesToString(4).equals("RIFF")) {
|
|
||||||
throw new InvalidParameterException("RIFF tag not found in header.");
|
|
||||||
}
|
}
|
||||||
dataSize = littleEndianIntBytes();
|
|
||||||
|
|
||||||
if (!readBytesToString(4).equals("WAVE")) {
|
|
||||||
throw new InvalidParameterException("WAVE format tag not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!readBytesToString(4).equals("fmt ")) {
|
|
||||||
throw new InvalidParameterException("fmt header not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readStream.readByte() != 16) {
|
|
||||||
throw new InvalidParameterException("Data not pcm?");
|
|
||||||
}
|
|
||||||
|
|
||||||
readStream.skipBytes(3);
|
|
||||||
if (readStream.readByte() != 1) {
|
|
||||||
throw new InvalidParameterException("Data not pcm?");
|
|
||||||
}
|
|
||||||
readStream.skipBytes(1);
|
|
||||||
|
|
||||||
channels = readStream.readByte();
|
|
||||||
readStream.skipBytes(1);
|
|
||||||
|
|
||||||
sampleRate = littleEndianIntBytes();
|
|
||||||
|
|
||||||
byteRate = littleEndianIntBytes();
|
|
||||||
|
|
||||||
readStream.skipBytes(38);
|
|
||||||
|
|
||||||
if (!readBytesToString(4).equals("data")) {
|
|
||||||
throw new InvalidParameterException("initial data section tag not found");
|
|
||||||
}
|
|
||||||
readStream.skipBytes(4);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readBytesToString(int bytesToRead) throws IOException {
|
|
||||||
byte byteString[] = new byte[bytesToRead];
|
|
||||||
readStream.read(byteString);
|
|
||||||
return new String(byteString);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int littleEndianIntBytes() throws IOException {
|
|
||||||
int data = readStream.readInt();
|
|
||||||
return Integer.reverseBytes(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private short readLittleEndianShort() throws IOException {
|
|
||||||
short data = readStream.readShort();
|
|
||||||
return Short.reverseBytes(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChannels() {
|
|
||||||
return channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getSampleRate() {
|
|
||||||
return sampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getByteRate() {
|
|
||||||
return byteRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDataSize() {
|
|
||||||
return dataSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSamples(float[] samples) {
|
public int readSamples(float[] samples) {
|
||||||
int samplesRead = 0;
|
int samplesRead = 0;
|
||||||
|
|
||||||
@ -98,13 +18,18 @@ public class WavDecoder {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
int currentSample = 0;
|
int currentSample = 0;
|
||||||
for (int channel = 0; channel < channels; channel++) {
|
for (int channel = 0; channel < initialData.getChannels(); channel++) {
|
||||||
currentSample += readLittleEndianShort();
|
currentSample += initialData.readLittleEndianShort();
|
||||||
}
|
}
|
||||||
currentSample /= channels*Short.MAX_VALUE+1;
|
currentSample /= initialData.getChannels()*Short.MAX_VALUE+1;
|
||||||
samples[i] = currentSample;
|
samples[i] = currentSample;
|
||||||
samplesRead++;
|
samplesRead++;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
try {
|
||||||
|
initialData.closeStreams();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
114
core/src/zero1hd/wavedecoder/WavInfo.java
Executable file
114
core/src/zero1hd/wavedecoder/WavInfo.java
Executable file
@ -0,0 +1,114 @@
|
|||||||
|
package zero1hd.wavedecoder;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
|
public class WavInfo {
|
||||||
|
private int channels;
|
||||||
|
private double sampleRate;
|
||||||
|
private int dataSize;
|
||||||
|
private int byteRate;
|
||||||
|
private FileInputStream audioFile;
|
||||||
|
private DataInputStream readStream;
|
||||||
|
|
||||||
|
public WavInfo(File file) throws InvalidParameterException {
|
||||||
|
try {
|
||||||
|
audioFile = new FileInputStream(file);
|
||||||
|
initDataStream();
|
||||||
|
getHeaderInfo();
|
||||||
|
closeStreams();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void getHeaderInfo() throws IOException {
|
||||||
|
if (!readBytesToString(4).equals("RIFF")) { //4
|
||||||
|
throw new InvalidParameterException("RIFF tag not found in header.");
|
||||||
|
}
|
||||||
|
dataSize = littleEndianIntBytes(); //4
|
||||||
|
|
||||||
|
if (!readBytesToString(4).equals("WAVE")) { //4
|
||||||
|
throw new InvalidParameterException("WAVE format tag not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readBytesToString(4).equals("fmt ")) { //4
|
||||||
|
throw new InvalidParameterException("fmt header not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readStream.readByte() != 16) { //1
|
||||||
|
throw new InvalidParameterException("Data not pcm?");
|
||||||
|
}
|
||||||
|
|
||||||
|
readStream.skipBytes(3); //3
|
||||||
|
if (readStream.readByte() != 1) { //1
|
||||||
|
throw new InvalidParameterException("Data not pcm?");
|
||||||
|
}
|
||||||
|
readStream.skipBytes(1); //1
|
||||||
|
|
||||||
|
channels = readStream.readByte(); //1
|
||||||
|
readStream.skipBytes(1); //1
|
||||||
|
|
||||||
|
sampleRate = littleEndianIntBytes(); //4
|
||||||
|
|
||||||
|
byteRate = littleEndianIntBytes(); //4
|
||||||
|
|
||||||
|
readStream.skipBytes(38); //38
|
||||||
|
|
||||||
|
if (!readBytesToString(4).equals("data")) { // 4
|
||||||
|
throw new InvalidParameterException("initial data section tag not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initDataStream() {
|
||||||
|
readStream = new DataInputStream(audioFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void closeStreams() throws IOException {
|
||||||
|
readStream.close();
|
||||||
|
audioFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readBytesToString(int bytesToRead) throws IOException {
|
||||||
|
byte byteString[] = new byte[bytesToRead];
|
||||||
|
readStream.read(byteString);
|
||||||
|
return new String(byteString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int littleEndianIntBytes() throws IOException {
|
||||||
|
int data = readStream.readInt();
|
||||||
|
return Integer.reverseBytes(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected short readLittleEndianShort() throws IOException {
|
||||||
|
short data = readStream.readShort();
|
||||||
|
return Short.reverseBytes(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DataInputStream getReadStream() {
|
||||||
|
return readStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChannels() {
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getByteRate() {
|
||||||
|
return byteRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDataSize() {
|
||||||
|
return dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSampleRate() {
|
||||||
|
return sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDurationInSeconds() {
|
||||||
|
return (long) (dataSize/sampleRate);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user