2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void PCM1BIT::initialize()
18 last_vol_l = last_vol_r = 0;
20 register_frame_event(this);
25 prev_clock = get_current_clock();
26 positive_clocks = negative_clocks = 0;
29 void PCM1BIT::write_signal(int id, uint32_t data, uint32_t mask)
31 if(id == SIG_PCM1BIT_SIGNAL) {
32 bool next = ((data & mask) != 0);
35 positive_clocks += get_passed_clock(prev_clock);
37 negative_clocks += get_passed_clock(prev_clock);
39 prev_clock = get_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_t* buffer, int cnt)
60 if(on && !mute && changed) {
62 positive_clocks += get_passed_clock(prev_clock);
64 negative_clocks += get_passed_clock(prev_clock);
66 int clocks = positive_clocks + negative_clocks;
67 int sample = clocks ? (max_vol * positive_clocks - max_vol * negative_clocks) / clocks : signal ? max_vol : -max_vol;
69 last_vol_l = apply_volume(sample, volume_l);
70 last_vol_r = apply_volume(sample, volume_r);
72 for(int i = 0; i < cnt; i++) {
73 *buffer++ += last_vol_l; // L
74 *buffer++ += last_vol_r; // R
77 // suppress petite noise when go to mute
78 for(int i = 0; i < cnt; i++) {
79 *buffer++ += last_vol_l; // L
80 *buffer++ += last_vol_r; // R
84 } else if(last_vol_l < 0) {
89 } else if(last_vol_r < 0) {
94 prev_clock = get_current_clock();
95 positive_clocks = negative_clocks = 0;
98 void PCM1BIT::set_volume(int ch, int decibel_l, int decibel_r)
100 volume_l = decibel_to_volume(decibel_l);
101 volume_r = decibel_to_volume(decibel_r);
104 void PCM1BIT::initialize_sound(int rate, int volume)
109 #define STATE_VERSION 2
111 void PCM1BIT::save_state(FILEIO* state_fio)
113 state_fio->FputUint32(STATE_VERSION);
114 state_fio->FputInt32(this_device_id);
116 state_fio->FputBool(signal);
117 state_fio->FputBool(on);
118 state_fio->FputBool(mute);
119 state_fio->FputInt32(changed);
120 state_fio->FputUint32(prev_clock);
121 state_fio->FputInt32(positive_clocks);
122 state_fio->FputInt32(negative_clocks);
125 bool PCM1BIT::load_state(FILEIO* state_fio)
127 if(state_fio->FgetUint32() != STATE_VERSION) {
130 if(state_fio->FgetInt32() != this_device_id) {
133 signal = state_fio->FgetBool();
134 on = state_fio->FgetBool();
135 mute = state_fio->FgetBool();
136 changed = state_fio->FgetInt32();
137 prev_clock = state_fio->FgetUint32();
138 positive_clocks = state_fio->FgetInt32();
139 negative_clocks = state_fio->FgetInt32();
142 last_vol_l = last_vol_r = 0;