2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void PCM1BIT::initialize()
20 last_vol_l = last_vol_r = 0;
22 register_frame_event(this);
27 prev_clock = get_current_clock();
28 positive_clocks = negative_clocks = 0;
31 void PCM1BIT::write_signal(int id, uint32_t data, uint32_t mask)
33 if(id == SIG_PCM1BIT_SIGNAL) {
34 bool next = ((data & mask) != 0);
38 positive_clocks += get_passed_clock(prev_clock);
40 negative_clocks += get_passed_clock(prev_clock);
42 prev_clock = get_current_clock();
43 // mute if signal is not changed in 2 frames
47 } else if(id == SIG_PCM1BIT_ON) {
49 on = ((data & mask) != 0);
50 set_realtime_render(this, on & !mute);
51 } else if(id == SIG_PCM1BIT_MUTE) {
53 mute = ((data & mask) != 0);
54 set_realtime_render(this, on & !mute);
58 void PCM1BIT::event_frame()
65 void PCM1BIT::mix(int32_t* buffer, int cnt)
67 if(on && !mute && changed) {
69 positive_clocks += get_passed_clock(prev_clock);
71 negative_clocks += get_passed_clock(prev_clock);
73 int clocks = positive_clocks + negative_clocks;
74 int sample = clocks ? (max_vol * positive_clocks - max_vol * negative_clocks) / clocks : signal ? max_vol : -max_vol;
76 last_vol_l = apply_volume(sample, volume_l);
77 last_vol_r = apply_volume(sample, volume_r);
79 for(int i = 0; i < cnt; i++) {
80 *buffer++ += last_vol_l; // L
81 *buffer++ += last_vol_r; // R
84 // suppress petite noise when go to mute
85 for(int i = 0; i < cnt; i++) {
86 *buffer++ += last_vol_l; // L
87 *buffer++ += last_vol_r; // R
91 } else if(last_vol_l < 0) {
96 } else if(last_vol_r < 0) {
101 prev_clock = get_current_clock();
102 positive_clocks = negative_clocks = 0;
105 void PCM1BIT::set_volume(int ch, int decibel_l, int decibel_r)
107 volume_l = decibel_to_volume(decibel_l);
108 volume_r = decibel_to_volume(decibel_r);
111 void PCM1BIT::initialize_sound(int rate, int volume)
116 #define STATE_VERSION 3
118 void PCM1BIT::save_state(FILEIO* state_fio)
120 state_fio->FputUint32(STATE_VERSION);
121 state_fio->FputInt32(this_device_id);
123 state_fio->FputBool(signal);
124 state_fio->FputBool(on);
125 state_fio->FputBool(mute);
126 state_fio->FputBool(realtime);
127 state_fio->FputInt32(changed);
128 state_fio->FputUint32(prev_clock);
129 state_fio->FputInt32(positive_clocks);
130 state_fio->FputInt32(negative_clocks);
133 bool PCM1BIT::load_state(FILEIO* state_fio)
135 if(state_fio->FgetUint32() != STATE_VERSION) {
138 if(state_fio->FgetInt32() != this_device_id) {
141 signal = state_fio->FgetBool();
142 on = state_fio->FgetBool();
143 mute = state_fio->FgetBool();
144 realtime = state_fio->FgetBool();
145 changed = state_fio->FgetInt32();
146 prev_clock = state_fio->FgetUint32();
147 positive_clocks = state_fio->FgetInt32();
148 negative_clocks = state_fio->FgetInt32();
151 last_vol_l = last_vol_r = 0;
153 set_realtime_render(on & !mute);