Skip to content

Commit 43f7760

Browse files
committed
Greatly reduce audio latency, remove popping sound when loading saves
1 parent bdfb967 commit 43f7760

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

src/org/the429ers/gameboy/GameBoy.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.text.SimpleDateFormat;
88
import java.util.*;
99

10+
import javax.sound.sampled.SourceDataLine;
1011
import javax.swing.*;
1112

1213
class MainMenuBar extends MenuBar {
@@ -223,6 +224,8 @@ public class GameBoy extends JFrame{
223224
InputStream loadFile = null;
224225
LinkedList<ByteArrayOutputStream> autoSaves = new LinkedList<>();
225226

227+
SourceDataLine sourceDL;
228+
226229
private static GameBoy gb;
227230

228231
public static GameBoy getInstance() {
@@ -255,6 +258,7 @@ public void windowOpened(WindowEvent e) { }
255258
};
256259

257260
public void switchRom(String newRom) {
261+
this.sourceDL = mmu.soundChip.getSourceDL();
258262
this.romFileName = newRom;
259263
if(mmu != null) mmu.cleanUp();
260264
mmu = new MMU(newRom);
@@ -271,11 +275,10 @@ public void switchRom(String newRom) {
271275
ppu = new PPU(mmu, gbs);
272276
}
273277
mmu.setPPU(ppu);
278+
mmu.soundChip.setSourceDL(this.sourceDL);
274279
cable = new LinkCable(mmu, cpu.interruptHandler);
275280
joypad = new Joypad(mmu, cpu.interruptHandler);
276281
gbs.addKeyListener(joypad);
277-
278-
279282
}
280283

281284
public GameBoy(String fileName) {
@@ -317,6 +320,7 @@ public GameBoy(String fileName) {
317320
}
318321

319322
public void saveState() {
323+
this.sourceDL = this.mmu.soundChip.getSourceDL();
320324
try {
321325
ObjectOutputStream saveState = new ObjectOutputStream(this.saveFile);
322326
saveState.writeObject(mmu);
@@ -351,6 +355,7 @@ public void loadState() {
351355
}
352356
gbs.addKeyListener(this.mmu.getJoypad());
353357
ppu.setGBS(gbs);
358+
this.mmu.soundChip.setSourceDL(this.sourceDL);
354359
}
355360

356361
public void tick() {

src/org/the429ers/gameboy/SoundChannel.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ class SoundChip implements Serializable {
2828
public static final int WAVE = 2;
2929
public static final int NOISE = 3;
3030

31-
private transient SourceDataLine sourceDL;
31+
transient SourceDataLine sourceDL;
3232

33-
byte[] masterBuffer = new byte[2 * SAMPLES_PER_FRAME];
34-
byte[] tempBuffer = new byte[SAMPLES_PER_FRAME];
33+
byte[] masterBuffer = new byte[6 * SAMPLES_PER_FRAME];
34+
byte[] tempBuffer = new byte[3 * SAMPLES_PER_FRAME];
35+
36+
long totalSamplesWritten = 0;
3537

3638
boolean[] leftEnabled = new boolean[4];
3739
boolean[] rightEnabled = new boolean[4];
@@ -40,16 +42,13 @@ class SoundChip implements Serializable {
4042
Arrays.fill(rightEnabled, true);
4143
}
4244

43-
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
44-
in.defaultReadObject();
45-
46-
try {
47-
sourceDL = AudioSystem.getSourceDataLine(AUDIO_FORMAT);
48-
sourceDL.open(AUDIO_FORMAT);
49-
sourceDL.start();
50-
} catch (LineUnavailableException e) {
51-
e.printStackTrace();
52-
}
45+
public void setSourceDL(SourceDataLine sourceDL){
46+
this.sourceDL = sourceDL;
47+
this.totalSamplesWritten = sourceDL.getLongFramePosition();
48+
}
49+
50+
public SourceDataLine getSourceDL(){
51+
return this.sourceDL;
5352
}
5453

5554
SoundChip() {
@@ -82,7 +81,10 @@ public void tick() {
8281
e.printStackTrace();
8382
}
8483
}
85-
int samplesToWrite = Math.min(sourceDL.available() / 3, SAMPLES_PER_FRAME);
84+
long residualSamples = totalSamplesWritten - sourceDL.getLongFramePosition();
85+
int samplesToWrite = Math.max(0, (int)(3 * SAMPLES_PER_FRAME - residualSamples)); //try to keep 3 frames buffered at all times
86+
samplesToWrite = Math.min(sourceDL.available() / 2, Math.min(3 * SAMPLES_PER_FRAME, samplesToWrite)); //never want to block here
87+
totalSamplesWritten += samplesToWrite;
8688

8789
Arrays.fill(masterBuffer, (byte) 0);
8890

0 commit comments

Comments
 (0)