comparison vgm.c @ 2041:638eb2d25696 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Thu, 05 Aug 2021 09:29:33 -0700
parents 327332138c5c
children
comparison
equal deleted inserted replaced
1984:0d5f88e53dca 2041:638eb2d25696
58 uint8_t cmd[3] = {CMD_WAIT, delta, delta >> 8}; 58 uint8_t cmd[3] = {CMD_WAIT, delta, delta >> 8};
59 fwrite(cmd, 1, sizeof(cmd), writer->f); 59 fwrite(cmd, 1, sizeof(cmd), writer->f);
60 } 60 }
61 } 61 }
62 62
63 #include "util.h"
63 static void add_wait(vgm_writer *writer, uint32_t cycle) 64 static void add_wait(vgm_writer *writer, uint32_t cycle)
64 { 65 {
65 uint64_t delta = cycle - writer->last_cycle; 66 if (cycle < writer->last_cycle) {
66 delta *= (uint64_t)44100; 67 //This can happen when a YM-2612 write happens immediately after a PSG write
67 delta /= (uint64_t)writer->master_clock; 68 //due to the relatively low granularity of the PSG's internal clock
69 //given that VGM only has a granularity of 44.1 kHz ignoring this is harmless
70 return;
71 }
72 uint64_t last_sample = (uint64_t)writer->last_cycle * (uint64_t)44100;
73 last_sample /= (uint64_t)writer->master_clock;
74 uint64_t sample = ((uint64_t)cycle + (uint64_t)writer->extra_delta) * (uint64_t)44100;
75 sample /= (uint64_t)writer->master_clock;
76 uint32_t delta = sample - last_sample;
68 77
69 uint32_t mclks_per_sample = writer->master_clock / 44100; 78 writer->last_cycle = cycle;
70 writer->last_cycle += delta * mclks_per_sample; 79 writer->extra_delta = 0;
71 writer->header.num_samples += delta; 80 writer->header.num_samples += delta;
72 wait_commands(writer, delta); 81 wait_commands(writer, delta);
73 } 82 }
74 83
84 static uint8_t last_cmd;
75 void vgm_sn76489_write(vgm_writer *writer, uint32_t cycle, uint8_t value) 85 void vgm_sn76489_write(vgm_writer *writer, uint32_t cycle, uint8_t value)
76 { 86 {
77 add_wait(writer, cycle); 87 add_wait(writer, cycle);
78 uint8_t cmd[2] = {CMD_PSG, value}; 88 uint8_t cmd[2] = {CMD_PSG, value};
89 last_cmd = CMD_PSG;
79 fwrite(cmd, 1, sizeof(cmd), writer->f); 90 fwrite(cmd, 1, sizeof(cmd), writer->f);
80 } 91 }
81 92
82 void vgm_ym2612_init(vgm_writer *writer, uint32_t clock) 93 void vgm_ym2612_init(vgm_writer *writer, uint32_t clock)
83 { 94 {
86 97
87 void vgm_ym2612_part1_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value) 98 void vgm_ym2612_part1_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value)
88 { 99 {
89 add_wait(writer, cycle); 100 add_wait(writer, cycle);
90 uint8_t cmd[3] = {CMD_YM2612_0, reg, value}; 101 uint8_t cmd[3] = {CMD_YM2612_0, reg, value};
102 last_cmd = CMD_YM2612_0;
91 fwrite(cmd, 1, sizeof(cmd), writer->f); 103 fwrite(cmd, 1, sizeof(cmd), writer->f);
92 } 104 }
93 105
94 void vgm_ym2612_part2_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value) 106 void vgm_ym2612_part2_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value)
95 { 107 {
96 add_wait(writer, cycle); 108 add_wait(writer, cycle);
97 uint8_t cmd[3] = {CMD_YM2612_1, reg, value}; 109 uint8_t cmd[3] = {CMD_YM2612_1, reg, value};
110 last_cmd = CMD_YM2612_1;
98 fwrite(cmd, 1, sizeof(cmd), writer->f); 111 fwrite(cmd, 1, sizeof(cmd), writer->f);
99 } 112 }
100 113
101 void vgm_adjust_cycles(vgm_writer *writer, uint32_t deduction) 114 void vgm_adjust_cycles(vgm_writer *writer, uint32_t deduction)
102 { 115 {
103 if (deduction > writer->last_cycle) { 116 if (deduction > writer->last_cycle) {
117 writer->extra_delta += deduction - writer->last_cycle;
104 writer->last_cycle = 0; 118 writer->last_cycle = 0;
105 } else { 119 } else {
106 writer->last_cycle -= deduction; 120 writer->last_cycle -= deduction;
107 } 121 }
108 } 122 }
109 123
110 void vgm_close(vgm_writer *writer) 124 void vgm_close(vgm_writer *writer)
111 { 125 {
126 uint8_t cmd = 0x66;
127 fwrite(&cmd, 1, sizeof(cmd), writer->f);
112 writer->header.eof_offset = ftell(writer->f) - offsetof(vgm_header, eof_offset); 128 writer->header.eof_offset = ftell(writer->f) - offsetof(vgm_header, eof_offset);
113 fseek(writer->f, SEEK_SET, 0); 129 fseek(writer->f, SEEK_SET, 0);
114 fwrite(&writer->header, sizeof(writer->header), 1, writer->f); 130 fwrite(&writer->header, sizeof(writer->header), 1, writer->f);
115 fclose(writer->f); 131 fclose(writer->f);
116 free(writer); 132 free(writer);