2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void PCM1BIT::initialize()
20 register_frame_event(this);
25 prev_clock = current_clock();
26 positive_clocks = negative_clocks = 0;
29 void PCM1BIT::write_signal(int id, uint32 data, uint32 mask)
31 if(id == SIG_PCM1BIT_SIGNAL) {
32 bool next = ((data & mask) != 0);
35 positive_clocks += passed_clock(prev_clock);
37 negative_clocks += passed_clock(prev_clock);
39 prev_clock = current_clock();
40 // mute if signal is not changed in 2 frames
44 } else if(id == SIG_PCM1BIT_ON) {
45 on = ((data & mask) != 0);
46 } else if(id == SIG_PCM1BIT_MUTE) {
47 mute = ((data & mask) != 0);
51 void PCM1BIT::event_frame()
58 void PCM1BIT::mix(int32* buffer, int cnt)
60 if(on && !mute && changed) {
62 positive_clocks += passed_clock(prev_clock);
64 negative_clocks += passed_clock(prev_clock);
66 int clocks = positive_clocks + negative_clocks;
67 last_vol = clocks ? (max_vol * positive_clocks - max_vol * negative_clocks) / clocks : signal ? max_vol : -max_vol;
69 for(int i = 0; i < cnt; i++) {
70 *buffer++ += last_vol; // L
71 *buffer++ += last_vol; // R
73 } else if(last_vol > 0) {
74 // suppress petite noise when go to mute
75 for(int i = 0; i < cnt && last_vol != 0; i++, last_vol--) {
76 *buffer++ += last_vol; // L
77 *buffer++ += last_vol; // R
79 } else if(last_vol < 0) {
80 // suppress petite noise when go to mute
81 for(int i = 0; i < cnt && last_vol != 0; i++, last_vol++) {
82 *buffer++ += last_vol; // L
83 *buffer++ += last_vol; // R
86 prev_clock = current_clock();
87 positive_clocks = negative_clocks = 0;
90 void PCM1BIT::init(int rate, int volume)
95 #define STATE_VERSION 2
97 void PCM1BIT::save_state(FILEIO* state_fio)
99 state_fio->FputUint32(STATE_VERSION);
100 state_fio->FputInt32(this_device_id);
102 state_fio->FputBool(signal);
103 state_fio->FputBool(on);
104 state_fio->FputBool(mute);
105 state_fio->FputInt32(changed);
106 state_fio->FputUint32(prev_clock);
107 state_fio->FputInt32(positive_clocks);
108 state_fio->FputInt32(negative_clocks);
111 bool PCM1BIT::load_state(FILEIO* state_fio)
113 if(state_fio->FgetUint32() != STATE_VERSION) {
116 if(state_fio->FgetInt32() != this_device_id) {
119 signal = state_fio->FgetBool();
120 on = state_fio->FgetBool();
121 mute = state_fio->FgetBool();
122 changed = state_fio->FgetInt32();
123 prev_clock = state_fio->FgetUint32();
124 positive_clocks = state_fio->FgetInt32();
125 negative_clocks = state_fio->FgetInt32();