2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
11 #include "../fileio.h"
13 void PCM1BIT::initialize()
21 register_frame_event(this);
26 prev_clock = current_clock();
27 positive_clocks = negative_clocks = 0;
30 void PCM1BIT::write_signal(int id, uint32 data, uint32 mask)
32 if(id == SIG_PCM1BIT_SIGNAL) {
33 bool next = ((data & mask) != 0);
36 positive_clocks += passed_clock(prev_clock);
38 negative_clocks += passed_clock(prev_clock);
40 prev_clock = current_clock();
41 // mute if signal is not changed in 2 frames
45 } else if(id == SIG_PCM1BIT_ON) {
46 on = ((data & mask) != 0);
47 } else if(id == SIG_PCM1BIT_MUTE) {
48 mute = ((data & mask) != 0);
52 void PCM1BIT::event_frame()
59 void PCM1BIT::mix(int32* buffer, int cnt)
61 if(on && !mute && changed) {
63 positive_clocks += passed_clock(prev_clock);
65 negative_clocks += passed_clock(prev_clock);
67 int clocks = positive_clocks + negative_clocks;
68 last_vol = clocks ? (max_vol * positive_clocks - max_vol * negative_clocks) / clocks : signal ? max_vol : -max_vol;
70 for(int i = 0; i < cnt; i++) {
71 *buffer++ += last_vol; // L
72 *buffer++ += last_vol; // R
74 } else if(last_vol > 0) {
75 // suppress petite noise when go to mute
76 for(int i = 0; i < cnt && last_vol != 0; i++, last_vol--) {
77 *buffer++ += last_vol; // L
78 *buffer++ += last_vol; // R
80 } else if(last_vol < 0) {
81 // suppress petite noise when go to mute
82 for(int i = 0; i < cnt && last_vol != 0; i++, last_vol++) {
83 *buffer++ += last_vol; // L
84 *buffer++ += last_vol; // R
87 prev_clock = current_clock();
88 positive_clocks = negative_clocks = 0;
91 void PCM1BIT::init(int rate, int volume)
96 #define STATE_VERSION 2
98 void PCM1BIT::save_state(FILEIO* state_fio)
100 state_fio->FputUint32(STATE_VERSION);
101 state_fio->FputInt32(this_device_id);
103 state_fio->FputBool(signal);
104 state_fio->FputBool(on);
105 state_fio->FputBool(mute);
106 state_fio->FputInt32(changed);
107 state_fio->FputUint32(prev_clock);
108 state_fio->FputInt32(positive_clocks);
109 state_fio->FputInt32(negative_clocks);
112 bool PCM1BIT::load_state(FILEIO* state_fio)
114 if(state_fio->FgetUint32() != STATE_VERSION) {
117 if(state_fio->FgetInt32() != this_device_id) {
120 signal = state_fio->FgetBool();
121 on = state_fio->FgetBool();
122 mute = state_fio->FgetBool();
123 changed = state_fio->FgetInt32();
124 prev_clock = state_fio->FgetUint32();
125 positive_clocks = state_fio->FgetInt32();
126 negative_clocks = state_fio->FgetInt32();