2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
11 #include "../fileio.h"
13 void PCM1BIT::initialize()
19 #ifdef PCM1BIT_HIGH_QUALITY
26 register_frame_event(this);
29 void PCM1BIT::write_signal(int id, uint32 data, uint32 mask)
31 if(id == SIG_PCM1BIT_SIGNAL) {
32 bool next = ((data & mask) != 0);
34 #ifdef PCM1BIT_HIGH_QUALITY
35 if(sample_count < 1024) {
36 samples_signal[sample_count] = signal;
37 samples_out[sample_count] = (on && !mute);
38 samples_clock[sample_count] = passed_clock(prev_clock);
42 // mute if signal is not changed in 2 frames
46 } else if(id == SIG_PCM1BIT_ON) {
47 on = ((data & mask) != 0);
48 } else if(id == SIG_PCM1BIT_MUTE) {
49 mute = ((data & mask) != 0);
53 void PCM1BIT::event_frame()
55 if(update && --update == 0) {
56 #ifdef PCM1BIT_HIGH_QUALITY
62 void PCM1BIT::mix(int32* buffer, int cnt)
64 #ifdef PCM1BIT_HIGH_QUALITY
65 uint32 cur_clock = current_clock();
67 if(sample_count < 1024) {
68 samples_signal[sample_count] = signal;
69 samples_out[sample_count] = (on && !mute);
70 samples_clock[sample_count] = passed_clock(prev_clock);
73 uint32 start_clock = 0;
75 for(int i = 0; i < cnt; i++) {
76 uint32 end_clock = ((cur_clock - prev_clock) * (i + 1)) / cnt;
77 int on_clocks = 0, off_clocks = 0;
78 for(int s = start_index; s < sample_count; s++) {
79 uint32 clock = samples_clock[s];
80 if(clock <= end_clock) {
82 if(samples_signal[s]) {
83 on_clocks += clock - start_clock;
85 off_clocks += clock - start_clock;
92 if(samples_signal[s]) {
93 on_clocks += end_clock - start_clock;
95 off_clocks += end_clock - start_clock;
98 start_clock = end_clock;
103 int clocks = on_clocks + off_clocks;
105 prev_vol = max_vol * (on_clocks - off_clocks) / clocks;
107 *buffer++ += prev_vol; // L
108 *buffer++ += prev_vol; // R
111 prev_clock = cur_clock;
114 if(on && !mute && signal) {
115 for(int i = 0; i < cnt; i++) {
116 *buffer++ += max_vol; // L
117 *buffer++ += max_vol; // R
123 void PCM1BIT::init(int rate, int volume)
128 #define STATE_VERSION 1
130 void PCM1BIT::save_state(FILEIO* state_fio)
132 state_fio->FputUint32(STATE_VERSION);
133 state_fio->FputInt32(this_device_id);
135 state_fio->FputBool(signal);
136 state_fio->FputBool(on);
137 state_fio->FputBool(mute);
138 #ifdef PCM1BIT_HIGH_QUALITY
139 state_fio->Fwrite(samples_signal, sizeof(samples_signal), 1);
140 state_fio->Fwrite(samples_out, sizeof(samples_out), 1);
141 state_fio->Fwrite(samples_clock, sizeof(samples_clock), 1);
142 state_fio->FputInt32(sample_count);
143 state_fio->FputUint32(prev_clock);
144 state_fio->FputInt32(prev_vol);
146 state_fio->FputInt32(update);
149 bool PCM1BIT::load_state(FILEIO* state_fio)
151 if(state_fio->FgetUint32() != STATE_VERSION) {
154 if(state_fio->FgetInt32() != this_device_id) {
157 signal = state_fio->FgetBool();
158 on = state_fio->FgetBool();
159 mute = state_fio->FgetBool();
160 #ifdef PCM1BIT_HIGH_QUALITY
161 state_fio->Fread(samples_signal, sizeof(samples_signal), 1);
162 state_fio->Fread(samples_out, sizeof(samples_out), 1);
163 state_fio->Fread(samples_clock, sizeof(samples_clock), 1);
164 sample_count = state_fio->FgetInt32();
165 prev_clock = state_fio->FgetUint32();
166 prev_vol = state_fio->FgetInt32();
168 update = state_fio->FgetInt32();