From eff87589ecf7c92475f9fe245f37c17b9b1d5c72 Mon Sep 17 00:00:00 2001 From: JetSetIlly Date: Tue, 6 Aug 2024 21:33:24 +0100 Subject: [PATCH] TIA audio sampled every colour clock sum of samples is averaged and output twice per scanline this fixes issues with ROMs that change the volume of the audio multiple times per scanline. for example, the experimental ROM in the following thread now works correctly https://forums.atariage.com/topic/370460-8-bit-digital-audio-from-2600/ note that the ROM does not initialise the machine cleanly and so running the emulator with developer options (random memory etc.) can cause incorrect audio --- src/emucore/tia/Audio.cxx | 12 ++++++++++-- src/emucore/tia/Audio.hxx | 10 ++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/emucore/tia/Audio.cxx b/src/emucore/tia/Audio.cxx index 7d35c9a89..427073496 100644 --- a/src/emucore/tia/Audio.cxx +++ b/src/emucore/tia/Audio.cxx @@ -47,6 +47,9 @@ void Audio::reset() { myCounter = 0; mySampleIndex = 0; + sumChannel0 = 0; + sumChannel1 = 0; + sumCt = 0; myChannel0.reset(); myChannel1.reset(); @@ -64,8 +67,13 @@ void Audio::setAudioQueue(const shared_ptr& queue) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Audio::phase1() { - const uInt8 sample0 = myChannel0.phase1(); - const uInt8 sample1 = myChannel1.phase1(); + // calculate average of all recent volume samples. the average for each + // channel is mixed to create a single audible value + const uInt8 sample0 = (uInt8)(sumChannel0/sumCt); + const uInt8 sample1 = (uInt8)(sumChannel1/sumCt); + sumChannel0 = 0; + sumChannel1 = 0; + sumCt = 0; addSample(sample0, sample1); #ifdef GUI_SUPPORT diff --git a/src/emucore/tia/Audio.hxx b/src/emucore/tia/Audio.hxx index 9a054c5b0..c656ed5a3 100644 --- a/src/emucore/tia/Audio.hxx +++ b/src/emucore/tia/Audio.hxx @@ -68,6 +68,10 @@ class Audio : public Serializable AudioChannel myChannel0; AudioChannel myChannel1; + uInt32 sumChannel0; + uInt32 sumChannel1; + uInt32 sumCt; + std::array myMixingTableSum; std::array myMixingTableIndividual; @@ -92,6 +96,12 @@ class Audio : public Serializable // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Audio::tick() { + // volume for each channel is sampled every color clock. the average of + // these samples will be taken twice a scanline in the phase1() function + sumChannel0 += (uInt32)myChannel0.phase1(); + sumChannel1 += (uInt32)myChannel1.phase1(); + sumCt++; + switch (myCounter) { case 9: case 81: