2 Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5 [ADPCM RF6C68 with RAM]
8 #include "../../common.h"
11 #define EVENT_DAC_SAMPLE 1
13 void RF5C68::initialize()
16 memset(wave_memory, 0x00, sizeof(wave_memory));
22 for(int i = 0; i < 8; i++) {
23 dac_addr_st[i].d = 0x00;
24 dac_env[i] = 0x0000000;
25 dac_lpan[i] = 0x000000f;
26 dac_rpan[i] = 0x000000f;
27 dac_tmpval_l[i] = 0x00000000;
28 dac_tmpval_r[i] = 0x00000000;
32 dac_addr[i] = 0x00000000;
33 dac_force_load[i] = true;
43 for(int i = 0; i < 8; i++) {
44 dac_addr_st[i].d = 0x00;
45 dac_env[i] = 0x0000000;
46 dac_lpan[i] = 0x000000f;
47 dac_rpan[i] = 0x000000f;
48 dac_tmpval_l[i] = 0x00000000;
49 dac_tmpval_r[i] = 0x00000000;
53 dac_addr[i] = 0x00000000;
54 dac_force_load[i] = true;
56 if((sample_buffer != NULL) && (sample_length > 0)) {
57 memset(sample_buffer, 0x00, sample_length * sizeof(int32_t) * 2);
59 if(event_dac_sample != -1) {
60 cancel_event(this, event_dac_sample);
61 event_dac_sample = -1;
64 sample_tick_us = 1.0e6 / ((double)mix_rate);
65 register_event(this, EVENT_DAC_SAMPLE, sample_tick_us, true, &event_dac_sample);
72 uint32_t RF5C68::read_signal(int ch)
77 void RF5C68::write_signal(int ch, uint32_t data, uint32_t mask)
81 case SIG_RF5C68_DAC_PERIOD:
83 for(int ch = 0; ch < 8; ch++) {
85 uint32_t addr_old = (dac_addr[ch] & 0x7fffffff) >> 11;
87 dac_addr[ch] += dac_fd[ch].d;
88 dac_addr[ch] = dac_addr[ch] & 0x7fffffff;
89 addr_new = dac_addr[ch] >> 11;
90 if((addr_old != addr_new) || (dac_force_load[ch])) {
92 tmpval.b.l = wave_memory[addr_new & 0xffff];
93 if((addr_new & 0xf000) != (addr_old & 0xf000)) { // Boundary
94 if((addr_new & 0x1000) != 0) {
95 write_signals(&interrupt_boundary, ((addr_new & 0xe000) >> 13) | 0x00000008);
98 if(dac_force_load[ch]) {
99 dac_addr[ch] = (uint32_t)(dac_addr_st[ch].w.l) << 11;
100 addr_new = dac_addr[ch] >> 11;
101 tmpval.b.l = wave_memory[addr_new & 0xffff];
103 dac_force_load[ch] = false;
105 if(tmpval.b.l == 0xff) {
107 dac_force_load[ch] = true;
108 // Q: Is clear data reg?
110 dac_tmpval_l[ch] = 0;
111 dac_tmpval_r[ch] = 0;
112 } else { // Normal OP
113 uint32_t sign = tmpval[ch].d & 0x80;
114 uint32_t val = tmpval[ch].d & 0x7f;
116 val = val * dac_env[ch];
117 lval = val * dac_lpan[ch];
118 rval = val * dac_rpan[ch];
119 if(sign != 0) { // ADD
120 dac_tmpval_l[ch] += lval;
121 dac_tmpval_r[ch] += rval;
123 dac_tmpval_l[ch] -= lval;
124 dac_tmpval_r[ch] -= rval;
127 if(dac_tmpval_l[ch] >= (127 << 6)) {
128 dac_tmpval_l[ch] = 127 << 6;
129 } else if(dacval_tmpval_l[ch] < -(127 << 6)) {
130 dac_tmpval_l[ch] = -(127 << 6);
132 if(dac_tmpval_r[ch] >= (127 << 6)) {
133 dac_tmpval_r[ch] = 127 << 6;
134 } else if(dacval_tmpval_r[ch] < -(127 << 6)) {
135 dac_tmpval_r[ch] = -(127 << 6);
140 dac_tmpval_l[ch] = 0;
141 dac_tmpval_r[ch] = 0;
146 case SIG_RF5C68_CLEAR_INTR:
147 write_signals(&interrupt_boundary, 0x80000000);
149 case SIG_RF5C68_SET_ALL_INTR:
150 write_signals(&interrupt_boundary, 0x80000008);
157 void RF5C68::write_io8(uint32_t addr, uint32_t data)
159 uint32_t naddr = addr & 0x0f;
162 dac_env[dac_ch] = data & 0xff;
165 dac_lpan[dac_ch] = data & 0x0f;
166 dac_rpan[dac_ch] = (data & 0xf0) >> 4;
169 dac_fd[dac_ch].b.l = data & 0xff;
172 dac_fd[dac_ch].b.h = data & 0xff;
175 dac_ls[dac_ch].b.l = data & 0xff;
178 dac_ls[dac_ch].b.h = data & 0xff;
181 dac_addr_st[dac_ch].d = 0;
182 dac_addr_st[dac_ch].b.h = data & 0xff;
184 case 0x07: // Control
185 dac_on = ((data & 0x80) != 0) ? true : false;
186 if((data & 0x40) != 0) { // CB2-0
187 dac_ch = data & 0x07;
189 dac_bank = ((data & 0x0cf) << 12);
192 case 0x08: // ON/OFF per CH
194 uint32_t mask = 0x01;
195 for(int i = 0; i < 8; i++) {
196 bool onoff = dac_onoff[i];
197 if((mask & data) != 0) {
200 dac_onoff[i] = false;
202 if(onoff != dac_onoff[i]) {
203 dac_force_load[i] = true;
214 uint32_t RF5C68::read_io8(uint32_t addr)
220 uint32_t RF5C68::read_data8(uint32_t addr)
226 return wave_memory[(addr & 0x0fff) | dac_bank];
229 void RF5C68::write_data8(uint32_t addr, uint32_t data)
231 // if(dac_on) don't write <- Is correct?
233 wave_memory[(addr & 0x0fff) | dac_bank] = (uint8_t)data;
237 void RF5C68::set_volume(int ch, int decibel_l, int decibel_r)
239 volume_l = decibel_to_volume(decibel_l);
240 volume_r = decibel_to_volume(decibel_r);
243 void RF5C68::event_callback(int id, int err)
245 if(id == EVENT_DAC_SAMPLE) {
249 if(sample_count < sample_length) {
251 for(int ch = 0; ch < 8; ch++) {
253 lval = lval + (dac_tmpval_l[ch] << 0);
254 rval = rval + (dac_tmpval_r[ch] << 0);
258 sample_buffer[sample_count << 1] = lval;
259 sample_buffer[(sample_count << 1) + 1] = rval;
265 void RF5C68::mix(int32_t* buffer, int cnt)
269 // ToDo: supress pop noise.
270 if(sample_length < cnt) cnt = sample_length;
271 if(sample_length < sample_count) sample_count = sample_length;
274 if(sample_buffer != NULL) {
275 for(int i = 0; i < (cnt << 1); i += 2) {
276 // ToDo: interpoolate.
277 buffer[i] += apply_volume(sample_buffer[i], volume_l);
278 buffer[i + 1] += apply_volume(sample_buffer[i + 1], volume_r);
280 if(sample_count > cnt) {
282 memcpy(&(sample_buffer[0]), &(sample_buffer[cnt * 2]), sample_count * sizeof(int32_t) * 2);
283 memset(&(sample_buffer[cnt * 2]), 0x00, (sample_length - sample_count) * sizeof(int32_t) * 2);
285 memset(&(sample_buffer[0]), 0x00, sample_length * sizeof(int32_t) * 2);
291 void RF5C68::initialize_sound(int sample_rate, int samples)
293 if((sample_rate > 0) && (samples > 0)) {
294 mix_rate = sample_rate;
295 sample_length = samples;
296 if(sample_buffer != NULL) {
299 sample_buffer = (int32_t*)malloc(sample_length * sizeof(int32_t) * 2);
300 if(sample_buffer != NULL) {
301 memset(sample_buffer, 0x00, sample_length * sizeof(int32_t) * 2);
303 if(event_dac_sample != -1) {
304 cancel_event(this, event_dac_sample);
307 sample_tick_us = 1.0e6 / ((double)mix_rate);
308 register_event(this, EVENT_DAC_SAMPLE, sample_tick_us, true, &event_dac_sample);
310 if(sample_buffer != NULL) {
313 sample_buffer = NULL;
316 if(event_dac_sample != -1) {
317 cancel_event(this, event_dac_sample);
318 event_dac_sample = -1;
320 sample_tick_us = 0.0;
325 #define STATE_VERSION 1
327 bool RF5C68::process_state(FILEIO* state_fio, bool loading)
329 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
332 if(!state_fio->StateCheckInt32(this_device_id)) {
335 state_fio->StateValue(dac_on);
336 state_fio->StateValue(dac_bank);
337 state_fio->StateValue(dac_ch);
338 state_fio->StateArray(dac_on);
339 state_fio->StateArray(dac_onoff, sizeof(dac_onoff), 1);
340 state_fio->StateArray(dac_addr_st, sizeof(dac_addr_st), 1);
341 state_fio->StateArray(dac_addr, sizeof(dac_addr), 1);
342 state_fio->StateArray(dac_env, sizeof(dac_env), 1);
343 state_fio->StateArray(dac_lpan, sizeof(dac_lpan), 1);
344 state_fio->StateArray(dac_rpan, sizeof(dac_rpan), 1);
345 state_fio->StateArray(dac_ls, sizeof(dac_ls), 1);
346 state_fio->StateArray(dac_fd, sizeof(dac_fd), 1);
347 state_fio->StateArray(dac_force_load, sizeof(dac_force_load), 1);
348 state_fio->StateArray(dac_tmpval_l, sizeof(dac_tmpval_l), 1);
349 state_fio->StateArray(dac_tmpval_r, sizeof(dac_tmpval_r), 1);
351 state_fio->StateArray(wave_memory, sizeof(wave_memory), 1);
353 // ToDo: OLD_mix_rate != mix_rate.
354 state_fio->StateValue(mix_rate);
355 // ToDo: OLD_sample_length != sample_length.
356 state_fio->StateValue(sample_length);
357 state_fio->StateValue(event_dac_sample);
360 if((sample_buffer != NULL) && (sample_length > 0)) {
361 memset(sample_buffer, 0x00, sample_length * sizeof(int32_t) * 2);
367 sample_tick_us = 1.0e6 / ((double)mix_rate);