OSDN Git Service

[VM] Add EMU::set_vm_screen_lines() to some VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / datarec.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2006.08.18 -
6
7         [ data recorder ]
8 */
9
10 #include "datarec.h"
11 //#include "event.h"
12 #include "noise.h"
13
14 #define EVENT_SIGNAL    0
15 #define EVENT_SOUND     1
16
17 //#ifndef DATAREC_FAST_FWD_SPEED
18 //#define DATAREC_FAST_FWD_SPEED        10
19 //#endif
20 //#ifndef DATAREC_FAST_REW_SPEED
21 //#define DATAREC_FAST_REW_SPEED        10
22 //#endif
23
24 void DATAREC::initialize()
25 {
26         DEVICE::initialize();
27         __DATAREC_SOUND = osd->check_feature(_T("DATAREC_SOUND"));
28         if(osd->check_feature(_T("DATAREC_PCM_VOLUME"))) {
29                 pcm_max_vol = (int)osd->get_feature_int_value(_T("DATAREC_PCM_VOLUME"));
30         }
31         __DATAREC_SOUND_LEFT  = osd->check_feature(_T("DATAREC_SOUND_LEFT"));
32         __DATAREC_SOUND_RIGHT = osd->check_feature(_T("DATAREC_SOUND_RIGHT"));
33
34         __DATAREC_FAST_FWD_SPEED = 10.0;
35         if(osd->check_feature(_T("DATAREC_FAST_FWD_SPEED"))) {
36                 __DATAREC_FAST_FWD_SPEED = osd->get_feature_double_value(_T("DATAREC_FAST_FWD_SPEED"));
37         }
38         __DATAREC_FAST_REW_SPEED = 10.0;
39         if(osd->check_feature(_T("DATAREC_FAST_REW_SPEED"))) {
40                 __DATAREC_FAST_REW_SPEED = osd->get_feature_double_value(_T("DATAREC_FAST_REW_SPEED"));
41         }
42         __TYPE_MZ80B = false;
43         if(osd->check_feature(_T("_MZ80B")))  __TYPE_MZ80B = true;
44         if(osd->check_feature(_T("_MZ2000"))) __TYPE_MZ80B = true;
45         if(osd->check_feature(_T("_MZ2200"))) __TYPE_MZ80B = true;
46         play_fio = new FILEIO();
47         rec_fio = new FILEIO();
48         
49         memset(rec_file_path, sizeof(rec_file_path), 1);
50         play = rec = remote = trigger = false;
51         ff_rew = 0;
52         in_signal = out_signal = false;
53         register_id = -1;
54         realtime = false;
55         
56         buffer = buffer_bak = NULL;
57 //#ifdef DATAREC_SOUND
58         sound_buffer = NULL;
59 //#endif
60         apss_buffer = NULL;
61         buffer_ptr = buffer_length = 0;
62         is_wav = is_tap = is_t77 = false;
63         ave_hi_freq = 0;
64         
65         pcm_changed = 0;
66         pcm_last_vol_l = pcm_last_vol_r = 0;
67 //#ifdef DATAREC_SOUND
68         sound_last_vol_l = sound_last_vol_r = 0;
69 //#endif
70         
71         // initialize noise
72         if(d_noise_play != NULL) {
73                 d_noise_play->set_device_name(_T("Noise Player (CMT Play)"));
74                 d_noise_play->load_wav_file(_T("RELAY_ON.WAV"));
75                 d_noise_play->set_mute(!config.sound_noise_cmt);
76         }
77         if(d_noise_stop != NULL) {
78                 d_noise_stop->set_device_name(_T("Noise Player (CMT Stop)"));
79                 d_noise_stop->load_wav_file(_T("RELAYOFF.WAV"));
80                 d_noise_stop->set_mute(!config.sound_noise_cmt);
81         }
82         if(d_noise_fast != NULL) {
83                 d_noise_fast->set_device_name(_T("Noise Player (CMT Fast)"));
84                 d_noise_fast->load_wav_file(_T("FAST_FWD.WAV"));
85                 d_noise_fast->set_loop(true);
86                 d_noise_fast->set_mute(!config.sound_noise_cmt);
87         }
88         
89         // skip frames
90         signal_changed = 0;
91         register_frame_event(this);
92 }
93
94 void DATAREC::reset()
95 {
96         touch_sound();
97         close_tape();
98         pcm_prev_clock = get_current_clock();
99         pcm_positive_clocks = pcm_negative_clocks = 0;
100 }
101
102 void DATAREC::release()
103 {
104         close_file();
105         delete play_fio;
106         delete rec_fio;
107 }
108
109 void DATAREC::write_signal(int id, uint32_t data, uint32_t mask)
110 {
111         bool signal = ((data & mask) != 0);
112         
113         if(id == SIG_DATAREC_MIC) {
114                 if(out_signal != signal) {
115                         touch_sound();
116                         if(rec && remote) {
117                                 if(out_signal) {
118                                         pcm_positive_clocks += get_passed_clock(pcm_prev_clock);
119                                 } else {
120                                         pcm_negative_clocks += get_passed_clock(pcm_prev_clock);
121                                 }
122                                 pcm_prev_clock = get_current_clock();
123                                 pcm_changed = 2;
124                                 signal_changed++;
125                         }
126                         if(prev_clock != 0) {
127                                 if(out_signal) {
128                                         positive_clocks += get_passed_clock(prev_clock);
129                                 } else {
130                                         negative_clocks += get_passed_clock(prev_clock);
131                                 }
132                                 prev_clock = get_current_clock();
133                         }
134                         out_signal = signal;
135                 }
136         } else if(id == SIG_DATAREC_REMOTE) {
137                 touch_sound();
138                 set_remote(signal);
139         } else if(id == SIG_DATAREC_TRIG) {
140                 // L->H: remote signal is switched
141                 if(signal && !trigger) {
142                         touch_sound();
143                         set_remote(!remote);
144                 }
145                 trigger = signal;
146         }
147 }
148
149 void DATAREC::event_frame()
150 {
151         if(pcm_changed) {
152                 pcm_changed--;
153         }
154 //#ifdef DATAREC_SOUND
155         if(__DATAREC_SOUND) {
156                 if(remote && (play || rec) && ff_rew == 0 && signal_changed > 10 && !config.sound_play_tape && sound_sample == 0) {
157                         request_skip_frames();
158                 }
159         } else {
160 //#else
161                 if(remote && (play || rec) && ff_rew == 0 && signal_changed > 10 && !config.sound_play_tape) {
162 //#endif
163                         request_skip_frames();
164                 }
165         }
166         signal_changed = 0;
167 }
168
169 void DATAREC::event_callback(int event_id, int err)
170 {
171         if(event_id == EVENT_SIGNAL) {
172                 if(play) {
173                         if(ff_rew > 0) {
174                                 my_stprintf_s(message, 1024, _T("Fast Forward (%d %%)"), get_tape_position());
175                         } else if(ff_rew < 0) {
176                                 my_stprintf_s(message, 1024, _T("Fast Rewind (%d %%)"), get_tape_position());
177                         } else {
178                                 my_stprintf_s(message, 1024, _T("Play (%d %%)"), get_tape_position());
179                         }
180                         bool signal = in_signal;
181                         if(is_wav) {
182                                 if(buffer_ptr >= 0 && buffer_ptr < buffer_length) {
183                                         if(buffer != NULL) {
184                                                 signal = ((buffer[buffer_ptr] & 0x80) != 0);
185                                         } else {
186                                                 signal = false;
187                                         }
188 //#ifdef DATAREC_SOUND
189                                         if(__DATAREC_SOUND) {
190                                                 if(sound_buffer != NULL && ff_rew == 0) {
191                                                         sound_sample = sound_buffer[buffer_ptr];
192                                                 } else {
193                                                         sound_sample = 0;
194                                                 }
195                                         }
196 //#endif
197                                 }
198                                 if(ff_rew < 0) {
199                                         if((buffer_ptr = max(buffer_ptr - 1, 0)) == 0) {
200                                                 set_remote(false);      // top of tape
201                                                 signal = false;
202                                         }
203                                 } else {
204                                         if((buffer_ptr = min(buffer_ptr + 1, buffer_length)) == buffer_length) {
205                                                 set_remote(false);      // end of tape
206                                                 signal = false;
207                                         }
208                                 }
209                                 update_event();
210                         } else {
211                                 if(ff_rew < 0) {
212                                         if((buffer_bak != NULL) && (buffer != NULL)) {
213                                                 my_memcpy(buffer, buffer_bak, buffer_length);
214                                         }
215                                         buffer_ptr = 0;
216                                         set_remote(false);      // top of tape
217                                 } else {
218                                         if(buffer != NULL) {
219                                                 while(buffer_ptr < buffer_length) {
220                                                         if((buffer[buffer_ptr] & 0x7f) == 0) {
221                                                                 if(++buffer_ptr == buffer_length) {
222                                                                         set_remote(false);      // end of tape
223                                                                         signal = false;
224                                                                         break;
225                                                                 }
226                                                                 signal = ((buffer[buffer_ptr] & 0x80) != 0);
227                                                         } else {
228                                                                 signal = ((buffer[buffer_ptr] & 0x80) != 0);
229                                                                 uint8_t tmp = buffer[buffer_ptr];
230                                                                 buffer[buffer_ptr] = (tmp & 0x80) | ((tmp & 0x7f) - 1);
231                                                                 break;
232                                                         }
233                                                 }
234                                         } else {
235                                                 set_remote(false);      // end of tape
236                                                 signal = false;
237                                         }
238                                 }
239                         }
240                         // notify the signal is changed
241                         if(signal != in_signal) {
242                                 if(in_signal) {
243                                         pcm_positive_clocks += get_passed_clock(pcm_prev_clock);
244                                 } else {
245                                         pcm_negative_clocks += get_passed_clock(pcm_prev_clock);
246                                 }
247                                 pcm_prev_clock = get_current_clock();
248                                 pcm_changed = 2;
249                                 in_signal = signal;
250                                 signal_changed++;
251                                 touch_sound();
252                                 write_signals(&outputs_ear, in_signal ? 0xffffffff : 0);
253                         }
254                         // chek apss state
255                         if(apss_buffer != NULL) {
256                                 int ptr = (apss_ptr++) % (sample_rate * 2);
257                                 if(apss_buffer[ptr]) {
258                                         apss_count--;
259                                 }
260                                 if(in_signal) {
261                                         apss_count++;
262                                 }
263                                 apss_buffer[ptr] = in_signal;
264                                 
265                                 if(apss_ptr >= sample_rate * 2) {
266                                         double rate = (double)apss_count / (double)(sample_rate * 2);
267                                         if(rate > 0.9 || rate < 0.1) {
268                                                 if(apss_signals) {
269                                                         if(apss_remain > 0) {
270                                                                 apss_remain--;
271                                                         } else if(apss_remain < 0) {
272                                                                 apss_remain++;
273                                                         }
274                                                         write_signals(&outputs_apss, 0xffffffff);
275                                                         apss_signals = false;
276                                                 }
277                                         } else {
278                                                 if(!apss_signals) {
279                                                         write_signals(&outputs_apss, 0);
280                                                         apss_signals = true;
281                                                 }
282                                         }
283                                 }
284                         }
285                 } else if(rec && buffer != NULL) {
286                         if(out_signal) {
287                                 positive_clocks += get_passed_clock(prev_clock);
288                         } else {
289                                 negative_clocks += get_passed_clock(prev_clock);
290                         }
291                         if(is_wav) {
292                                 if(positive_clocks != 0 || negative_clocks != 0) {
293                                         buffer[buffer_ptr] = (255 * positive_clocks) / (positive_clocks + negative_clocks);
294                                 } else {
295                                         buffer[buffer_ptr] = 0;
296                                 }
297                                 if(++buffer_ptr >= buffer_length) {
298                                         if(is_tap) {
299                                                 for(int i = 0; i < buffer_length; i += 8) {
300                                                         uint8_t val = 0;
301                                                         for(int j = 0, bit = 0x80; j < 8; j++, bit >>= 1) {
302                                                                 if(i + j < buffer_length && buffer[i + j] >= 0x80) {
303                                                                         val |= bit;
304                                                                 }
305                                                         }
306                                                         rec_fio->FputUint8(val);
307                                                 }
308                                         } else {
309                                                 rec_fio->Fwrite(buffer, buffer_length, 1);
310                                         }
311                                         buffer_ptr = 0;
312                                 }
313                         } else if(is_t77) {
314                                 bool signal = (positive_clocks > negative_clocks);
315                                 uint16_t data = (buffer[buffer_ptr] << 8) | buffer[buffer_ptr + 1];
316                                 if(signal != ((data & 0x8000) != 0)) {
317                                         if((buffer_ptr += 2) >= buffer_length) {
318                                                 rec_fio->Fwrite(buffer, buffer_length, 1);
319                                                 buffer_ptr = 0;
320                                         }
321                                         data = signal ? 0x8001 : 0x0001;
322                                 } else if((data & 0x7fff) < 0x7fff) {
323                                         data++;
324                                 }
325                                 buffer[buffer_ptr + 0] = data >> 8;
326                                 buffer[buffer_ptr + 1] = data & 0xff;
327                         } else {
328                                 bool prev_signal = ((buffer[buffer_ptr] & 0x80) != 0);
329                                 bool cur_signal = (positive_clocks > negative_clocks);
330                                 if(prev_signal != cur_signal || (buffer[buffer_ptr] & 0x7f) == 0x7f) {
331                                         if(++buffer_ptr >= buffer_length) {
332                                                 rec_fio->Fwrite(buffer, buffer_length, 1);
333                                                 buffer_ptr = 0;
334                                         }
335                                         buffer[buffer_ptr] = cur_signal ? 0x80 : 0;
336                                 }
337                                 buffer[buffer_ptr]++;
338                         }
339                         prev_clock = get_current_clock();
340                         positive_clocks = negative_clocks = 0;
341                 }
342         }
343 }
344
345 void DATAREC::set_remote(bool value)
346 {
347         if(remote != value) {
348                 if(value) {
349                         if(d_noise_play != NULL) {
350                                 d_noise_play->play();
351                         }
352                         if(d_noise_fast != NULL && ff_rew != 0) {
353                                 d_noise_fast->play();
354                         }
355                 } else {
356                         if(d_noise_stop != NULL) {
357                                 d_noise_stop->play();
358                         }
359                         if(d_noise_fast != NULL) {
360                                 d_noise_fast->stop();
361                         }
362                 }
363                 remote = value;
364                 update_event();
365         }
366 }
367
368 void DATAREC::set_ff_rew(int value)
369 {
370         if(ff_rew != value) {
371                 if(register_id != -1) {
372                         cancel_event(this, register_id);
373                         register_id = -1;
374                 }
375                 if(value != 0) {
376                         if(d_noise_fast != NULL && remote) {
377                                 d_noise_fast->play();
378                         }
379                 } else {
380                         if(d_noise_fast != NULL) {
381                                 d_noise_fast->stop();
382                         }
383                 }
384                 ff_rew = value;
385                 apss_signals = false;
386                 update_event();
387         }
388 }
389
390 bool DATAREC::do_apss(int value)
391 {
392         bool result = false;
393         
394         if(play) {
395                 set_ff_rew(0);
396                 set_remote(true);
397                 set_ff_rew(value > 0 ? 1 : -1);
398                 apss_remain = value;
399                 
400                 while(apss_remain != 0 && remote) {
401                         event_callback(EVENT_SIGNAL, 0);
402                 }
403                 result = (apss_remain == 0);
404         }
405         
406         // stop cmt
407         set_remote(false);
408         set_ff_rew(0);
409         
410         if(value > 0) {
411                 if(play) {
412                         my_stprintf_s(message, 1024, _T("APSS Forward (%d %%)"), get_tape_position());
413                 } else {
414                         my_stprintf_s(message, 1024, _T("APSS Forward"));
415                 }
416         } else {
417                 if(play) {
418                         my_stprintf_s(message, 1024, _T("APSS Rewind (%d %%)"), get_tape_position());
419                 } else {
420                         my_stprintf_s(message, 1024, _T("APSS Rewind"));
421                 }
422         }
423         return result;
424 }
425
426 void DATAREC::update_event()
427 {
428         if(remote && (play || rec)) {
429                 if(register_id == -1) {
430                         if(ff_rew > 0) {
431                                 register_event(this, EVENT_SIGNAL, sample_usec / __DATAREC_FAST_FWD_SPEED, true, &register_id);
432                         } else if(ff_rew < 0) {
433                                 register_event(this, EVENT_SIGNAL, sample_usec / __DATAREC_FAST_REW_SPEED, true, &register_id);
434                         } else {
435                                 if(rec) {
436                                         my_stprintf_s(message, 1024, _T("Record"));
437                                 }
438                                 register_event(this, EVENT_SIGNAL, sample_usec, true, &register_id);
439                         }
440                         prev_clock = get_current_clock();
441                         positive_clocks = negative_clocks = 0;
442                 }
443         } else {
444                 if(register_id != -1) {
445                         cancel_event(this, register_id);
446                         register_id = -1;
447                         if(play) {
448                                 if(buffer_ptr >= buffer_length) {
449                                         my_stprintf_s(message, 1024, _T("Stop (End-of-Tape)"));
450                                 } else if(buffer_ptr <= 0) {
451                                         my_stprintf_s(message, 1024, _T("Stop (Beginning-of-Tape)"));
452                                 } else {
453                                         my_stprintf_s(message, 1024, _T("Stop (%d %%)"), get_tape_position());
454                                 }
455                         } else {
456                                 my_stprintf_s(message, 1024, _T("Stop"));
457                         }
458                 }
459                 prev_clock = 0;
460         }
461         
462         // update signals
463 //#ifdef DATAREC_SOUND
464         if(__DATAREC_SOUND) {
465                 if(!(play && remote)) {
466                         sound_sample = 0;
467                 }
468         }
469 //#endif
470         write_signals(&outputs_remote, remote ? 0xffffffff : 0);
471         write_signals(&outputs_rotate, (register_id != -1) ? 0xffffffff : 0);
472         write_signals(&outputs_end, (buffer_ptr == buffer_length) ? 0xffffffff : 0);
473         write_signals(&outputs_top, (buffer_ptr == 0) ? 0xffffffff : 0);
474         
475         update_realtime_render();
476 }
477
478 void DATAREC::update_realtime_render()
479 {
480         bool value = (remote && (play || rec) && ff_rew == 0 && config.sound_play_tape);
481         
482         if(realtime != value) {
483                 set_realtime_render(this, value);
484                 realtime = value;
485         }
486 }
487
488 bool DATAREC::play_tape(const _TCHAR* file_path)
489 {
490         close_tape();
491         
492         if(play_fio->Fopen(file_path, FILEIO_READ_BINARY)) {
493                 if(check_file_extension(play_fio->FilePath(), _T(".wav")) || check_file_extension(play_fio->FilePath(), _T(".mti"))) {
494                         // standard PCM wave file
495                         if((buffer_length = load_wav_image(0)) != 0) {
496                                 play = is_wav = true;
497                         }
498                 } else if(check_file_extension(play_fio->FilePath(), _T(".t77"))) {
499                         // FUJITSU FM-7 series tape image
500                         if((buffer_length = load_t77_image()) != 0) {
501                                 buffer = (uint8_t *)malloc(buffer_length);
502                                 load_t77_image();
503                                 play = is_wav = true;
504                         }
505                 } else if(check_file_extension(play_fio->FilePath(), _T(".tap"))) {
506                         // SHARP X1 series tape image
507                         if((buffer_length = load_tap_image()) != 0) {
508                                 buffer = (uint8_t *)malloc(buffer_length);
509                                 load_tap_image();
510                                 play = is_wav = true;
511                         }
512                 } else if(check_file_extension(play_fio->FilePath(), _T(".mzt")) || check_file_extension(play_fio->FilePath(), _T(".mzf")) || check_file_extension(play_fio->FilePath(), _T(".m12"))) {
513                         // SHARP MZ series tape image
514                         if((buffer_length = load_mzt_image()) != 0) {
515                                 buffer = (uint8_t *)malloc(buffer_length);
516                                 load_mzt_image();
517                                 play = is_wav = true;
518                         }
519                 } else if(check_file_extension(play_fio->FilePath(), _T(".mtw"))) {
520                         // skip mzt image
521                         uint8_t header[128];
522                         play_fio->Fread(header, sizeof(header), 1);
523                         uint16_t size = header[0x12] | (header[0x13] << 8);
524                         // load standard PCM wave file
525                         if((buffer_length = load_wav_image(sizeof(header) + size)) != 0) {
526                                 play = is_wav = true;
527                         }
528                 } else if(check_file_extension(play_fio->FilePath(), _T(".p6"))) {
529                         // NEC PC-6001/6601 series tape image
530                         if((buffer_length = load_p6_image(false)) != 0) {
531                                 buffer = (uint8_t *)malloc(buffer_length);
532                                 load_p6_image(false);
533                                 play = is_wav = true;
534                         }
535                 } else if(check_file_extension(play_fio->FilePath(), _T(".p6t"))) {
536                         // NEC PC-6001/6601 series tape image
537                         if((buffer_length = load_p6_image(true)) != 0) {
538                                 buffer = (uint8_t *)malloc(buffer_length);
539                                 load_p6_image(true);
540                                 play = is_wav = true;
541                         }
542                 } else if(check_file_extension(play_fio->FilePath(), _T(".bin"))) {
543                         // HITACH BASIC Master Jr tape image (bm2)
544                         if((buffer_length = load_bmjr_image()) != 0) {
545                                 buffer = (uint8_t *)malloc(buffer_length);
546                                 load_bmjr_image();
547                                 play = is_wav = true;
548                         }
549                 } else if(check_file_extension(play_fio->FilePath(), _T(".cas"))) {
550                         // standard cas image for my emulator
551                         if((buffer_length = load_cas_image()) != 0) {
552                                 buffer = (uint8_t *)malloc(buffer_length);
553                                 load_cas_image();
554                                 play = is_wav = true;
555                         }
556                 }
557                 play_fio->Fclose();
558         }
559         if(play) {
560                 if(!is_wav && buffer_length != 0) {
561                         buffer_bak = (uint8_t *)malloc(buffer_length);
562                         my_memcpy(buffer_bak, buffer, buffer_length);
563                 }
564                 
565                 // get the first signal
566                 bool signal = ((buffer[0] & 0x80) != 0);
567                 if(signal != in_signal) {
568                         touch_sound();
569                         write_signals(&outputs_ear, signal ? 0xffffffff : 0);
570                         in_signal = signal;
571                 }
572                 
573                 // initialize apss
574                 apss_buffer_length = sample_rate * 2;
575                 apss_buffer = (bool *)calloc(apss_buffer_length, 1);
576                 apss_ptr = apss_count = 0;
577                 apss_signals = false;
578                 write_signals(&outputs_apss, 0);
579                 
580                 update_event();
581         }
582         return play;
583 }
584
585 bool DATAREC::rec_tape(const _TCHAR* file_path)
586 {
587         close_tape();
588         
589         if(rec_fio->Fopen(file_path, FILEIO_READ_WRITE_NEW_BINARY)) {
590                 my_tcscpy_s(rec_file_path, _MAX_PATH, file_path);
591                 sample_rate = 48000;
592                 sample_usec = 1000000. / sample_rate;
593                 buffer_length = 1024 * 1024;
594                 buffer = (uint8_t *)calloc(buffer_length, 1);
595                 
596                 if(check_file_extension(file_path, _T(".wav"))) {
597                         // write wave header
598                         uint8_t dummy[sizeof(wav_header_t) + sizeof(wav_chunk_t)];
599                         memset(dummy, 0, sizeof(dummy));
600                         rec_fio->Fwrite(dummy, sizeof(dummy), 1);
601                         is_wav = true;
602                 } else if(check_file_extension(file_path, _T(".tap"))) {
603                         // write frequency
604                         rec_fio->FputUint32((uint32_t)sample_rate);
605                         is_wav = is_tap = true;
606                 } else if(check_file_extension(file_path, _T(".t77"))) {
607                         // 9us/sample
608                         sample_usec = 9;
609                         sample_rate = (int)(1000000.0 / sample_usec + 0.5);
610                         // write header
611                         rec_fio->Fwrite((void *)("XM7 TAPE IMAGE 0"), 16, 1);
612                         rec_fio->FputUint16(0); // marker
613                         is_t77 = true;
614                         // initialize buffer
615                         buffer[0] = out_signal ? 0x80 : 0;
616                         buffer[1] = 0;
617                 } else {
618                         // initialize buffer
619                         buffer[0] = out_signal ? 0x80 : 0;
620                 }
621                 rec = true;
622                 update_event();
623         }
624         return rec;
625 }
626
627 void DATAREC::close_tape()
628 {
629         touch_sound();
630         close_file();
631         
632         play = rec = is_wav = is_tap = is_t77 = false;
633         buffer_ptr = buffer_length = 0;
634         ave_hi_freq = 0;
635         
636         update_event();
637         
638         // no sounds
639         write_signals(&outputs_ear, 0);
640         in_signal = false;
641 }
642
643 void DATAREC::close_file()
644 {
645         if(play_fio->IsOpened()) {
646                 play_fio->Fclose();
647         }
648         if(rec_fio->IsOpened()) {
649                 if(rec) {
650                         if(is_tap) {
651                                 for(int i = 0; i < buffer_ptr; i += 8) {
652                                         uint8_t val = 0;
653                                         for(int j = 0, bit = 0x80; j < 8; j++, bit >>= 1) {
654                                                 if(i + j < buffer_ptr && buffer[i + j] >= 0x80) {
655                                                         val |= bit;
656                                                 }
657                                         }
658                                         rec_fio->FputUint8(val);
659                                 }
660                         } else if(is_t77) {
661                                 rec_fio->Fwrite(buffer, buffer_ptr + 2, 1);
662                         } else if(is_wav) {
663                                 save_wav_image();
664                         } else {
665                                 rec_fio->Fwrite(buffer, buffer_ptr + 1, 1);
666                         }
667                 }
668                 rec_fio->Fclose();
669         }
670         if(buffer != NULL) {
671                 free(buffer);
672                 buffer = NULL;
673         }
674         if(buffer_bak != NULL) {
675                 free(buffer_bak);
676                 buffer_bak = NULL;
677         }
678 //#ifdef DATAREC_SOUND
679         if(__DATAREC_SOUND) {
680                 if(sound_buffer != NULL) {
681                         free(sound_buffer);
682                         sound_buffer = NULL;
683                 }
684         }
685 //#endif
686         if(apss_buffer != NULL) {
687                 free(apss_buffer);
688                 apss_buffer = NULL;
689         }
690 }
691
692 // standard PCM wave file
693
694 void adjust_zero_position(int16_t *wav_buffer, int samples, int sample_rate)
695 {
696         int16_t *zero_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
697         int width = (int)((double)sample_rate / 1000.0 + 0.5);
698         
699         for(int i = width; i < samples - width; i++) {
700                 int max_sample = -65536, min_sample = 65536;
701                 for(int j = -width; j < width; j++) {
702                         if(max_sample < (int)wav_buffer[i + j]) max_sample = (int)wav_buffer[i + j];
703                         if(min_sample > (int)wav_buffer[i + j]) min_sample = (int)wav_buffer[i + j];
704                 }
705                 if(max_sample - min_sample > 4096) {
706                         zero_buffer[i] = (int16_t)((max_sample + min_sample) / 2);
707                 } else {
708                         zero_buffer[i] = wav_buffer[i];
709                 }
710         }
711         for(int i = 0; i < samples; i++) {
712                 wav_buffer[i] -= zero_buffer[(i < width) ? width : (i < samples - width) ? i : (samples - width - 1)];
713         }
714         free(zero_buffer);
715 }
716 int DATAREC::load_wav_image(int offset)
717 {
718         // check wave header
719         wav_header_t header;
720         wav_chunk_t chunk;
721         
722         play_fio->Fseek(offset, FILEIO_SEEK_SET);
723         play_fio->Fread(&header, sizeof(header), 1);
724         if(header.format_id != 1 || !(header.sample_bits == 8 || header.sample_bits == 16)) {
725                 return 0;
726         }
727         play_fio->Fseek(header.fmt_chunk.size - 16, FILEIO_SEEK_CUR);
728         while(1) {
729                 play_fio->Fread(&chunk, sizeof(chunk), 1);
730                 if(strncmp(chunk.id, "data", 4) == 0) {
731                         break;
732                 }
733                 play_fio->Fseek(chunk.size, FILEIO_SEEK_CUR);
734         }
735         
736         int samples = chunk.size / header.channels, loaded_samples = 0;
737         if(header.sample_bits == 16) {
738                 samples /= 2;
739         }
740         sample_rate = header.sample_rate;
741         sample_usec = 1000000. / sample_rate;
742         
743         // load samples
744         if(samples > 0) {
745                 #define TMP_LENGTH (0x10000 * header.channels)
746                 
747                 uint8_t *tmp_buffer = (uint8_t *)malloc(TMP_LENGTH);
748                 play_fio->Fread(tmp_buffer, TMP_LENGTH, 1);
749                 
750                 #define GET_SAMPLE { \
751                         for(int ch = 0; ch < header.channels; ch++) { \
752                                 if(header.sample_bits == 16) { \
753                                         union { \
754                                                 int16_t s16; \
755                                                 struct { \
756                                                         uint8_t l, h; \
757                                                 } b; \
758                                         } pair; \
759                                         pair.b.l = tmp_buffer[tmp_ptr++]; \
760                                         pair.b.h = tmp_buffer[tmp_ptr++]; \
761                                         sample[ch] = pair.s16; \
762                                 } else { \
763                                         sample[ch] = (tmp_buffer[tmp_ptr++] - 128) * 256; \
764                                 } \
765                         } \
766                         if(tmp_ptr == TMP_LENGTH) { \
767                                 play_fio->Fread(tmp_buffer, TMP_LENGTH, 1); \
768                                 tmp_ptr = 0; \
769                         } \
770                 }
771
772                 bool __t = false;
773                 if(__DATAREC_SOUND) {
774                    if(!config.wave_shaper[drive_num] || header.channels > 1) {
775                            __t = true;
776                    }
777                 } else {
778                         if(!config.wave_shaper[drive_num]) {
779                                 __t = true;
780                         }
781                 }
782 //#ifdef DATAREC_SOUND
783 //              if(!config.wave_shaper[drive_num] || header.channels > 1) {
784 //#else
785 //              if(!config.wave_shaper[drive_num]) {
786 //#endif
787                 if(__t) {
788                         // load samples
789 //#ifdef DATAREC_SOUND
790                         if(__DATAREC_SOUND) {
791                                 if(header.channels > 1) {
792                                         sound_buffer_length = samples * sizeof(int16_t);
793                                         sound_buffer = (int16_t *)malloc(sound_buffer_length);
794                                 }
795                         }
796 //#endif
797                         int16_t *wav_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
798                         for(int i = 0, tmp_ptr = 0; i < samples; i++) {
799                                 int16_t sample[16];
800                                 GET_SAMPLE
801                                 int16_t sample_signal = sample[0];
802 //#ifdef DATAREC_SOUND
803                                 if(__DATAREC_SOUND) {
804                                         if(header.channels > 1) {
805 //#ifdef DATAREC_SOUND_LEFT
806                                                 if(__DATAREC_SOUND_LEFT) {
807                                                         sample_signal = sample[1];
808                                                         sound_buffer[i] = sample[0];
809                                                 } else {
810 //#else
811                                                         sound_buffer[i] = sample[1];
812                                                 }
813 //#endif
814                                         }
815                                 }
816 //#endif
817                                 wav_buffer[i] = sample_signal;
818                         }
819                         adjust_zero_position(wav_buffer, samples, header.sample_rate);
820                         
821                         // copy to dest buffer
822                         buffer = (uint8_t *)malloc(samples);
823                         bool prev_signal = false;
824                         int top_index = 0;
825                         int16_t max_sample = 0, min_sample = 0;
826                         
827                         for(int i = 0 /*, tmp_ptr = 0 */; i < samples; i++) {
828                                 int16_t sample_signal = wav_buffer[i];
829                                 bool signal = (sample_signal > 0);
830                                 
831                                 if(!prev_signal && signal) {
832                                         if(!(min_sample < -2048)) {
833                                                 for(int j = top_index; j < i; j++) {
834                                                         buffer[j] = 0;
835                                                 }
836                                         }
837                                 } else if(prev_signal && !signal) {
838                                         if(!(max_sample > 2048)) {
839                                                 for(int j = top_index; j < i; j++) {
840                                                         buffer[j] = 0;
841                                                 }
842                                         }
843                                 }
844                                 if(prev_signal != signal) {
845                                         top_index = i;
846                                         max_sample = min_sample = 0;
847                                 }
848                                 if(signal) {
849                                         if(max_sample < sample_signal) {
850                                                 max_sample = sample_signal;
851                                         }
852                                 } else {
853                                         if(min_sample > sample_signal) {
854                                                 min_sample = sample_signal;
855                                         }
856                                 }
857                                 buffer[i] = (signal ? 0xff : 0);
858                                 prev_signal = signal;
859                         }
860                         if(!prev_signal) {
861                                 if(!(min_sample < -2048)) {
862                                         for(int j = top_index; j < samples; j++) {
863                                                 buffer[j] = 0;
864                                         }
865                                 }
866                         } else {
867                                 if(!(max_sample > 2048)) {
868                                         for(int j = top_index; j < samples; j++) {
869                                                 buffer[j] = 0;
870                                         }
871                                 }
872                         }
873                         free(wav_buffer);
874                         
875                         loaded_samples = samples;
876                 } else {
877                         // load samples
878                         int16_t *wav_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
879                         for(int i = 0, tmp_ptr = 0; i < samples; i++) {
880                                 int16_t sample[16];
881                                 GET_SAMPLE
882                                 wav_buffer[i] = sample[0];
883                         }
884                         adjust_zero_position(wav_buffer, samples, header.sample_rate);
885                         
886                         // t=0 : get thresholds
887                         // t=1 : get number of samples
888                         // t=2 : load samples
889                         #define FREQ_SCALE 16
890                         int min_threshold = (int)(header.sample_rate * FREQ_SCALE / 2400.0 / 2.0 / 3.0 + 0.5);
891                         int max_threshold = (int)(header.sample_rate * FREQ_SCALE / 1200.0 / 2.0 * 3.0 + 0.5);
892                         int half_threshold, hi_count, lo_count;
893                         int *counts = (int *)calloc(max_threshold, sizeof(int));
894                         
895                         for(int t = 0; t < 3; t++) {
896                                 int count_positive = 0, count_negative = 0;
897                                 bool prev_signal = false;
898                                 
899                                 for(int i = 0; i < samples - 1; i++) {
900                                         int prev = wav_buffer[i], next = wav_buffer[i + 1];
901                                         double diff = (double)(next - prev) / FREQ_SCALE;
902                                         for(int j = 0; j < FREQ_SCALE; j++) {
903                                                 int sample = prev + (int)(diff * j + 0.5);
904                                                 bool signal = (sample > 0);
905                                                 
906                                                 if(!prev_signal && signal) {
907                                                         if(t == 0) {
908                                                                 if(count_positive < max_threshold && count_positive > min_threshold && count_negative > min_threshold) {
909                                                                         counts[count_positive]++;
910                                                                 }
911                                                         } else {
912                                                                 int count_p = count_positive / FREQ_SCALE;
913                                                                 int count_n = count_negative / FREQ_SCALE;
914                                                                 if(count_positive < max_threshold && count_positive > min_threshold && count_negative > min_threshold) {
915                                                                         count_p = (count_positive > half_threshold) ? hi_count : lo_count;
916                                                                         if(count_negative < max_threshold) {
917                                                                                 count_n = count_p;
918                                                                         }
919                                                                 }
920                                                                 if(buffer != NULL) {
921                                                                         for(int j = 0; j < count_p; j++) buffer[loaded_samples++] = 0xff;
922                                                                         for(int j = 0; j < count_n; j++) buffer[loaded_samples++] = 0x00;
923                                                                 } else {
924                                                                         loaded_samples += count_p + count_n;
925                                                                 }
926                                                         }
927                                                         count_positive = count_negative = 0;
928                                                 }
929                                                 if(signal) {
930                                                         count_positive++;
931                                                 } else {
932                                                         count_negative++;
933                                                 }
934                                                 prev_signal = signal;
935                                         }
936                                 }
937                                 if(t == 0) {
938                                         long sum_value = 0, sum_count = 0, half_tmp;
939                                         for(int i = 0; i < max_threshold; i++) {
940                                                 sum_value += i * counts[i];
941                                                 sum_count += counts[i];
942                                         }
943                                         // 1920 = 2400 * 0.6 + 1200 * 0.4
944                                         if(sum_count > 60 * 1920) {
945                                                 half_tmp = (int)((double)sum_value / (double)sum_count + 0.5);
946                                         } else {
947                                                 half_tmp = (int)(header.sample_rate * FREQ_SCALE / 1920.0 / 2.0 + 0.5);
948                                         }
949                                         
950                                         sum_value = sum_count = 0;
951                                         for(int i = 0; i < half_tmp; i++) {
952                                                 sum_value += i * counts[i];
953                                                 sum_count += counts[i];
954                                         }
955                                         double lo_tmp = (double)sum_value / (double)sum_count;
956                                         
957                                         sum_value = sum_count = 0;
958                                         for(int i = half_tmp; i < half_tmp * 2; i++) {
959                                                 sum_value += i * counts[i];
960                                                 sum_count += counts[i];
961                                         }
962                                         double hi_tmp = (double)sum_value / (double)sum_count;
963                                         
964                                         half_threshold = (int)((lo_tmp + hi_tmp) / 2 + 0.5);
965                                         min_threshold = (int)(2 * lo_tmp - half_threshold + 0.5);
966                                         max_threshold = (int)(2 * hi_tmp - half_threshold + 0.5);
967                                         lo_count = (int)(lo_tmp / FREQ_SCALE + 0.5);
968                                         hi_count = (int)(hi_tmp / FREQ_SCALE + 0.5);
969                                 } else {
970                                         int count_p = count_positive / FREQ_SCALE;
971                                         int count_n = count_negative / FREQ_SCALE;
972                                         if(count_positive < max_threshold && count_positive > min_threshold && count_negative > min_threshold) {
973                                                 count_p = (count_positive > half_threshold) ? hi_count : lo_count;
974                                                 if(count_negative < max_threshold) {
975                                                         count_n = count_p;
976                                                 }
977                                         }
978                                         if(buffer != NULL) {
979                                                 for(int j = 0; j < count_p; j++) buffer[loaded_samples++] = 0xff;
980                                                 for(int j = 0; j < count_n; j++) buffer[loaded_samples++] = 0x00;
981                                         } else {
982                                                 loaded_samples += count_p + count_n;
983                                         }
984                                 }
985                                 if(t == 1) {
986                                         buffer = (uint8_t *)malloc(loaded_samples);
987 //#ifdef DATAREC_SOUND
988                                         if(__DATAREC_SOUND) {
989                                                 if(header.channels > 1) {
990                                                         sound_buffer_length = loaded_samples * sizeof(int16_t);
991                                                         sound_buffer = (int16_t *)malloc(sound_buffer_length);
992                                                 }
993                                         }
994 //#endif
995                                         loaded_samples = 0;
996                                 }
997                         }
998                         free(counts);
999                         free(wav_buffer);
1000                 }
1001                 free(tmp_buffer);
1002         }
1003         return loaded_samples;
1004 }
1005
1006
1007 void DATAREC::save_wav_image()
1008 {
1009         // write samples remained in buffer
1010         if(buffer_ptr > 0) {
1011                 rec_fio->Fwrite(buffer, buffer_ptr, 1);
1012         }
1013         uint32_t length = rec_fio->Ftell();
1014         
1015         wav_header_t wav_header;
1016         wav_chunk_t wav_chunk;
1017         
1018         memcpy(wav_header.riff_chunk.id, "RIFF", 4);
1019         wav_header.riff_chunk.size = length - 8;
1020         memcpy(wav_header.wave, "WAVE", 4);
1021         memcpy(wav_header.fmt_chunk.id, "fmt ", 4);
1022         wav_header.fmt_chunk.size = 16;
1023         wav_header.format_id = 1;
1024         wav_header.channels = 1;
1025         wav_header.sample_rate = sample_rate;
1026         wav_header.data_speed = sample_rate;
1027         wav_header.block_size = 1;
1028         wav_header.sample_bits = 8;
1029         
1030         memcpy(wav_chunk.id, "data", 4);
1031         wav_chunk.size = length - sizeof(wav_header) - sizeof(wav_chunk);
1032         
1033         rec_fio->Fseek(0, FILEIO_SEEK_SET);
1034         rec_fio->Fwrite(&wav_header, sizeof(wav_header), 1);
1035         rec_fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
1036 }
1037
1038 // FUJITSU FM-7 series tape image
1039
1040 #define T77_PUT_SIGNAL(signal, len) { \
1041         int remain = len; \
1042         while(remain > 0) { \
1043                 if(buffer != NULL) { \
1044                         buffer[ptr++] = (signal) ? 0xff : 0x00; \
1045                 } else { \
1046                         ptr++; \
1047                 } \
1048                 remain--; \
1049         } \
1050 }
1051
1052 int DATAREC::load_t77_image()
1053 {
1054         sample_usec = 9;
1055         sample_rate = (int)(1000000.0 / sample_usec + 0.5);
1056         
1057         // load t77 file
1058         uint8_t tmpbuf[17];
1059         int ptr = 0;
1060         int file_size = (int)play_fio->FileLength();
1061         
1062         if(file_size <= 0) {
1063                 return 0; // over 2GB
1064         }
1065         play_fio->Fseek(0, FILEIO_SEEK_SET);
1066         play_fio->Fread(tmpbuf, 16, 1);
1067         tmpbuf[16] = '\0';
1068         if(strcmp((char *)tmpbuf, "XM7 TAPE IMAGE 0") != 0) {
1069                 return 0;
1070         }
1071         file_size -= 16;
1072         
1073         while(file_size > 0) {
1074                 uint16_t h = play_fio->FgetUint8();
1075                 uint16_t l = play_fio->FgetUint8();
1076                 uint16_t v = h * 256 + l;
1077                 
1078                 if((file_size -= 2) < 0) {
1079                         break;
1080                 }
1081                 if(v & 0x7fff) {
1082                         T77_PUT_SIGNAL((h & 0x80) != 0, v & 0x7fff);
1083                 }
1084         }
1085         return ptr;
1086 }
1087
1088 // SHARP X1 series tape image
1089
1090 /*
1091         new tape file format for t-tune (from tape_fmt.txt)
1092
1093         offset:size :
1094         00H   :  4  : \8e¯\95Ê\83C\83\93\83f\83b\83N\83X "TAPE"
1095         04H   : 17  : \83e\81[\83v\82Ì\96¼\91O(asciiz)
1096         15H   :  5  : \83\8a\83U\81[\83u
1097         1AH   :  1  : \83\89\83C\83g\83v\83\8d\83e\83N\83g\83m\83b\83`(00H=\8f\91\82«\8d\9e\82Ý\89Â\81A10H=\8f\91\82«\8d\9e\82Ý\8bÖ\8e~\81j
1098         1BH   :  1  : \8bL\98^\83t\83H\81[\83}\83b\83g\82Ì\8eí\97Þ(01H=\92è\91¬\83T\83\93\83v\83\8a\83\93\83O\95û\96@\81j
1099         1CH   :  4  : \83T\83\93\83v\83\8a\83\93\83O\8eü\94g\90\94(\82g\82\9a\92P\88Ê\81j
1100         20H   :  4  : \83e\81[\83v\83f\81[\83^\82Ì\83T\83C\83Y\81i\83r\83b\83g\92P\88Ê\81j
1101         24H   :  4  : \83e\81[\83v\82Ì\88Ê\92u\81i\83r\83b\83g\92P\88Ê\81j
1102         28H   :  ?  : \83e\81[\83v\82Ì\83f\81[\83^
1103 */
1104
1105 int DATAREC::load_tap_image()
1106 {
1107         // get file size
1108         play_fio->Fseek(0, FILEIO_SEEK_END);
1109         //int file_size = play_fio->Ftell();
1110         play_fio->Fseek(0, FILEIO_SEEK_SET);
1111         
1112         // check header
1113         uint8_t header[4];
1114         play_fio->Fread(header, 4, 1);
1115         
1116         if(header[0] == 'T' && header[1] == 'A' && header[2] == 'P' && header[3] == 'E') {
1117                 // skip name, reserved, write protect notch
1118                 play_fio->Fseek(17 + 5 + 1, FILEIO_SEEK_CUR);
1119                 // format
1120                 if(play_fio->Fgetc() != 0x01) {
1121                         // unknown data format
1122                         return 0;
1123                 }
1124                 // sample rate
1125                 play_fio->Fread(header, 4, 1);
1126                 sample_rate = header[0] | (header[1] << 8) | (header[2] << 16) | (header[3] << 24);
1127                 sample_usec = 1000000. / sample_rate;
1128                 // data length
1129                 play_fio->Fread(header, 4, 1);
1130                 // play position
1131                 play_fio->Fread(header, 4, 1);
1132         } else {
1133                 // sample rate
1134                 sample_rate = header[0] | (header[1] << 8) | (header[2] << 16) | (header[3] << 24);
1135                 sample_usec = 1000000. / sample_rate;
1136         }
1137         
1138         // load samples
1139         int ptr = 0, data;
1140         while((data = play_fio->Fgetc()) != EOF) {
1141                 for(int i = 0, bit = 0x80; i < 8; i++, bit >>= 1) {
1142                         if(buffer != NULL) {
1143                                 buffer[ptr] = ((data & bit) != 0) ? 255 : 0;
1144                         }
1145                         ptr++;
1146                 }
1147         }
1148         return ptr;
1149 }
1150
1151 // SHARP MZ series tape image
1152
1153 //#define MZT_PUT_SIGNAL(signal, len) { \
1154 //      int remain = len; \
1155 //      while(remain > 0) { \
1156 //              if(buffer != NULL) { \
1157 //                      buffer[ptr++] = ((signal != 0) ? 0x80 : 0) | min(remain, 0x7f); \
1158 //              } else { \
1159 //                      ptr++; \
1160 //              } \
1161 //              remain -= min(remain, 0x7f); \
1162 //      } \
1163 //}
1164
1165 #define MZT_PUT_SIGNAL(signal, len) { \
1166         int remain = len; \
1167         while(remain > 0) { \
1168                 if(buffer != NULL) { \
1169                         buffer[ptr++] = (signal != 0) ? 0xff : 0; \
1170                 } else { \
1171                         ptr++; \
1172                 } \
1173                 remain--; \
1174         } \
1175 }
1176
1177 #define MZT_PUT_BIT(bit, len) { \
1178         for(int l = 0; l < (len); l++) { \
1179                 if(bit) { \
1180                         MZT_PUT_SIGNAL(1, len1); \
1181                         MZT_PUT_SIGNAL(0, len2); \
1182                 } else { \
1183                         MZT_PUT_SIGNAL(1, len3); \
1184                         MZT_PUT_SIGNAL(0, len4); \
1185                 } \
1186         } \
1187 }
1188
1189 #define MZT_PUT_BYTE(byte) { \
1190         MZT_PUT_BIT(1, 1); \
1191         for(int j = 0; j < 8; j++) { \
1192                 if((byte) & (0x80 >> j)) { \
1193                         MZT_PUT_BIT(1, 1); \
1194                         count++; \
1195                 } else { \
1196                         MZT_PUT_BIT(0, 1); \
1197                 } \
1198         } \
1199 }
1200
1201 #define MZT_PUT_BLOCK(buf, len) { \
1202         int count = 0; \
1203         for(int i = 0; i < (len); i++) { \
1204                 MZT_PUT_BYTE((buf)[i]); \
1205         } \
1206         uint8_t hi = (count >> 8) & 0xff; \
1207         uint8_t lo = (count >> 0) & 0xff; \
1208         MZT_PUT_BYTE(hi); \
1209         MZT_PUT_BYTE(lo); \
1210 }
1211
1212 int DATAREC::load_mzt_image()
1213 {
1214         int len1, len2, len3, len4;
1215         sample_rate = 48000;
1216         sample_usec = 1000000. / sample_rate;
1217         if(__TYPE_MZ80B) {
1218                 len1 = len2 = (int)(120.0 / 16.0 * sample_rate / 22050.0 + 0.5);
1219                 len3 = len4 = (int)(60.0 / 16.0 * sample_rate / 22050.0 + 0.5);
1220         } else {
1221                 len1 = (int)(24.0 * sample_rate / 48000.0 + 0.5);
1222                 len2 = (int)(29.0 * sample_rate / 48000.0 + 0.5);
1223                 len3 = (int)(11.0 * sample_rate / 48000.0 + 0.5);
1224                 len4 = (int)(15.0 * sample_rate / 48000.0 + 0.5);
1225         }
1226         
1227         
1228         // get file size
1229         play_fio->Fseek(0, FILEIO_SEEK_END);
1230         int file_size = play_fio->Ftell();
1231         play_fio->Fseek(0, FILEIO_SEEK_SET);
1232         
1233         // load mzt file
1234         int ptr = 0;
1235         while(file_size > 128) {
1236                 // load header
1237                 uint8_t header[128], ram[0x20000];
1238                 play_fio->Fread(header, sizeof(header), 1);
1239                 file_size -= sizeof(header);
1240                 
1241                 uint16_t size = header[0x12] | (header[0x13] << 8);
1242                 uint16_t offs = header[0x14] | (header[0x15] << 8);
1243                 memset(ram, 0, sizeof(ram));
1244                 play_fio->Fread(ram + offs, size, 1);
1245                 file_size -= size;
1246 //#if defined(_MZ80K) || defined(_MZ700) || defined(_MZ1200) || defined(_MZ1500)
1247 #if 0
1248                 // apply mz700win patch
1249                 if(header[0x40] == 'P' && header[0x41] == 'A' && header[0x42] == 'T' && header[0x43] == ':') {
1250                         int patch_ofs = 0x44;
1251                         for(; patch_ofs < 0x80; ) {
1252                                 uint16_t patch_addr = header[patch_ofs] | (header[patch_ofs + 1] << 8);
1253                                 patch_ofs += 2;
1254                                 if(patch_addr == 0xffff) {
1255                                         break;
1256                                 }
1257                                 int patch_len = header[patch_ofs++];
1258                                 for(int i = 0; i < patch_len; i++) {
1259                                         ram[patch_addr + i] = header[patch_ofs++];
1260                                 }
1261                         }
1262                         for(int i = 0x40; i < patch_ofs; i++) {
1263                                 header[i] = 0;
1264                         }
1265                 }
1266 #endif
1267                 // output to buffer
1268                 MZT_PUT_SIGNAL(0, sample_rate);
1269 //#if defined(_MZ80B) || defined(_MZ2000) || defined(_MZ2200)
1270                 if(__TYPE_MZ80B) {
1271                 // Bin2Wav Ver 0.03
1272                         MZT_PUT_BIT(0, 22000);
1273                         MZT_PUT_BIT(1, 40);
1274                         MZT_PUT_BIT(0, 41);
1275                         MZT_PUT_BLOCK(header, 128);
1276                         MZT_PUT_BIT(1, 1);
1277                         MZT_PUT_SIGNAL(1, (int)(22.0 * sample_rate / 22050.0 + 0.5));
1278                         MZT_PUT_SIGNAL(0, (int)(22.0 * sample_rate / 22050.0 + 0.5));
1279                         MZT_PUT_SIGNAL(0, sample_rate);
1280                         MZT_PUT_BIT(0, 11000);
1281                         MZT_PUT_BIT(1, 20);
1282                         MZT_PUT_BIT(0, 21);
1283                         MZT_PUT_BLOCK(ram + offs, size);
1284                         MZT_PUT_BIT(1, 1);
1285                 } else {
1286 //#else
1287                         // format info written in \8e\8e\8c±\82É\8fo\82éX1
1288                         MZT_PUT_BIT(0, 10000);
1289                         MZT_PUT_BIT(1, 40);
1290                         MZT_PUT_BIT(0, 40);
1291                         MZT_PUT_BIT(1, 1);
1292                         MZT_PUT_BLOCK(header, 128);
1293                         MZT_PUT_BIT(1, 1);
1294                         MZT_PUT_BIT(0, 256);
1295                         MZT_PUT_BLOCK(header, 128);
1296                         MZT_PUT_BIT(1, 1);
1297                         MZT_PUT_SIGNAL(0, sample_rate);
1298                         MZT_PUT_BIT(0, 10000);
1299                         MZT_PUT_BIT(1, 20);
1300                         MZT_PUT_BIT(0, 20);
1301                         MZT_PUT_BIT(1, 1);
1302                         MZT_PUT_BLOCK(ram + offs, size);
1303                         MZT_PUT_BIT(1, 1);
1304                 }
1305 //#endif
1306         }
1307         return ptr;
1308 }
1309
1310 // NEC PC-6001/6601 series tape image
1311
1312 #define P6_PUT_1200HZ() { \
1313         if(buffer != NULL) { \
1314                 for(int p = 0; p < 20; p++) buffer[ptr++] = 0xff; \
1315                 for(int p = 0; p < 20; p++) buffer[ptr++] = 0x00; \
1316         } else { \
1317                 ptr += 40; \
1318         } \
1319 }
1320
1321 #define P6_PUT_2400HZ() { \
1322         if(buffer != NULL) { \
1323                 for(int p = 0; p < 10; p++) buffer[ptr++] = 0xff; \
1324                 for(int p = 0; p < 10; p++) buffer[ptr++] = 0x00; \
1325         } else { \
1326                 ptr += 20; \
1327         } \
1328 }
1329
1330 #define P6_PUT_2400HZ_X2() { \
1331         if(buffer != NULL) { \
1332                 for(int p = 0; p < 10; p++) buffer[ptr++] = 0xff; \
1333                 for(int p = 0; p < 10; p++) buffer[ptr++] = 0x00; \
1334                 for(int p = 0; p < 10; p++) buffer[ptr++] = 0xff; \
1335                 for(int p = 0; p < 10; p++) buffer[ptr++] = 0x00; \
1336         } else { \
1337                 ptr += 40; \
1338         } \
1339 }
1340
1341 int DATAREC::load_p6_image(bool is_p6t)
1342 {
1343         sample_rate = 48000;
1344         sample_usec = 1000000. / sample_rate;
1345         
1346         int ptr = 0, remain = 0x10000, data;
1347         if(is_p6t) {
1348                 // get info block offset
1349                 play_fio->Fseek(-4, FILEIO_SEEK_END);
1350                 int length = play_fio->FgetInt32();
1351                 // check info block
1352                 play_fio->Fseek(length, FILEIO_SEEK_SET);
1353                 char id_p = play_fio->Fgetc();
1354                 char id_6 = play_fio->Fgetc();
1355                 uint8_t ver = play_fio->FgetUint8();
1356                 if(id_p == 'P' && id_6 == '6' && ver == 2) {
1357                         uint8_t blocks = play_fio->FgetUint8();
1358                         if(blocks >= 1) {
1359                                 play_fio->FgetUint8();
1360                                 play_fio->FgetUint8();
1361                                 play_fio->FgetUint8();
1362                                 uint16_t cmd = play_fio->FgetUint16();
1363                                 play_fio->Fseek(cmd, FILEIO_SEEK_CUR);
1364                                 uint16_t exp = play_fio->FgetUint16();
1365                                 play_fio->Fseek(exp, FILEIO_SEEK_CUR);
1366                                 // check 1st data block
1367                                 char id_t = play_fio->Fgetc();
1368                                 char id_i = play_fio->Fgetc();
1369                                 if(id_t == 'T' && id_i == 'I') {
1370                                         play_fio->FgetUint8();
1371                                         play_fio->Fseek(16, FILEIO_SEEK_CUR);
1372                                         uint16_t baud = play_fio->FgetUint16(); // 600 or 1200
1373                                         sample_rate = sample_rate * baud / 1200;
1374                                         sample_usec = 1000000. / sample_rate;
1375                                 }
1376                         }
1377                         remain = min(length, 0x10000);
1378                 }
1379         }
1380         play_fio->Fseek(0, FILEIO_SEEK_SET);
1381         
1382         for(int i = 0; i < 9600; i++) {
1383                 P6_PUT_2400HZ();
1384         }
1385         for(int i = 0; i < 16; i++) {
1386                 data = play_fio->Fgetc();
1387                 P6_PUT_1200HZ();
1388                 for(int j = 0; j < 8; j++) {
1389                         if(data & (1 << j)) {
1390                                 P6_PUT_2400HZ_X2();
1391                         } else {
1392                                 P6_PUT_1200HZ();
1393                         }
1394                 }
1395                 P6_PUT_2400HZ_X2();
1396                 P6_PUT_2400HZ_X2();
1397                 P6_PUT_2400HZ_X2();
1398                 remain--;
1399         }
1400 //      for(int i = 0; i < 1280; i++) {
1401         for(int i = 0; i < 2400; i++) {
1402                 P6_PUT_2400HZ();
1403         }
1404         while((data = play_fio->Fgetc()) != EOF && remain > 0) {
1405                 P6_PUT_1200HZ();
1406                 for(int j = 0; j < 8; j++) {
1407                         if(data & (1 << j)) {
1408                                 P6_PUT_2400HZ_X2();
1409                         } else {
1410                                 P6_PUT_1200HZ();
1411                         }
1412                 }
1413                 P6_PUT_2400HZ_X2();
1414                 P6_PUT_2400HZ_X2();
1415                 P6_PUT_2400HZ_X2();
1416                 remain--;
1417         }
1418 #if 1
1419         for(int i = 0; i < 16; i++) {
1420                 P6_PUT_1200HZ();
1421                 for(int j = 0; j < 8; j++) {
1422                         P6_PUT_1200HZ();
1423                 }
1424                 P6_PUT_2400HZ_X2();
1425                 P6_PUT_2400HZ_X2();
1426                 P6_PUT_2400HZ_X2();
1427         }
1428 #endif
1429         return ptr;
1430 }
1431
1432 // HITACH BASIC Master Jr tape image (bm2)
1433
1434 #define BMJR_PUT_1200HZ_X4() { \
1435         if(buffer != NULL) { \
1436                 for(int k = 0; k < 4; k++) { \
1437                         for(int p = 0; p < 20; p++) buffer[ptr++] = 0xff; \
1438                         for(int p = 0; p < 20; p++) buffer[ptr++] = 0x00; \
1439                 } \
1440         } else { \
1441                 ptr += 40 * 4; \
1442         } \
1443 }
1444
1445 #define BMJR_PUT_2400HZ_X8() { \
1446         if(buffer != NULL) { \
1447                 for(int k = 0; k < 8; k++) { \
1448                         for(int p = 0; p < 10; p++) buffer[ptr++] = 0xff; \
1449                         for(int p = 0; p < 10; p++) buffer[ptr++] = 0x00; \
1450                 } \
1451         } else { \
1452                 ptr += 20 * 8; \
1453         } \
1454 }
1455
1456 int DATAREC::load_bmjr_image()
1457 {
1458         sample_rate = 48000;
1459         sample_usec = 1000000. / sample_rate;
1460         
1461         play_fio->Fseek(0, FILEIO_SEEK_SET);
1462         
1463         int ptr = 0, data;
1464         while((data = play_fio->Fgetc()) != EOF) {
1465                 // start bit = 0
1466                 BMJR_PUT_1200HZ_X4();
1467                 // data bits
1468                 for(int j = 0; j < 8; j++) {
1469                         if(data & (1 << j)) {
1470                                 BMJR_PUT_2400HZ_X8();
1471                         } else {
1472                                 BMJR_PUT_1200HZ_X4();
1473                         }
1474                 }
1475                 // stop bits = 1,1
1476                 BMJR_PUT_2400HZ_X8();
1477                 BMJR_PUT_2400HZ_X8();
1478         }
1479         return ptr;
1480 }
1481
1482 // standard cas image for my emulator
1483
1484 static const uint8_t msx_cas_header[8] = {0x1f, 0xa6, 0xde, 0xba, 0xcc, 0x13, 0x7d, 0x74};
1485
1486 int DATAREC::load_cas_image()
1487 {
1488         sample_rate = 48000;
1489         sample_usec = 1000000. / sample_rate;
1490         
1491         // SORD m5 or NEC PC-6001 series cas image ?
1492         static const uint8_t momomomomomo[6] = {0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3};
1493         uint8_t tmp_header[8];
1494         play_fio->Fseek(0, FILEIO_SEEK_SET);
1495         play_fio->Fread(tmp_header, sizeof(tmp_header), 1);
1496         
1497         if(memcmp(tmp_header, "SORDM5", 6) == 0) {
1498                 return load_m5_cas_image();
1499         } else if(memcmp(tmp_header, msx_cas_header, 8) == 0) {
1500                 return load_msx_cas_image();
1501         } else if(memcmp(tmp_header, momomomomomo, 6) == 0) {
1502                 return load_p6_image(false);
1503         }
1504         
1505         // this is the standard cas image for my emulator
1506         play_fio->Fseek(0, FILEIO_SEEK_SET);
1507         int ptr = 0, data;
1508         while((data = play_fio->Fgetc()) != EOF) {
1509                 for(int i = 0; i < (data & 0x7f); i++) {
1510                         if(buffer != NULL) {
1511                                 buffer[ptr] = (data & 0x80) ? 255 : 0;
1512                         }
1513                         ptr++;
1514                 }
1515         }
1516         return ptr;
1517 }
1518
1519 // SORD M5 tape image
1520
1521 #define M5_PUT_BIT(val, len) { \
1522         int remain = len; \
1523         while(remain > 0) { \
1524                 if(buffer != NULL) { \
1525                         buffer[ptr] = val ? 0 : 0xff; \
1526                 } \
1527                 ptr++; \
1528                 remain--; \
1529         } \
1530 }
1531
1532 #define M5_PUT_BYTE(data) { \
1533         for(int j = 0; j < 10; j++) { \
1534                 int bit = (j == 0) ? 1 : (j == 1) ? 0 : ((data >> (j - 2)) & 1); \
1535                 if(bit) { \
1536                         M5_PUT_BIT(0xff, 8); \
1537                         M5_PUT_BIT(0x00, 7); \
1538                 } else { \
1539                         M5_PUT_BIT(0xff, 16); \
1540                         M5_PUT_BIT(0x00, 14); \
1541                 } \
1542         } \
1543 }
1544
1545 int DATAREC::load_m5_cas_image()
1546 {
1547         play_fio->Fseek(16, FILEIO_SEEK_SET);
1548         int ptr = 0, block_type;
1549         
1550         while((block_type = play_fio->Fgetc()) != EOF) {
1551                 if(block_type != 'H' && block_type != 'D') {
1552                         return 0;
1553                 }
1554                 int block_size = play_fio->Fgetc();
1555                 
1556                 if(block_type == 'H') {
1557                         M5_PUT_BIT(0x00, 1);
1558                 }
1559                 for(int i = 0; i < (block_type == 'H' ? 945 : 59); i++) {
1560                         M5_PUT_BIT(0xff, 8);
1561                         M5_PUT_BIT(0x00, 7);
1562                 }
1563                 M5_PUT_BYTE(block_type);
1564                 M5_PUT_BYTE(block_size);
1565                 
1566                 for(int i = 0; i < ((block_size == 0) ? 0x101 : (block_size + 1)); i++) {
1567                         uint8_t data = play_fio->Fgetc();
1568                         M5_PUT_BYTE(data);
1569                 }
1570                 M5_PUT_BIT(0xff, 8);
1571                 M5_PUT_BIT(0x00, 7);
1572         }
1573         M5_PUT_BIT(0x00, 1);
1574         return ptr;
1575 }
1576
1577 // ASCII MSX tape image (fMSX)
1578 // MAME/MESS /src/lib/formats/fmsx_cas.c by Mr.Sean Young
1579
1580 #define CAS_PERIOD              (16)
1581 #define CAS_HEADER_PERIODS      (4000)
1582 #define CAS_EMPTY_PERIODS       (1000)
1583
1584 int DATAREC::load_msx_cas_image()
1585 {
1586         sample_rate = 22050;
1587         sample_usec = 1000000. / sample_rate;
1588         
1589         play_fio->Fseek(0, FILEIO_SEEK_END);
1590         int cas_size = play_fio->Ftell();
1591         uint8_t *bytes = (uint8_t *)malloc(cas_size);
1592         play_fio->Fseek(0, FILEIO_SEEK_SET);
1593         play_fio->Fread(bytes, cas_size, 1);
1594         
1595         int cas_pos, bit, state = 1, samples_pos, size, n, i, p;
1596         
1597         cas_pos = 0;
1598         samples_pos = 0;
1599         
1600         while(/*samples_pos < sample_count && */cas_pos < cas_size) {
1601                 /* Check if we need to output a header */
1602                 if(cas_pos + 8 < cas_size) {
1603                         if(!memcmp( bytes + cas_pos, msx_cas_header, 8)) {
1604                                 /* Write CAS_EMPTY_PERIODS of silence */
1605                                 n = CAS_EMPTY_PERIODS * CAS_PERIOD;
1606                                 while(n--) {
1607                                         if(buffer != NULL) {
1608                                                 buffer[samples_pos] = 0;
1609                                         }
1610                                         samples_pos++;
1611                                 }
1612                                 /* Write CAS_HEADER_PERIODS of header (high frequency) */
1613                                 for(i = 0; i < CAS_HEADER_PERIODS * 4 ; i++) {
1614                                         for(n = 0; n < CAS_PERIOD / 4; n++) {
1615                                                 if(buffer != NULL) {
1616                                                         buffer[samples_pos + n] = (state ? 0xff : 0);
1617                                                 }
1618                                         }
1619                                         samples_pos += CAS_PERIOD / 4 ;
1620                                         state = !state;
1621                                 }
1622                                 cas_pos += 8;
1623                         }
1624                 }
1625                 
1626                 for(i = 0; i <= 11; i++) {
1627                         if(i == 0) {
1628                                 bit = 0;
1629                         } else if(i < 9) {
1630                                 bit = (bytes[cas_pos] & (1 << (i - 1) ) );
1631                         } else {
1632                                 bit = 1;
1633                         }
1634                         
1635                         /* write this one bit */
1636                         for(n = 0; n < (bit ? 4 : 2); n++) {
1637                                 size = (bit ? CAS_PERIOD / 4 : CAS_PERIOD / 2);
1638                                 for(p = 0; p < size; p++) {
1639                                         if(buffer != NULL) {
1640                                                 buffer[samples_pos + p] = (state ? 0xff : 0);
1641                                         }
1642                                 }
1643                                 state = !state;
1644                                 samples_pos += size;
1645                         }
1646                 }
1647                 cas_pos++;
1648         }
1649         free(bytes);
1650         return samples_pos;
1651 }
1652
1653 void DATAREC::mix(int32_t* buffer, int cnt)
1654 {
1655         int32_t* buffer_tmp = buffer;
1656         
1657         if(config.sound_play_tape && pcm_changed && remote && (play || rec) && ff_rew == 0) {
1658                 bool signal = ((play && in_signal) || (rec && out_signal));
1659                 if(signal) {
1660                         pcm_positive_clocks += get_passed_clock(pcm_prev_clock);
1661                 } else {
1662                         pcm_negative_clocks += get_passed_clock(pcm_prev_clock);
1663                 }
1664                 int clocks = pcm_positive_clocks + pcm_negative_clocks;
1665                 int sample = clocks ? (pcm_max_vol * pcm_positive_clocks - pcm_max_vol * pcm_negative_clocks) / clocks : signal ? pcm_max_vol : -pcm_max_vol;
1666                 
1667                 pcm_last_vol_l = apply_volume(sample, pcm_volume_l);
1668                 pcm_last_vol_r = apply_volume(sample, pcm_volume_r);
1669                 
1670                 for(int i = 0; i < cnt; i++) {
1671                         *buffer++ += pcm_last_vol_l; // L
1672                         *buffer++ += pcm_last_vol_r; // R
1673                 }
1674         } else if(pcm_last_vol_l || pcm_last_vol_r) {
1675                 // suppress petite noise when go to mute
1676                 for(int i = 0; i < cnt; i++) {
1677                         *buffer++ += pcm_last_vol_l; // L
1678                         *buffer++ += pcm_last_vol_r; // R
1679                         
1680                         if(pcm_last_vol_l > 0) {
1681                                 pcm_last_vol_l--;
1682                         } else if(pcm_last_vol_l < 0) {
1683                                 pcm_last_vol_l++;
1684                         }
1685                         if(pcm_last_vol_r > 0) {
1686                                 pcm_last_vol_r--;
1687                         } else if(pcm_last_vol_r < 0) {
1688                                 pcm_last_vol_r++;
1689                         }
1690                 }
1691         }
1692         pcm_prev_clock = get_current_clock();
1693         pcm_positive_clocks = pcm_negative_clocks = 0;
1694         
1695 //#ifdef DATAREC_SOUND
1696         if(__DATAREC_SOUND) {
1697                 if(/*config.sound_play_tape && */remote && play && ff_rew == 0) {
1698                         sound_last_vol_l = apply_volume(sound_sample, sound_volume_l);
1699                         sound_last_vol_r = apply_volume(sound_sample, sound_volume_r);
1700                         buffer = buffer_tmp; // restore
1701                         for(int i = 0; i < cnt; i++) {
1702                                 *buffer += sound_last_vol_l; // L
1703                                 *buffer += sound_last_vol_r; // R
1704                         }
1705                 } else if(sound_last_vol_l || sound_last_vol_r) {
1706                         // suppress petite noise when go to mute
1707                         for(int i = 0; i < cnt; i++) {
1708                                 *buffer++ += sound_last_vol_l; // L
1709                                 *buffer++ += sound_last_vol_r; // R
1710                                 
1711                                 if(sound_last_vol_l > 0) {
1712                                         sound_last_vol_l--;
1713                                 } else if(sound_last_vol_l < 0) {
1714                                         sound_last_vol_l++;
1715                                 }
1716                                 if(sound_last_vol_r > 0) {
1717                                         sound_last_vol_r--;
1718                                 } else if(sound_last_vol_r < 0) {
1719                                         sound_last_vol_r++;
1720                                 }
1721                         }
1722                 }
1723         }
1724 //#endif
1725 }
1726
1727 void DATAREC::set_volume(int ch, int decibel_l, int decibel_r)
1728 {
1729         if(ch == 0) {
1730                 pcm_volume_l = decibel_to_volume(decibel_l);
1731                 pcm_volume_r = decibel_to_volume(decibel_r);
1732 //#ifdef DATAREC_SOUND
1733         } else if(ch == 1) {
1734                 if(__DATAREC_SOUND) {
1735                         sound_volume_l = decibel_to_volume(decibel_l);
1736                         sound_volume_r = decibel_to_volume(decibel_r);
1737                 }
1738 //#endif
1739         }
1740 }
1741
1742 double DATAREC::get_ave_hi_freq()
1743 {
1744         if(ave_hi_freq == 0 && play && is_wav) {
1745                 bool prev_signal = false;
1746                 int positive = 0, negative = 0, pulse_count = 0;
1747                 double sum = 0;
1748                 double base_usec = 1000000.0 / (double)sample_rate;
1749                 
1750                 for(int i=0; i < buffer_length; i++) {
1751                         bool next_signal = ((buffer[i] & 0x80) != 0);
1752                         if(!prev_signal && next_signal) {
1753                                 double usec = base_usec * (positive + negative);
1754                                 if(316.667 <= usec && usec < 516.667) {
1755                                         sum += usec;
1756                                         pulse_count += 1;
1757                                 } else if(633.333 <= usec && usec < 1033.333) {
1758                                         sum += usec;
1759                                         pulse_count += 2;
1760                                 }
1761                                 positive = negative = 0;
1762                         }
1763                         if(next_signal) {
1764                                 positive++;
1765                         } else {
1766                                 negative++;
1767                         }
1768                         prev_signal = next_signal;
1769                 }
1770                 if(sum != 0 && pulse_count != 0) {
1771                         double average = sum / pulse_count;
1772                         ave_hi_freq = 1000000.0 / average;
1773                 }
1774         }
1775         if(ave_hi_freq == 0) {
1776                 ave_hi_freq = 2400;
1777         }
1778         return ave_hi_freq;
1779 }
1780
1781 void DATAREC::update_config()
1782 {
1783         if(d_noise_play != NULL) {
1784                 d_noise_play->set_mute(!config.sound_noise_cmt);
1785         }
1786         if(d_noise_stop != NULL) {
1787                 d_noise_stop->set_mute(!config.sound_noise_cmt);
1788         }
1789         if(d_noise_fast != NULL) {
1790                 d_noise_fast->set_mute(!config.sound_noise_cmt);
1791         }
1792         update_realtime_render();
1793 }
1794
1795 #define STATE_VERSION   8
1796
1797 void DATAREC::save_state(FILEIO* state_fio)
1798 {
1799         state_fio->FputUint32(STATE_VERSION);
1800         state_fio->FputInt32(this_device_id);
1801         
1802         state_fio->FputBool(play);
1803         state_fio->FputBool(rec);
1804         state_fio->FputBool(remote);
1805         state_fio->FputBool(trigger);
1806         state_fio->Fwrite(rec_file_path, sizeof(rec_file_path), 1);
1807         if(rec && rec_fio->IsOpened()) {
1808                 int length_tmp = (int)rec_fio->Ftell();
1809                 rec_fio->Fseek(0, FILEIO_SEEK_SET);
1810                 state_fio->FputInt32(length_tmp);
1811                 while(length_tmp != 0) {
1812                         uint8_t buffer_tmp[1024];
1813                         int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
1814                         rec_fio->Fread(buffer_tmp, length_rw, 1);
1815                         state_fio->Fwrite(buffer_tmp, length_rw, 1);
1816                         length_tmp -= length_rw;
1817                 }
1818         } else {
1819                 state_fio->FputInt32(0);
1820         }
1821         state_fio->FputInt32(ff_rew);
1822         state_fio->FputBool(in_signal);
1823         state_fio->FputBool(out_signal);
1824         state_fio->FputUint32(prev_clock);
1825         state_fio->FputInt32(positive_clocks);
1826         state_fio->FputInt32(negative_clocks);
1827         state_fio->FputInt32(signal_changed);
1828         state_fio->FputInt32(register_id);
1829         state_fio->FputBool(realtime);
1830         state_fio->FputInt32(sample_rate);
1831         state_fio->FputDouble(sample_usec);
1832         state_fio->FputInt32(buffer_ptr);
1833         if(buffer) {
1834                 state_fio->FputInt32(buffer_length);
1835                 state_fio->Fwrite(buffer, buffer_length, 1);
1836         } else {
1837                 state_fio->FputInt32(0);
1838         }
1839         if(buffer_bak) {
1840                 state_fio->FputInt32(buffer_length);
1841                 state_fio->Fwrite(buffer_bak, buffer_length, 1);
1842         } else {
1843                 state_fio->FputInt32(0);
1844         }
1845 //#ifdef DATAREC_SOUND
1846         if(__DATAREC_SOUND) {
1847                 if(sound_buffer) {
1848                         state_fio->FputInt32(sound_buffer_length);
1849                         state_fio->Fwrite(sound_buffer, sound_buffer_length, 1);
1850                 } else {
1851                         state_fio->FputInt32(0);
1852                 }
1853                 state_fio->FputInt16(sound_sample);
1854         }
1855 //#endif
1856         state_fio->FputBool(is_wav);
1857         state_fio->FputBool(is_tap);
1858         state_fio->FputBool(is_t77);
1859         if(apss_buffer) {
1860                 state_fio->FputInt32(apss_buffer_length);
1861                 state_fio->Fwrite(apss_buffer, apss_buffer_length, 1);
1862         } else {
1863                 state_fio->FputInt32(0);
1864         }
1865         state_fio->FputInt32(apss_ptr);
1866         state_fio->FputInt32(apss_count);
1867         state_fio->FputInt32(apss_remain);
1868         state_fio->FputBool(apss_signals);
1869         state_fio->FputInt32(pcm_changed);
1870         state_fio->FputUint32(pcm_prev_clock);
1871         state_fio->FputInt32(pcm_positive_clocks);
1872         state_fio->FputInt32(pcm_negative_clocks);
1873 }
1874
1875 bool DATAREC::load_state(FILEIO* state_fio)
1876 {
1877         close_file();
1878         
1879         if(state_fio->FgetUint32() != STATE_VERSION) {
1880                 return false;
1881         }
1882         if(state_fio->FgetInt32() != this_device_id) {
1883                 return false;
1884         }
1885         play = state_fio->FgetBool();
1886         rec = state_fio->FgetBool();
1887         remote = state_fio->FgetBool();
1888         trigger = state_fio->FgetBool();
1889         state_fio->Fread(rec_file_path, sizeof(rec_file_path), 1);
1890         int length_tmp = state_fio->FgetInt32();
1891         if(rec) {
1892                 rec_fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
1893                 while(length_tmp != 0) {
1894                         uint8_t buffer_tmp[1024];
1895                         int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
1896                         state_fio->Fread(buffer_tmp, length_rw, 1);
1897                         if(rec_fio->IsOpened()) {
1898                                 rec_fio->Fwrite(buffer_tmp, length_rw, 1);
1899                         }
1900                         length_tmp -= length_rw;
1901                 }
1902         }
1903         ff_rew = state_fio->FgetInt32();
1904         in_signal = state_fio->FgetBool();
1905         out_signal = state_fio->FgetBool();
1906         prev_clock = state_fio->FgetUint32();
1907         positive_clocks = state_fio->FgetInt32();
1908         negative_clocks = state_fio->FgetInt32();
1909         signal_changed = state_fio->FgetInt32();
1910         register_id = state_fio->FgetInt32();
1911         realtime = state_fio->FgetBool();
1912         sample_rate = state_fio->FgetInt32();
1913         sample_usec = state_fio->FgetDouble();
1914         buffer_ptr = state_fio->FgetInt32();
1915         if((buffer_length = state_fio->FgetInt32()) != 0) {
1916                 buffer = (uint8_t *)malloc(buffer_length);
1917                 state_fio->Fread(buffer, buffer_length, 1);
1918         }
1919         if((length_tmp = state_fio->FgetInt32()) != 0) {
1920                 buffer_bak = (uint8_t *)malloc(length_tmp);
1921                 state_fio->Fread(buffer_bak, length_tmp, 1);
1922         }
1923 //#ifdef DATAREC_SOUND
1924         if(__DATAREC_SOUND) {
1925                 if((sound_buffer_length = state_fio->FgetInt32()) != 0) {
1926                         sound_buffer = (int16_t *)malloc(sound_buffer_length);
1927                         state_fio->Fread(sound_buffer, sound_buffer_length, 1);
1928                 }
1929                 sound_sample = state_fio->FgetInt16();
1930         }
1931 //#endif
1932         is_wav = state_fio->FgetBool();
1933         is_tap = state_fio->FgetBool();
1934         is_t77 = state_fio->FgetBool();
1935         if((apss_buffer_length = state_fio->FgetInt32()) != 0) {
1936                 apss_buffer = (bool *)malloc(apss_buffer_length);
1937                 state_fio->Fread(apss_buffer, apss_buffer_length, 1);
1938         }
1939         apss_ptr = state_fio->FgetInt32();
1940         apss_count = state_fio->FgetInt32();
1941         apss_remain = state_fio->FgetInt32();
1942         apss_signals = state_fio->FgetBool();
1943         pcm_changed = state_fio->FgetInt32();
1944         pcm_prev_clock = state_fio->FgetUint32();
1945         pcm_positive_clocks = state_fio->FgetInt32();
1946         pcm_negative_clocks = state_fio->FgetInt32();
1947         
1948         // post process
1949         pcm_last_vol_l = pcm_last_vol_r = 0;
1950 //#ifdef DATAREC_SOUND
1951         sound_last_vol_l = sound_last_vol_r = 0;
1952 //#endif
1953         return true;
1954 }
1955