comparison vgmsplit.c @ 850:215b5dabbc20

Make vgmsplit smarter about how it handles delays. Force GD3 offset to zero since it is not being copied currently
author Michael Pavone <pavone@retrodev.com>
date Sun, 01 Nov 2015 20:40:30 -0800
parents 7068a9db6dd0
children
comparison
equal deleted inserted replaced
849:1416c4261d5b 850:215b5dabbc20
13 #define OUT_CHANNELS 10 13 #define OUT_CHANNELS 10
14 #define DAC_CHANNEL 5 14 #define DAC_CHANNEL 5
15 #define PSG_BASE 6 15 #define PSG_BASE 6
16 #define SAMPLE_THRESHOLD 100 16 #define SAMPLE_THRESHOLD 100
17 17
18 uint32_t total_delay;
19 void accum_wait(uint32_t *delays, uint32_t samples)
20 {
21 total_delay += samples;
22 for (int i = 0; i < OUT_CHANNELS; i++)
23 {
24 delays[i] += samples;
25 }
26 }
27
28 void write_wait(uint8_t **out_buffer, uint32_t *delay)
29 {
30 while (*delay >= 65535)
31 {
32 *((*out_buffer)++) = CMD_WAIT;
33 *((*out_buffer)++) = 0xFF;
34 *((*out_buffer)++) = 0xFF;
35 *delay -= 65535;
36 }
37 if (*delay) {
38 if (*delay == 735) {
39 *((*out_buffer)++) = CMD_WAIT_60;
40 } else if (*delay > 735 && *delay <= 751) {
41 *((*out_buffer)++) = CMD_WAIT_60;
42 *((*out_buffer)++) = CMD_WAIT_SHORT + *delay - 736;
43 } else if (*delay == 882) {
44 *((*out_buffer)++) = CMD_WAIT_50;
45 } else if (*delay > 882 && *delay <= 898) {
46 *((*out_buffer)++) = CMD_WAIT_50;
47 *((*out_buffer)++) = CMD_WAIT_SHORT + *delay - 882;
48 } else if (*delay <= 16) {
49 *((*out_buffer)++) = CMD_WAIT_SHORT + *delay - 1;
50 } else {
51 *((*out_buffer)++) = CMD_WAIT;
52 *((*out_buffer)++) = *delay;
53 *((*out_buffer)++) = *delay >> 8;
54 }
55 *delay = 0;
56 }
57 }
58
18 int main(int argc, char ** argv) 59 int main(int argc, char ** argv)
19 { 60 {
20 data_block *blocks = NULL; 61 data_block *blocks = NULL;
21 data_block *seek_block = NULL; 62 data_block *seek_block = NULL;
22 uint32_t seek_offset; 63 uint32_t seek_offset;
39 data_size = fread(data, 1, data_size, f); 80 data_size = fread(data, 1, data_size, f);
40 fclose(f); 81 fclose(f);
41 uint8_t *buffers[OUT_CHANNELS]; 82 uint8_t *buffers[OUT_CHANNELS];
42 uint8_t *out_pos[OUT_CHANNELS]; 83 uint8_t *out_pos[OUT_CHANNELS];
43 uint8_t has_real_data[OUT_CHANNELS]; 84 uint8_t has_real_data[OUT_CHANNELS];
85 uint32_t delay[OUT_CHANNELS];
44 86
45 buffers[0] = malloc(data_size * OUT_CHANNELS); 87 buffers[0] = malloc(data_size * OUT_CHANNELS);
46 out_pos[0] = buffers[0]; 88 out_pos[0] = buffers[0];
47 has_real_data[0] = 0; 89 has_real_data[0] = 0;
90 delay[0] = 0;
48 for (int i = 1; i < OUT_CHANNELS; i++) 91 for (int i = 1; i < OUT_CHANNELS; i++)
49 { 92 {
50 buffers[i] = buffers[i-1] + data_size; 93 buffers[i] = buffers[i-1] + data_size;
51 out_pos[i] = buffers[i]; 94 out_pos[i] = buffers[i];
52 has_real_data[i] = 0; 95 has_real_data[i] = 0;
96 delay[i] = 0;
53 } 97 }
54 98
55 uint8_t * end = data + data_size; 99 uint8_t * end = data + data_size;
56 uint8_t * cur = data; 100 uint8_t * cur = data;
57 uint32_t current_cycle = 0; 101 uint32_t current_cycle = 0;
74 psg_latch = param; 118 psg_latch = param;
75 channel = param >> 5 & 3; 119 channel = param >> 5 & 3;
76 } else { 120 } else {
77 channel = psg_latch >> 5 & 3; 121 channel = psg_latch >> 5 & 3;
78 } 122 }
123 write_wait(out_pos + PSG_BASE+channel, delay + PSG_BASE+channel);
79 *(out_pos[PSG_BASE+channel]++) = cmd; 124 *(out_pos[PSG_BASE+channel]++) = cmd;
80 *(out_pos[PSG_BASE+channel]++) = param; 125 *(out_pos[PSG_BASE+channel]++) = param;
81 has_real_data[PSG_BASE+channel] = 1; 126 has_real_data[PSG_BASE+channel] = 1;
82 break; 127 break;
83 case CMD_YM2612_0: 128 case CMD_YM2612_0:
84 reg = *(cur++); 129 reg = *(cur++);
85 param = *(cur++); 130 param = *(cur++);
86 if (reg < REG_KEY_ONOFF) { 131 if (reg < REG_KEY_ONOFF) {
87 for (int i = 0; i < 6; i++) 132 for (int i = 0; i < 6; i++)
88 { 133 {
134 write_wait(out_pos + i, delay + i);
89 *(out_pos[i]++) = cmd; 135 *(out_pos[i]++) = cmd;
90 *(out_pos[i]++) = reg; 136 *(out_pos[i]++) = reg;
91 *(out_pos[i]++) = param; 137 *(out_pos[i]++) = param;
92 } 138 }
93 break; 139 break;
123 } else { 169 } else {
124 fprintf(stderr, "WARNING: Skipping nrecognized write to register %X on part %d\n", reg, (cmd == CMD_YM2612_0 ? 1 : 2)); 170 fprintf(stderr, "WARNING: Skipping nrecognized write to register %X on part %d\n", reg, (cmd == CMD_YM2612_0 ? 1 : 2));
125 } 171 }
126 } 172 }
127 if (channel < PSG_BASE) { 173 if (channel < PSG_BASE) {
174 write_wait(out_pos + channel, delay + channel);
128 *(out_pos[channel]++) = cmd; 175 *(out_pos[channel]++) = cmd;
129 *(out_pos[channel]++) = reg; 176 *(out_pos[channel]++) = reg;
130 *(out_pos[channel]++) = param; 177 *(out_pos[channel]++) = param;
131 } 178 }
132 break; 179 break;
133 case CMD_WAIT: { 180 case CMD_WAIT: {
134 reg = *(cur++); 181 uint32_t wait_time = *(cur++);
135 param = *(cur++); 182 wait_time |= *(cur++) << 8;
136 for (int i = 0; i < OUT_CHANNELS; i++) 183 accum_wait(delay, wait_time);
137 {
138 *(out_pos[i]++) = cmd;
139 *(out_pos[i]++) = reg;
140 *(out_pos[i]++) = param;
141 }
142 break; 184 break;
143 } 185 }
144 case CMD_WAIT_60: 186 case CMD_WAIT_60:
187 accum_wait(delay, 735);
188 break;
145 case CMD_WAIT_50: 189 case CMD_WAIT_50:
190 accum_wait(delay, 882);
191 break;
146 case CMD_END: 192 case CMD_END:
147 for (int i = 0; i < OUT_CHANNELS; i++) 193 for (int i = 0; i < OUT_CHANNELS; i++)
148 { 194 {
195 write_wait(out_pos + i, delay + i);
149 *(out_pos[i]++) = cmd; 196 *(out_pos[i]++) = cmd;
150 } 197 }
151 cur = end; 198 cur = end;
152 break; 199 break;
153 case CMD_DATA: { 200 case CMD_DATA: {
161 if (cur + data_size > end) { 208 if (cur + data_size > end) {
162 data_size = end - cur; 209 data_size = end - cur;
163 } 210 }
164 cur += data_size; 211 cur += data_size;
165 if (data_type == DATA_YM2612_PCM) { 212 if (data_type == DATA_YM2612_PCM) {
213 write_wait(out_pos + DAC_CHANNEL, delay + DAC_CHANNEL);
166 memcpy(out_pos[DAC_CHANNEL], start, cur-start); 214 memcpy(out_pos[DAC_CHANNEL], start, cur-start);
167 out_pos[DAC_CHANNEL] += cur-start; 215 out_pos[DAC_CHANNEL] += cur-start;
168 } else { 216 } else {
169 fprintf(stderr, "WARNING: Skipping data block with unrecognized type %X\n", data_type); 217 fprintf(stderr, "WARNING: Skipping data block with unrecognized type %X\n", data_type);
170 } 218 }
171 break; 219 break;
172 } 220 }
173 case CMD_DATA_SEEK: { 221 case CMD_DATA_SEEK: {
222 write_wait(out_pos + DAC_CHANNEL, delay + DAC_CHANNEL);
174 memcpy(out_pos[DAC_CHANNEL], cur-1, 5); 223 memcpy(out_pos[DAC_CHANNEL], cur-1, 5);
175 out_pos[DAC_CHANNEL] += 5; 224 out_pos[DAC_CHANNEL] += 5;
176 cur += 4; 225 cur += 4;
177 break; 226 break;
178 } 227 }
179 228
180 default: 229 default:
181 if (cmd >= CMD_WAIT_SHORT && cmd < (CMD_WAIT_SHORT + 0x10)) { 230 if (cmd >= CMD_WAIT_SHORT && cmd < (CMD_WAIT_SHORT + 0x10)) {
231 accum_wait(delay, (cmd & 0xF) + 1);
232 } else if (cmd >= CMD_YM2612_DAC && cmd < CMD_DAC_STREAM_SETUP) {
233 write_wait(out_pos + DAC_CHANNEL, delay + DAC_CHANNEL);
234 *(out_pos[DAC_CHANNEL]++) = cmd;
182 for (int i = 0; i < OUT_CHANNELS; i++) 235 for (int i = 0; i < OUT_CHANNELS; i++)
183 { 236 {
184 *(out_pos[i]++) = cmd; 237 if (i != DAC_CHANNEL)
185 } 238 {
186 } else if (cmd >= CMD_YM2612_DAC && cmd < CMD_DAC_STREAM_SETUP) { 239 delay[i] += cmd & 0xF;
187 *(out_pos[DAC_CHANNEL]++) = cmd; 240 }
241 }
188 sample_count++; 242 sample_count++;
189 } else { 243 } else {
190 fprintf(stderr, "unimplemented command: %X at offset %X, last valid command was %X\n", cmd, (unsigned int)(cur - data - 1), last_cmd); 244 fprintf(stderr, "unimplemented command: %X at offset %X, last valid command was %X\n", cmd, (unsigned int)(cur - data - 1), last_cmd);
191 exit(1); 245 exit(1);
192 } 246 }
206 fprintf(stderr, "Failed to open %s for writing\n", fname); 260 fprintf(stderr, "Failed to open %s for writing\n", fname);
207 exit(1); 261 exit(1);
208 } 262 }
209 data_size = out_pos[i] - buffers[i]; 263 data_size = out_pos[i] - buffers[i];
210 header.eof_offset = (header.data_offset + 0x34) + data_size - 4; 264 header.eof_offset = (header.data_offset + 0x34) + data_size - 4;
265 header.gd3_offset = 0;
211 fwrite(&header, 1, sizeof(header), f); 266 fwrite(&header, 1, sizeof(header), f);
212 fseek(f, header.data_offset + 0x34, SEEK_SET); 267 fseek(f, header.data_offset + 0x34, SEEK_SET);
213 fwrite(buffers[i], 1, data_size, f); 268 fwrite(buffers[i], 1, data_size, f);
214 fclose(f); 269 fclose(f);
215 } 270 }
216 } 271 }
272 printf("total_delay: %d\n", total_delay);
217 return 0; 273 return 0;
218 } 274 }