Common Source Code Project for Qt (a.k.a for FM-7).
リビジョン | 119acac57857bdc0ca4132a7cd5d7ceea4cd765d (tree) |
---|---|
日時 | 2020-05-28 09:15:30 |
作者 | K.Ohta <whatisthis.sowhat@gmai...> |
コミッター | K.Ohta |
[VM][FMTOWNS][RF5C68] Add interpollation LPF.
@@ -244,6 +244,7 @@ __DECL_VECTORIZED_LOOP | ||
244 | 244 | } |
245 | 245 | sample_pointer = (sample_pointer + 1) % sample_length; |
246 | 246 | sample_words++; |
247 | + sample_words = (sample_words >= sample_length) ? sample_length : sample_words; | |
247 | 248 | } |
248 | 249 | break; |
249 | 250 | case SIG_RF5C68_CLEAR_INTR: |
@@ -401,8 +402,8 @@ void RF5C68::write_memory_mapped_io16(uint32_t addr, uint32_t data) | ||
401 | 402 | |
402 | 403 | void RF5C68::set_volume(int ch, int decibel_l, int decibel_r) |
403 | 404 | { |
404 | - volume_l = decibel_to_volume(decibel_l); | |
405 | - volume_r = decibel_to_volume(decibel_r); | |
405 | + volume_l = decibel_to_volume(decibel_l - 4); | |
406 | + volume_r = decibel_to_volume(decibel_r - 4); | |
406 | 407 | } |
407 | 408 | |
408 | 409 | void RF5C68::event_callback(int id, int err) |
@@ -445,16 +446,70 @@ void RF5C68::mix(int32_t* buffer, int cnt) | ||
445 | 446 | { |
446 | 447 | |
447 | 448 | int32_t lval, rval; |
449 | + int32_t lval2, rval2; | |
448 | 450 | // ToDo: supress pop noise. |
449 | 451 | if(cnt <= 0) return; |
450 | 452 | if(is_mute) return; |
451 | 453 | |
452 | 454 | if(sample_buffer != NULL) { |
453 | - int32_t lval; | |
454 | - int32_t rval; | |
455 | - lval = apply_volume(sample_buffer[(read_pointer << 1) + 0], volume_l) >> 1; | |
456 | - rval = apply_volume(sample_buffer[(read_pointer << 1) + 1], volume_r) >> 1; | |
455 | + __DECL_ALIGNED(16) int32_t val[4] = {0}; | |
456 | + if(sample_pointer > read_pointer) { | |
457 | + if((sample_pointer - 2) >= (read_pointer)) { | |
458 | + val[0] = sample_buffer[(read_pointer << 1) + 2]; | |
459 | + val[1] = sample_buffer[(read_pointer << 1) + 3]; | |
460 | + val[2] = sample_buffer[(read_pointer << 1) + 0]; | |
461 | + val[3] = sample_buffer[(read_pointer << 1) + 1]; | |
462 | + } else { | |
463 | + val[2] = sample_buffer[(read_pointer << 1) + 0]; | |
464 | + val[3] = sample_buffer[(read_pointer << 1) + 1]; | |
465 | + if(read_pointer == 0) { | |
466 | + val[0] = val[2]; | |
467 | + val[1] = val[3]; | |
468 | + } else { | |
469 | + val[0] = sample_buffer[((read_pointer + 1) << 1) + 0]; | |
470 | + val[1] = sample_buffer[((read_pointer + 1) << 1) + 1]; | |
471 | + } | |
472 | + } | |
473 | + } else if(sample_pointer == read_pointer) { | |
474 | + if(read_pointer < 2) { | |
475 | + val[2] = sample_buffer[(read_pointer << 1) + 0]; | |
476 | + val[3] = sample_buffer[(read_pointer << 1) + 1]; | |
477 | + val[0] = sample_buffer[(read_pointer << 1) + 0]; | |
478 | + val[1] = sample_buffer[(read_pointer << 1) + 1]; | |
479 | + } else { | |
480 | + val[2] = sample_buffer[((read_pointer - 2) << 1) + 0]; | |
481 | + val[3] = sample_buffer[((read_pointer - 2) << 1) + 1]; | |
482 | + val[0] = sample_buffer[((read_pointer - 1) << 1) + 0]; | |
483 | + val[1] = sample_buffer[((read_pointer - 1) << 1) + 1]; | |
484 | + } | |
485 | + } else { | |
486 | + if(sample_words > 1) { | |
487 | + val[2] = sample_buffer[((read_pointer + 0) << 1) + 0]; | |
488 | + val[3] = sample_buffer[((read_pointer + 0) << 1) + 1]; | |
489 | + val[0] = sample_buffer[((read_pointer + 1) << 1) + 0]; | |
490 | + val[1] = sample_buffer[((read_pointer + 1) << 1) + 1]; | |
491 | + } else { | |
492 | + val[0] = sample_buffer[((read_pointer + 0) << 1) + 0]; | |
493 | + val[1] = sample_buffer[((read_pointer + 0) << 1) + 1]; | |
494 | + val[2] = sample_buffer[((read_pointer + 0) << 1) + 0]; | |
495 | + val[3] = sample_buffer[((read_pointer + 0) << 1) + 1]; | |
496 | + } | |
497 | + } | |
498 | +// lval = apply_volume(sample_buffer[(read_pointer << 1) + 0], volume_l) >> 1; | |
499 | +// rval = apply_volume(sample_buffer[(read_pointer << 1) + 1], volume_r) >> 1; | |
457 | 500 | for(int i = 0; i < (cnt << 1); i += 2) { |
501 | + int32_t interp_p = mix_count; | |
502 | + int32_t interp_n = 4096 - mix_count; | |
503 | + lval2 = (interp_p * (val[0] - val[2])) >> 12; | |
504 | + rval2 = (interp_p * (val[1] - val[3])) >> 12; | |
505 | +// lval = (val[0] * ((4096 >> 4) * 3)) + (lval2 * (4096 - ((4096 >> 4) * 3))); | |
506 | +// rval = (val[1] * ((4096 >> 4) * 3)) + (rval2 * (4096 - ((4096 >> 4) * 3))); | |
507 | +// lval >>= 12; | |
508 | +// rval >>= 12; | |
509 | + lval = val[2] + lval2; | |
510 | + rval = val[3] + rval2; | |
511 | + lval = apply_volume(lval, volume_l) >> 1; | |
512 | + rval = apply_volume(rval, volume_r) >> 1; | |
458 | 513 | // ToDo: interpoolate. |
459 | 514 | buffer[i] += lval; |
460 | 515 | buffer[i + 1] += rval; |
@@ -466,8 +521,10 @@ void RF5C68::mix(int32_t* buffer, int cnt) | ||
466 | 521 | if(sample_words > 0) { |
467 | 522 | // Reload data |
468 | 523 | read_pointer = (read_pointer + n) % sample_length; |
469 | - lval = apply_volume(sample_buffer[(read_pointer << 1) + 0], volume_l) >> 1; | |
470 | - rval = apply_volume(sample_buffer[(read_pointer << 1) + 1], volume_r) >> 1; | |
524 | + val[0] = val[2]; | |
525 | + val[1] = val[3]; | |
526 | + val[2] = sample_buffer[(read_pointer << 1) + 0]; | |
527 | + val[3] = sample_buffer[(read_pointer << 1) + 1]; | |
471 | 528 | } else { |
472 | 529 | read_pointer = sample_pointer; |
473 | 530 | } |