annotate vgm.c @ 1975:3701517d852c

Avoid expensive re-init from switching to external sync after render_init has been called
author Michael Pavone <pavone@retrodev.com>
date Fri, 08 May 2020 16:52:32 -0700
parents 508522f08e4d
children a9449608d0b0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1909
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include <stdlib.h>
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include <string.h>
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3 #include <stddef.h>
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 #include "vgm.h"
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 vgm_writer *vgm_write_open(char *filename, uint32_t rate, uint32_t clock, uint32_t cycle)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 FILE *f = fopen(filename, "wb");
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 if (!f) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 return NULL;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12 vgm_writer *writer = calloc(sizeof(vgm_writer), 1);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13 memcpy(writer->header.ident, "Vgm ", 4);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 writer->header.version = 0x150;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 writer->header.data_offset = sizeof(writer->header) - offsetof(vgm_header, data_offset);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16 writer->header.rate = rate;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17 writer->f = f;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 if (1 != fwrite(&writer->header, sizeof(writer->header), 1, f)) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19 free(writer);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20 fclose(f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 return NULL;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23 writer->master_clock = clock;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 writer->last_cycle = cycle;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 return writer;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29 void vgm_sn76489_init(vgm_writer *writer, uint32_t clock, uint16_t feedback, uint8_t shift_reg_size, uint8_t flags)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 if (flags && writer->header.version < 0x151) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32 writer->header.version = 0x151;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34 writer->header.sn76489_clk = clock,
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 writer->header.sn76489_fb = feedback;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 writer->header.sn76489_shift = shift_reg_size;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 writer->header.sn76489_flags = flags;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 static void wait_commands(vgm_writer *writer, uint32_t delta)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 if (!delta) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 return;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 if (delta <= 0x10) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 fputc(CMD_WAIT_SHORT + (delta - 1), writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 } else if (delta >= 735 && delta <= (735 + 0x10)) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 fputc(CMD_WAIT_60, writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 wait_commands(writer, delta - 735);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 } else if (delta >= 882 && delta <= (882 + 0x10)) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 fputc(CMD_WAIT_50, writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52 wait_commands(writer, delta - 882);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 } else if (delta > 0xFFFF) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 uint8_t cmd[3] = {CMD_WAIT, 0xFF, 0xFF};
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 fwrite(cmd, 1, sizeof(cmd), writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 wait_commands(writer, delta - 0xFFFF);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 } else {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 uint8_t cmd[3] = {CMD_WAIT, delta, delta >> 8};
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59 fwrite(cmd, 1, sizeof(cmd), writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 static void add_wait(vgm_writer *writer, uint32_t cycle)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65 uint64_t delta = cycle - writer->last_cycle;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 delta *= (uint64_t)44100;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67 delta /= (uint64_t)writer->master_clock;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 uint32_t mclks_per_sample = writer->master_clock / 44100;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 writer->last_cycle += delta * mclks_per_sample;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 writer->header.num_samples += delta;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 wait_commands(writer, delta);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 void vgm_sn76489_write(vgm_writer *writer, uint32_t cycle, uint8_t value)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 add_wait(writer, cycle);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 uint8_t cmd[2] = {CMD_PSG, value};
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
79 fwrite(cmd, 1, sizeof(cmd), writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
81
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
82 void vgm_ym2612_init(vgm_writer *writer, uint32_t clock)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
83 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
84 writer->header.ym2612_clk = clock;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
85 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
86
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
87 void vgm_ym2612_part1_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
88 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
89 add_wait(writer, cycle);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
90 uint8_t cmd[3] = {CMD_YM2612_0, reg, value};
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
91 fwrite(cmd, 1, sizeof(cmd), writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
92 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
93
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
94 void vgm_ym2612_part2_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
95 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
96 add_wait(writer, cycle);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
97 uint8_t cmd[3] = {CMD_YM2612_1, reg, value};
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
98 fwrite(cmd, 1, sizeof(cmd), writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
99 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
100
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101 void vgm_adjust_cycles(vgm_writer *writer, uint32_t deduction)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
103 if (deduction > writer->last_cycle) {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 writer->last_cycle = 0;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
105 } else {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106 writer->last_cycle -= deduction;
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 }
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110 void vgm_close(vgm_writer *writer)
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
111 {
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112 writer->header.eof_offset = ftell(writer->f) - offsetof(vgm_header, eof_offset);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
113 fseek(writer->f, SEEK_SET, 0);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
114 fwrite(&writer->header, sizeof(writer->header), 1, writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
115 fclose(writer->f);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
116 free(writer);
508522f08e4d Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
117 }