diff --git a/src/emucore/tia/Audio.cxx b/src/emucore/tia/Audio.cxx index 7d35c9a89..49b3145f6 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(); @@ -62,10 +65,15 @@ void Audio::setAudioQueue(const shared_ptr& queue) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Audio::phase1() +void Audio::createSample() { - 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..a18019b80 100644 --- a/src/emucore/tia/Audio.hxx +++ b/src/emucore/tia/Audio.hxx @@ -57,7 +57,7 @@ class Audio : public Serializable bool load(Serializer& in) override; private: - void phase1(); + void createSample(); void addSample(uInt8 sample0, uInt8 sample1); private: @@ -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.actualVolume(); + sumChannel1 += (uInt32)myChannel1.actualVolume(); + sumCt++; + switch (myCounter) { case 9: case 81: @@ -101,7 +111,9 @@ void Audio::tick() case 37: case 149: - phase1(); + myChannel0.phase1(); + myChannel1.phase1(); + createSample(); break; default: diff --git a/src/emucore/tia/AudioChannel.cxx b/src/emucore/tia/AudioChannel.cxx index 72db5a076..ad82fd801 100644 --- a/src/emucore/tia/AudioChannel.cxx +++ b/src/emucore/tia/AudioChannel.cxx @@ -77,7 +77,7 @@ void AudioChannel::phase0() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 AudioChannel::phase1() +void AudioChannel::phase1() { if (myClockEnable) { bool pulseFeedback = false; @@ -118,7 +118,12 @@ uInt8 AudioChannel::phase1() } } } +} +// the actual volume of a chaneel is the volume register multiplied by the +// lowest of the pulse counter +uInt8 AudioChannel::actualVolume() +{ return (myPulseCounter & 0x01) * myAudv; } diff --git a/src/emucore/tia/AudioChannel.hxx b/src/emucore/tia/AudioChannel.hxx index 6302dcba3..ed62afafb 100644 --- a/src/emucore/tia/AudioChannel.hxx +++ b/src/emucore/tia/AudioChannel.hxx @@ -30,7 +30,9 @@ class AudioChannel : public Serializable void phase0(); - uInt8 phase1(); + void phase1(); + + uInt8 actualVolume(); void audc(uInt8 value);