summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/gew.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/gew.h')
-rw-r--r--src/devices/sound/gew.h160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/devices/sound/gew.h b/src/devices/sound/gew.h
new file mode 100644
index 00000000000..233a02227c5
--- /dev/null
+++ b/src/devices/sound/gew.h
@@ -0,0 +1,160 @@
+// license:BSD-3-Clause
+// copyright-holders:Miguel Angel Horna
+#ifndef MAME_SOUND_GEW_H
+#define MAME_SOUND_GEW_H
+
+#pragma once
+
+#include "dirom.h"
+
+#define MULTIPCM_LOG_SAMPLES 0
+
+#if MULTIPCM_LOG_SAMPLES
+#include <map>
+#endif
+
+class gew_pcm_device : public device_t,
+ public device_sound_interface,
+ public device_rom_interface<22, 0, 0, ENDIANNESS_BIG>
+{
+public:
+ static constexpr feature_type imperfect_features() { return feature::SOUND; }
+
+protected:
+ gew_pcm_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock,
+ uint32_t voices, uint32_t clock_divider);
+
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+ virtual void device_clock_changed() override;
+
+ // sound stream update overrides
+ virtual void sound_stream_update(sound_stream &stream) override;
+
+ // device_rom_interface overrides
+ virtual void rom_bank_pre_change() override;
+
+ struct sample_t
+ {
+ uint32_t m_start = 0;
+ uint32_t m_loop = 0;
+ uint32_t m_end = 0;
+ uint8_t m_attack_reg = 0;
+ uint8_t m_decay1_reg = 0;
+ uint8_t m_decay2_reg = 0;
+ uint8_t m_decay_level = 0;
+ uint8_t m_release_reg = 0;
+ uint8_t m_key_rate_scale = 0;
+ uint8_t m_lfo_vibrato_reg = 0;
+ uint8_t m_lfo_amplitude_reg = 0;
+ uint8_t m_format = 0;
+ };
+
+ enum class state_t : u8
+ {
+ ATTACK,
+ DECAY1,
+ DECAY2,
+ RELEASE
+ };
+
+ struct envelope_gen_t
+ {
+ int32_t m_volume = 0;
+ state_t m_state = state_t::ATTACK;
+ uint8_t m_reverb = 0;
+ int32_t step = 0;
+ //step vals
+ int32_t m_attack_rate = 0; // Attack
+ int32_t m_decay1_rate = 0; // Decay1
+ int32_t m_decay2_rate = 0; // Decay2
+ int32_t m_release_rate = 0; // Release
+ int32_t m_decay_level = 0; // Decay level
+ };
+
+ struct lfo_t
+ {
+ uint16_t m_phase = 0;
+ uint32_t m_phase_step = 0;
+ int32_t *m_table = nullptr;
+ int32_t *m_scale = nullptr;
+ };
+
+ struct slot_t
+ {
+ uint8_t m_regs[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ bool m_playing = false;
+ sample_t m_sample;
+ uint32_t m_offset = 0;
+ uint8_t m_octave = 0;
+ uint16_t m_pitch = 0;
+ uint32_t m_step = 0;
+ bool m_reverse = false;
+ uint32_t m_pan = 0;
+ uint32_t m_total_level = 0;
+ uint32_t m_dest_total_level = 0;
+ int32_t m_total_level_step = 0;
+ int32_t m_prev_sample = 0;
+ envelope_gen_t m_envelope_gen;
+ uint8_t m_lfo_frequency;
+ lfo_t m_pitch_lfo; // Pitch lfo
+ uint8_t m_vibrato = 0;
+ lfo_t m_amplitude_lfo; // AM lfo
+ uint8_t m_tremolo = 0;
+ };
+
+ uint32_t value_to_fixed(const uint32_t bits, const float value);
+
+ void retrigger_sample(slot_t &slot);
+ void update_step(slot_t &slot);
+
+ static constexpr uint32_t TL_SHIFT = 12;
+ static constexpr uint32_t EG_SHIFT = 16;
+ static constexpr uint32_t LFO_SHIFT = 8;
+
+ // Internal LFO functions
+ void lfo_init();
+ void lfo_compute_step(lfo_t &lfo, uint32_t lfo_frequency, uint32_t LFOS, int32_t amplitude_lfo);
+ int32_t pitch_lfo_step(lfo_t &lfo);
+ int32_t amplitude_lfo_step(lfo_t &lfo);
+
+ // Internal envelope functions
+ void envelope_generator_init(const double (&rates)[64], double attack_decay_ratio);
+ int32_t envelope_generator_update(slot_t &slot);
+ void envelope_generator_calc(slot_t &slot);
+ uint32_t get_rate(uint32_t *steps, int32_t rate, uint32_t val);
+
+#if MULTIPCM_LOG_SAMPLES
+ void dump_sample(slot_t &slot);
+ std::map<uint32_t, bool> m_logged_map;
+#endif
+
+ static const double BASE_TIMES[64];
+
+ static const float LFO_FREQ[8];
+ static const float PHASE_SCALE_LIMIT[8];
+ static const float AMPLITUDE_SCALE_LIMIT[8];
+
+ // internal state
+ sound_stream* m_stream;
+ std::unique_ptr<slot_t[]> m_slots;
+ float m_rate;
+ uint32_t m_voices;
+ uint32_t m_clock_divider;
+
+ std::unique_ptr<uint32_t[]> m_attack_step;
+ std::unique_ptr<uint32_t[]> m_decay_release_step; // Envelope step tables
+ std::unique_ptr<uint32_t[]> m_freq_step_table; // Frequency step table
+
+ std::unique_ptr<int32_t[]> m_left_pan_table;
+ std::unique_ptr<int32_t[]> m_right_pan_table;
+ std::unique_ptr<int32_t[]> m_linear_to_exp_volume;
+ std::unique_ptr<int32_t[]> m_total_level_steps;
+
+ std::unique_ptr<int32_t[]> m_pitch_table;
+ std::unique_ptr<int32_t[]> m_pitch_scale_tables[8];
+ std::unique_ptr<int32_t[]> m_amplitude_table;
+ std::unique_ptr<int32_t[]> m_amplitude_scale_tables[8];
+};
+
+#endif // MAME_SOUND_GEW_H