Skip to content

Commit 135451e

Browse files
committed
feat: substantial improvements to DLS->SF2 conversion
This patch updates the conversions from DLS to SF2 required for TSF to be usable. It improves initial DLS parsing, ADPCM decoding and adds many more generator and modulator translations. It improves some issues mentioned by Try in #4, including improved drums in Gothic 2's `OWD_DayStd`.
1 parent afc88e1 commit 135451e

File tree

5 files changed

+522
-272
lines changed

5 files changed

+522
-272
lines changed

src/Dls.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,14 @@ static int clamp_16bit(int v) {
150150

151151
// TODO(lmichaelis): These are the 'built in' set of 7 predictor value pairs; additional values can be added
152152
// to this table by including them as metadata chunks in the WAVE header
153-
static int ADPCM_ADAPT_COEFF1[7] = {256, 512, 0, 192, 240, 460, 392};
154-
static int ADPCM_ADAPT_COEFF2[7] = {0, -256, 0, 64, 0, -208, -232};
155153
static int16_t ADPCM_ADAPT_TABLE[16] = {230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230};
156154

157155
#define DmInt_read(src, tgt) \
158156
memcpy((tgt), (src), sizeof(*(tgt))); \
159157
(src) += sizeof(*(tgt))
160158

161159
// See https://wiki.multimedia.cx/index.php/Microsoft_ADPCM
162-
static uint8_t const* DmDls_decodeAdpcmBlock(uint8_t const* adpcm, float* pcm, uint32_t block_size) {
160+
static uint8_t const* DmDls_decodeAdpcmBlock(uint8_t const* adpcm, float* pcm, uint32_t block_size, int16_t const* coeff1, int16_t const* coeff2) {
163161
uint8_t block_predictor;
164162
DmInt_read(adpcm, &block_predictor);
165163

@@ -176,8 +174,8 @@ static uint8_t const* DmDls_decodeAdpcmBlock(uint8_t const* adpcm, float* pcm, u
176174
*pcm++ = (float) sample_b / (float) INT16_MAX;
177175
*pcm++ = (float) sample_a / (float) INT16_MAX;
178176

179-
int coeff_1 = ADPCM_ADAPT_COEFF1[block_predictor];
180-
int coeff_2 = ADPCM_ADAPT_COEFF2[block_predictor];
177+
int coeff_1 = coeff1[block_predictor];
178+
int coeff_2 = coeff2[block_predictor];
181179

182180
uint32_t remaining = block_size - 7 /* header */;
183181
for (uint32_t i = 0; i < remaining; ++i) {
@@ -232,7 +230,7 @@ static size_t DmDls_decodeAdpcm(DmDlsWave const* slf, float* out, size_t len) {
232230
break;
233231
}
234232

235-
adpcm = DmDls_decodeAdpcmBlock(adpcm, out + offset, slf->block_align);
233+
adpcm = DmDls_decodeAdpcmBlock(adpcm, out + offset, slf->block_align, slf->coefficient_table_0 , slf->coefficient_table_1);
236234
offset += frames_per_block;
237235
}
238236

src/_Dls.h

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,6 @@
33
#pragma once
44
#include "_Riff.h"
55

6-
typedef enum DmDlsRegionFlags {
7-
DmDlsRegion_NONEXCLUSIVE = 1 << 0,
8-
} DmDlsRegionFlags;
9-
10-
typedef enum DmDlsWaveSampleFlags {
11-
DmDlsWave_NO_TRUNCATION = 0x11,
12-
DmDlsWave_NO_COMPRESSION = 0x21,
13-
} DmDlsWaveSampleFlags;
14-
15-
typedef enum DmDlsLoopType {
16-
DmDlsLoop_FORWARD = 0,
17-
} DmDlsLoopType;
18-
19-
typedef enum DmDlsWaveLinkFlags {
20-
DmDlsWaveLink_MASTER_PHASE = 1 << 0,
21-
} DmDlsWaveLinkFlags;
22-
236
typedef enum DmDlsArticulatorSource {
247
DmDlsArticulatorSource_NONE = 0,
258
DmDlsArticulatorSource_LFO = 1,
@@ -81,10 +64,25 @@ typedef enum DmDlsArticulatorDestination {
8164
} DmDlsArticulatorDestination;
8265

8366
typedef enum DmDlsArticulatorTransform {
84-
DmDlsArticulatorTransform_NONE = 0,
67+
DmDlsArticulatorTransform_LINEAR = 0,
8568
DmDlsArticulatorTransform_CONCAVE = 1,
8669
DmDlsArticulatorTransform_CONVEX = 2,
8770
DmDlsArticulatorTransform_SWITCH = 3,
71+
72+
DmDlsArticulatorTransform_LINEAR_BIPOLAR = 0x10,
73+
DmDlsArticulatorTransform_CONCAVE_BIPOLAR = 0x11,
74+
DmDlsArticulatorTransform_CONVEX_BIPOLAR = 0x12,
75+
DmDlsArticulatorTransform_SWITCH_BIPOLAR = 0x13,
76+
77+
DmDlsArticulatorTransform_LINEAR_INVERTED = 0x20,
78+
DmDlsArticulatorTransform_CONCAVE_INVERTED = 0x21,
79+
DmDlsArticulatorTransform_CONVEX_INVERTED = 0x22,
80+
DmDlsArticulatorTransform_SWITCH_INVERTED = 0x23,
81+
82+
DmDlsArticulatorTransform_LINEAR_INVERTED_BIPOLAR = 0x30,
83+
DmDlsArticulatorTransform_CONCAVE_INVERTED_BIPOLAR = 0x31,
84+
DmDlsArticulatorTransform_CONVEX_INVERTED_BIPOLAR = 0x32,
85+
DmDlsArticulatorTransform_SWITCH_INVERTED_BIPOLAR = 0x33,
8886
} DmDlsArticulatorTransform;
8987

9088
enum {
@@ -96,11 +94,12 @@ enum {
9694
typedef struct DmDlsWaveSample {
9795
uint16_t unity_note;
9896
uint16_t fine_tune;
99-
int32_t attenuation;
100-
DmDlsWaveSampleFlags flags;
97+
int32_t gain;
98+
bool allow_truncation;
99+
bool allow_compression;
101100

102101
bool looping;
103-
DmDlsLoopType loop_type;
102+
bool loop_with_release;
104103
uint32_t loop_start;
105104
uint32_t loop_length;
106105
} DmDlsWaveSample;
@@ -110,9 +109,11 @@ typedef struct DmDlsArticulator {
110109
uint32_t connection_count;
111110
struct DmDlsArticulatorConnection {
112111
DmDlsArticulatorSource source;
113-
uint16_t control;
112+
DmDlsArticulatorSource control;
114113
DmDlsArticulatorDestination destination;
115-
DmDlsArticulatorTransform transform;
114+
DmDlsArticulatorTransform output_transform;
115+
DmDlsArticulatorTransform control_transform;
116+
DmDlsArticulatorTransform source_transform;
116117
int32_t scale;
117118
}* connections;
118119
} DmDlsArticulator;
@@ -122,12 +123,14 @@ typedef struct DmDlsRegion {
122123
uint16_t range_high;
123124
uint16_t velocity_low;
124125
uint16_t velocity_high;
125-
DmDlsRegionFlags flags;
126126
uint16_t key_group;
127+
bool nonexclusive;
127128

129+
DmInfo info;
128130
DmDlsWaveSample sample;
129131

130-
DmDlsWaveLinkFlags link_flags;
132+
bool link_phase_master;
133+
bool link_multi_channel;
131134
uint16_t link_phase_group;
132135
uint32_t link_channel;
133136
uint32_t link_table_index;
@@ -168,7 +171,8 @@ typedef struct DmDlsWave {
168171

169172
// ADPCM only:
170173
uint16_t samples_per_block;
171-
uint16_t coefficient_table[14];
174+
int16_t coefficient_table_0[7];
175+
int16_t coefficient_table_1[7];
172176

173177
DmDlsWaveSample sample;
174178

src/_Riff.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#define DM_FOURCC_INSH DM_FOURCC('i', 'n', 's', 'h')
5151
#define DM_FOURCC_LRGN DM_FOURCC('l', 'r', 'g', 'n')
5252
#define DM_FOURCC_RGN_ DM_FOURCC('r', 'g', 'n', ' ')
53+
#define DM_FOURCC_RGN2 DM_FOURCC('r', 'g', 'n', '2')
5354
#define DM_FOURCC_RGNH DM_FOURCC('r', 'g', 'n', 'h')
5455
#define DM_FOURCC_WSMP DM_FOURCC('w', 's', 'm', 'p')
5556
#define DM_FOURCC_WLNK DM_FOURCC('w', 'l', 'n', 'k')
@@ -64,6 +65,11 @@
6465
#define DM_FOURCC_WAVH DM_FOURCC('w', 'a', 'v', 'h')
6566
#define DM_FOURCC_WAVU DM_FOURCC('w', 'a', 'v', 'u')
6667
#define DM_FOURCC_SMPL DM_FOURCC('s', 'm', 'p', 'l')
68+
#define DM_FOURCC_WVST DM_FOURCC('w', 'v', 's', 't')
69+
#define DM_FOURCC_CUE_ DM_FOURCC('c', 'u', 'e', ' ')
70+
#define DM_FOURCC_ADTL DM_FOURCC('a', 'd', 't', 'l')
71+
#define DM_FOURCC_PAD_ DM_FOURCC('P', 'A', 'D', ' ')
72+
#define DM_FOURCC_INST DM_FOURCC('i', 'n', 's', 't')
6773
#define DM_FOURCC_STYH DM_FOURCC('s', 't', 'y', 'h')
6874
#define DM_FOURCC_PART DM_FOURCC('p', 'a', 'r', 't')
6975
#define DM_FOURCC_PRTH DM_FOURCC('p', 'r', 't', 'h')

0 commit comments

Comments
 (0)