1 // T6W28_Snd_Emu
2 
3 #ifndef SMS_APU_H
4 #define SMS_APU_H
5 
6 namespace MDFN_IEN_NGP
7 {
8 
9 typedef long sms_time_t; // clock cycle count
10 
11 }
12 
13 #include "T6W28_Oscs.h"
14 
15 namespace MDFN_IEN_NGP
16 {
17 
18 typedef struct
19 {
20 	int32 sq_period[3];
21 	int32 sq_phase[3];
22 	uint32 noise_period;
23 	uint32 noise_period_extra;
24 	uint32 noise_shifter;
25 	uint32 noise_tap;
26 
27 	int32 delay[4];
28 	int32 volume_left[4];
29 	int32 volume_right[4];
30 	uint8 latch_left, latch_right;
31 } T6W28_ApuState;
32 
33 class T6W28_Apu {
34 public:
35 	// Set overall volume of all oscillators, where 1.0 is full volume
36 	void volume( double );
37 
38 	// Set treble equalization
39 	void treble_eq( const blip_eq_t& );
40 
41 	// Outputs can be assigned to a single buffer for mono output, or to three
42 	// buffers for stereo output (using Stereo_Buffer to do the mixing).
43 
44 	// Assign all oscillator outputs to specified buffer(s). If buffer
45 	// is NULL, silences all oscillators.
46 	void output( Blip_Buffer* mono );
47 	void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
48 
49 	// Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
50 	// which refer to Square 1, Square 2, Square 3, and Noise. If buffer is NULL,
51 	// silences oscillator.
52 	enum { osc_count = 4 };
53 	void osc_output( int index, Blip_Buffer* mono );
54 	void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
55 
56 	// Reset oscillators and internal state
57 	void reset();
58 
59 	// Write to data port
60 	void write_data_left( sms_time_t, int );
61 	void write_data_right( sms_time_t, int );
62 
63 	// Run all oscillators up to specified time, end current frame, then
64 	// start a new frame at time 0. Returns true if any oscillators added
65 	// sound to one of the left/right buffers, false if they only added
66 	// to the center buffer.
67 	bool end_frame( sms_time_t );
68 
69 	void save_state(T6W28_ApuState*);
70 	void load_state(const T6W28_ApuState*);
71 public:
72 	T6W28_Apu();
73 	~T6W28_Apu();
74 private:
75 	// noncopyable
76 	T6W28_Apu( const T6W28_Apu& );
77 	T6W28_Apu& operator = ( const T6W28_Apu& );
78 
79 	T6W28_Osc*    oscs [osc_count];
80 	T6W28_Square  squares [3];
81 	T6W28_Square::Synth square_synth; // used by squares
82 	sms_time_t  last_time;
83 	int         latch_left, latch_right;
84 	T6W28_Noise   noise;
85 
86 	void run_until( sms_time_t );
87 };
88 
output(Blip_Buffer * b)89 inline void T6W28_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
90 
osc_output(int i,Blip_Buffer * b)91 inline void T6W28_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
92 
93 }
94 
95 #endif
96 
97