Skip to content

Commit da93067

Browse files
committed
Work on audio config panel
1 parent 62acf8a commit da93067

File tree

11 files changed

+89
-34
lines changed

11 files changed

+89
-34
lines changed

Emulator/VAmiga/Components/Amiga.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ Amiga::checkOption(Opt opt, i64 value)
225225

226226
case Opt::AMIGA_RUN_AHEAD:
227227

228-
if (value < 0 || value > 12) {
229-
throw CoreException(CoreError::OPT_INV_ARG, "0...12");
228+
if (value < -7 || value > 7) {
229+
throw CoreException(CoreError::OPT_INV_ARG, "-7...7");
230230
}
231231
return;
232232

Emulator/VAmiga/Components/Denise/PixelEngine.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,9 @@ PixelEngine::adjustRGB(u8 &r, u8 &g, u8 &b)
280280
}
281281

282282
const FrameBuffer &
283-
PixelEngine::getStableBuffer(isize delayedFrames) const
283+
PixelEngine::getStableBuffer(isize offset) const
284284
{
285-
auto nr = activeBuffer - delayedFrames - 1;
285+
auto nr = activeBuffer + offset - 1;
286286
return emuTexture[(nr + NUM_TEXTURES) % NUM_TEXTURES];
287287
}
288288

