117 lines
2.2 KiB
C++
117 lines
2.2 KiB
C++
/*
|
|
License: BSD-3-Clause
|
|
see https://gitlab.com/cam900/vgsound_emu/-/blob/V1/LICENSE for more details
|
|
|
|
Copyright holder(s): cam900
|
|
Modifiers and Contributors for Furnace: tildearrow
|
|
Dialogic ADPCM core
|
|
*/
|
|
|
|
#include "util.hpp"
|
|
#include <algorithm>
|
|
#include <memory>
|
|
|
|
#ifndef _VGSOUND_EMU_CORE_VOX_HPP
|
|
#define _VGSOUND_EMU_CORE_VOX_HPP
|
|
|
|
#pragma once
|
|
|
|
#define MODIFIED_CLAMP(x,xMin,xMax) (std::min(std::max((x),(xMin)),(xMax)))
|
|
|
|
class vox_core
|
|
{
|
|
protected:
|
|
struct vox_decoder_t
|
|
{
|
|
vox_decoder_t(vox_core &vox)
|
|
: m_curr(vox)
|
|
, m_loop(vox)
|
|
{ };
|
|
|
|
virtual void reset()
|
|
{
|
|
m_curr.reset();
|
|
m_loop.reset();
|
|
m_loop_saved = false;
|
|
}
|
|
|
|
void save()
|
|
{
|
|
if (!m_loop_saved)
|
|
{
|
|
m_loop.copy(m_curr);
|
|
m_loop_saved = true;
|
|
}
|
|
}
|
|
|
|
void restore()
|
|
{
|
|
if (m_loop_saved)
|
|
m_curr.copy(m_loop);
|
|
}
|
|
|
|
s32 out() { return m_curr.m_step; }
|
|
|
|
struct decoder_state_t
|
|
{
|
|
decoder_state_t(vox_core &vox)
|
|
: m_vox(vox)
|
|
{ };
|
|
|
|
void reset()
|
|
{
|
|
m_index = 0;
|
|
m_step = 16;
|
|
}
|
|
|
|
void copy(decoder_state_t src)
|
|
{
|
|
m_index = src.m_index;
|
|
m_step = src.m_step;
|
|
}
|
|
|
|
void decode(u8 nibble)
|
|
{
|
|
const u8 delta = bitfield(nibble, 0, 3);
|
|
s16 ss = m_vox.m_step_table[m_index]; // ss(n)
|
|
|
|
// d(n) = (ss(n) * B2) + ((ss(n) / 2) * B1) + ((ss(n) / 4) * B0) + (ss(n) / 8)
|
|
s16 d = ss >> 3;
|
|
if (bitfield(delta, 2))
|
|
d += ss;
|
|
if (bitfield(delta, 1))
|
|
d += (ss >> 1);
|
|
if (bitfield(delta, 0))
|
|
d += (ss >> 2);
|
|
|
|
// if (B3 = 1) then d(n) = d(n) * (-1) X(n) = X(n-1) * d(n)
|
|
if (bitfield(nibble, 3))
|
|
m_step = std::max(m_step - d, -2048);
|
|
else
|
|
m_step = std::min(m_step + d, 2047);
|
|
|
|
// adjust step index
|
|
m_index = MODIFIED_CLAMP(m_index + m_vox.m_index_table[delta], 0, 48);
|
|
}
|
|
|
|
vox_core &m_vox;
|
|
s8 m_index = 0;
|
|
s32 m_step = 16;
|
|
};
|
|
|
|
decoder_state_t m_curr;
|
|
decoder_state_t m_loop;
|
|
bool m_loop_saved = false;
|
|
};
|
|
|
|
s8 m_index_table[8] = {-1, -1, -1, -1, 2, 4, 6, 8};
|
|
s32 m_step_table[49] = {
|
|
16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
|
|
50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
|
|
157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
|
|
494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
|
|
};
|
|
};
|
|
|
|
#endif
|