From 60c1da6a66484ddcf42f07336d51f4aef013b1b6 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Thu, 5 Apr 2018 21:04:46 -0400
Subject: [PATCH] Causes the 6560 to obey `set_sample_volume_range`.

Thereby resolves a clipping issue.
---
 Components/6560/6560.cpp | 7 ++++---
 Components/6560/6560.hpp | 3 ++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/Components/6560/6560.cpp b/Components/6560/6560.cpp
index ffe950b24..8790d50bb 100644
--- a/Components/6560/6560.cpp
+++ b/Components/6560/6560.cpp
@@ -18,7 +18,7 @@ AudioGenerator::AudioGenerator(Concurrency::DeferringAsyncTaskQueue &audio_queue
 
 void AudioGenerator::set_volume(uint8_t volume) {
 	audio_queue_.defer([=]() {
-		volume_ = volume;
+		volume_ = static_cast<int16_t>(volume) * range_multiplier_;
 	});
 }
 
@@ -114,12 +114,12 @@ void AudioGenerator::get_samples(std::size_t number_of_samples, int16_t *target)
 
 		// this sums the output of all three sounds channels plus a DC offset for volume;
 		// TODO: what's the real ratio of this stuff?
-		target[c] = (
+		target[c] = static_cast<int16_t>(
 			(shift_registers_[0]&1) +
 			(shift_registers_[1]&1) +
 			(shift_registers_[2]&1) +
 			((noise_pattern[shift_registers_[3] >> 3] >> (shift_registers_[3]&7))&(control_registers_[3] >> 7)&1)
-		) * volume_ * 700 + volume_ * 44;
+		) * volume_ + (volume_ >> 4);
 	}
 }
 
@@ -133,6 +133,7 @@ void AudioGenerator::skip_samples(std::size_t number_of_samples) {
 }
 
 void AudioGenerator::set_sample_volume_range(std::int16_t range) {
+	range_multiplier_ = static_cast<int16_t>(range / 64);
 }
 
 #undef shift
diff --git a/Components/6560/6560.hpp b/Components/6560/6560.hpp
index ba461ea38..621c885a2 100644
--- a/Components/6560/6560.hpp
+++ b/Components/6560/6560.hpp
@@ -36,7 +36,8 @@ class AudioGenerator: public ::Outputs::Speaker::SampleSource {
 		unsigned int counters_[4] = {2, 1, 0, 0}; 	// create a slight phase offset for the three channels
 		unsigned int shift_registers_[4] = {0, 0, 0, 0};
 		uint8_t control_registers_[4] = {0, 0, 0, 0};
-		uint8_t volume_ = 0;
+		int16_t volume_ = 0;
+		int16_t range_multiplier_ = 1;
 };
 
 /*!