--- nono/vm/adpcm.h 2026/04/29 17:05:29 1.1.1.4 +++ nono/vm/adpcm.h 2026/04/29 17:05:55 1.1.1.6 @@ -11,10 +11,10 @@ #pragma once #include "device.h" -#include "event.h" class DMACDevice; -class PPIDevice; +class SoundRenderer; +class SoundTrack; class ADPCMDevice : public IODevice { @@ -39,8 +39,14 @@ class ADPCMDevice : public IODevice void SetClock(bool); // DMAC から呼ばれる。 - void AssertDACK(bool tc); - void NegateDACK(); + void AssertDACK(); + + // PPI + bool GetPanOutL() const { return panout_L; } + bool GetPanOutR() const { return panout_R; } + void SetPanOutL(bool on); + void SetPanOutR(bool on); + void SetRate(uint32 idx); protected: // BusIO インタフェース @@ -51,19 +57,64 @@ class ADPCMDevice : public IODevice bool PokePort(uint32 offset, uint32 data); private: - void StartPlay(); + DECLARE_MONITOR_CALLBACK(MonitorUpdate); - void EventCallback(Event&); + uint32 GetSTAT() const; + void StartPlay(); + void StopPlay(); + void WriteData(uint32 data); + void CalcRate(); + + void EventCallback(Event *); + + void DecodeADPCM(uint32 data); + void WritePCM(uint64 vtime, int16 target); + + uint32 pcm2adpcm_step(int16 pcm); + int16 adpcm2pcm_step(uint32 data); + inline uint32 adpcm_encode(int32 dn); + inline int32 adpcm_decode(uint32 data, int32 xn); + inline void adpcm_calcstep(uint32 data); bool playing {}; - bool dack {}; - int clk {}; - int div {}; + int clkMHz {}; // 入力クロック[MHz] (4 or 8) + int div {}; // 512, 768, 1024 + + bool panout_L {}; + bool panout_R {}; + + // 選択周波数での 1フレームにかかる時間 [nsec] + uint64 guest_frame_nsec {}; + + // 周波数 + uint32 freq {}; + + // データバッファ(1バイト) + uint8 databuf {}; + + // ADPCM<->PCM 変換 + int32 xprev {}; + int stepidx {}; + + // 最後に書き込んだサンプル値 (線形補間用) + int16 pcm0 {}; + + // ミキサー周波数での1フレームにかかる時間 [nsec] + uint64 mixer_frame_nsec {}; + + // ミキサー周波数にアップスキャンするための倍率。 + // 15625 Hz なら 4(倍)。 + uint scale_factor {}; DMACDevice *dmac {}; - PPIDevice *ppi {}; + SoundRenderer *sound {}; + SoundTrack *track {}; + + Event *event {}; + Monitor *monitor {}; - Event event { this }; + static const int adpcm_stepadj[16]; + static const int32 adpcm_stepsize[49]; }; static inline ADPCMDevice *GetADPCMDevice() {