2 CASIO PV-1000 Emulator 'ePV-1000'
4 Author : Takeda.Toshiya
14 #define PSG_VOLUME 8192
19 memset(ch, 0, sizeof(ch));
22 void PSG::write_io8(uint32_t addr, uint32_t data)
25 ch[addr & 3].period = 0x3f - (data & 0x3f);
28 void PSG::initialize_sound(int rate)
30 diff = (int)(1.3 * (double)CPU_CLOCKS / (double)rate + 0.5);
33 void PSG::mix(int32_t* buffer, int cnt)
35 // create sound buffer
36 for(int i = 0; i < cnt; i++) {
38 for(int j = 0; j < 3; j++) {
42 bool prev_signal = ch[j].signal;
43 int prev_count = ch[j].count;
46 ch[j].count += ch[j].period << 8;
47 ch[j].signal = !ch[j].signal;
49 int vol_tmp = (prev_signal != ch[j].signal && prev_count < diff) ? (PSG_VOLUME * (2 * prev_count - diff)) / diff : PSG_VOLUME;
50 vol += prev_signal ? vol_tmp : -vol_tmp;
52 *buffer++ += apply_volume(vol, volume_l); // L
53 *buffer++ += apply_volume(vol, volume_l); // R
57 void PSG::set_volume(int ch, int decibel_l, int decibel_r)
59 volume_l = decibel_to_volume(decibel_l);
60 volume_r = decibel_to_volume(decibel_r);
63 #define STATE_VERSION 1
65 #include "../../statesub.h"
67 void PSG::decl_state()
69 enter_decl_state(STATE_VERSION);
71 DECL_STATE_ENTRY_INT32_STRIDE((ch[0].period), 3, sizeof(ch[0]));
76 void PSG::save_state(FILEIO* state_fio)
78 if(state_entry != NULL) {
79 state_entry->save_state(state_fio);
81 // state_fio->FputUint32(STATE_VERSION);
82 // state_fio->FputInt32(this_device_id);
84 // for(int i = 0; i < 3; i++) {
85 // state_fio->FputInt32(ch[i].period);
89 bool PSG::load_state(FILEIO* state_fio)
92 if(state_entry != NULL) {
93 mb = state_entry->load_state(state_fio);
98 // if(state_fio->FgetUint32() != STATE_VERSION) {
101 // if(state_fio->FgetInt32() != this_device_id) {
104 // for(int i = 0; i < 3; i++) {
105 // ch[i].period = state_fio->FgetInt32();
110 bool PSG::process_state(FILEIO* state_fio, bool loading)
112 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
115 if(!state_fio->StateCheckInt32(this_device_id)) {
118 for(int i = 0; i < 3; i++) {
119 state_fio->StateInt32(ch[i].period);