comparison ym2612.c @ 1692:5dacaef602a7 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 05 Jan 2019 00:58:08 -0800
parents 804f13c090b4
children 5278b6e44fc1
comparison
equal deleted inserted replaced
1504:95b3a1a8b26c 1692:5dacaef602a7
114 wave_finalize(log_context->channels[i].logfile); 114 wave_finalize(log_context->channels[i].logfile);
115 } 115 }
116 } 116 }
117 log_context = NULL; 117 log_context = NULL;
118 } 118 }
119 #define BUFFER_INC_RES 0x40000000UL
120 119
121 void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock) 120 void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock)
122 { 121 {
123 uint64_t old_inc = context->buffer_inc; 122 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS);
124 context->buffer_inc = ((BUFFER_INC_RES * (uint64_t)context->sample_rate) / (uint64_t)master_clock) * (uint64_t)context->clock_inc * NUM_OPERATORS;
125 } 123 }
126 124
127 #ifdef __ANDROID__ 125 #ifdef __ANDROID__
128 #define log2(x) (log(x)/log(2)) 126 #define log2(x) (log(x)/log(2))
129 #endif 127 #endif
135 void ym_reset(ym2612_context *context) 133 void ym_reset(ym2612_context *context)
136 { 134 {
137 memset(context->part1_regs, 0, sizeof(context->part1_regs)); 135 memset(context->part1_regs, 0, sizeof(context->part1_regs));
138 memset(context->part2_regs, 0, sizeof(context->part2_regs)); 136 memset(context->part2_regs, 0, sizeof(context->part2_regs));
139 memset(context->operators, 0, sizeof(context->operators)); 137 memset(context->operators, 0, sizeof(context->operators));
138 FILE* savedlogs[NUM_CHANNELS];
139 for (int i = 0; i < NUM_CHANNELS; i++)
140 {
141 savedlogs[i] = context->channels[i].logfile;
142 }
140 memset(context->channels, 0, sizeof(context->channels)); 143 memset(context->channels, 0, sizeof(context->channels));
141 memset(context->ch3_supp, 0, sizeof(context->ch3_supp)); 144 memset(context->ch3_supp, 0, sizeof(context->ch3_supp));
142 context->selected_reg = 0; 145 context->selected_reg = 0;
143 context->csm_keyon = 0; 146 context->csm_keyon = 0;
144 context->ch3_mode = 0; 147 context->ch3_mode = 0;
153 //TODO: Reset LFO state 156 //TODO: Reset LFO state
154 157
155 //some games seem to expect that the LR flags start out as 1 158 //some games seem to expect that the LR flags start out as 1
156 for (int i = 0; i < NUM_CHANNELS; i++) { 159 for (int i = 0; i < NUM_CHANNELS; i++) {
157 context->channels[i].lr = 0xC0; 160 context->channels[i].lr = 0xC0;
161 context->channels[i].logfile = savedlogs[i];
158 } 162 }
159 context->write_cycle = CYCLE_NEVER; 163 context->write_cycle = CYCLE_NEVER;
160 for (int i = 0; i < NUM_OPERATORS; i++) { 164 for (int i = 0; i < NUM_OPERATORS; i++) {
161 context->operators[i].envelope = MAX_ENVELOPE; 165 context->operators[i].envelope = MAX_ENVELOPE;
162 context->operators[i].env_phase = PHASE_RELEASE; 166 context->operators[i].env_phase = PHASE_RELEASE;
163 } 167 }
164 } 168 }
165 169
166 void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clock, uint32_t clock_div, uint32_t sample_limit, uint32_t options, uint32_t lowpass_cutoff) 170 void ym_init(ym2612_context * context, uint32_t master_clock, uint32_t clock_div, uint32_t options)
167 { 171 {
168 static uint8_t registered_finalize; 172 static uint8_t registered_finalize;
169 dfopen(debug_file, "ym_debug.txt", "w"); 173 dfopen(debug_file, "ym_debug.txt", "w");
170 memset(context, 0, sizeof(*context)); 174 memset(context, 0, sizeof(*context));
171 context->audio_buffer = malloc(sizeof(*context->audio_buffer) * sample_limit*2);
172 context->back_buffer = malloc(sizeof(*context->audio_buffer) * sample_limit*2);
173 context->sample_rate = sample_rate;
174 context->clock_inc = clock_div * 6; 175 context->clock_inc = clock_div * 6;
175 ym_adjust_master_clock(context, master_clock); 176 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2);
176
177 double rc = (1.0 / (double)lowpass_cutoff) / (2.0 * M_PI);
178 double dt = 1.0 / ((double)master_clock / (double)(context->clock_inc * NUM_OPERATORS));
179 double alpha = dt / (dt + rc);
180 context->lowpass_alpha = (int32_t)(((double)0x10000) * alpha);
181
182 context->sample_limit = sample_limit*2;
183 177
184 //some games seem to expect that the LR flags start out as 1 178 //some games seem to expect that the LR flags start out as 1
185 for (int i = 0; i < NUM_CHANNELS; i++) { 179 for (int i = 0; i < NUM_CHANNELS; i++) {
186 if (options & YM_OPT_WAVE_LOG) { 180 if (options & YM_OPT_WAVE_LOG) {
187 char fname[64]; 181 char fname[64];
189 FILE * f = context->channels[i].logfile = fopen(fname, "wb"); 183 FILE * f = context->channels[i].logfile = fopen(fname, "wb");
190 if (!f) { 184 if (!f) {
191 fprintf(stderr, "Failed to open WAVE log file %s for writing\n", fname); 185 fprintf(stderr, "Failed to open WAVE log file %s for writing\n", fname);
192 continue; 186 continue;
193 } 187 }
194 if (!wave_init(f, sample_rate, 16, 1)) { 188 if (!wave_init(f, master_clock / (context->clock_inc * NUM_OPERATORS), 16, 1)) {
195 fclose(f); 189 fclose(f);
196 context->channels[i].logfile = NULL; 190 context->channels[i].logfile = NULL;
197 } 191 }
198 } 192 }
199 } 193 }
264 ym_reset(context); 258 ym_reset(context);
265 } 259 }
266 260
267 void ym_free(ym2612_context *context) 261 void ym_free(ym2612_context *context)
268 { 262 {
263 render_free_source(context->audio);
269 if (context == log_context) { 264 if (context == log_context) {
270 ym_finalize_log(); 265 ym_finalize_log();
271 } 266 }
272 free(context->audio_buffer);
273 //TODO: Figure out how to make this 100% safe
274 //audio thread could still be using this
275 free(context->back_buffer);
276 free(context); 267 free(context);
277 } 268 }
278 269
279 #define YM_VOLUME_MULTIPLIER 2 270 #define YM_VOLUME_MULTIPLIER 2
280 #define YM_VOLUME_DIVIDER 3 271 #define YM_VOLUME_DIVIDER 3
473 ym_operator * operator = context->operators + op; 464 ym_operator * operator = context->operators + op;
474 ym_channel * chan = context->channels + channel; 465 ym_channel * chan = context->channels + channel;
475 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; 466 uint16_t phase = operator->phase_counter >> 10 & 0x3FF;
476 operator->phase_counter += ym_calc_phase_inc(context, operator, context->current_op); 467 operator->phase_counter += ym_calc_phase_inc(context, operator, context->current_op);
477 int16_t mod = 0; 468 int16_t mod = 0;
478 switch (op % 4) 469 if (op & 3) {
479 { 470 if (operator->mod_src[0]) {
480 case 0://Operator 1 471 mod = *operator->mod_src[0];
472 if (operator->mod_src[1]) {
473 mod += *
474 operator->mod_src[1];
475 }
476 mod >>= YM_MOD_SHIFT;
477 }
478 } else {
481 if (chan->feedback) { 479 if (chan->feedback) {
482 mod = (chan->op1_old + operator->output) >> (10-chan->feedback); 480 mod = (chan->op1_old + operator->output) >> (10-chan->feedback);
483 } 481 }
484 break;
485 case 1://Operator 3
486 switch(chan->algorithm)
487 {
488 case 0:
489 case 2:
490 //modulate by operator 2
491 mod = context->operators[op+1].output >> YM_MOD_SHIFT;
492 break;
493 case 1:
494 //modulate by operator 1+2
495 mod = (context->operators[op-1].output + context->operators[op+1].output) >> YM_MOD_SHIFT;
496 break;
497 case 5:
498 //modulate by operator 1
499 mod = context->operators[op-1].output >> YM_MOD_SHIFT;
500 }
501 break;
502 case 2://Operator 2
503 if (chan->algorithm != 1 && chan->algorithm != 2 && chan->algorithm != 7) {
504 //modulate by Operator 1
505 mod = context->operators[op-2].output >> YM_MOD_SHIFT;
506 }
507 break;
508 case 3://Operator 4
509 switch(chan->algorithm)
510 {
511 case 0:
512 case 1:
513 case 4:
514 //modulate by operator 3
515 mod = context->operators[op-2].output >> YM_MOD_SHIFT;
516 break;
517 case 2:
518 //modulate by operator 1+3
519 mod = (context->operators[op-3].output + context->operators[op-2].output) >> YM_MOD_SHIFT;
520 break;
521 case 3:
522 //modulate by operator 2+3
523 mod = (context->operators[op-1].output + context->operators[op-2].output) >> YM_MOD_SHIFT;
524 break;
525 case 5:
526 //modulate by operator 1
527 mod = context->operators[op-3].output >> YM_MOD_SHIFT;
528 break;
529 }
530 break;
531 } 482 }
532 uint16_t env = operator->envelope; 483 uint16_t env = operator->envelope;
533 if (operator->ssg) { 484 if (operator->ssg) {
534 if (env >= SSG_CENTER) { 485 if (env >= SSG_CENTER) {
535 if (operator->ssg & SSG_ALTERNATE) { 486 if (operator->ssg & SSG_ALTERNATE) {
605 } 556 }
606 context->current_op++; 557 context->current_op++;
607 if (context->current_op == NUM_OPERATORS) { 558 if (context->current_op == NUM_OPERATORS) {
608 context->current_op = 0; 559 context->current_op = 0;
609 560
610 context->buffer_fraction += context->buffer_inc;
611 int16_t left = 0, right = 0; 561 int16_t left = 0, right = 0;
612 for (int i = 0; i < NUM_CHANNELS; i++) { 562 for (int i = 0; i < NUM_CHANNELS; i++) {
613 int16_t value = context->channels[i].output; 563 int16_t value = context->channels[i].output;
614 if (value > 0x1FE0) { 564 if (value > 0x1FE0) {
615 value = 0x1FE0; 565 value = 0x1FE0;
619 value &= 0x3FE0; 569 value &= 0x3FE0;
620 if (value & 0x2000) { 570 if (value & 0x2000) {
621 value |= 0xC000; 571 value |= 0xC000;
622 } 572 }
623 } 573 }
624 if (context->channels[i].logfile && context->buffer_fraction > BUFFER_INC_RES) { 574 if (context->channels[i].logfile) {
625 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); 575 fwrite(&value, sizeof(value), 1, context->channels[i].logfile);
626 } 576 }
627 if (context->channels[i].lr & 0x80) { 577 if (context->channels[i].lr & 0x80) {
628 left += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; 578 left += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER;
629 } 579 }
630 if (context->channels[i].lr & 0x40) { 580 if (context->channels[i].lr & 0x40) {
631 right += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; 581 right += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER;
632 } 582 }
633 } 583 }
634 int32_t tmp = left * context->lowpass_alpha + context->last_left * (0x10000 - context->lowpass_alpha); 584 render_put_stereo_sample(context->audio, left, right);
635 left = tmp >> 16;
636 tmp = right * context->lowpass_alpha + context->last_right * (0x10000 - context->lowpass_alpha);
637 right = tmp >> 16;
638 while (context->buffer_fraction > BUFFER_INC_RES) {
639 context->buffer_fraction -= BUFFER_INC_RES;
640
641 int64_t tmp = context->last_left * ((context->buffer_fraction << 16) / context->buffer_inc);
642 tmp += left * (0x10000 - ((context->buffer_fraction << 16) / context->buffer_inc));
643 context->audio_buffer[context->buffer_pos] = tmp >> 16;
644
645 tmp = context->last_right * ((context->buffer_fraction << 16) / context->buffer_inc);
646 tmp += right * (0x10000 - ((context->buffer_fraction << 16) / context->buffer_inc));
647 context->audio_buffer[context->buffer_pos+1] = tmp >> 16;
648
649 context->buffer_pos += 2;
650 if (context->buffer_pos == context->sample_limit) {
651 if (!headless) {
652 render_wait_ym(context);
653 }
654 }
655 }
656 context->last_left = left;
657 context->last_right = right;
658 } 585 }
659 586
660 } 587 }
661 if (context->current_cycle >= context->write_cycle + (context->busy_cycles * context->clock_inc / 6)) { 588 if (context->current_cycle >= context->write_cycle + (context->busy_cycles * context->clock_inc / 6)) {
662 context->status &= 0x7F; 589 context->status &= 0x7F;
967 context->ch3_supp[channel].block_fnum_latch = value; 894 context->ch3_supp[channel].block_fnum_latch = value;
968 } 895 }
969 break; 896 break;
970 case REG_ALG_FEEDBACK: 897 case REG_ALG_FEEDBACK:
971 context->channels[channel].algorithm = value & 0x7; 898 context->channels[channel].algorithm = value & 0x7;
899 switch (context->channels[channel].algorithm)
900 {
901 case 0:
902 //operator 3 modulated by operator 2
903 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output;
904 context->operators[channel*4+1].mod_src[1] = NULL;
905
906 //operator 2 modulated by operator 1
907 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
908
909 //operator 4 modulated by operator 3
910 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
911 context->operators[channel*4+3].mod_src[1] = NULL;
912 break;
913 case 1:
914 //operator 3 modulated by operator 1+2
915 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output;
916 context->operators[channel*4+1].mod_src[1] = &context->operators[channel*4+2].output;
917
918 //operator 2 unmodulated
919 context->operators[channel*4+2].mod_src[0] = NULL;
920
921 //operator 4 modulated by operator 3
922 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
923 context->operators[channel*4+3].mod_src[1] = NULL;
924 break;
925 case 2:
926 //operator 3 modulated by operator 2
927 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output;
928 context->operators[channel*4+1].mod_src[1] = NULL;
929
930 //operator 2 unmodulated
931 context->operators[channel*4+2].mod_src[0] = NULL;
932
933 //operator 4 modulated by operator 1+3
934 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output;
935 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output;
936 break;
937 case 3:
938 //operator 3 unmodulated
939 context->operators[channel*4+1].mod_src[0] = NULL;
940 context->operators[channel*4+1].mod_src[1] = NULL;
941
942 //operator 2 modulated by operator 1
943 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
944
945 //operator 4 modulated by operator 2+3
946 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+2].output;
947 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output;
948 break;
949 case 4:
950 //operator 3 unmodulated
951 context->operators[channel*4+1].mod_src[0] = NULL;
952 context->operators[channel*4+1].mod_src[1] = NULL;
953
954 //operator 2 modulated by operator 1
955 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
956
957 //operator 4 modulated by operator 3
958 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
959 context->operators[channel*4+3].mod_src[1] = NULL;
960 break;
961 case 5:
962 //operator 3 modulated by operator 1
963 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output;
964 context->operators[channel*4+1].mod_src[1] = NULL;
965
966 //operator 2 modulated by operator 1
967 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
968
969 //operator 4 modulated by operator 1
970 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output;
971 context->operators[channel*4+3].mod_src[1] = NULL;
972 break;
973 case 6:
974 //operator 3 unmodulated
975 context->operators[channel*4+1].mod_src[0] = NULL;
976 context->operators[channel*4+1].mod_src[1] = NULL;
977
978 //operator 2 modulated by operator 1
979 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
980
981 //operator 4 unmodulated
982 context->operators[channel*4+3].mod_src[0] = NULL;
983 context->operators[channel*4+3].mod_src[1] = NULL;
984 break;
985 case 7:
986 //everything is an output so no modulation (except for op 1 feedback)
987 context->operators[channel*4+1].mod_src[0] = NULL;
988 context->operators[channel*4+1].mod_src[1] = NULL;
989
990 context->operators[channel*4+2].mod_src[0] = NULL;
991
992 context->operators[channel*4+3].mod_src[0] = NULL;
993 context->operators[channel*4+3].mod_src[1] = NULL;
994 break;
995 }
972 context->channels[channel].feedback = value >> 3 & 0x7; 996 context->channels[channel].feedback = value >> 3 & 0x7;
973 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel); 997 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel);
974 break; 998 break;
975 case REG_LR_AMS_PMS: 999 case REG_LR_AMS_PMS:
976 context->channels[channel].pms = (value & 0x7) * 32; 1000 context->channels[channel].pms = (value & 0x7) * 32;