2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void PCM1BIT::initialize()
19 last_vol_l = last_vol_r = 0;
21 register_frame_event(this);
26 prev_clock = get_current_clock();
27 positive_clocks = negative_clocks = 0;
30 void PCM1BIT::write_signal(int id, uint32_t data, uint32_t mask)
32 if(id == SIG_PCM1BIT_SIGNAL) {
33 bool next = ((data & mask) != 0);
37 positive_clocks += get_passed_clock(prev_clock);
39 negative_clocks += get_passed_clock(prev_clock);
41 prev_clock = get_current_clock();
42 // mute if signal is not changed in 2 frames
46 } else if(id == SIG_PCM1BIT_ON) {
48 on = ((data & mask) != 0);
49 set_realtime_render(this, on & !mute);
50 } else if(id == SIG_PCM1BIT_MUTE) {
52 mute = ((data & mask) != 0);
53 set_realtime_render(this, on & !mute);
57 void PCM1BIT::event_frame()
64 void PCM1BIT::mix(int32_t* buffer, int cnt)
66 if(on && !mute && changed) {
68 positive_clocks += get_passed_clock(prev_clock);
70 negative_clocks += get_passed_clock(prev_clock);
72 int clocks = positive_clocks + negative_clocks;
73 int sample = clocks ? (max_vol * positive_clocks - max_vol * negative_clocks) / clocks : signal ? max_vol : -max_vol;
75 last_vol_l = apply_volume(sample, volume_l);
76 last_vol_r = apply_volume(sample, volume_r);
78 for(int i = 0; i < cnt; i++) {
79 *buffer++ += last_vol_l; // L
80 *buffer++ += last_vol_r; // R
83 // suppress petite noise when go to mute
84 for(int i = 0; i < cnt; i++) {
85 *buffer++ += last_vol_l; // L
86 *buffer++ += last_vol_r; // R
90 } else if(last_vol_l < 0) {
95 } else if(last_vol_r < 0) {
100 prev_clock = get_current_clock();
101 positive_clocks = negative_clocks = 0;
104 void PCM1BIT::set_volume(int ch, int decibel_l, int decibel_r)
106 volume_l = decibel_to_volume(decibel_l);
107 volume_r = decibel_to_volume(decibel_r);
110 void PCM1BIT::initialize_sound(int rate, int volume)
115 #define STATE_VERSION 3
117 void PCM1BIT::save_state(FILEIO* state_fio)
119 state_fio->FputUint32(STATE_VERSION);
120 state_fio->FputInt32(this_device_id);
122 state_fio->FputBool(signal);
123 state_fio->FputBool(on);
124 state_fio->FputBool(mute);
125 state_fio->FputBool(realtime);
126 state_fio->FputInt32(changed);
127 state_fio->FputUint32(prev_clock);
128 state_fio->FputInt32(positive_clocks);
129 state_fio->FputInt32(negative_clocks);
132 bool PCM1BIT::load_state(FILEIO* state_fio)
134 if(state_fio->FgetUint32() != STATE_VERSION) {
137 if(state_fio->FgetInt32() != this_device_id) {
140 signal = state_fio->FgetBool();
141 on = state_fio->FgetBool();
142 mute = state_fio->FgetBool();
143 realtime = state_fio->FgetBool();
144 changed = state_fio->FgetInt32();
145 prev_clock = state_fio->FgetUint32();
146 positive_clocks = state_fio->FgetInt32();
147 negative_clocks = state_fio->FgetInt32();
150 last_vol_l = last_vol_r = 0;
152 set_realtime_render(on & !mute);