From cd59eb5f43a9d4e37160ee8bbb902b1ea4e864a3 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 19 Oct 2016 23:07:51 -0400 Subject: [PATCH] Implemented non-linear volume. --- Components/AY38910/AY38910.cpp | 19 ++++++++++++++----- Components/AY38910/AY38910.hpp | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index 1d7d31fcd..8595db8d9 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -64,6 +64,15 @@ AY38910::AY38910() : } } } + + // set up volume lookup table + float max_volume = 8192; + float root_two = sqrtf(2.0f); + for(int v = 0; v < 16; v++) + { + _volumes[v] = (int)(max_volume / powf(root_two, (float)(v ^ 0xf))); + } + _volumes[0] = 0; } void AY38910::set_clock_rate(double clock_rate) @@ -147,11 +156,11 @@ void AY38910::get_samples(unsigned int number_of_samples, int16_t *target) #undef channel_volume // Mix additively. TODO: non-linear volume. - target[c] = (int16_t)(( - volumes[0] * channel_levels[0] + - volumes[1] * channel_levels[1] + - volumes[2] * channel_levels[2] - ) * 512); + target[c] = (int16_t)( + _volumes[volumes[0]] * channel_levels[0] + + _volumes[volumes[1]] * channel_levels[1] + + _volumes[volumes[2]] * channel_levels[2] + ); } } diff --git a/Components/AY38910/AY38910.hpp b/Components/AY38910/AY38910.hpp index e15f75f54..c6b5f7f78 100644 --- a/Components/AY38910/AY38910.hpp +++ b/Components/AY38910/AY38910.hpp @@ -59,6 +59,7 @@ class AY38910: public ::Outputs::Filter { int _channel_dividers[3]; int _channel_output[3]; + int _volumes[16]; int _master_divider;