annotate cdd_fader.c @ 2496:187bc857a76a default tip

Fix bug in MED mapper protection bit implementation
author Michael Pavone <pavone@retrodev.com>
date Sun, 28 Apr 2024 23:33:11 -0700
parents 9ead0fe69d9b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2080
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include "cdd_fader.h"
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include <stdio.h>
2278
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
3 #define CDDA_MCLKS 16934400
2080
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5 void cdd_fader_init(cdd_fader *fader)
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 {
2278
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
7 fader->audio = render_audio_source("CDDA", CDDA_MCLKS, 384, 2);
2080
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 fader->cur_attenuation = 0x4000;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 fader->dst_attenuation = 0x4000;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 fader->attenuation_step = 0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11 }
2164
4fbe1e7c4a73 Don't leak all Sega CD resources when freeing a Genesis instance
Michael Pavone <pavone@retrodev.com>
parents: 2081
diff changeset
12
4fbe1e7c4a73 Don't leak all Sega CD resources when freeing a Genesis instance
Michael Pavone <pavone@retrodev.com>
parents: 2081
diff changeset
13 void cdd_fader_deinit(cdd_fader *fader)
4fbe1e7c4a73 Don't leak all Sega CD resources when freeing a Genesis instance
Michael Pavone <pavone@retrodev.com>
parents: 2081
diff changeset
14 {
4fbe1e7c4a73 Don't leak all Sega CD resources when freeing a Genesis instance
Michael Pavone <pavone@retrodev.com>
parents: 2081
diff changeset
15 render_free_source(fader->audio);
4fbe1e7c4a73 Don't leak all Sega CD resources when freeing a Genesis instance
Michael Pavone <pavone@retrodev.com>
parents: 2081
diff changeset
16 }
4fbe1e7c4a73 Don't leak all Sega CD resources when freeing a Genesis instance
Michael Pavone <pavone@retrodev.com>
parents: 2081
diff changeset
17
2278
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
18 void cdd_fader_set_speed_percent(cdd_fader *fader, uint32_t percent)
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
19 {
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
20 uint32_t new_clock = ((uint64_t)CDDA_MCLKS * (uint64_t)percent) / 100;
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
21 render_audio_adjust_clock(fader->audio, new_clock, 384);
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
22 }
5a21bc0ec583 Implement turbo/slo mo for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2164
diff changeset
23
2080
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 void cdd_fader_attenuation_write(cdd_fader *fader, uint16_t attenuation)
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 fader->dst_attenuation = attenuation & 0xFFF0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 fader->flags = attenuation & 0xE;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 if (fader->dst_attenuation > fader->cur_attenuation) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29 fader->attenuation_step = (fader->dst_attenuation - fader->cur_attenuation) >> 4;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 } else if (fader->dst_attenuation < fader->cur_attenuation) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 fader->attenuation_step = (fader->cur_attenuation - fader->dst_attenuation) >> 4;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32 } else {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 fader->attenuation_step = 0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 void cdd_fader_data(cdd_fader *fader, uint8_t byte)
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 fader->bytes[fader->byte_counter++] = byte;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 if (fader->byte_counter == sizeof(fader->bytes)) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 fader->byte_counter = 0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 int32_t left = (fader->bytes[1] << 8) | fader->bytes[0];
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 int32_t right = (fader->bytes[3] << 8) | fader->bytes[2];
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 if (left & 0x8000) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 left |= 0xFFFF0000;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 if (right & 0x8000) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 right |= 0xFFFF0000;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 if (!fader->cur_attenuation) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 left = right = 0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52 } else if (fader->cur_attenuation >= 4) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 left *= fader->cur_attenuation & 0x7FF0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 right *= fader->cur_attenuation & 0x7FF0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 left >>= 14;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 right >>= 14;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 } else {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 //TODO: FIXME
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59 left = right = 0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 render_put_stereo_sample(fader->audio, left, right);
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 if (fader->attenuation_step) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 if (fader->dst_attenuation > fader->cur_attenuation) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 fader->cur_attenuation += fader->attenuation_step;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65 if (fader->cur_attenuation >= fader->dst_attenuation) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 fader->cur_attenuation = fader->dst_attenuation;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67 fader->attenuation_step = 0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 } else {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 fader->cur_attenuation -= fader->attenuation_step;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 if (fader->cur_attenuation <= fader->dst_attenuation) {
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 fader->cur_attenuation = fader->dst_attenuation;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 fader->attenuation_step = 0;
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 }
bafb757e1cd2 Implement CD audio
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 }
2280
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
79
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
80 void cdd_fader_serialize(cdd_fader *fader, serialize_buffer *buf)
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
81 {
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
82 save_int16(buf, fader->cur_attenuation);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
83 save_int16(buf, fader->dst_attenuation);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
84 save_int16(buf, fader->attenuation_step);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
85 save_int8(buf, fader->flags);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
86 save_buffer8(buf, fader->bytes, sizeof(fader->bytes));
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
87 save_int8(buf, fader->byte_counter);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
88 }
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
89
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
90 void cdd_fader_deserialize(deserialize_buffer *buf, void *vfader)
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
91 {
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
92 cdd_fader *fader = vfader;
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
93 fader->cur_attenuation = load_int16(buf);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
94 fader->dst_attenuation = load_int16(buf);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
95 fader->attenuation_step = load_int16(buf);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
96 fader->flags = load_int8(buf);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
97 load_buffer8(buf, fader->bytes, sizeof(fader->bytes));
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
98 fader->byte_counter = load_int8(buf);
9ead0fe69d9b Implement savestate support for Sega CD
Michael Pavone <pavone@retrodev.com>
parents: 2278
diff changeset
99 }