Mercurial > repos > blastem
annotate cdd_fader.c @ 2345:c76c81c21ae5
Fix stupid off by one in PCM RAM writes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 06 Oct 2023 00:20:37 -0700 |
parents | 9ead0fe69d9b |
children |
rev | line source |
---|---|
2080 | 1 #include "cdd_fader.h" |
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 | 4 |
5 void cdd_fader_init(cdd_fader *fader) | |
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 | 8 fader->cur_attenuation = 0x4000; |
9 fader->dst_attenuation = 0x4000; | |
10 fader->attenuation_step = 0; | |
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 | 24 void cdd_fader_attenuation_write(cdd_fader *fader, uint16_t attenuation) |
25 { | |
26 fader->dst_attenuation = attenuation & 0xFFF0; | |
27 fader->flags = attenuation & 0xE; | |
28 if (fader->dst_attenuation > fader->cur_attenuation) { | |
29 fader->attenuation_step = (fader->dst_attenuation - fader->cur_attenuation) >> 4; | |
30 } else if (fader->dst_attenuation < fader->cur_attenuation) { | |
31 fader->attenuation_step = (fader->cur_attenuation - fader->dst_attenuation) >> 4; | |
32 } else { | |
33 fader->attenuation_step = 0; | |
34 } | |
35 } | |
36 | |
37 void cdd_fader_data(cdd_fader *fader, uint8_t byte) | |
38 { | |
39 fader->bytes[fader->byte_counter++] = byte; | |
40 if (fader->byte_counter == sizeof(fader->bytes)) { | |
41 fader->byte_counter = 0; | |
42 int32_t left = (fader->bytes[1] << 8) | fader->bytes[0]; | |
43 int32_t right = (fader->bytes[3] << 8) | fader->bytes[2]; | |
44 if (left & 0x8000) { | |
45 left |= 0xFFFF0000; | |
46 } | |
47 if (right & 0x8000) { | |
48 right |= 0xFFFF0000; | |
49 } | |
50 if (!fader->cur_attenuation) { | |
51 left = right = 0; | |
52 } else if (fader->cur_attenuation >= 4) { | |
53 left *= fader->cur_attenuation & 0x7FF0; | |
54 right *= fader->cur_attenuation & 0x7FF0; | |
55 left >>= 14; | |
56 right >>= 14; | |
57 } else { | |
58 //TODO: FIXME | |
59 left = right = 0; | |
60 } | |
61 render_put_stereo_sample(fader->audio, left, right); | |
62 if (fader->attenuation_step) { | |
63 if (fader->dst_attenuation > fader->cur_attenuation) { | |
64 fader->cur_attenuation += fader->attenuation_step; | |
65 if (fader->cur_attenuation >= fader->dst_attenuation) { | |
66 fader->cur_attenuation = fader->dst_attenuation; | |
67 fader->attenuation_step = 0; | |
68 } | |
69 } else { | |
70 fader->cur_attenuation -= fader->attenuation_step; | |
71 if (fader->cur_attenuation <= fader->dst_attenuation) { | |
72 fader->cur_attenuation = fader->dst_attenuation; | |
73 fader->attenuation_step = 0; | |
74 } | |
75 } | |
76 } | |
77 } | |
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 } |