Music and render engine.

main
Joshua Sigona 3 years ago
commit d0d1e497e7
  1. 11
      LLSIG/.classpath
  2. 2
      LLSIG/.gitignore
  3. 17
      LLSIG/.project
  4. 12
      LLSIG/.settings/org.eclipse.jdt.core.prefs
  5. BIN
      LLSIG/lib/jlayer-1.0.1.jar
  6. 42
      LLSIG/src/Canvas.java
  7. 334
      LLSIG/src/JLayerPlayerPausable.java
  8. 74
      LLSIG/src/LLSIG.java
  9. 26
      LLSIG/src/Lane.java
  10. 31
      LLSIG/src/Note.java
  11. 5
      LLSIG/src/NoteType.java
  12. 45
      LLSIG/src/Player.java
  13. BIN
      LLSIG/windows_64_bits_ffmpeg.exe

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="C:/Users/sigon/eclipse-workspace/LLSIG/lib/jlayer-1.0.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

2
LLSIG/.gitignore vendored

@ -0,0 +1,2 @@
/bin/
/music/

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>LLSIG</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

@ -0,0 +1,12 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

Binary file not shown.

@ -0,0 +1,42 @@
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Canvas extends JPanel{
final Color NOTE_COLOR = new Color(196,116,116);
public Canvas(Dimension size) {
super();
this.setSize(size);
this.setMinimumSize(size);
}
public void paintComponent(Graphics g) {
final int MIDDLE_X = this.getWidth()/2;
final int MIDDLE_Y = this.getHeight()/2;
final int JUDGEMENT_LINE_WIDTH = 64;
final int JUDGEMENT_LINE_HEIGHT = 4;
final int NOTE_SIZE = 16;
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0,0,this.getWidth(),this.getHeight());
g.setColor(Color.WHITE);
g.drawString(Integer.toString(LLSIG.game!=null?LLSIG.game.frameCount:0),0,16);
g.setColor(Color.GRAY);
g.fillRect(MIDDLE_X-JUDGEMENT_LINE_WIDTH/2,MIDDLE_Y-JUDGEMENT_LINE_HEIGHT/2,JUDGEMENT_LINE_WIDTH,JUDGEMENT_LINE_HEIGHT);
g.setColor(NOTE_COLOR);
int noteCounter = 0;
Lane lane1 = LLSIG.game.lanes.get(0);
while (lane1.noteExists(noteCounter)) {
Note n = lane1.getNote(noteCounter);
int NOTE_Y_OFFSET = (int)((((double)LLSIG.game.musicPlayer.getPlayPosition()-n.getStartFrame())/1000)*60*LLSIG.game.noteSpeed);
g.fillOval(MIDDLE_X-NOTE_SIZE/2,MIDDLE_Y-NOTE_SIZE/2+NOTE_Y_OFFSET,NOTE_SIZE,NOTE_SIZE);
noteCounter++;
}
}
}

