mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-09-29 11:55:21 +00:00
Working sound playback with LWGJL finally! (still some bugs)
This commit is contained in:
parent
e99bd01741
commit
580e760fae
2
Platform/Apple/tools/jace/.gitignore
vendored
2
Platform/Apple/tools/jace/.gitignore
vendored
@ -4,4 +4,4 @@
|
|||||||
/.jace.conf
|
/.jace.conf
|
||||||
*.classpath
|
*.classpath
|
||||||
*.project
|
*.project
|
||||||
/src/main/resources/jace/data/sound/*.mp3
|
/src/main/resources/jace/data/sound/*.ogg
|
||||||
|
@ -215,6 +215,11 @@
|
|||||||
<artifactId>lwjgl-openal</artifactId>
|
<artifactId>lwjgl-openal</artifactId>
|
||||||
<classifier>${lwjgl.natives}</classifier>
|
<classifier>${lwjgl.natives}</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.lwjgl</groupId>
|
||||||
|
<artifactId>lwjgl-stb</artifactId>
|
||||||
|
<classifier>${lwjgl.natives}</classifier>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.badlogicgames.jlayer</groupId>
|
<groupId>com.badlogicgames.jlayer</groupId>
|
||||||
<artifactId>jlayer</artifactId>
|
<artifactId>jlayer</artifactId>
|
||||||
|
@ -60,7 +60,7 @@ public class SoundMixer extends Device {
|
|||||||
* Sample playback rate
|
* Sample playback rate
|
||||||
*/
|
*/
|
||||||
@ConfigurableField(name = "Playback Rate", shortName = "freq")
|
@ConfigurableField(name = "Playback Rate", shortName = "freq")
|
||||||
public static int RATE = 48000;
|
public static int RATE = 44100;
|
||||||
@ConfigurableField(name = "Mute", shortName = "mute")
|
@ConfigurableField(name = "Mute", shortName = "mute")
|
||||||
public static boolean MUTE = false;
|
public static boolean MUTE = false;
|
||||||
|
|
||||||
@ -239,10 +239,11 @@ public class SoundMixer extends Device {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isAlive = false;
|
isAlive = false;
|
||||||
performSoundOperation(()->AL10.alSourceStop(sourceId));
|
|
||||||
performSoundOperation(()->AL10.alDeleteSources(sourceId));
|
performSoundOperation(()->{if (AL10.alIsSource(sourceId)) AL10.alSourceStop(sourceId);});
|
||||||
performSoundOperation(()->AL10.alDeleteBuffers(alternateBufferId));
|
performSoundOperation(()->{if (AL10.alIsSource(sourceId)) AL10.alDeleteSources(sourceId);});
|
||||||
performSoundOperation(()->AL10.alDeleteBuffers(currentBufferId));
|
performSoundOperation(()->{if (AL10.alIsBuffer(alternateBufferId)) AL10.alDeleteBuffers(alternateBufferId);});
|
||||||
|
performSoundOperation(()->{if (AL10.alIsBuffer(currentBufferId)) AL10.alDeleteBuffers(currentBufferId);});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@ import java.io.BufferedReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -109,7 +107,7 @@ public class LawlessHacks extends Cheats {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSongName(int number) {
|
public String getSongName(int number) {
|
||||||
Map<Integer, String> score = scores.get(currentScore);
|
Map<Integer, String> score = scores.get(currentScore);
|
||||||
if (score == null) {
|
if (score == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -125,24 +123,24 @@ public class LawlessHacks extends Cheats {
|
|||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Media getAudioTrack(int number) {
|
public Media getAudioTrack(int number) {
|
||||||
String filename = getSongName(number);
|
String filename = getSongName(number);
|
||||||
String pathStr = "/jace/data/sound/" + filename;
|
String pathStr = "/jace/data/sound/" + filename;
|
||||||
URL path = getClass().getResource(pathStr);
|
// URL path = getClass().getResource(pathStr);
|
||||||
if (path == null) {
|
// if (path == null) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
String resourcePath = path.toString();
|
// String resourcePath = path.toString();
|
||||||
System.out.println("Playing " + resourcePath);
|
// System.out.println("Playing " + resourcePath);
|
||||||
if (resourcePath.startsWith("resource:")) {
|
// if (resourcePath.startsWith("resource:")) {
|
||||||
resourcePath = Paths.get(resourcePath).toFile().getAbsolutePath();
|
// resourcePath = Paths.get(resourcePath).toFile().getAbsolutePath();
|
||||||
System.out.println("Playing " + resourcePath);
|
// System.out.println("Playing " + resourcePath);
|
||||||
}
|
// }
|
||||||
// Log path
|
// Log path
|
||||||
try {
|
try {
|
||||||
return new Media(resourcePath);
|
return new Media(pathStr);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Unable to load audio track " + resourcePath, e);
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Unable to load audio track " + pathStr, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,7 +313,7 @@ public class LawlessHacks extends Cheats {
|
|||||||
Pattern COMMENT = Pattern.compile("\\s*[-#;']+.*");
|
Pattern COMMENT = Pattern.compile("\\s*[-#;']+.*");
|
||||||
Pattern LABEL = Pattern.compile("(8-)?[A-Za-z\\s\\-_]+");
|
Pattern LABEL = Pattern.compile("(8-)?[A-Za-z\\s\\-_]+");
|
||||||
Pattern ENTRY = Pattern.compile("([0-9]+)\\s+(.*)");
|
Pattern ENTRY = Pattern.compile("([0-9]+)\\s+(.*)");
|
||||||
private final Map<String, Map<Integer, String>> scores = new HashMap<>();
|
public final Map<String, Map<Integer, String>> scores = new HashMap<>();
|
||||||
private final Set<Integer> autoResume = new HashSet<>();
|
private final Set<Integer> autoResume = new HashSet<>();
|
||||||
private final Map<Integer, Long> lastTime = new HashMap<>();
|
private final Map<Integer, Long> lastTime = new HashMap<>();
|
||||||
private void readScores() {
|
private void readScores() {
|
||||||
@ -323,7 +321,7 @@ public class LawlessHacks extends Cheats {
|
|||||||
readScores(data);
|
readScores(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readScores(InputStream data) {
|
public void readScores(InputStream data) {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(data));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(data));
|
||||||
reader.lines().forEach(line -> {
|
reader.lines().forEach(line -> {
|
||||||
boolean useAutoResume = false;
|
boolean useAutoResume = false;
|
||||||
|
@ -1,83 +1,138 @@
|
|||||||
package jace.lawless;
|
package jace.lawless;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.net.URLDecoder;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
import org.lwjgl.stb.STBVorbis;
|
import org.lwjgl.stb.STBVorbis;
|
||||||
import org.lwjgl.stb.STBVorbisInfo;
|
import org.lwjgl.stb.STBVorbisInfo;
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
public class Media {
|
public class Media {
|
||||||
long streamHandle = -1;
|
int totalSamples = 0;
|
||||||
long totalSamples = 0;
|
|
||||||
float totalDuration = 0;
|
float totalDuration = 0;
|
||||||
long sampleRate = 0;
|
long sampleRate = 0;
|
||||||
boolean isStereo = true;
|
boolean isStereo = true;
|
||||||
ShortBuffer sampleBuffer = ShortBuffer.allocate(2);
|
ShortBuffer sampleBuffer;
|
||||||
|
|
||||||
public Media(String resourcePath) throws IOException {
|
public Media(String resourcePath) throws IOException {
|
||||||
// Load resource into memory
|
// Get caononical file path from relative resource path
|
||||||
try (InputStream inputStream = getClass().getResourceAsStream(resourcePath)) {
|
String canonicalPath = URLDecoder.decode(getClass().getResource(resourcePath).getPath(), "UTF-8");
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
System.out.println("Loading media: " + canonicalPath);
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int bytesRead;
|
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
IntBuffer error = stack.callocInt(1);
|
||||||
outputStream.write(buffer, 0, bytesRead);
|
Long decoder = STBVorbis.stb_vorbis_open_filename(canonicalPath, error, null);
|
||||||
|
if (decoder == null || decoder <= 0) {
|
||||||
|
throw new RuntimeException("Failed to open Ogg Vorbis file. Error: " + getError(error.get(0)));
|
||||||
}
|
}
|
||||||
ByteBuffer byteBuffer = ByteBuffer.wrap(outputStream.toByteArray());
|
|
||||||
|
|
||||||
IntBuffer error = IntBuffer.allocate(1);
|
|
||||||
streamHandle = STBVorbis.stb_vorbis_open_memory(byteBuffer, error, null);
|
|
||||||
|
|
||||||
MemoryStack stack = MemoryStack.stackPush();
|
|
||||||
STBVorbisInfo info = STBVorbisInfo.malloc(stack);
|
STBVorbisInfo info = STBVorbisInfo.malloc(stack);
|
||||||
STBVorbis.stb_vorbis_get_info(streamHandle, info);
|
STBVorbis.stb_vorbis_get_info(decoder, info);
|
||||||
totalSamples = STBVorbis.stb_vorbis_stream_length_in_samples(streamHandle);
|
totalSamples = STBVorbis.stb_vorbis_stream_length_in_samples(decoder);
|
||||||
totalDuration = STBVorbis.stb_vorbis_stream_length_in_seconds(streamHandle);
|
totalDuration = STBVorbis.stb_vorbis_stream_length_in_seconds(decoder);
|
||||||
sampleRate = info.sample_rate();
|
sampleRate = info.sample_rate();
|
||||||
isStereo = info.channels() == 2;
|
isStereo = info.channels() == 2;
|
||||||
info.free();
|
|
||||||
|
sampleBuffer = MemoryUtil.memAllocShort(totalSamples);
|
||||||
|
STBVorbis.stb_vorbis_get_samples_short_interleaved(decoder, isStereo?2:1, sampleBuffer);
|
||||||
|
STBVorbis.stb_vorbis_close(decoder);
|
||||||
|
sampleBuffer.rewind();
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getError(int vorbisErrorCode) {
|
||||||
|
switch (vorbisErrorCode) {
|
||||||
|
case STBVorbis.VORBIS__no_error:
|
||||||
|
return "VORBIS_no_error";
|
||||||
|
case STBVorbis.VORBIS_need_more_data:
|
||||||
|
return "VORBIS_need_more_data";
|
||||||
|
case STBVorbis.VORBIS_invalid_api_mixing:
|
||||||
|
return "VORBIS_invalid_api_mixing";
|
||||||
|
case STBVorbis.VORBIS_outofmem:
|
||||||
|
return "VORBIS_outofmem";
|
||||||
|
case STBVorbis.VORBIS_feature_not_supported:
|
||||||
|
return "VORBIS_feature_not_supported";
|
||||||
|
case STBVorbis.VORBIS_too_many_channels:
|
||||||
|
return "VORBIS_too_many_channels";
|
||||||
|
case STBVorbis.VORBIS_file_open_failure:
|
||||||
|
return "VORBIS_file_open_failure";
|
||||||
|
case STBVorbis.VORBIS_seek_without_length:
|
||||||
|
return "VORBIS_seek_without_length";
|
||||||
|
case STBVorbis.VORBIS_unexpected_eof:
|
||||||
|
return "VORBIS_unexpected_eof";
|
||||||
|
case STBVorbis.VORBIS_seek_invalid:
|
||||||
|
return "VORBIS_seek_invalid";
|
||||||
|
case STBVorbis.VORBIS_invalid_setup:
|
||||||
|
return "VORBIS_invalid_setup";
|
||||||
|
case STBVorbis.VORBIS_invalid_stream:
|
||||||
|
return "VORBIS_invalid_stream";
|
||||||
|
case STBVorbis.VORBIS_missing_capture_pattern:
|
||||||
|
return "VORBIS_missing_capture_pattern";
|
||||||
|
case STBVorbis.VORBIS_invalid_stream_structure_version:
|
||||||
|
return "VORBIS_invalid_stream_structure_version";
|
||||||
|
case STBVorbis.VORBIS_continued_packet_flag_invalid:
|
||||||
|
return "VORBIS_continued_packet_flag_invalid";
|
||||||
|
case STBVorbis.VORBIS_incorrect_stream_serial_number:
|
||||||
|
return "VORBIS_incorrect_stream_serial_number";
|
||||||
|
case STBVorbis.VORBIS_invalid_first_page:
|
||||||
|
return "VORBIS_invalid_first_page";
|
||||||
|
case STBVorbis.VORBIS_bad_packet_type:
|
||||||
|
return "VORBIS_bad_packet_type";
|
||||||
|
case STBVorbis.VORBIS_cant_find_last_page:
|
||||||
|
return "VORBIS_cant_find_last_page";
|
||||||
|
case STBVorbis.VORBIS_seek_failed:
|
||||||
|
return "VORBIS_seek_failed";
|
||||||
|
case STBVorbis.VORBIS_ogg_skeleton_not_supported:
|
||||||
|
return "VORBIS_ogg_skeleton_not_supported";
|
||||||
|
default:
|
||||||
|
return "Unknown error code: " + vorbisErrorCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
STBVorbis.stb_vorbis_close(streamHandle);
|
MemoryUtil.memFree(sampleBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seekToTime(Duration millis) {
|
public void seekToTime(Duration millis) {
|
||||||
int sampleNumber = (int) (millis.toMillis() * sampleRate / 1000);
|
int sampleNumber = (int) (millis.toMillis() * sampleRate / 1000);
|
||||||
STBVorbis.stb_vorbis_seek(streamHandle, sampleNumber);
|
sampleBuffer.position(sampleNumber * (isStereo ? 2 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnded() {
|
public boolean isEnded() {
|
||||||
return STBVorbis.stb_vorbis_get_sample_offset(streamHandle) >= totalSamples;
|
return sampleBuffer.remaining() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restart() {
|
public void restart() {
|
||||||
STBVorbis.stb_vorbis_seek_start(streamHandle);
|
sampleBuffer.rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getNextLeftSample() {
|
public short getNextLeftSample() {
|
||||||
// read next sample for left and right channels
|
// read next sample for left and right channels
|
||||||
int numSamples = STBVorbis.stb_vorbis_get_frame_short_interleaved(streamHandle, isStereo ? 2 : 1, sampleBuffer);
|
if (isEnded()) {
|
||||||
if (numSamples == 0) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return sampleBuffer.get(0);
|
return sampleBuffer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getNextRightSample() {
|
public short getNextRightSample() {
|
||||||
return isStereo ? sampleBuffer.get(1) : sampleBuffer.get(0);
|
if (isEnded()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return isStereo ? sampleBuffer.get() : sampleBuffer.get(sampleBuffer.position());
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.time.Duration getCurrentTime() {
|
public java.time.Duration getCurrentTime() {
|
||||||
int sampleNumber = STBVorbis.stb_vorbis_get_sample_offset(streamHandle);
|
int sampleNumber = sampleBuffer.position() / (isStereo ? 2 : 1);
|
||||||
return java.time.Duration.ofMillis((long) (sampleNumber * 1000 / sampleRate));
|
return java.time.Duration.ofMillis((long) (sampleNumber * 1000 / sampleRate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getTotalDuration() {
|
||||||
|
return totalDuration;
|
||||||
|
}
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ public class MediaPlayer {
|
|||||||
double vol = 1.0;
|
double vol = 1.0;
|
||||||
int repeats = 0;
|
int repeats = 0;
|
||||||
int maxRepetitions = 1;
|
int maxRepetitions = 1;
|
||||||
Status status = Status.STOPPED;
|
Status status = Status.NOT_STARTED;
|
||||||
Media song;
|
Media song;
|
||||||
SoundBuffer playbackBuffer;
|
SoundBuffer playbackBuffer;
|
||||||
Executor executor = Executors.newSingleThreadExecutor();
|
Executor executor = Executors.newSingleThreadExecutor();
|
||||||
@ -47,9 +47,10 @@ public class MediaPlayer {
|
|||||||
playbackBuffer.shutdown();
|
playbackBuffer.shutdown();
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
// Ignore exception on shutdown
|
// Ignore exception on shutdown
|
||||||
}
|
} finally {
|
||||||
song.close();
|
song.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setCycleCount(int i) {
|
public void setCycleCount(int i) {
|
||||||
maxRepetitions = i;
|
maxRepetitions = i;
|
||||||
@ -72,12 +73,13 @@ public class MediaPlayer {
|
|||||||
return;
|
return;
|
||||||
} else if (status == Status.NOT_STARTED) {
|
} else if (status == Status.NOT_STARTED) {
|
||||||
repeats = 0;
|
repeats = 0;
|
||||||
status = Status.PLAYING;
|
|
||||||
if (playbackBuffer == null || !playbackBuffer.isAlive()) {
|
if (playbackBuffer == null || !playbackBuffer.isAlive()) {
|
||||||
playbackBuffer = SoundMixer.createBuffer(true);
|
playbackBuffer = SoundMixer.createBuffer(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
executor.execute(() -> {
|
executor.execute(() -> {
|
||||||
|
status = Status.PLAYING;
|
||||||
|
System.out.println("Song playback thread started");
|
||||||
while (status == Status.PLAYING && (maxRepetitions == INDEFINITE || repeats < maxRepetitions)) {
|
while (status == Status.PLAYING && (maxRepetitions == INDEFINITE || repeats < maxRepetitions)) {
|
||||||
if (song.isEnded()) {
|
if (song.isEnded()) {
|
||||||
if (maxRepetitions == INDEFINITE) {
|
if (maxRepetitions == INDEFINITE) {
|
||||||
@ -87,16 +89,15 @@ public class MediaPlayer {
|
|||||||
if (repeats < maxRepetitions) {
|
if (repeats < maxRepetitions) {
|
||||||
song.restart();
|
song.restart();
|
||||||
} else {
|
} else {
|
||||||
|
System.out.println("Song ended");
|
||||||
this.stop();
|
this.stop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
short leftSample = song.getNextLeftSample();
|
|
||||||
short rightSample = song.getNextRightSample();
|
|
||||||
try {
|
try {
|
||||||
playbackBuffer.playSample((short) (leftSample * vol));
|
playbackBuffer.playSample((short) (song.getNextLeftSample() * vol));
|
||||||
playbackBuffer.playSample((short) (rightSample * vol));
|
playbackBuffer.playSample((short) (song.getNextRightSample() * vol));
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
this.stop();
|
this.stop();
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
---- Lines that contain an asterisk will use auto-resume, otherwise will always restart
|
---- Lines that contain an asterisk will use auto-resume, otherwise will always restart
|
||||||
Common
|
Common
|
||||||
--- Sound effects start at number 129
|
--- Sound effects start at number 129
|
||||||
129 bang.mp3
|
--129 bang.ogg
|
||||||
130 boom.mp3
|
--130 boom.ogg
|
||||||
|
|
||||||
-- 1: Theme (Copyright)
|
-- 1: Theme (Copyright)
|
||||||
-- 2: Train station (intro), Fort Miller
|
-- 2: Train station (intro), Fort Miller
|
||||||
@ -30,45 +30,45 @@ Common
|
|||||||
|
|
||||||
---- Chiptune version uses the blips and bleeps that are the voice of a generation
|
---- Chiptune version uses the blips and bleeps that are the voice of a generation
|
||||||
8-bit Chipmusic
|
8-bit Chipmusic
|
||||||
1 8 Bit Weapon - Lawless Legends Original Double Score - 02 Lawless Legends 8-Bit C64.mp3
|
1 8 Bit Weapon - Lawless Legends Original Double Score - 02 Lawless Legends 8-Bit C64.ogg
|
||||||
2 8 Bit Weapon - Lawless Legends Original Double Score - 03 Fort Miller 8-Bit C64.mp3
|
2 8 Bit Weapon - Lawless Legends Original Double Score - 03 Fort Miller 8-Bit C64.ogg
|
||||||
3 8 Bit Weapon - Lawless Legends Original Double Score - 04 Tragedy in the West 8-Bit C64.mp3
|
3 8 Bit Weapon - Lawless Legends Original Double Score - 04 Tragedy in the West 8-Bit C64.ogg
|
||||||
4 8 Bit Weapon - Lawless Legends Original Double Score - 05 Victory! 8-Bit C64.mp3
|
4 8 Bit Weapon - Lawless Legends Original Double Score - 05 Victory! 8-Bit C64.ogg
|
||||||
5 8 Bit Weapon - Lawless Legends Original Double Score - 06 Grub Gulch 8-Bit C64.mp3
|
5 8 Bit Weapon - Lawless Legends Original Double Score - 06 Grub Gulch 8-Bit C64.ogg
|
||||||
6 8 Bit Weapon - Lawless Legends Original Double Score - 07 Mines of Mystery 8-Bit C64.mp3
|
6 8 Bit Weapon - Lawless Legends Original Double Score - 07 Mines of Mystery 8-Bit C64.ogg
|
||||||
7 8 Bit Weapon - Lawless Legends Original Double Score - 08 Texas Flats 8-Bit C64.mp3
|
7 8 Bit Weapon - Lawless Legends Original Double Score - 08 Texas Flats 8-Bit C64.ogg
|
||||||
8 8 Bit Weapon - Lawless Legends Original Double Score - 09 Strange Tales 8-Bit C64.mp3
|
8 8 Bit Weapon - Lawless Legends Original Double Score - 09 Strange Tales 8-Bit C64.ogg
|
||||||
9 8 Bit Weapon - Lawless Legends Original Double Score - 10 Oro's Villa 8-Bit C64.mp3
|
9 8 Bit Weapon - Lawless Legends Original Double Score - 10 Oro's Villa 8-Bit C64.ogg
|
||||||
10 8 Bit Weapon - Lawless Legends Original Double Score - 11 Tahnku Village 8-Bit C64.mp3
|
10 8 Bit Weapon - Lawless Legends Original Double Score - 11 Tahnku Village 8-Bit C64.ogg
|
||||||
11 8 Bit Weapon - Lawless Legends Original Double Score - 12 Tahnku Sanctuary 8-Bit C64.mp3
|
11 8 Bit Weapon - Lawless Legends Original Double Score - 12 Tahnku Sanctuary 8-Bit C64.ogg
|
||||||
12 8 Bit Weapon - Lawless Legends Original Double Score - 13 Mariposa 8-Bit C64.mp3
|
12 8 Bit Weapon - Lawless Legends Original Double Score - 13 Mariposa 8-Bit C64.ogg
|
||||||
13 8 Bit Weapon - Lawless Legends Original Double Score - 14 Freemont Estate 8-Bit C64.mp3
|
13 8 Bit Weapon - Lawless Legends Original Double Score - 14 Freemont Estate 8-Bit C64.ogg
|
||||||
14 8 Bit Weapon - Lawless Legends Original Double Score - 15 Fort Littlecreek 8-Bit C64.mp3
|
14 8 Bit Weapon - Lawless Legends Original Double Score - 15 Fort Littlecreek 8-Bit C64.ogg
|
||||||
15 8 Bit Weapon - Lawless Legends Original Double Score - 16 Sacred Grove 8-Bit C64.mp3
|
15 8 Bit Weapon - Lawless Legends Original Double Score - 16 Sacred Grove 8-Bit C64.ogg
|
||||||
16 8 Bit Weapon - Lawless Legends Original Double Score - 17 Poverty Flats 8-Bit C64.mp3
|
16 8 Bit Weapon - Lawless Legends Original Double Score - 17 Poverty Flats 8-Bit C64.ogg
|
||||||
17 8 Bit Weapon - Lawless Legends Original Double Score - 18 Combat! 8-Bit C64.mp3
|
17 8 Bit Weapon - Lawless Legends Original Double Score - 18 Combat! 8-Bit C64.ogg
|
||||||
18 8 Bit Weapon - Lawless Legends Original Double Score - 19 Killed in Cold Blood 8-Bit C64.mp3
|
18 8 Bit Weapon - Lawless Legends Original Double Score - 19 Killed in Cold Blood 8-Bit C64.ogg
|
||||||
19 *8 Bit Weapon - Lawless Legends Original Double Score - 20 The Sierra Nevada Wilderness 8-Bit C64.mp3
|
19 *8 Bit Weapon - Lawless Legends Original Double Score - 20 The Sierra Nevada Wilderness 8-Bit C64.ogg
|
||||||
20 *8 Bit Weapon - Lawless Legends Original Double Score - 20 The Sierra Nevada Wilderness 8-Bit C64.mp3
|
20 *8 Bit Weapon - Lawless Legends Original Double Score - 20 The Sierra Nevada Wilderness 8-Bit C64.ogg
|
||||||
|
|
||||||
8-bit Orchestral samples
|
8-bit Orchestral samples
|
||||||
1 8 Bit Weapon - Lawless Legends Original Double Score - 21 Lawless Legends 8-Bit Samples.mp3
|
1 8 Bit Weapon - Lawless Legends Original Double Score - 21 Lawless Legends 8-Bit Samples.ogg
|
||||||
2 8 Bit Weapon - Lawless Legends Original Double Score - 22 Fort Miller 8-Bit Samples.mp3
|
2 8 Bit Weapon - Lawless Legends Original Double Score - 22 Fort Miller 8-Bit Samples.ogg
|
||||||
3 8 Bit Weapon - Lawless Legends Original Double Score - 23 Tragedy in the West 8-Bit Samples.mp3
|
3 8 Bit Weapon - Lawless Legends Original Double Score - 23 Tragedy in the West 8-Bit Samples.ogg
|
||||||
4 8 Bit Weapon - Lawless Legends Original Double Score - 24 Victory! 8-Bit Samples.mp3
|
4 8 Bit Weapon - Lawless Legends Original Double Score - 24 Victory! 8-Bit Samples.ogg
|
||||||
5 8 Bit Weapon - Lawless Legends Original Double Score - 25 Grub Gulch 8-Bit Samples.mp3
|
5 8 Bit Weapon - Lawless Legends Original Double Score - 25 Grub Gulch 8-Bit Samples.ogg
|
||||||
6 8 Bit Weapon - Lawless Legends Original Double Score - 27 Mines of Mystery 8-Bit Samples.mp3
|
6 8 Bit Weapon - Lawless Legends Original Double Score - 27 Mines of Mystery 8-Bit Samples.ogg
|
||||||
7 8 Bit Weapon - Lawless Legends Original Double Score - 26 Texas Flats 8-Bit Samples.mp3
|
7 8 Bit Weapon - Lawless Legends Original Double Score - 26 Texas Flats 8-Bit Samples.ogg
|
||||||
8 8 Bit Weapon - Lawless Legends Original Double Score - 28 Strange Tales 8-Bit Samples.mp3
|
8 8 Bit Weapon - Lawless Legends Original Double Score - 28 Strange Tales 8-Bit Samples.ogg
|
||||||
9 8 Bit Weapon - Lawless Legends Original Double Score - 29 Oro's Villa 8-Bit Samples.mp3
|
9 8 Bit Weapon - Lawless Legends Original Double Score - 29 Oro's Villa 8-Bit Samples.ogg
|
||||||
10 8 Bit Weapon - Lawless Legends Original Double Score - 30 Tahnku Village 8-Bit Samples.mp3
|
10 8 Bit Weapon - Lawless Legends Original Double Score - 30 Tahnku Village 8-Bit Samples.ogg
|
||||||
11 8 Bit Weapon - Lawless Legends Original Double Score - 31 Tahnku Sanctuary 8-Bit Samples.mp3
|
11 8 Bit Weapon - Lawless Legends Original Double Score - 31 Tahnku Sanctuary 8-Bit Samples.ogg
|
||||||
12 8 Bit Weapon - Lawless Legends Original Double Score - 32 Mariposa City 8-Bit Samples.mp3
|
12 8 Bit Weapon - Lawless Legends Original Double Score - 32 Mariposa City 8-Bit Samples.ogg
|
||||||
13 8 Bit Weapon - Lawless Legends Original Double Score - 33 Freemont Estate 8-Bit Samples.mp3
|
13 8 Bit Weapon - Lawless Legends Original Double Score - 33 Freemont Estate 8-Bit Samples.ogg
|
||||||
14 8 Bit Weapon - Lawless Legends Original Double Score - 34 Fort Littlecreek 8-Bit Samples.mp3
|
14 8 Bit Weapon - Lawless Legends Original Double Score - 34 Fort Littlecreek 8-Bit Samples.ogg
|
||||||
15 8 Bit Weapon - Lawless Legends Original Double Score - 35 Sacred Grove 8-Bit Samples.mp3
|
15 8 Bit Weapon - Lawless Legends Original Double Score - 35 Sacred Grove 8-Bit Samples.ogg
|
||||||
16 8 Bit Weapon - Lawless Legends Original Double Score - 36 Poverty Flats 8-Bit Samples.mp3
|
16 8 Bit Weapon - Lawless Legends Original Double Score - 36 Poverty Flats 8-Bit Samples.ogg
|
||||||
17 8 Bit Weapon - Lawless Legends Original Double Score - 37 Combat! 8-Bit Samples.mp3
|
17 8 Bit Weapon - Lawless Legends Original Double Score - 37 Combat! 8-Bit Samples.ogg
|
||||||
18 8 Bit Weapon - Lawless Legends Original Double Score - 38 Killed in Cold Blood 8-Bit Samples.mp3
|
18 8 Bit Weapon - Lawless Legends Original Double Score - 38 Killed in Cold Blood 8-Bit Samples.ogg
|
||||||
19 *8 Bit Weapon - Lawless Legends Original Double Score - 39 The Sierra Nevada Wilderness 8-Bit Samples.mp3
|
19 *8 Bit Weapon - Lawless Legends Original Double Score - 39 The Sierra Nevada Wilderness 8-Bit Samples.ogg
|
||||||
20 *8 Bit Weapon - Lawless Legends Original Double Score - 39 The Sierra Nevada Wilderness 8-Bit Samples.mp3
|
20 *8 Bit Weapon - Lawless Legends Original Double Score - 39 The Sierra Nevada Wilderness 8-Bit Samples.ogg
|
||||||
|
@ -2,10 +2,28 @@ package jace;
|
|||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import jace.core.SoundMixer;
|
import jace.core.SoundMixer;
|
||||||
import jace.core.SoundMixer.SoundBuffer;
|
import jace.core.SoundMixer.SoundBuffer;
|
||||||
|
import jace.lawless.LawlessHacks;
|
||||||
|
import jace.lawless.Media;
|
||||||
|
|
||||||
public class SoundTest {
|
public class SoundTest {
|
||||||
|
@Test
|
||||||
|
public void musicDecodeTest() {
|
||||||
|
// For every song in the music folder, decode it and print out the duration
|
||||||
|
// This is to make sure that the decoding is working properly
|
||||||
|
LawlessHacks lawless = Emulator.withComputer(LawlessHacks::new, null);
|
||||||
|
for (String score : lawless.scores.keySet()) {
|
||||||
|
lawless.changeMusicScore(score);
|
||||||
|
for (int track : lawless.scores.get(score).keySet()) {
|
||||||
|
System.out.println("Loading score %s, track %d".formatted(score, track));
|
||||||
|
Media m = lawless.getAudioTrack(track);
|
||||||
|
System.out.println("Duration: " + m.getTotalDuration());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @Test
|
// @Test
|
||||||
public void soundGenerationTest() {
|
public void soundGenerationTest() {
|
||||||
|
Loading…
Reference in New Issue
Block a user