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