@ -0,0 +1,334 @@
/* *-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Original by: http://thiscouldbebetter.wordpress.com/2011/07/04/pausing-an-mp3-file-using-jlayer/
* Last modified: 21-jul-2012 by Arthur Assuncao
*----------------------------------------------------------------------
*/
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.decoder.SampleBuffer;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;
//use with JLayerPausableTest
public class JLayerPlayerPausable{
// This class is loosely based on javazoom.jl.player.AdvancedPlayer.
private java.net.URL urlToStreamFrom;
private String audioPath;
private Bitstream bitstream;
private Decoder decoder;
private AudioDevice audioDevice;
private boolean closed;
private boolean complete;
private boolean paused;
private boolean stopped;
private PlaybackListener listener;
private int frameIndexCurrent;
private int resumePoint;
private final int lostFrames = 20; //some fraction of a second of the sound gets "lost" after every pause. 52 in original code
public JLayerPlayerPausable(URL urlToStreamFrom) throws JavaLayerException{
this.urlToStreamFrom = urlToStreamFrom;
this.listener = new PlaybackAdapter();
}
public JLayerPlayerPausable(String audioPath) throws JavaLayerException{
this.audioPath = audioPath;
this.listener = new PlaybackAdapter();
}
public void setPlaybackListener(PlaybackListener newPlaybackListener){
if(newPlaybackListener != null){
this.listener = newPlaybackListener;
}
else{
throw new NullPointerException("PlaybackListener is null");
}
}
public int getPosition() {
return this.audioDevice!=null?this.audioDevice.getPosition()+resumePoint:resumePoint;
}
private InputStream getAudioInputStream() throws IOException{
if(this.audioPath != null){
return new FileInputStream(this.audioPath);
}
else if(this.urlToStreamFrom != null){
this.urlToStreamFrom.openStream();
}
return null;
}
public boolean play() throws JavaLayerException{
return this.play(0);
}
public boolean play(int frameIndexStart) throws JavaLayerException {
//return this.play(frameIndexStart, -1, 52); //original, mas voltava num ponto anterior ao do pause. 52 Sao os frames perdidos ao dar pause
return this.play(frameIndexStart, -1, lostFrames);
}
public boolean play(int frameIndexStart, int frameIndexFinal, int correctionFactorInFrames) throws JavaLayerException{
try {
this.bitstream = new Bitstream(this.getAudioInputStream());
}
catch (IOException e) {
e.printStackTrace();
}
this.audioDevice = FactoryRegistry.systemRegistry().createAudioDevice();
this.decoder = new Decoder();
this.audioDevice.open(this.decoder);
boolean shouldContinueReadingFrames = true;
this.paused = false;
this.stopped = false;
this.frameIndexCurrent = 0;
while (shouldContinueReadingFrames == true && this.frameIndexCurrent < frameIndexStart - correctionFactorInFrames){
shouldContinueReadingFrames = this.skipFrame();
this.frameIndexCurrent++;
}
if (this.listener != null) {
this.listener.playbackStarted(new PlaybackEvent(this, PlaybackEvent.EventType.Instances.Started, this.audioDevice.getPosition()));
}
if (frameIndexFinal < 0){
frameIndexFinal = Integer.MAX_VALUE;
}
while (shouldContinueReadingFrames == true && this.frameIndexCurrent < frameIndexFinal){
if (this.paused || this.stopped){
shouldContinueReadingFrames = false;
try{
Thread.sleep(1);
}
catch (Exception ex){
ex.printStackTrace();
}
}
else{
shouldContinueReadingFrames = this.decodeFrame();
this.frameIndexCurrent++;
}
}
// last frame, ensure all data flushed to the audio device.
if (this.audioDevice != null && !this.paused){
this.audioDevice.flush();
synchronized (this){
this.complete = (this.closed == false);
this.close();
}
// report to listener
if (this.listener != null) {
int audioDevicePosition = -1;
if(this.audioDevice != null){
audioDevicePosition = this.audioDevice.getPosition();
}
else{
//throw new NullPointerException("attribute audioDevice in " + this.getClass() + " is NULL");
}
PlaybackEvent playbackEvent = new PlaybackEvent(this, PlaybackEvent.EventType.Instances.Stopped, audioDevicePosition);
this.listener.playbackFinished(playbackEvent);
}
}
return shouldContinueReadingFrames;
}
public boolean resume() throws JavaLayerException{
return this.play(this.frameIndexCurrent);
}
public synchronized void close(){
if (this.audioDevice != null){
this.closed = true;
this.audioDevice.close();
this.audioDevice = null;
try{
this.bitstream.close();
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
protected boolean decodeFrame() throws JavaLayerException{
boolean returnValue = false;
if(this.stopped){ //nothing for decode
return false;
}
try{
if (this.audioDevice != null){
Header header = this.bitstream.readFrame();
if (header != null){
// sample buffer set when decoder constructed
SampleBuffer output = (SampleBuffer) this.decoder.decodeFrame(header, this.bitstream);
synchronized (this){
if (this.audioDevice != null){
this.audioDevice.write(output.getBuffer(), 0, output.getBufferLength());
}
}
this.bitstream.closeFrame();
returnValue = true;
}
else{
System.out.println("End of file"); //end of file
//this.stop();
returnValue = false;
}
}
}
catch (RuntimeException ex){
throw new JavaLayerException("Exception decoding audio frame", ex);
}
return returnValue;
}
public void pause(){
if(!this.stopped){
this.paused = true;
if (this.listener != null) {
this.resumePoint = getPosition();
System.out.println("Resume Point: "+resumePoint);
this.listener.playbackPaused(new PlaybackEvent(this, PlaybackEvent.EventType.Instances.Paused, this.audioDevice.getPosition()));
}
this.close();
}
}
protected boolean skipFrame() throws JavaLayerException{
boolean returnValue = false;
Header header = this.bitstream.readFrame();
if (header != null) {
this.bitstream.closeFrame();
returnValue = true;
}
return returnValue;
}
public void stop(){
if(!this.stopped){
if(!this.closed){
this.listener.playbackFinished(new PlaybackEvent(this, PlaybackEvent.EventType.Instances.Stopped, this.audioDevice.getPosition()));
this.close();
}
else if(this.paused){
int audioDevicePosition = -1; //this.audioDevice.getPosition(), audioDevice is null
this.listener.playbackFinished(new PlaybackEvent(this, PlaybackEvent.EventType.Instances.Stopped, audioDevicePosition));
}
this.stopped = true;
}
}
/**
* @return the closed
*/
public boolean isClosed() {
return closed;
}
/**
* @return the complete
*/
public boolean isComplete() {
return complete;
}
/**
* @return the paused
*/
public boolean isPaused() {
return paused;
}
/**
* @return the stopped
*/
public boolean isStopped() {
return stopped;
}
// inner classes
public static class PlaybackEvent{
public JLayerPlayerPausable source;
public EventType eventType;
public int frameIndex;
public PlaybackEvent(JLayerPlayerPausable source, EventType eventType, int frameIndex) {
this.source = source;
this.eventType = eventType;
this.frameIndex = frameIndex;
}
public static class EventType{
public String name;
public EventType(String name){
this.name = name;
}
public static class Instances{
public static EventType Started = new EventType("Started");
public static EventType Paused = new EventType("Paused");
public static EventType Stopped = new EventType("Stopped");
}
}
}
public static class PlaybackAdapter implements PlaybackListener{
@Override
public void playbackStarted(PlaybackEvent event){
System.err.println("Playback started");
}
@Override
public void playbackPaused(PlaybackEvent event){
System.err.println("Playback paused");
}
@Override
public void playbackFinished(PlaybackEvent event){
System.err.println("Playback stopped");
}
}
public static interface PlaybackListener{
public void playbackStarted(PlaybackEvent event);
public void playbackPaused(PlaybackEvent event);
public void playbackFinished(PlaybackEvent event);
}
}

@ -0,0 +1,74 @@
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javazoom.jl.decoder.JavaLayerException;
public class LLSIG implements KeyListener{
Player musicPlayer;
JFrame window;
Thread gameLoop;
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(1);
int frameCount;
public static LLSIG game;
int noteSpeed = 4;
List<Lane> lanes = new ArrayList<Lane>();
LLSIG(JFrame f) {
this.window = f;
this.musicPlayer = new Player("music/MiChi - ONE-315959669.mp3");
musicPlayer.play();
lanes.add(new Lane(Arrays.asList(new Note[] {
new Note(NoteType.NORMAL,1000),
new Note(NoteType.NORMAL,2000),
new Note(NoteType.NORMAL,3000),
new Note(NoteType.NORMAL,4000),
})));
Canvas canvas = new Canvas(f.getSize());
window.add(canvas);
window.setVisible(true);
window.addKeyListener(this);
gameLoop = new Thread() {
public void run() {
frameCount++;
window.repaint();
}
};
stpe.scheduleAtFixedRate(gameLoop, 0, 16666666l, TimeUnit.NANOSECONDS);
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(640, 640);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game = new LLSIG(f);
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Pressed "+e.getKeyChar()+" on frame "+musicPlayer.getPlayPosition());
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}

@ -0,0 +1,26 @@
import java.util.ArrayList;
import java.util.List;
public class Lane{
List<Note> noteChart;
int currentNoteIndex = 0;
public Lane(List<Note> noteChart) {
super();
this.noteChart = noteChart;
}
public boolean endOfChart() {
return currentNoteIndex==noteChart.size()-1;
}
public void consumeNote() {
currentNoteIndex = Math.min(currentNoteIndex+1,noteChart.size()-1);
}
public boolean noteExists(int noteOffset) {
return currentNoteIndex+noteOffset<noteChart.size();
}
public Note getNote(int noteOffset) throws IndexOutOfBoundsException {
return noteChart.get(currentNoteIndex+noteOffset);
}
public Note getNote() {
return getNote(0);
}
}

@ -0,0 +1,31 @@
public class Note {
NoteType type;
int start,end;
public Note(NoteType type,int start,int end) {
this.type=type;
this.start=start;
this.end=end;
}
public Note(NoteType type,int start) {
this(type,start,-1);
}
public NoteType getNoteType() {
return type;
}
public void setNoteType(NoteType type) {
this.type = type;
}
public int getStartFrame() {
return start;
}
public void setStartFrame(int start) {
this.start = start;
}
public int getEndFrame() {
return end;
}
public void setEndFrame(int end) {
this.end = end;
}
}

@ -0,0 +1,5 @@
public enum NoteType {
NORMAL,
HOLD;
}

@ -0,0 +1,45 @@
import javazoom.jl.decoder.JavaLayerException;
public class Player {
JLayerPlayerPausable jlpp;
String song;
public Player(String song) {
this.song=song;
try {
jlpp = new JLayerPlayerPausable(song);
} catch (JavaLayerException e) {
e.printStackTrace();
}
}
public void play() {
new Thread() {
public void run() {
try {
jlpp.play();
} catch (JavaLayerException e) {
e.printStackTrace();
}
}
}.start();
}
public void pause() {
jlpp.pause();
}
public void resume() {
new Thread() {
public void run() {
try {
jlpp.resume();
} catch (JavaLayerException e) {
e.printStackTrace();
}
}
}.start();
}
public void kill() {
jlpp.close();
}
public int getPlayPosition() {
return jlpp.getPosition();
}
}

Binary file not shown.
Loading…
Cancel
Save