summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MetalliC <0vetal0@gmail.com>2017-10-26 22:23:17 +0300
committer MetalliC <0vetal0@gmail.com>2017-10-26 22:23:17 +0300
commit95ad1a3d813596eb2e4b0fd115c546342df676f8 (patch)
tree8b78e7739af845eb92800423bd481774da489b9f
parent30a55d89744af14eddbdfc707805f8a10dfe5181 (diff)
ymz770.cpp: add pan, main volume level and clip limit control
-rw-r--r--src/devices/sound/ymz770.cpp40
1 files changed, 35 insertions, 5 deletions
diff --git a/src/devices/sound/ymz770.cpp b/src/devices/sound/ymz770.cpp
index 11b30d08eb1..506de02da15 100644
--- a/src/devices/sound/ymz770.cpp
+++ b/src/devices/sound/ymz770.cpp
@@ -11,8 +11,8 @@
TODO:
- A lot of unimplemented features, even simple ones like panning,
these should be added once we find out any software that uses it.
-- Is channel volume linear(current implementation) or logarithmic?
- Sequencer is very preliminary
+- verify if pan 100% correct
- What does channel ATBL mean?
- Is YMZ774(and other variants) the same family as this chip?
What are the differences?
@@ -167,14 +167,17 @@ void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **
}
// process channels
- int32_t mix = 0;
+ int32_t mixl = 0;
+ int32_t mixr = 0;
for (auto & elem : m_channels)
{
if (elem.output_remaining > 0)
{
// force finish current block
- mix += (elem.output_data[elem.output_ptr++]*elem.volume);
+ int32_t smpl = elem.output_data[elem.output_ptr++] * elem.volume; // volume is linear, 0 - 128 (100%)
+ mixr += (smpl * elem.pan) >> 11; // pan seems linear, 0 - 16, where 0 = 100% left, 16 = 100% right, 8 = 50% left 50% right
+ mixl += (smpl * (16 - elem.pan)) >> 11;
elem.output_remaining--;
if (elem.output_remaining == 0 && !elem.is_playing)
@@ -217,12 +220,39 @@ retry:
elem.output_remaining--;
elem.output_ptr = 1;
- mix += (elem.output_data[0]*elem.volume);
+ int32_t smpl = elem.output_data[0] * elem.volume;
+ mixr += (smpl * elem.pan) >> 11;
+ mixl += (smpl * (16 - elem.pan)) >> 11;
}
}
}
- outL[i] = outR[i] = mix>>8;
+ mixr *= m_vlma; // main volume is linear, 0 - 255, where 128 = 100%
+ mixl *= m_vlma;
+ mixr >>= 7 - m_bsl;
+ mixl >>= 7 - m_bsl;
+ // Clip limiter: 0 - off, 1 - 6.02 dB (100%), 2 - 4.86 dB (87.5%), 3 - 3.52 dB (75%). values taken from YMZ773 docs, might be incorrect for YMZ770.
+ constexpr int32_t ClipMax3 = 32768 * 75 / 100;
+ constexpr int32_t ClipMax2 = 32768 * 875 / 1000;
+ switch (m_cpl)
+ {
+ case 3:
+ mixl = (mixl > ClipMax3) ? ClipMax3 : (mixl < -ClipMax3) ? -ClipMax3 : mixl;
+ mixr = (mixr > ClipMax3) ? ClipMax3 : (mixr < -ClipMax3) ? -ClipMax3 : mixr;
+ break;
+ case 2:
+ mixl = (mixl > ClipMax2) ? ClipMax2 : (mixl < -ClipMax2) ? -ClipMax2 : mixl;
+ mixr = (mixr > ClipMax2) ? ClipMax2 : (mixr < -ClipMax2) ? -ClipMax2 : mixr;
+ break;
+ case 1:
+ mixl = (mixl > 32767) ? 32767 : (mixl < -32768) ? -32768 : mixl;
+ mixr = (mixr > 32767) ? 32767 : (mixr < -32768) ? -32768 : mixr;
+ break;
+ }
+ if (m_mute)
+ mixr = mixl = 0;
+ outL[i] = mixl;
+ outR[i] = mixr;
}
}