Emulator/VAmiga/Components/Denise/PixelEngine.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class PixelEngine final : public SubComponent {
4747

4848
private:
4949

50-
static constexpr isize NUM_TEXTURES = 2;
50+
static constexpr isize NUM_TEXTURES = 8;
5151

5252
/* The emulator manages textures in a ring buffer to allow access to older
5353
* frames ("run-behind" feature). At any time, one texture serves as the
@@ -215,7 +215,7 @@ class PixelEngine final : public SubComponent {
215215

216216
// Returns the working buffer or the stable buffer
217217
FrameBuffer &getWorkingBuffer();
218-
const FrameBuffer &getStableBuffer(isize delayedFrames = 0) const;
218+
const FrameBuffer &getStableBuffer(isize offset = 0) const;
219219

220220
// Return a pointer into the pixel storage
221221
Texel *workingPtr(isize row = 0, isize col = 0);

Emulator/VAmiga/Emulator.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,21 @@ Emulator::missingFrames() const
265265
const FrameBuffer &
266266
Emulator::getTexture() const
267267
{
268-
// If paused, display the most recent texture from the main instance
269-
if (!isRunning()) ahead.videoPort.getTexture();
268+
if (isRunning()) {
270269

271-
if (main.config.runAhead > 0) {
272-
return ahead.videoPort.getTexture();
273-
} else {
274-
return main.videoPort.getTexture();
270+
// In run-ahead mode, return the texture from the run-ahead instance
271+
if (main.config.runAhead > 0) {
272+
return ahead.videoPort.getTexture();
273+
}
274+
275+
// In run-behind mode, return a texture from the texture buffer
276+
if (main.config.runAhead < 0) {
277+
return main.videoPort.getTexture(main.config.runAhead);
278+
}
275279
}
280+
281+
// Return the most recent texture from the main instance
282+
return main.videoPort.getTexture();
276283
}
277284

278285
void

Emulator/VAmiga/Ports/VideoPort.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ VideoPort::cacheStats(VideoPortStats &result) const
111111
}
112112

113113
const FrameBuffer &
114-
VideoPort::getTexture() const
114+
VideoPort::getTexture(isize offset) const
115115
{
116116
if (isPoweredOn()) {
117117

118-
auto &result = denise.pixelEngine.getStableBuffer();
118+
auto &result = denise.pixelEngine.getStableBuffer(offset);
119119
info.latestGrabbedFrame = result.nr;
120120
return result;
121121
}

Emulator/VAmiga/Ports/VideoPort.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class VideoPort final : public SubComponent, public Inspectable<VideoPortInfo, V
117117
public:
118118

119119
// Returns a pointer to the stable emulator texture
120-
const class FrameBuffer &getTexture() const;
120+
const class FrameBuffer &getTexture(isize offset = 0) const;
121121

122122
// Informs the video port about a buffer swap
123123
void buffersWillSwap();

GUI/Defaults.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,12 +1263,14 @@ extension DefaultsProxy {
12631263
remove(.AUD_VOL3)
12641264
remove(.AUD_VOLL)
12651265
remove(.AUD_VOLR)
1266-
remove(.AUD_SAMPLING_METHOD)
12671266
remove(.DRIVE_STEP_VOLUME, [0, 1, 2, 3])
12681267
remove(.DRIVE_POLL_VOLUME, [0, 1, 2, 3])
12691268
remove(.DRIVE_INSERT_VOLUME, [0, 1, 2, 3])
12701269
remove(.DRIVE_EJECT_VOLUME, [0, 1, 2, 3])
12711270
remove(.AUD_FILTER_TYPE)
1271+
remove(.AUD_SAMPLING_METHOD)
1272+
remove(.AUD_BUFFER_SIZE)
1273+
remove(.AUD_ASR)
12721274
}
12731275
}
12741276

@@ -1292,7 +1294,6 @@ extension Configuration {
12921294
defaults.set(.AUD_PAN3, pan3)
12931295
defaults.set(.AUD_VOLL, volL)
12941296
defaults.set(.AUD_VOLR, volR)
1295-
defaults.set(.AUD_SAMPLING_METHOD, samplingMethod)
12961297
defaults.set(.DRIVE_PAN, 0, df0Pan)
12971298
defaults.set(.DRIVE_PAN, 1, df1Pan)
12981299
defaults.set(.DRIVE_PAN, 2, df2Pan)
@@ -1306,6 +1307,10 @@ extension Configuration {
13061307
defaults.set(.DRIVE_INSERT_VOLUME, [0, 1, 2, 3], insertVolume)
13071308
defaults.set(.DRIVE_EJECT_VOLUME, [0, 1, 2, 3], ejectVolume)
13081309
defaults.set(.AUD_FILTER_TYPE, filterType)
1310+
defaults.set(.AUD_SAMPLING_METHOD, samplingMethod)
1311+
defaults.set(.AUD_BUFFER_SIZE, audioBufferSize)
1312+
defaults.set(.AUD_ASR, asr)
1313+
13091314
defaults.save()
13101315

13111316
amiga.resume()
@@ -1340,12 +1345,15 @@ extension Configuration {
13401345

13411346
volL = defaults.get(.AUD_VOLL)
13421347
volR = defaults.get(.AUD_VOLR)
1343-
samplingMethod = defaults.get(.AUD_SAMPLING_METHOD)
13441348
stepVolume = defaults.get(.DRIVE_STEP_VOLUME, 0)
13451349
pollVolume = defaults.get(.DRIVE_POLL_VOLUME, 0)
13461350
insertVolume = defaults.get(.DRIVE_INSERT_VOLUME, 0)
13471351
ejectVolume = defaults.get(.DRIVE_EJECT_VOLUME, 0)
13481352
filterType = defaults.get(.AUD_FILTER_TYPE)
1353+
1354+
samplingMethod = defaults.get(.AUD_SAMPLING_METHOD)
1355+
audioBufferSize = defaults.get(.AUD_BUFFER_SIZE, audioBufferSize)
1356+
asr = defaults.get(.AUD_ASR, asr)
13491357

13501358
amiga.resume()
13511359
}

GUI/Dialogs/Configuration/AudioConf.swift

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
extension ConfigurationController {
1212

1313
func refreshAudioTab() {
14-
14+
1515
//
1616
// Mixer
1717
//
@@ -25,11 +25,11 @@ extension ConfigurationController {
2525
audPan1.integerValue = config.pan1
2626
audPan2.integerValue = config.pan2
2727
audPan3.integerValue = config.pan3
28-
28+
2929
// Out
3030
audVolL.integerValue = config.volL
3131
audVolR.integerValue = config.volR
32-
32+
3333
// Drives
3434
audStepVolume.integerValue = config.stepVolume
3535
audPollVolume.integerValue = config.pollVolume
@@ -43,10 +43,10 @@ extension ConfigurationController {
4343
audHd1Pan.integerValue = config.hd1Pan
4444
audHd2Pan.integerValue = config.hd2Pan
4545
audHd3Pan.integerValue = config.hd3Pan
46-
46+
4747
// Audio filter
4848
audFilterType.selectItem(withTag: config.filterType)
49-
49+
5050
//
5151
// Sampler
5252
//
@@ -56,7 +56,24 @@ extension ConfigurationController {
5656
audCapacity.integerValue = config.audioBufferSize
5757
audCapacityText.stringValue = "\(config.audioBufferSize) samples"
5858

59-
59+
switch SamplingMethod(rawValue: Int32(config.samplingMethod)) {
60+
case .NONE:
61+
audSamplingMethodText.stringValue = "Instructs the sampler to select the most recent sample from the ring buffer. This minimizes latency but may introduce jitter when the sample rate fluctuates."
62+
case .NEAREST:
63+
audSamplingMethodText.stringValue = "Instructs the sampler to pick the sample closest to the target timestamp. It improves timing accuracy over the latest-sample method but may still have minor mismatches."
64+
case .LINEAR:
65+
audSamplingMethodText.stringValue = "Instructs the sampler to compute a value between two neighboring samples for smoother output. Increases computation slightly but reduces artifacts and improves fidelity."
66+
default:
67+
break
68+
}
69+
70+
switch (config.asr) {
71+
case 0:
72+
audASRText.stringValue = "Audio samples are synthesized at a constant sampling rate, ignoring drift between emulated and real-time playback rates. This may cause buffer underflows and overflows over time, leading to audio stutter or glitches."
73+
default:
74+
audASRText.stringValue = "ASR (Adaptive Sample Rate) dynamically adjusts the sampling rate to maintain audio sync. This prevents buffer underflows and overflows by adapting to slight drift between emulated and real-time playback rates."
75+
}
76+
6077
//
6178
// Commons
6279
//

GUI/Dialogs/Configuration/ConfigurationController.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,9 @@ class ConfigurationController: DialogController {
275275

276276
// Mixer
277277
@IBOutlet weak var audSamplingMethod: NSPopUpButton!
278+
@IBOutlet weak var audSamplingMethodText: NSTextField!
278279
@IBOutlet weak var audASR: NSPopUpButton!
280+
@IBOutlet weak var audASRText: NSTextField!
279281
@IBOutlet weak var audCapacity: NSSlider!
280282
@IBOutlet weak var audCapacityText: NSTextField!
281283

0 commit comments

Comments
 (0)