Subversion Repositories eduke32

Rev

Rev 8775 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8775 Rev 8784
1
/* TinySoundFont - v0.8 - SoundFont2 synthesizer - https://github.com/schellingb/TinySoundFont
1
/* TinySoundFont - v0.8 - SoundFont2 synthesizer - https://github.com/schellingb/TinySoundFont
2
                                     no warranty implied; use at your own risk
2
                                     no warranty implied; use at your own risk
3
   Do this:
3
   Do this:
4
      #define TSF_IMPLEMENTATION
4
      #define TSF_IMPLEMENTATION
5
   before you include this file in *one* C or C++ file to create the implementation.
5
   before you include this file in *one* C or C++ file to create the implementation.
6
   // i.e. it should look like this:
6
   // i.e. it should look like this:
7
   #include ...
7
   #include ...
8
   #include ...
8
   #include ...
9
   #define TSF_IMPLEMENTATION
9
   #define TSF_IMPLEMENTATION
10
   #include "tsf.h"
10
   #include "tsf.h"
11

11

12
   [OPTIONAL] #define TSF_NO_STDIO to remove stdio dependency
12
   [OPTIONAL] #define TSF_NO_STDIO to remove stdio dependency
13
   [OPTIONAL] #define TSF_MALLOC, TSF_REALLOC, and TSF_FREE to avoid stdlib.h
13
   [OPTIONAL] #define TSF_MALLOC, TSF_REALLOC, and TSF_FREE to avoid stdlib.h
14
   [OPTIONAL] #define TSF_MEMCPY, TSF_MEMSET to avoid string.h
14
   [OPTIONAL] #define TSF_MEMCPY, TSF_MEMSET to avoid string.h
15
   [OPTIONAL] #define TSF_POW, TSF_POWF, TSF_EXPF, TSF_LOG, TSF_TAN, TSF_LOG10, TSF_SQRT to avoid math.h
15
   [OPTIONAL] #define TSF_POW, TSF_POWF, TSF_EXPF, TSF_LOG, TSF_TAN, TSF_LOG10, TSF_SQRT to avoid math.h
16

16

17
   NOT YET IMPLEMENTED
17
   NOT YET IMPLEMENTED
18
     - Support for ChorusEffectsSend and ReverbEffectsSend generators
18
     - Support for ChorusEffectsSend and ReverbEffectsSend generators
19
     - Better low-pass filter without lowering performance too much
19
     - Better low-pass filter without lowering performance too much
20
     - Support for modulators
20
     - Support for modulators
21

21

22
   LICENSE (MIT)
22
   LICENSE (MIT)
23

23

24
   Copyright (C) 2017, 2018 Bernhard Schelling
24
   Copyright (C) 2017, 2018 Bernhard Schelling
25
   Based on SFZero, Copyright (C) 2012 Steve Folta (https://github.com/stevefolta/SFZero)
25
   Based on SFZero, Copyright (C) 2012 Steve Folta (https://github.com/stevefolta/SFZero)
26

26

27
   Permission is hereby granted, free of charge, to any person obtaining a copy of this
27
   Permission is hereby granted, free of charge, to any person obtaining a copy of this
28
   software and associated documentation files (the "Software"), to deal in the Software
28
   software and associated documentation files (the "Software"), to deal in the Software
29
   without restriction, including without limitation the rights to use, copy, modify, merge,
29
   without restriction, including without limitation the rights to use, copy, modify, merge,
30
   publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
30
   publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
31
   to whom the Software is furnished to do so, subject to the following conditions:
31
   to whom the Software is furnished to do so, subject to the following conditions:
32

32

33
   The above copyright notice and this permission notice shall be included in all
33
   The above copyright notice and this permission notice shall be included in all
34
   copies or substantial portions of the Software.
34
   copies or substantial portions of the Software.
35

35

36
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
36
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
37
   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37
   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38
   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
38
   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
39
   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
39
   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
40
   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
40
   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
41
   USE OR OTHER DEALINGS IN THE SOFTWARE.
41
   USE OR OTHER DEALINGS IN THE SOFTWARE.
42

42

43
*/
43
*/
44
44
45
#ifndef TSF_INCLUDE_TSF_INL
45
#ifndef TSF_INCLUDE_TSF_INL
46
#define TSF_INCLUDE_TSF_INL
46
#define TSF_INCLUDE_TSF_INL
47
47
48
#ifdef __cplusplus
48
#ifdef __cplusplus
49
extern "C" {
49
extern "C" {
50
#  define CPP_DEFAULT0 = 0
50
#  define CPP_DEFAULT0 = 0
51
#else
51
#else
52
#  define CPP_DEFAULT0
52
#  define CPP_DEFAULT0
53
#endif
53
#endif
54
54
55
//define this if you want the API functions to be static
55
//define this if you want the API functions to be static
56
#ifdef TSF_STATIC
56
#ifdef TSF_STATIC
57
#define TSFDEF static
57
#define TSFDEF static
58
#else
58
#else
59
#define TSFDEF extern
59
#define TSFDEF extern
60
#endif
60
#endif
61
61
62
// The load functions will return a pointer to a struct tsf which all functions
62
// The load functions will return a pointer to a struct tsf which all functions
63
// thereafter take as the first parameter.
63
// thereafter take as the first parameter.
64
// On error the tsf_load* functions will return NULL most likely due to invalid
64
// On error the tsf_load* functions will return NULL most likely due to invalid
65
// data (or if the file did not exist in tsf_load_filename).
65
// data (or if the file did not exist in tsf_load_filename).
66
typedef struct tsf tsf;
66
typedef struct tsf tsf;
67
67
68
#ifndef TSF_NO_STDIO
68
#ifndef TSF_NO_STDIO
69
// Directly load a SoundFont from a .sf2 file path
69
// Directly load a SoundFont from a .sf2 file path
70
TSFDEF tsf* tsf_load_filename(const char* filename);
70
TSFDEF tsf* tsf_load_filename(const char* filename);
71
#endif
71
#endif
72
72
73
// Load a SoundFont from a block of memory
73
// Load a SoundFont from a block of memory
74
TSFDEF tsf* tsf_load_memory(const void* buffer, int size);
74
TSFDEF tsf* tsf_load_memory(const void* buffer, int size);
75
75
76
// Stream structure for the generic loading
76
// Stream structure for the generic loading
77
struct tsf_stream
77
struct tsf_stream
78
{
78
{
79
        // Custom data given to the functions as the first parameter
79
        // Custom data given to the functions as the first parameter
80
        void* data;
80
        void* data;
81
81
82
        // Function pointer will be called to read 'size' bytes into ptr (returns number of read bytes)
82
        // Function pointer will be called to read 'size' bytes into ptr (returns number of read bytes)
83
        int (*read)(void* data, void* ptr, unsigned int size);
83
        int (*read)(void* data, void* ptr, unsigned int size);
84
84
85
        // Function pointer will be called to skip ahead over 'count' bytes (returns 1 on success, 0 on error)
85
        // Function pointer will be called to skip ahead over 'count' bytes (returns 1 on success, 0 on error)
86
        int (*skip)(void* data, unsigned int count);
86
        int (*skip)(void* data, unsigned int count);
87
};
87
};
88
88
89
// Generic SoundFont loading method using the stream structure above
89
// Generic SoundFont loading method using the stream structure above
90
TSFDEF tsf* tsf_load(struct tsf_stream* stream);
90
TSFDEF tsf* tsf_load(struct tsf_stream* stream);
91
91
92
// Free the memory related to this tsf instance
92
// Free the memory related to this tsf instance
93
TSFDEF void tsf_close(tsf* f);
93
TSFDEF void tsf_close(tsf* f);
94
94
95
// Stop all playing notes immediatly and reset all channel parameters
95
// Stop all playing notes immediatly and reset all channel parameters
96
TSFDEF void tsf_reset(tsf* f);
96
TSFDEF void tsf_reset(tsf* f);
97
97
98
// Returns the preset index from a bank and preset number, or -1 if it does not exist in the loaded SoundFont
98
// Returns the preset index from a bank and preset number, or -1 if it does not exist in the loaded SoundFont
99
TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number);
99
TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number);
100
100
101
// Returns the number of presets in the loaded SoundFont
101
// Returns the number of presets in the loaded SoundFont
102
TSFDEF int tsf_get_presetcount(const tsf* f);
102
TSFDEF int tsf_get_presetcount(const tsf* f);
103
103
104
// Returns the name of a preset index >= 0 and < tsf_get_presetcount()
104
// Returns the name of a preset index >= 0 and < tsf_get_presetcount()
105
TSFDEF const char* tsf_get_presetname(const tsf* f, int preset_index);
105
TSFDEF const char* tsf_get_presetname(const tsf* f, int preset_index);
106
106
107
// Returns the name of a preset by bank and preset number
107
// Returns the name of a preset by bank and preset number
108
TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number);
108
TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number);
109
109
110
// Supported output modes by the render methods
110
// Supported output modes by the render methods
111
enum TSFOutputMode
111
enum TSFOutputMode
112
{
112
{
113
        // Two channels with single left/right samples one after another
113
        // Two channels with single left/right samples one after another
114
        TSF_STEREO_INTERLEAVED,
114
        TSF_STEREO_INTERLEAVED,
115
        // Two channels with all samples for the left channel first then right
115
        // Two channels with all samples for the left channel first then right
116
        TSF_STEREO_UNWEAVED,
116
        TSF_STEREO_UNWEAVED,
117
        // A single channel (stereo instruments are mixed into center)
117
        // A single channel (stereo instruments are mixed into center)
118
        TSF_MONO,
118
        TSF_MONO,
119
};
119
};
120
120
121
// Thread safety:
121
// Thread safety:
122
// Your audio output which calls the tsf_render* functions will most likely
122
// Your audio output which calls the tsf_render* functions will most likely
123
// run on a different thread than where the playback tsf_note* functions
123
// run on a different thread than where the playback tsf_note* functions
124
// are called. In which case some sort of concurrency control like a
124
// are called. In which case some sort of concurrency control like a
125
// mutex needs to be used so they are not called at the same time.
125
// mutex needs to be used so they are not called at the same time.
126
126
127
// Setup the parameters for the voice render methods
127
// Setup the parameters for the voice render methods
128
//   outputmode: if mono or stereo and how stereo channel data is ordered
128
//   outputmode: if mono or stereo and how stereo channel data is ordered
129
//   samplerate: the number of samples per second (output frequency)
129
//   samplerate: the number of samples per second (output frequency)
130
//   global_gain_db: volume gain in decibels (>0 means higher, <0 means lower)
130
//   global_gain_db: volume gain in decibels (>0 means higher, <0 means lower)
131
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db CPP_DEFAULT0);
131
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db CPP_DEFAULT0);
132
132
133
// Start playing a note
133
// Start playing a note
134
//   preset_index: preset index >= 0 and < tsf_get_presetcount()
134
//   preset_index: preset index >= 0 and < tsf_get_presetcount()
135
//   key: note value between 0 and 127 (60 being middle C)
135
//   key: note value between 0 and 127 (60 being middle C)
136
//   vel: velocity as a float between 0.0 (equal to note off) and 1.0 (full)
136
//   vel: velocity as a float between 0.0 (equal to note off) and 1.0 (full)
137
//   bank: instrument bank number (alternative to preset_index)
137
//   bank: instrument bank number (alternative to preset_index)
138
//   preset_number: preset number (alternative to preset_index)
138
//   preset_number: preset number (alternative to preset_index)
139
//   (bank_note_on returns 0 if preset does not exist, otherwise 1)
139
//   (bank_note_on returns 0 if preset does not exist, otherwise 1)
140
TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel);
140
TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel);
141
TSFDEF int  tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel);
141
TSFDEF int  tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel);
142
142
143
// Stop playing a note
143
// Stop playing a note
144
//   (bank_note_off returns 0 if preset does not exist, otherwise 1)
144
//   (bank_note_off returns 0 if preset does not exist, otherwise 1)
145
TSFDEF void tsf_note_off(tsf* f, int preset_index, int key);
145
TSFDEF void tsf_note_off(tsf* f, int preset_index, int key);
146
TSFDEF int  tsf_bank_note_off(tsf* f, int bank, int preset_number, int key);
146
TSFDEF int  tsf_bank_note_off(tsf* f, int bank, int preset_number, int key);
147
147
148
// Stop playing all notes (end with sustain and release)
148
// Stop playing all notes (end with sustain and release)
149
TSFDEF void tsf_note_off_all(tsf* f);
149
TSFDEF void tsf_note_off_all(tsf* f);
150
150
151
// Returns the number of active voices
151
// Returns the number of active voices
152
TSFDEF int tsf_active_voice_count(tsf* f);
152
TSFDEF int tsf_active_voice_count(tsf* f);
153
153
154
// Render output samples into a buffer
154
// Render output samples into a buffer
155
// You can either render as signed 16-bit values (tsf_render_short) or
155
// You can either render as signed 16-bit values (tsf_render_short) or
156
// as 32-bit float values (tsf_render_float)
156
// as 32-bit float values (tsf_render_float)
157
//   buffer: target buffer of size samples * output_channels * sizeof(type)
157
//   buffer: target buffer of size samples * output_channels * sizeof(type)
158
//   samples: number of samples to render
158
//   samples: number of samples to render
159
//   flag_mixing: if 0 clear the buffer first, otherwise mix into existing data
159
//   flag_mixing: if 0 clear the buffer first, otherwise mix into existing data
160
TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing CPP_DEFAULT0);
160
TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing CPP_DEFAULT0);
161
TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing CPP_DEFAULT0);
161
TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing CPP_DEFAULT0);
162
162
163
// Higher level channel based functions, set up channel parameters
163
// Higher level channel based functions, set up channel parameters
164
//   channel: channel number
164
//   channel: channel number
165
//   preset_index: preset index >= 0 and < tsf_get_presetcount()
165
//   preset_index: preset index >= 0 and < tsf_get_presetcount()
166
//   preset_number: preset number (alternative to preset_index)
166
//   preset_number: preset number (alternative to preset_index)
167
//   flag_mididrums: 0 for normal channels, otherwise apply MIDI drum channel rules
167
//   flag_mididrums: 0 for normal channels, otherwise apply MIDI drum channel rules
168
//   bank: instrument bank number (alternative to preset_index)
168
//   bank: instrument bank number (alternative to preset_index)
169
//   pan: stereo panning value from 0.0 (left) to 1.0 (right) (default 0.5 center)
169
//   pan: stereo panning value from 0.0 (left) to 1.0 (right) (default 0.5 center)
170
//   volume: linear volume scale factor (default 1.0 full)
170
//   volume: linear volume scale factor (default 1.0 full)
171
//   pitch_wheel: pitch wheel position 0 to 16383 (default 8192 unpitched)
171
//   pitch_wheel: pitch wheel position 0 to 16383 (default 8192 unpitched)
172
//   pitch_range: range of the pitch wheel in semitones (default 2.0, total +/- 2 semitones)
172
//   pitch_range: range of the pitch wheel in semitones (default 2.0, total +/- 2 semitones)
173
//   tuning: tuning of all playing voices in semitones (default 0.0, standard (A440) tuning)
173
//   tuning: tuning of all playing voices in semitones (default 0.0, standard (A440) tuning)
174
//   (set_preset_number and set_bank_preset return 0 if preset does not exist, otherwise 1)
174
//   (set_preset_number and set_bank_preset return 0 if preset does not exist, otherwise 1)
175
TSFDEF void tsf_channel_set_presetindex(tsf* f, int channel, int preset_index);
175
TSFDEF void tsf_channel_set_presetindex(tsf* f, int channel, int preset_index);
176
TSFDEF int  tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums CPP_DEFAULT0);
176
TSFDEF int  tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums CPP_DEFAULT0);
177
TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank);
177
TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank);
178
TSFDEF int  tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number);
178
TSFDEF int  tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number);
179
TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan);
179
TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan);
180
TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume);
180
TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume);
181
TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel);
181
TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel);
182
TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range);
182
TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range);
183
TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning);
183
TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning);
184
184
185
// Start or stop playing notes on a channel (needs channel preset to be set)
185
// Start or stop playing notes on a channel (needs channel preset to be set)
186
//   channel: channel number
186
//   channel: channel number
187
//   key: note value between 0 and 127 (60 being middle C)
187
//   key: note value between 0 and 127 (60 being middle C)
188
//   vel: velocity as a float between 0.0 (equal to note off) and 1.0 (full)
188
//   vel: velocity as a float between 0.0 (equal to note off) and 1.0 (full)
189
TSFDEF void tsf_channel_note_on(tsf* f, int channel, int key, float vel);
189
TSFDEF void tsf_channel_note_on(tsf* f, int channel, int key, float vel);
190
TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key);
190
TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key);
191
TSFDEF void tsf_channel_note_off_all(tsf* f, int channel); //end with sustain and release
191
TSFDEF void tsf_channel_note_off_all(tsf* f, int channel); //end with sustain and release
192
TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel); //end immediatly
192
TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel); //end immediatly
193
193
194
// Apply a MIDI control change to the channel (not all controllers are supported!)
194
// Apply a MIDI control change to the channel (not all controllers are supported!)
195
TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value);
195
TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value);
196
196
197
// Get current values set on the channels
197
// Get current values set on the channels
198
TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel);
198
TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel);
199
TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel);
199
TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel);
200
TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel);
200
TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel);
201
TSFDEF float tsf_channel_get_pan(tsf* f, int channel);
201
TSFDEF float tsf_channel_get_pan(tsf* f, int channel);
202
TSFDEF float tsf_channel_get_volume(tsf* f, int channel);
202
TSFDEF float tsf_channel_get_volume(tsf* f, int channel);
203
TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel);
203
TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel);
204
TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel);
204
TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel);
205
TSFDEF float tsf_channel_get_tuning(tsf* f, int channel);
205
TSFDEF float tsf_channel_get_tuning(tsf* f, int channel);
206
206
207
#ifdef __cplusplus
207
#ifdef __cplusplus
208
#  undef CPP_DEFAULT0
208
#  undef CPP_DEFAULT0
209
}
209
}
210
#endif
210
#endif
211
211
212
// end header
212
// end header
213
// ---------------------------------------------------------------------------------------------------------
213
// ---------------------------------------------------------------------------------------------------------
214
#endif //TSF_INCLUDE_TSF_INL
214
#endif //TSF_INCLUDE_TSF_INL
215
215
216
#ifdef TSF_IMPLEMENTATION
216
#ifdef TSF_IMPLEMENTATION
217
217
218
// The lower this block size is the more accurate the effects are.
218
// The lower this block size is the more accurate the effects are.
219
// Increasing the value significantly lowers the CPU usage of the voice rendering.
219
// Increasing the value significantly lowers the CPU usage of the voice rendering.
220
// If LFO affects the low-pass filter it can be hearable even as low as 8.
220
// If LFO affects the low-pass filter it can be hearable even as low as 8.
221
#ifndef TSF_RENDER_EFFECTSAMPLEBLOCK
221
#ifndef TSF_RENDER_EFFECTSAMPLEBLOCK
222
#define TSF_RENDER_EFFECTSAMPLEBLOCK 64
222
#define TSF_RENDER_EFFECTSAMPLEBLOCK 64
223
#endif
223
#endif
224
224
225
// Grace release time for quick voice off (avoid clicking noise)
225
// Grace release time for quick voice off (avoid clicking noise)
226
#define TSF_FASTRELEASETIME 0.01f
226
#define TSF_FASTRELEASETIME 0.01f
227
227
228
#if !defined(TSF_MALLOC) || !defined(TSF_FREE) || !defined(TSF_REALLOC)
228
#if !defined(TSF_MALLOC) || !defined(TSF_FREE) || !defined(TSF_REALLOC)
229
#  include <stdlib.h>
229
#  include <stdlib.h>
230
#  define TSF_MALLOC  malloc
230
#  define TSF_MALLOC  malloc
231
#  define TSF_FREE    free
231
#  define TSF_FREE    free
232
#  define TSF_REALLOC realloc
232
#  define TSF_REALLOC realloc
233
#endif
233
#endif
234
234
235
#if !defined(TSF_MEMCPY) || !defined(TSF_MEMSET)
235
#if !defined(TSF_MEMCPY) || !defined(TSF_MEMSET)
236
#  include <string.h>
236
#  include <string.h>
237
#  define TSF_MEMCPY  memcpy
237
#  define TSF_MEMCPY  memcpy
238
#  define TSF_MEMSET  memset
238
#  define TSF_MEMSET  memset
239
#endif
239
#endif
240
240
241
#if !defined(TSF_POW) || !defined(TSF_POWF) || !defined(TSF_EXPF) || !defined(TSF_LOG) || !defined(TSF_TAN) || !defined(TSF_LOG10) || !defined(TSF_SQRT)
241
#if !defined(TSF_POW) || !defined(TSF_POWF) || !defined(TSF_EXPF) || !defined(TSF_LOG) || !defined(TSF_TAN) || !defined(TSF_LOG10) || !defined(TSF_SQRT)
242
#  include <math.h>
242
#  include <math.h>
243
#  if !defined(__cplusplus) && !defined(NAN) && !defined(powf) && !defined(expf) && !defined(sqrtf)
243
#  if !defined(__cplusplus) && !defined(NAN) && !defined(powf) && !defined(expf) && !defined(sqrtf)
244
#    define powf (float)pow // deal with old math.h
244
#    define powf (float)pow // deal with old math.h
245
#    define expf (float)exp // files that come without
245
#    define expf (float)exp // files that come without
246
#    define sqrtf (float)sqrt // powf, expf and sqrtf
246
#    define sqrtf (float)sqrt // powf, expf and sqrtf
247
#  endif
247
#  endif
248
#  define TSF_POW     pow
248
#  define TSF_POW     pow
249
#  define TSF_POWF    powf
249
#  define TSF_POWF    powf
250
#  define TSF_EXPF    expf
250
#  define TSF_EXPF    expf
251
#  define TSF_LOG     log
251
#  define TSF_LOG     log
252
#  define TSF_TAN     tan
252
#  define TSF_TAN     tan
253
#  define TSF_LOG10   log10
253
#  define TSF_LOG10   log10
254
#  define TSF_SQRTF   sqrtf
254
#  define TSF_SQRTF   sqrtf
255
#endif
255
#endif
256
256
257
#ifndef TSF_NO_STDIO
257
#ifndef TSF_NO_STDIO
258
#  include <stdio.h>
258
#  include <stdio.h>
259
#endif
259
#endif
260
260
261
#define TSF_TRUE 1
261
#define TSF_TRUE 1
262
#define TSF_FALSE 0
262
#define TSF_FALSE 0
263
#define TSF_BOOL char
263
#define TSF_BOOL char
264
#define TSF_PI 3.14159265358979323846264338327950288
264
#define TSF_PI 3.14159265358979323846264338327950288
265
#define TSF_NULL 0
265
#define TSF_NULL 0
266
266
267
#ifdef __cplusplus
267
#ifdef __cplusplus
268
extern "C" {
268
extern "C" {
269
#endif
269
#endif
270
270
271
typedef char tsf_fourcc[4];
271
typedef char tsf_fourcc[4];
272
typedef signed char tsf_s8;
272
typedef signed char tsf_s8;
273
typedef unsigned char tsf_u8;
273
typedef unsigned char tsf_u8;
274
typedef unsigned short tsf_u16;
274
typedef unsigned short tsf_u16;
275
typedef signed short tsf_s16;
275
typedef signed short tsf_s16;
276
typedef unsigned int tsf_u32;
276
typedef unsigned int tsf_u32;
277
typedef char tsf_char20[20];
277
typedef char tsf_char20[20];
278
278
279
#define TSF_FourCCEquals(value1, value2) (value1[0] == value2[0] && value1[1] == value2[1] && value1[2] == value2[2] && value1[3] == value2[3])
279
#define TSF_FourCCEquals(value1, value2) (value1[0] == value2[0] && value1[1] == value2[1] && value1[2] == value2[2] && value1[3] == value2[3])
280
280
281
struct tsf
281
struct tsf
282
{
282
{
283
        struct tsf_preset* presets;
283
        struct tsf_preset* presets;
284
        float* fontSamples;
284
        float* fontSamples;
285
        struct tsf_voice* voices;
285
        struct tsf_voice* voices;
286
        struct tsf_channels* channels;
286
        struct tsf_channels* channels;
287
        float* outputSamples;
287
        float* outputSamples;
288
288
289
        int presetNum;
289
        int presetNum;
290
        int voiceNum;
290
        int voiceNum;
291
        int outputSampleSize;
291
        int outputSampleSize;
292
        unsigned int voicePlayIndex;
292
        unsigned int voicePlayIndex;
293
293
294
        enum TSFOutputMode outputmode;
294
        enum TSFOutputMode outputmode;
295
        float outSampleRate;
295
        float outSampleRate;
296
        float globalGainDB;
296
        float globalGainDB;
297
};
297
};
298
298
299
#ifndef TSF_NO_STDIO
299
#ifndef TSF_NO_STDIO
300
static int tsf_stream_stdio_read(FILE* f, void* ptr, unsigned int size) { return (int)fread(ptr, 1, size, f); }
300
static int tsf_stream_stdio_read(FILE* f, void* ptr, unsigned int size) { return (int)fread(ptr, 1, size, f); }
301
static int tsf_stream_stdio_skip(FILE* f, unsigned int count) { return !fseek(f, count, SEEK_CUR); }
301
static int tsf_stream_stdio_skip(FILE* f, unsigned int count) { return !fseek(f, count, SEEK_CUR); }
302
TSFDEF tsf* tsf_load_filename(const char* filename)
302
TSFDEF tsf* tsf_load_filename(const char* filename)
303
{
303
{
304
        tsf* res;
304
        tsf* res;
305
        struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_stdio_read, (int(*)(void*,unsigned int))&tsf_stream_stdio_skip };
305
        struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_stdio_read, (int(*)(void*,unsigned int))&tsf_stream_stdio_skip };
306
        #if __STDC_WANT_SECURE_LIB__
306
        #if __STDC_WANT_SECURE_LIB__
307
        FILE* f = TSF_NULL; fopen_s(&f, filename, "rb");
307
        FILE* f = TSF_NULL; fopen_s(&f, filename, "rb");
308
        #else
308
        #else
309
        FILE* f = fopen(filename, "rb");
309
        FILE* f = fopen(filename, "rb");
310
        #endif
310
        #endif
311
        if (!f)
311
        if (!f)
312
        {
312
        {
313
                //if (e) *e = TSF_FILENOTFOUND;
313
                //if (e) *e = TSF_FILENOTFOUND;
314
                return TSF_NULL;
314
                return TSF_NULL;
315
        }
315
        }
316
        stream.data = f;
316
        stream.data = f;
317
        res = tsf_load(&stream);
317
        res = tsf_load(&stream);
318
        fclose(f);
318
        fclose(f);
319
        return res;
319
        return res;
320
}
320
}
321
#endif
321
#endif
322
322
323
struct tsf_stream_memory { const char* buffer; unsigned int total, pos; };
323
struct tsf_stream_memory { const char* buffer; unsigned int total, pos; };
324
static int tsf_stream_memory_read(struct tsf_stream_memory* m, void* ptr, unsigned int size) { if (size > m->total - m->pos) size = m->total - m->pos; TSF_MEMCPY(ptr, m->buffer+m->pos, size); m->pos += size; return size; }
324
static int tsf_stream_memory_read(struct tsf_stream_memory* m, void* ptr, unsigned int size) { if (size > m->total - m->pos) size = m->total - m->pos; TSF_MEMCPY(ptr, m->buffer+m->pos, size); m->pos += size; return size; }
325
static int tsf_stream_memory_skip(struct tsf_stream_memory* m, unsigned int count) { if (m->pos + count > m->total) return 0; m->pos += count; return 1; }
325
static int tsf_stream_memory_skip(struct tsf_stream_memory* m, unsigned int count) { if (m->pos + count > m->total) return 0; m->pos += count; return 1; }
326
TSFDEF tsf* tsf_load_memory(const void* buffer, int size)
326
TSFDEF tsf* tsf_load_memory(const void* buffer, int size)
327
{
327
{
328
        struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_memory_read, (int(*)(void*,unsigned int))&tsf_stream_memory_skip };
328
        struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_memory_read, (int(*)(void*,unsigned int))&tsf_stream_memory_skip };
329
        struct tsf_stream_memory f = { 0, 0, 0 };
329
        struct tsf_stream_memory f = { 0, 0, 0 };
330
        f.buffer = (const char*)buffer;
330
        f.buffer = (const char*)buffer;
331
        f.total = size;
331
        f.total = size;
332
        stream.data = &f;
332
        stream.data = &f;
333
        return tsf_load(&stream);
333
        return tsf_load(&stream);
334
}
334
}
335
335
336
enum { TSF_LOOPMODE_NONE, TSF_LOOPMODE_CONTINUOUS, TSF_LOOPMODE_SUSTAIN };
336
enum { TSF_LOOPMODE_NONE, TSF_LOOPMODE_CONTINUOUS, TSF_LOOPMODE_SUSTAIN };
337
337
338
enum { TSF_SEGMENT_NONE, TSF_SEGMENT_DELAY, TSF_SEGMENT_ATTACK, TSF_SEGMENT_HOLD, TSF_SEGMENT_DECAY, TSF_SEGMENT_SUSTAIN, TSF_SEGMENT_RELEASE, TSF_SEGMENT_DONE };
338
enum { TSF_SEGMENT_NONE, TSF_SEGMENT_DELAY, TSF_SEGMENT_ATTACK, TSF_SEGMENT_HOLD, TSF_SEGMENT_DECAY, TSF_SEGMENT_SUSTAIN, TSF_SEGMENT_RELEASE, TSF_SEGMENT_DONE };
339
339
340
struct tsf_hydra
340
struct tsf_hydra
341
{
341
{
342
        struct tsf_hydra_phdr *phdrs; struct tsf_hydra_pbag *pbags; struct tsf_hydra_pmod *pmods;
342
        struct tsf_hydra_phdr *phdrs; struct tsf_hydra_pbag *pbags; struct tsf_hydra_pmod *pmods;
343
        struct tsf_hydra_pgen *pgens; struct tsf_hydra_inst *insts; struct tsf_hydra_ibag *ibags;
343
        struct tsf_hydra_pgen *pgens; struct tsf_hydra_inst *insts; struct tsf_hydra_ibag *ibags;
344
        struct tsf_hydra_imod *imods; struct tsf_hydra_igen *igens; struct tsf_hydra_shdr *shdrs;
344
        struct tsf_hydra_imod *imods; struct tsf_hydra_igen *igens; struct tsf_hydra_shdr *shdrs;
345
        int phdrNum, pbagNum, pmodNum, pgenNum, instNum, ibagNum, imodNum, igenNum, shdrNum;
345
        int phdrNum, pbagNum, pmodNum, pgenNum, instNum, ibagNum, imodNum, igenNum, shdrNum;
346
};
346
};
347
347
348
union tsf_hydra_genamount { struct { tsf_u8 lo, hi; } range; tsf_s16 shortAmount; tsf_u16 wordAmount; };
348
union tsf_hydra_genamount { struct { tsf_u8 lo, hi; } range; tsf_s16 shortAmount; tsf_u16 wordAmount; };
349
struct tsf_hydra_phdr { tsf_char20 presetName; tsf_u16 preset, bank, presetBagNdx; tsf_u32 library, genre, morphology; };
349
struct tsf_hydra_phdr { tsf_char20 presetName; tsf_u16 preset, bank, presetBagNdx; tsf_u32 library, genre, morphology; };
350
struct tsf_hydra_pbag { tsf_u16 genNdx, modNdx; };
350
struct tsf_hydra_pbag { tsf_u16 genNdx, modNdx; };
351
struct tsf_hydra_pmod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; };
351
struct tsf_hydra_pmod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; };
352
struct tsf_hydra_pgen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; };
352
struct tsf_hydra_pgen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; };
353
struct tsf_hydra_inst { tsf_char20 instName; tsf_u16 instBagNdx; };
353
struct tsf_hydra_inst { tsf_char20 instName; tsf_u16 instBagNdx; };
354
struct tsf_hydra_ibag { tsf_u16 instGenNdx, instModNdx; };
354
struct tsf_hydra_ibag { tsf_u16 instGenNdx, instModNdx; };
355
struct tsf_hydra_imod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; };
355
struct tsf_hydra_imod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; };
356
struct tsf_hydra_igen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; };
356
struct tsf_hydra_igen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; };
357
struct tsf_hydra_shdr { tsf_char20 sampleName; tsf_u32 start, end, startLoop, endLoop, sampleRate; tsf_u8 originalPitch; tsf_s8 pitchCorrection; tsf_u16 sampleLink, sampleType; };
357
struct tsf_hydra_shdr { tsf_char20 sampleName; tsf_u32 start, end, startLoop, endLoop, sampleRate; tsf_u8 originalPitch; tsf_s8 pitchCorrection; tsf_u16 sampleLink, sampleType; };
358
358
359
#define TSFR(FIELD) stream->read(stream->data, &i->FIELD, sizeof(i->FIELD));
359
#define TSFR(FIELD) stream->read(stream->data, &i->FIELD, sizeof(i->FIELD));
360
static void tsf_hydra_read_phdr(struct tsf_hydra_phdr* i, struct tsf_stream* stream) { TSFR(presetName) TSFR(preset) TSFR(bank) TSFR(presetBagNdx) TSFR(library) TSFR(genre) TSFR(morphology) }
360
static void tsf_hydra_read_phdr(struct tsf_hydra_phdr* i, struct tsf_stream* stream) { TSFR(presetName) TSFR(preset) TSFR(bank) TSFR(presetBagNdx) TSFR(library) TSFR(genre) TSFR(morphology) }
361
static void tsf_hydra_read_pbag(struct tsf_hydra_pbag* i, struct tsf_stream* stream) { TSFR(genNdx) TSFR(modNdx) }
361
static void tsf_hydra_read_pbag(struct tsf_hydra_pbag* i, struct tsf_stream* stream) { TSFR(genNdx) TSFR(modNdx) }
362
static void tsf_hydra_read_pmod(struct tsf_hydra_pmod* i, struct tsf_stream* stream) { TSFR(modSrcOper) TSFR(modDestOper) TSFR(modAmount) TSFR(modAmtSrcOper) TSFR(modTransOper) }
362
static void tsf_hydra_read_pmod(struct tsf_hydra_pmod* i, struct tsf_stream* stream) { TSFR(modSrcOper) TSFR(modDestOper) TSFR(modAmount) TSFR(modAmtSrcOper) TSFR(modTransOper) }
363
static void tsf_hydra_read_pgen(struct tsf_hydra_pgen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) }
363
static void tsf_hydra_read_pgen(struct tsf_hydra_pgen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) }
364
static void tsf_hydra_read_inst(struct tsf_hydra_inst* i, struct tsf_stream* stream) { TSFR(instName) TSFR(instBagNdx) }
364
static void tsf_hydra_read_inst(struct tsf_hydra_inst* i, struct tsf_stream* stream) { TSFR(instName) TSFR(instBagNdx) }
365
static void tsf_hydra_read_ibag(struct tsf_hydra_ibag* i, struct tsf_stream* stream) { TSFR(instGenNdx) TSFR(instModNdx) }
365
static void tsf_hydra_read_ibag(struct tsf_hydra_ibag* i, struct tsf_stream* stream) { TSFR(instGenNdx) TSFR(instModNdx) }
366
static void tsf_hydra_read_imod(struct tsf_hydra_imod* i, struct tsf_stream* stream) { TSFR(modSrcOper) TSFR(modDestOper) TSFR(modAmount) TSFR(modAmtSrcOper) TSFR(modTransOper) }
366
static void tsf_hydra_read_imod(struct tsf_hydra_imod* i, struct tsf_stream* stream) { TSFR(modSrcOper) TSFR(modDestOper) TSFR(modAmount) TSFR(modAmtSrcOper) TSFR(modTransOper) }
367
static void tsf_hydra_read_igen(struct tsf_hydra_igen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) }
367
static void tsf_hydra_read_igen(struct tsf_hydra_igen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) }
368
static void tsf_hydra_read_shdr(struct tsf_hydra_shdr* i, struct tsf_stream* stream) { TSFR(sampleName) TSFR(start) TSFR(end) TSFR(startLoop) TSFR(endLoop) TSFR(sampleRate) TSFR(originalPitch) TSFR(pitchCorrection) TSFR(sampleLink) TSFR(sampleType) }
368
static void tsf_hydra_read_shdr(struct tsf_hydra_shdr* i, struct tsf_stream* stream) { TSFR(sampleName) TSFR(start) TSFR(end) TSFR(startLoop) TSFR(endLoop) TSFR(sampleRate) TSFR(originalPitch) TSFR(pitchCorrection) TSFR(sampleLink) TSFR(sampleType) }
369
#undef TSFR
369
#undef TSFR
370
370
371
struct tsf_riffchunk { tsf_fourcc id; tsf_u32 size; };
371
struct tsf_riffchunk { tsf_fourcc id; tsf_u32 size; };
372
struct tsf_envelope { float delay, attack, hold, decay, sustain, release, keynumToHold, keynumToDecay; };
372
struct tsf_envelope { float delay, attack, hold, decay, sustain, release, keynumToHold, keynumToDecay; };
373
struct tsf_voice_envelope { float level, slope; int samplesUntilNextSegment; short segment, midiVelocity; struct tsf_envelope parameters; TSF_BOOL segmentIsExponential, isAmpEnv; };
373
struct tsf_voice_envelope { float level, slope; int samplesUntilNextSegment; short segment, midiVelocity; struct tsf_envelope parameters; TSF_BOOL segmentIsExponential, isAmpEnv; };
374
struct tsf_voice_lowpass { double QInv, a0, a1, b1, b2, z1, z2; TSF_BOOL active; };
374
struct tsf_voice_lowpass { double QInv, a0, a1, b1, b2, z1, z2; TSF_BOOL active; };
375
struct tsf_voice_lfo { int samplesUntil; float level, delta; };
375
struct tsf_voice_lfo { int samplesUntil; float level, delta; };
376
376
377
struct tsf_region
377
struct tsf_region
378
{
378
{
379
        int loop_mode;
379
        int loop_mode;
380
        unsigned int sample_rate;
380
        unsigned int sample_rate;
381
        unsigned char lokey, hikey, lovel, hivel;
381
        unsigned char lokey, hikey, lovel, hivel;
382
        unsigned int group, offset, end, loop_start, loop_end;
382
        unsigned int group, offset, end, loop_start, loop_end;
383
        int transpose, tune, pitch_keycenter, pitch_keytrack;
383
        int transpose, tune, pitch_keycenter, pitch_keytrack;
384
        float attenuation, pan;
384
        float attenuation, pan;
385
        struct tsf_envelope ampenv, modenv;
385
        struct tsf_envelope ampenv, modenv;
386
        int initialFilterQ, initialFilterFc;
386
        int initialFilterQ, initialFilterFc;
387
        int modEnvToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume;
387
        int modEnvToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume;
388
        float delayModLFO;
388
        float delayModLFO;
389
        int freqModLFO, modLfoToPitch;
389
        int freqModLFO, modLfoToPitch;
390
        float delayVibLFO;
390
        float delayVibLFO;
391
        int freqVibLFO, vibLfoToPitch;
391
        int freqVibLFO, vibLfoToPitch;
392
};
392
};
393
393
394
struct tsf_preset
394
struct tsf_preset
395
{
395
{
396
        tsf_char20 presetName;
396
        tsf_char20 presetName;
397
        tsf_u16 preset, bank;
397
        tsf_u16 preset, bank;
398
        struct tsf_region* regions;
398
        struct tsf_region* regions;
399
        int regionNum;
399
        int regionNum;
400
};
400
};
401
401
402
struct tsf_voice
402
struct tsf_voice
403
{
403
{
404
        int playingPreset, playingKey, playingChannel;
404
        int playingPreset, playingKey, playingChannel;
405
        struct tsf_region* region;
405
        struct tsf_region* region;
406
        double pitchInputTimecents, pitchOutputFactor;
406
        double pitchInputTimecents, pitchOutputFactor;
407
        double sourceSamplePosition;
407
        double sourceSamplePosition;
408
        float  noteGainDB, panFactorLeft, panFactorRight;
408
        float  noteGainDB, panFactorLeft, panFactorRight;
409
        unsigned int playIndex, loopStart, loopEnd;
409
        unsigned int playIndex, loopStart, loopEnd;
410
        struct tsf_voice_envelope ampenv, modenv;
410
        struct tsf_voice_envelope ampenv, modenv;
411
        struct tsf_voice_lowpass lowpass;
411
        struct tsf_voice_lowpass lowpass;
412
        struct tsf_voice_lfo modlfo, viblfo;
412
        struct tsf_voice_lfo modlfo, viblfo;
413
};
413
};
414
414
415
struct tsf_channel
415
struct tsf_channel
416
{
416
{
417
        unsigned short presetIndex, bank, pitchWheel, midiPan, midiVolume, midiExpression, midiRPN, midiData;
417
        unsigned short presetIndex, bank, pitchWheel, midiPan, midiVolume, midiExpression, midiRPN, midiData;
418
        float panOffset, gainDB, pitchRange, tuning;
418
        float panOffset, gainDB, pitchRange, tuning;
419
};
419
};
420
420
421
struct tsf_channels
421
struct tsf_channels
422
{
422
{
423
        void (*setupVoice)(tsf* f, struct tsf_voice* voice);
423
        void (*setupVoice)(tsf* f, struct tsf_voice* voice);
424
        struct tsf_channel* channels;
424
        struct tsf_channel* channels;
425
        int channelNum, activeChannel;
425
        int channelNum, activeChannel;
426
};
426
};
427
427
428
static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); }
428
static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); }
429
static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); }
429
static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); }
430
static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); }
430
static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); }
431
static float tsf_decibelsToGain(float db) { return (db > -100.f ? TSF_POWF(10.0f, db * 0.05f) : 0); }
431
static float tsf_decibelsToGain(float db) { return (db > -100.f ? TSF_POWF(10.0f, db * 0.05f) : 0); }
432
static float tsf_gainToDecibels(float gain) { return (gain <= .00001f ? -100.f : (float)(20.0 * TSF_LOG10(gain))); }
432
static float tsf_gainToDecibels(float gain) { return (gain <= .00001f ? -100.f : (float)(20.0 * TSF_LOG10(gain))); }
433
433
434
static TSF_BOOL tsf_riffchunk_read(struct tsf_riffchunk* parent, struct tsf_riffchunk* chunk, struct tsf_stream* stream)
434
static TSF_BOOL tsf_riffchunk_read(struct tsf_riffchunk* parent, struct tsf_riffchunk* chunk, struct tsf_stream* stream)
435
{
435
{
436
        TSF_BOOL IsRiff, IsList;
436
        TSF_BOOL IsRiff, IsList;
437
        if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) > parent->size) return TSF_FALSE;
437
        if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) > parent->size) return TSF_FALSE;
438
        if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE;
438
        if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE;
439
        if (!stream->read(stream->data, &chunk->size, sizeof(tsf_u32))) return TSF_FALSE;
439
        if (!stream->read(stream->data, &chunk->size, sizeof(tsf_u32))) return TSF_FALSE;
440
        if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size > parent->size) return TSF_FALSE;
440
        if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size > parent->size) return TSF_FALSE;
441
        if (parent) parent->size -= sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size;
441
        if (parent) parent->size -= sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size;
442
        IsRiff = TSF_FourCCEquals(chunk->id, "RIFF"), IsList = TSF_FourCCEquals(chunk->id, "LIST");
442
        IsRiff = TSF_FourCCEquals(chunk->id, "RIFF"), IsList = TSF_FourCCEquals(chunk->id, "LIST");
443
        if (IsRiff && parent) return TSF_FALSE; //not allowed
443
        if (IsRiff && parent) return TSF_FALSE; //not allowed
444
        if (!IsRiff && !IsList) return TSF_TRUE; //custom type without sub type
444
        if (!IsRiff && !IsList) return TSF_TRUE; //custom type without sub type
445
        if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE;
445
        if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE;
446
        chunk->size -= sizeof(tsf_fourcc);
446
        chunk->size -= sizeof(tsf_fourcc);
447
        return TSF_TRUE;
447
        return TSF_TRUE;
448
}
448
}
449
449
450
static void tsf_region_clear(struct tsf_region* i, TSF_BOOL for_relative)
450
static void tsf_region_clear(struct tsf_region* i, TSF_BOOL for_relative)
451
{
451
{
452
        TSF_MEMSET(i, 0, sizeof(struct tsf_region));
452
        TSF_MEMSET(i, 0, sizeof(struct tsf_region));
453
        i->hikey = i->hivel = 127;
453
        i->hikey = i->hivel = 127;
454
        i->pitch_keycenter = 60; // C4
454
        i->pitch_keycenter = 60; // C4
455
        if (for_relative) return;
455
        if (for_relative) return;
456
456
457
        i->pitch_keytrack = 100;
457
        i->pitch_keytrack = 100;
458
458
459
        i->pitch_keycenter = -1;
459
        i->pitch_keycenter = -1;
460
460
461
        // SF2 defaults in timecents.
461
        // SF2 defaults in timecents.
462
        i->ampenv.delay = i->ampenv.attack = i->ampenv.hold = i->ampenv.decay = i->ampenv.release = -12000.0f;
462
        i->ampenv.delay = i->ampenv.attack = i->ampenv.hold = i->ampenv.decay = i->ampenv.release = -12000.0f;
463
        i->modenv.delay = i->modenv.attack = i->modenv.hold = i->modenv.decay = i->modenv.release = -12000.0f;
463
        i->modenv.delay = i->modenv.attack = i->modenv.hold = i->modenv.decay = i->modenv.release = -12000.0f;
464
464
465
        i->initialFilterFc = 13500;
465
        i->initialFilterFc = 13500;
466
466
467
        i->delayModLFO = -12000.0f;
467
        i->delayModLFO = -12000.0f;
468
        i->delayVibLFO = -12000.0f;
468
        i->delayVibLFO = -12000.0f;
469
}
469
}
470
470
471
static void tsf_region_operator(struct tsf_region* region, tsf_u16 genOper, union tsf_hydra_genamount* amount, struct tsf_region* merge_region)
471
static void tsf_region_operator(struct tsf_region* region, tsf_u16 genOper, union tsf_hydra_genamount* amount, struct tsf_region* merge_region)
472
{
472
{
473
        enum
473
        enum
474
        {
474
        {
475
                _GEN_TYPE_MASK       = 0x0F,
475
                _GEN_TYPE_MASK       = 0x0F,
476
                GEN_FLOAT            = 0x01,
476
                GEN_FLOAT            = 0x01,
477
                GEN_INT              = 0x02,
477
                GEN_INT              = 0x02,
478
                GEN_UINT_ADD         = 0x03,
478
                GEN_UINT_ADD         = 0x03,
479
                GEN_UINT_ADD15       = 0x04,
479
                GEN_UINT_ADD15       = 0x04,
480
                GEN_KEYRANGE         = 0x05,
480
                GEN_KEYRANGE         = 0x05,
481
                GEN_VELRANGE         = 0x06,
481
                GEN_VELRANGE         = 0x06,
482
                GEN_LOOPMODE         = 0x07,
482
                GEN_LOOPMODE         = 0x07,
483
                GEN_GROUP            = 0x08,
483
                GEN_GROUP            = 0x08,
484
                GEN_KEYCENTER        = 0x09,
484
                GEN_KEYCENTER        = 0x09,
485
485
486
                _GEN_LIMIT_MASK      = 0xF0,
486
                _GEN_LIMIT_MASK      = 0xF0,
487
                GEN_INT_LIMIT12K     = 0x10, //min -12000, max 12000
487
                GEN_INT_LIMIT12K     = 0x10, //min -12000, max 12000
488
                GEN_INT_LIMITFC      = 0x20, //min 1500, max 13500
488
                GEN_INT_LIMITFC      = 0x20, //min 1500, max 13500
489
                GEN_INT_LIMITQ       = 0x30, //min 0, max 960
489
                GEN_INT_LIMITQ       = 0x30, //min 0, max 960
490
                GEN_INT_LIMIT960     = 0x40, //min -960, max 960
490
                GEN_INT_LIMIT960     = 0x40, //min -960, max 960
491
                GEN_INT_LIMIT16K4500 = 0x50, //min -16000, max 4500
491
                GEN_INT_LIMIT16K4500 = 0x50, //min -16000, max 4500
492
                GEN_FLOAT_LIMIT12K5K = 0x60, //min -12000, max 5000
492
                GEN_FLOAT_LIMIT12K5K = 0x60, //min -12000, max 5000
493
                GEN_FLOAT_LIMIT12K8K = 0x70, //min -12000, max 8000
493
                GEN_FLOAT_LIMIT12K8K = 0x70, //min -12000, max 8000
494
                GEN_FLOAT_LIMIT1200  = 0x80, //min -1200, max 1200
494
                GEN_FLOAT_LIMIT1200  = 0x80, //min -1200, max 1200
495
                GEN_FLOAT_LIMITPAN   = 0x90, //* .001f, min -.5f, max .5f,
495
                GEN_FLOAT_LIMITPAN   = 0x90, //* .001f, min -.5f, max .5f,
496
                GEN_FLOAT_LIMITATTN  = 0xA0, //* .1f, min 0, max 144.0
496
                GEN_FLOAT_LIMITATTN  = 0xA0, //* .1f, min 0, max 144.0
497
                GEN_FLOAT_MAX1000    = 0xB0, //min 0, max 1000
497
                GEN_FLOAT_MAX1000    = 0xB0, //min 0, max 1000
498
                GEN_FLOAT_MAX1440    = 0xC0, //min 0, max 1440
498
                GEN_FLOAT_MAX1440    = 0xC0, //min 0, max 1440
499
499
500
                _GEN_MAX = 59,
500
                _GEN_MAX = 59,
501
        };
501
        };
502
        #define _TSFREGIONOFFSET(TYPE, FIELD) (unsigned char)(((TYPE*)&((struct tsf_region*)0)->FIELD) - (TYPE*)0)
502
        #define _TSFREGIONOFFSET(TYPE, FIELD) (unsigned char)(((TYPE*)&((struct tsf_region*)0)->FIELD) - (TYPE*)0)
503
        #define _TSFREGIONENVOFFSET(TYPE, ENV, FIELD) (unsigned char)(((TYPE*)&((&(((struct tsf_region*)0)->ENV))->FIELD)) - (TYPE*)0)
503
        #define _TSFREGIONENVOFFSET(TYPE, ENV, FIELD) (unsigned char)(((TYPE*)&((&(((struct tsf_region*)0)->ENV))->FIELD)) - (TYPE*)0)
504
        static const struct { unsigned char mode, offset; } genMetas[_GEN_MAX] =
504
        static const struct { unsigned char mode, offset; } genMetas[_GEN_MAX] =
505
        {
505
        {
506
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, offset               ) }, // 0 StartAddrsOffset
506
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, offset               ) }, // 0 StartAddrsOffset
507
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, end                  ) }, // 1 EndAddrsOffset
507
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, end                  ) }, // 1 EndAddrsOffset
508
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, loop_start           ) }, // 2 StartloopAddrsOffset
508
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, loop_start           ) }, // 2 StartloopAddrsOffset
509
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, loop_end             ) }, // 3 EndloopAddrsOffset
509
                { GEN_UINT_ADD                     , _TSFREGIONOFFSET(unsigned int, loop_end             ) }, // 3 EndloopAddrsOffset
510
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, offset               ) }, // 4 StartAddrsCoarseOffset
510
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, offset               ) }, // 4 StartAddrsCoarseOffset
511
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modLfoToPitch        ) }, // 5 ModLfoToPitch
511
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modLfoToPitch        ) }, // 5 ModLfoToPitch
512
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, vibLfoToPitch        ) }, // 6 VibLfoToPitch
512
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, vibLfoToPitch        ) }, // 6 VibLfoToPitch
513
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modEnvToPitch        ) }, // 7 ModEnvToPitch
513
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modEnvToPitch        ) }, // 7 ModEnvToPitch
514
                { GEN_INT   | GEN_INT_LIMITFC      , _TSFREGIONOFFSET(         int, initialFilterFc      ) }, // 8 InitialFilterFc
514
                { GEN_INT   | GEN_INT_LIMITFC      , _TSFREGIONOFFSET(         int, initialFilterFc      ) }, // 8 InitialFilterFc
515
                { GEN_INT   | GEN_INT_LIMITQ       , _TSFREGIONOFFSET(         int, initialFilterQ       ) }, // 9 InitialFilterQ
515
                { GEN_INT   | GEN_INT_LIMITQ       , _TSFREGIONOFFSET(         int, initialFilterQ       ) }, // 9 InitialFilterQ
516
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modLfoToFilterFc     ) }, //10 ModLfoToFilterFc
516
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modLfoToFilterFc     ) }, //10 ModLfoToFilterFc
517
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modEnvToFilterFc     ) }, //11 ModEnvToFilterFc
517
                { GEN_INT   | GEN_INT_LIMIT12K     , _TSFREGIONOFFSET(         int, modEnvToFilterFc     ) }, //11 ModEnvToFilterFc
518
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, end                  ) }, //12 EndAddrsCoarseOffset
518
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, end                  ) }, //12 EndAddrsCoarseOffset
519
                { GEN_INT   | GEN_INT_LIMIT960     , _TSFREGIONOFFSET(         int, modLfoToVolume       ) }, //13 ModLfoToVolume
519
                { GEN_INT   | GEN_INT_LIMIT960     , _TSFREGIONOFFSET(         int, modLfoToVolume       ) }, //13 ModLfoToVolume
520
                { 0                                , (0                                                  ) }, //   Unused
520
                { 0                                , (0                                                  ) }, //   Unused
521
                { 0                                , (0                                                  ) }, //15 ChorusEffectsSend (unsupported)
521
                { 0                                , (0                                                  ) }, //15 ChorusEffectsSend (unsupported)
522
                { 0                                , (0                                                  ) }, //16 ReverbEffectsSend (unsupported)
522
                { 0                                , (0                                                  ) }, //16 ReverbEffectsSend (unsupported)
523
                { GEN_FLOAT | GEN_FLOAT_LIMITPAN   , _TSFREGIONOFFSET(       float, pan                  ) }, //17 Pan
523
                { GEN_FLOAT | GEN_FLOAT_LIMITPAN   , _TSFREGIONOFFSET(       float, pan                  ) }, //17 Pan
524
                { 0                                , (0                                                  ) }, //   Unused
524
                { 0                                , (0                                                  ) }, //   Unused
525
                { 0                                , (0                                                  ) }, //   Unused
525
                { 0                                , (0                                                  ) }, //   Unused
526
                { 0                                , (0                                                  ) }, //   Unused
526
                { 0                                , (0                                                  ) }, //   Unused
527
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET(       float, delayModLFO          ) }, //21 DelayModLFO
527
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET(       float, delayModLFO          ) }, //21 DelayModLFO
528
                { GEN_INT   | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET(         int, freqModLFO           ) }, //22 FreqModLFO
528
                { GEN_INT   | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET(         int, freqModLFO           ) }, //22 FreqModLFO
529
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET(       float, delayVibLFO          ) }, //23 DelayVibLFO
529
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET(       float, delayVibLFO          ) }, //23 DelayVibLFO
530
                { GEN_INT   | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET(         int, freqVibLFO           ) }, //24 FreqVibLFO
530
                { GEN_INT   | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET(         int, freqVibLFO           ) }, //24 FreqVibLFO
531
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, modenv, delay        ) }, //25 DelayModEnv
531
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, modenv, delay        ) }, //25 DelayModEnv
532
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, modenv, attack       ) }, //26 AttackModEnv
532
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, modenv, attack       ) }, //26 AttackModEnv
533
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, modenv, hold         ) }, //27 HoldModEnv
533
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, modenv, hold         ) }, //27 HoldModEnv
534
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, modenv, decay        ) }, //28 DecayModEnv
534
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, modenv, decay        ) }, //28 DecayModEnv
535
                { GEN_FLOAT | GEN_FLOAT_MAX1000    , _TSFREGIONENVOFFSET(    float, modenv, sustain      ) }, //29 SustainModEnv
535
                { GEN_FLOAT | GEN_FLOAT_MAX1000    , _TSFREGIONENVOFFSET(    float, modenv, sustain      ) }, //29 SustainModEnv
536
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, modenv, release      ) }, //30 ReleaseModEnv
536
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, modenv, release      ) }, //30 ReleaseModEnv
537
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, modenv, keynumToHold ) }, //31 KeynumToModEnvHold
537
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, modenv, keynumToHold ) }, //31 KeynumToModEnvHold
538
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, modenv, keynumToDecay) }, //32 KeynumToModEnvDecay
538
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, modenv, keynumToDecay) }, //32 KeynumToModEnvDecay
539
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, ampenv, delay        ) }, //33 DelayVolEnv
539
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, ampenv, delay        ) }, //33 DelayVolEnv
540
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, ampenv, attack       ) }, //34 AttackVolEnv
540
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, ampenv, attack       ) }, //34 AttackVolEnv
541
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, ampenv, hold         ) }, //35 HoldVolEnv
541
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET(    float, ampenv, hold         ) }, //35 HoldVolEnv
542
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, ampenv, decay        ) }, //36 DecayVolEnv
542
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, ampenv, decay        ) }, //36 DecayVolEnv
543
                { GEN_FLOAT | GEN_FLOAT_MAX1440    , _TSFREGIONENVOFFSET(    float, ampenv, sustain      ) }, //37 SustainVolEnv
543
                { GEN_FLOAT | GEN_FLOAT_MAX1440    , _TSFREGIONENVOFFSET(    float, ampenv, sustain      ) }, //37 SustainVolEnv
544
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, ampenv, release      ) }, //38 ReleaseVolEnv
544
                { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET(    float, ampenv, release      ) }, //38 ReleaseVolEnv
545
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, ampenv, keynumToHold ) }, //39 KeynumToVolEnvHold
545
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, ampenv, keynumToHold ) }, //39 KeynumToVolEnvHold
546
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, ampenv, keynumToDecay) }, //40 KeynumToVolEnvDecay
546
                { GEN_FLOAT | GEN_FLOAT_LIMIT1200  , _TSFREGIONENVOFFSET(    float, ampenv, keynumToDecay) }, //40 KeynumToVolEnvDecay
547
                { 0                                , (0                                                  ) }, //   Instrument (special)
547
                { 0                                , (0                                                  ) }, //   Instrument (special)
548
                { 0                                , (0                                                  ) }, //   Reserved
548
                { 0                                , (0                                                  ) }, //   Reserved
549
                { GEN_KEYRANGE                     , (0                                                  ) }, //43 KeyRange
549
                { GEN_KEYRANGE                     , (0                                                  ) }, //43 KeyRange
550
                { GEN_VELRANGE                     , (0                                                  ) }, //44 VelRange
550
                { GEN_VELRANGE                     , (0                                                  ) }, //44 VelRange
551
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, loop_start           ) }, //45 StartloopAddrsCoarseOffset
551
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, loop_start           ) }, //45 StartloopAddrsCoarseOffset
552
                { 0                                , (0                                                  ) }, //46 Keynum (special)
552
                { 0                                , (0                                                  ) }, //46 Keynum (special)
553
                { 0                                , (0                                                  ) }, //47 Velocity (special)
553
                { 0                                , (0                                                  ) }, //47 Velocity (special)
554
                { GEN_FLOAT | GEN_FLOAT_LIMITATTN  , _TSFREGIONOFFSET(       float, attenuation          ) }, //48 InitialAttenuation
554
                { GEN_FLOAT | GEN_FLOAT_LIMITATTN  , _TSFREGIONOFFSET(       float, attenuation          ) }, //48 InitialAttenuation
555
                { 0                                , (0                                                  ) }, //   Reserved
555
                { 0                                , (0                                                  ) }, //   Reserved
556
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, loop_end             ) }, //50 EndloopAddrsCoarseOffset
556
                { GEN_UINT_ADD15                   , _TSFREGIONOFFSET(unsigned int, loop_end             ) }, //50 EndloopAddrsCoarseOffset
557
                { GEN_INT                          , _TSFREGIONOFFSET(         int, transpose            ) }, //51 CoarseTune
557
                { GEN_INT                          , _TSFREGIONOFFSET(         int, transpose            ) }, //51 CoarseTune
558
                { GEN_INT                          , _TSFREGIONOFFSET(         int, tune                 ) }, //52 FineTune
558
                { GEN_INT                          , _TSFREGIONOFFSET(         int, tune                 ) }, //52 FineTune
559
                { 0                                , (0                                                  ) }, //   SampleID (special)
559
                { 0                                , (0                                                  ) }, //   SampleID (special)
560
                { GEN_LOOPMODE                     , _TSFREGIONOFFSET(         int, loop_mode            ) }, //54 SampleModes
560
                { GEN_LOOPMODE                     , _TSFREGIONOFFSET(         int, loop_mode            ) }, //54 SampleModes
561
                { 0                                , (0                                                  ) }, //   Reserved
561
                { 0                                , (0                                                  ) }, //   Reserved
562
                { GEN_INT                          , _TSFREGIONOFFSET(         int, pitch_keytrack       ) }, //56 ScaleTuning
562
                { GEN_INT                          , _TSFREGIONOFFSET(         int, pitch_keytrack       ) }, //56 ScaleTuning
563
                { GEN_GROUP                        , _TSFREGIONOFFSET(unsigned int, group                ) }, //57 ExclusiveClass
563
                { GEN_GROUP                        , _TSFREGIONOFFSET(unsigned int, group                ) }, //57 ExclusiveClass
564
                { GEN_KEYCENTER                    , _TSFREGIONOFFSET(         int, pitch_keycenter      ) }, //58 OverridingRootKey
564
                { GEN_KEYCENTER                    , _TSFREGIONOFFSET(         int, pitch_keycenter      ) }, //58 OverridingRootKey
565
        };
565
        };
566
        #undef _TSFREGIONOFFSET
566
        #undef _TSFREGIONOFFSET
567
        #undef _TSFREGIONENVOFFSET
567
        #undef _TSFREGIONENVOFFSET
568
        if (amount)
568
        if (amount)
569
        {
569
        {
570
                int offset;
570
                int offset;
571
                if (genOper >= _GEN_MAX) return;
571
                if (genOper >= _GEN_MAX) return;
572
                offset = genMetas[genOper].offset;
572
                offset = genMetas[genOper].offset;
573
                switch (genMetas[genOper].mode & _GEN_TYPE_MASK)
573
                switch (genMetas[genOper].mode & _GEN_TYPE_MASK)
574
                {
574
                {
575
                        case GEN_FLOAT:      ((       float*)region)[offset]  = amount->shortAmount;     return;
575
                        case GEN_FLOAT:      ((       float*)region)[offset]  = amount->shortAmount;     return;
576
                        case GEN_INT:        ((         int*)region)[offset]  = amount->shortAmount;     return;
576
                        case GEN_INT:        ((         int*)region)[offset]  = amount->shortAmount;     return;
577
                        case GEN_UINT_ADD:   ((unsigned int*)region)[offset] += amount->shortAmount;     return;
577
                        case GEN_UINT_ADD:   ((unsigned int*)region)[offset] += amount->shortAmount;     return;
578
                        case GEN_UINT_ADD15: ((unsigned int*)region)[offset] += amount->shortAmount<<15; return;
578
                        case GEN_UINT_ADD15: ((unsigned int*)region)[offset] += amount->shortAmount<<15; return;
579
                        case GEN_KEYRANGE:   region->lokey = amount->range.lo; region->hikey = amount->range.hi; return;
579
                        case GEN_KEYRANGE:   region->lokey = amount->range.lo; region->hikey = amount->range.hi; return;
580
                        case GEN_VELRANGE:   region->lovel = amount->range.lo; region->hivel = amount->range.hi; return;
580
                        case GEN_VELRANGE:   region->lovel = amount->range.lo; region->hivel = amount->range.hi; return;
581
                        case GEN_LOOPMODE:   region->loop_mode       = ((amount->wordAmount&3) == 3 ? TSF_LOOPMODE_SUSTAIN : ((amount->wordAmount&3) == 1 ? TSF_LOOPMODE_CONTINUOUS : TSF_LOOPMODE_NONE)); return;
581
                        case GEN_LOOPMODE:   region->loop_mode       = ((amount->wordAmount&3) == 3 ? TSF_LOOPMODE_SUSTAIN : ((amount->wordAmount&3) == 1 ? TSF_LOOPMODE_CONTINUOUS : TSF_LOOPMODE_NONE)); return;
582
                        case GEN_GROUP:      region->group           = amount->wordAmount;  return;
582
                        case GEN_GROUP:      region->group           = amount->wordAmount;  return;
583
                        case GEN_KEYCENTER:  region->pitch_keycenter = amount->shortAmount; return;
583
                        case GEN_KEYCENTER:  region->pitch_keycenter = amount->shortAmount; return;
584
                }
584
                }
585
        }
585
        }
586
        else //merge regions and clamp values
586
        else //merge regions and clamp values
587
        {
587
        {
588
                for (genOper = 0; genOper != _GEN_MAX; genOper++)
588
                for (genOper = 0; genOper != _GEN_MAX; genOper++)
589
                {
589
                {
590
                        int offset = genMetas[genOper].offset;
590
                        int offset = genMetas[genOper].offset;
591
                        switch (genMetas[genOper].mode & _GEN_TYPE_MASK)
591
                        switch (genMetas[genOper].mode & _GEN_TYPE_MASK)
592
                        {
592
                        {
593
                                case GEN_FLOAT:
593
                                case GEN_FLOAT:
594
                                {
594
                                {
595
                                        float *val = &((float*)region)[offset], vfactor, vmin, vmax;
595
                                        float *val = &((float*)region)[offset], vfactor, vmin, vmax;
596
                                        *val += ((float*)merge_region)[offset];
596
                                        *val += ((float*)merge_region)[offset];
597
                                        switch (genMetas[genOper].mode & _GEN_LIMIT_MASK)
597
                                        switch (genMetas[genOper].mode & _GEN_LIMIT_MASK)
598
                                        {
598
                                        {
599
                                                case GEN_FLOAT_LIMIT12K5K: vfactor =   1.0f; vmin = -12000.0f; vmax = 5000.0f; break;
599
                                                case GEN_FLOAT_LIMIT12K5K: vfactor =   1.0f; vmin = -12000.0f; vmax = 5000.0f; break;
600
                                                case GEN_FLOAT_LIMIT12K8K: vfactor =   1.0f; vmin = -12000.0f; vmax = 8000.0f; break;
600
                                                case GEN_FLOAT_LIMIT12K8K: vfactor =   1.0f; vmin = -12000.0f; vmax = 8000.0f; break;
601
                                                case GEN_FLOAT_LIMIT1200:  vfactor =   1.0f; vmin =  -1200.0f; vmax = 1200.0f; break;
601
                                                case GEN_FLOAT_LIMIT1200:  vfactor =   1.0f; vmin =  -1200.0f; vmax = 1200.0f; break;
602
                                                case GEN_FLOAT_LIMITPAN:   vfactor = 0.001f; vmin =     -0.5f; vmax =    0.5f; break;
602
                                                case GEN_FLOAT_LIMITPAN:   vfactor = 0.001f; vmin =     -0.5f; vmax =    0.5f; break;
603
                                                case GEN_FLOAT_LIMITATTN:  vfactor =   0.1f; vmin =      0.0f; vmax =  144.0f; break;
603
                                                case GEN_FLOAT_LIMITATTN:  vfactor =   0.1f; vmin =      0.0f; vmax =  144.0f; break;
604
                                                case GEN_FLOAT_MAX1000:    vfactor =   1.0f; vmin =      0.0f; vmax = 1000.0f; break;
604
                                                case GEN_FLOAT_MAX1000:    vfactor =   1.0f; vmin =      0.0f; vmax = 1000.0f; break;
605
                                                case GEN_FLOAT_MAX1440:    vfactor =   1.0f; vmin =      0.0f; vmax = 1440.0f; break;
605
                                                case GEN_FLOAT_MAX1440:    vfactor =   1.0f; vmin =      0.0f; vmax = 1440.0f; break;
606
                                                default: continue;
606
                                                default: continue;
607
                                        }
607
                                        }
608
                                        *val *= vfactor;
608
                                        *val *= vfactor;
609
                                        if      (*val < vmin) *val = vmin;
609
                                        if      (*val < vmin) *val = vmin;
610
                                        else if (*val > vmax) *val = vmax;
610
                                        else if (*val > vmax) *val = vmax;
611
                                        continue;
611
                                        continue;
612
                                }
612
                                }
613
                                case GEN_INT:
613
                                case GEN_INT:
614
                                {
614
                                {
615
                                        int *val = &((int*)region)[offset], vmin, vmax;
615
                                        int *val = &((int*)region)[offset], vmin, vmax;
616
                                        *val += ((int*)merge_region)[offset];
616
                                        *val += ((int*)merge_region)[offset];
617
                                        switch (genMetas[genOper].mode & _GEN_LIMIT_MASK)
617
                                        switch (genMetas[genOper].mode & _GEN_LIMIT_MASK)
618
                                        {
618
                                        {
619
                                                case GEN_INT_LIMIT12K:     vmin = -12000; vmax = 12000; break;
619
                                                case GEN_INT_LIMIT12K:     vmin = -12000; vmax = 12000; break;
620
                                                case GEN_INT_LIMITFC:      vmin =   1500; vmax = 13500; break;
620
                                                case GEN_INT_LIMITFC:      vmin =   1500; vmax = 13500; break;
621
                                                case GEN_INT_LIMITQ:       vmin =      0; vmax =   960; break;
621
                                                case GEN_INT_LIMITQ:       vmin =      0; vmax =   960; break;
622
                                                case GEN_INT_LIMIT960:     vmin =   -960; vmax =   960; break;
622
                                                case GEN_INT_LIMIT960:     vmin =   -960; vmax =   960; break;
623
                                                case GEN_INT_LIMIT16K4500: vmin = -16000; vmax =  4500; break;
623
                                                case GEN_INT_LIMIT16K4500: vmin = -16000; vmax =  4500; break;
624
                                                default: continue;
624
                                                default: continue;
625
                                        }
625
                                        }
626
                                        if      (*val < vmin) *val = vmin;
626
                                        if      (*val < vmin) *val = vmin;
627
                                        else if (*val > vmax) *val = vmax;
627
                                        else if (*val > vmax) *val = vmax;
628
                                        continue;
628
                                        continue;
629
                                }
629
                                }
630
                                case GEN_UINT_ADD:
630
                                case GEN_UINT_ADD:
631
                                {
631
                                {
632
                                        ((unsigned int*)region)[offset] += ((unsigned int*)merge_region)[offset];
632
                                        ((unsigned int*)region)[offset] += ((unsigned int*)merge_region)[offset];
633
                                        continue;
633
                                        continue;
634
                                }
634
                                }
635
                        }
635
                        }
636
                }
636
                }
637
        }
637
        }
638
}
638
}
639
639
640
static void tsf_region_envtosecs(struct tsf_envelope* p, TSF_BOOL sustainIsGain)
640
static void tsf_region_envtosecs(struct tsf_envelope* p, TSF_BOOL sustainIsGain)
641
{
641
{
642
        // EG times need to be converted from timecents to seconds.
642
        // EG times need to be converted from timecents to seconds.
643
        // Pin very short EG segments.  Timecents don't get to zero, and our EG is
643
        // Pin very short EG segments.  Timecents don't get to zero, and our EG is
644
        // happier with zero values.
644
        // happier with zero values.
645
        p->delay   = (p->delay   < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->delay));
645
        p->delay   = (p->delay   < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->delay));
646
        p->attack  = (p->attack  < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->attack));
646
        p->attack  = (p->attack  < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->attack));
647
        p->release = (p->release < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->release));
647
        p->release = (p->release < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->release));
648
648
649
        // If we have dynamic hold or decay times depending on key number we need
649
        // If we have dynamic hold or decay times depending on key number we need
650
        // to keep the values in timecents so we can calculate it during startNote
650
        // to keep the values in timecents so we can calculate it during startNote
651
        if (!p->keynumToHold)  p->hold  = (p->hold  < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->hold));
651
        if (!p->keynumToHold)  p->hold  = (p->hold  < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->hold));
652
        if (!p->keynumToDecay) p->decay = (p->decay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->decay));
652
        if (!p->keynumToDecay) p->decay = (p->decay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->decay));
653
       
653
       
654
        if (p->sustain < 0.0f) p->sustain = 0.0f;
654
        if (p->sustain < 0.0f) p->sustain = 0.0f;
655
        else if (sustainIsGain) p->sustain = tsf_decibelsToGain(-p->sustain / 10.0f);
655
        else if (sustainIsGain) p->sustain = tsf_decibelsToGain(-p->sustain / 10.0f);
656
        else p->sustain = 1.0f - (p->sustain / 1000.0f);
656
        else p->sustain = 1.0f - (p->sustain / 1000.0f);
657
}
657
}
658
658
659
static void tsf_load_presets(tsf* res, struct tsf_hydra *hydra, unsigned int fontSampleCount)
659
static void tsf_load_presets(tsf* res, struct tsf_hydra *hydra, unsigned int fontSampleCount)
660
{
660
{
661
        enum { GenInstrument = 41, GenKeyRange = 43, GenVelRange = 44, GenSampleID = 53 };
661
        enum { GenInstrument = 41, GenKeyRange = 43, GenVelRange = 44, GenSampleID = 53 };
662
        // Read each preset.
662
        // Read each preset.
663
        struct tsf_hydra_phdr *pphdr, *pphdrMax;
663
        struct tsf_hydra_phdr *pphdr, *pphdrMax;
664
        for (pphdr = hydra->phdrs, pphdrMax = pphdr + hydra->phdrNum - 1; pphdr != pphdrMax; pphdr++)
664
        for (pphdr = hydra->phdrs, pphdrMax = pphdr + hydra->phdrNum - 1; pphdr != pphdrMax; pphdr++)
665
        {
665
        {
666
                int sortedIndex = 0, region_index = 0;
666
                int sortedIndex = 0, region_index = 0;
667
                struct tsf_hydra_phdr *otherphdr;
667
                struct tsf_hydra_phdr *otherphdr;
668
                struct tsf_preset* preset;
668
                struct tsf_preset* preset;
669
                struct tsf_hydra_pbag *ppbag, *ppbagEnd;
669
                struct tsf_hydra_pbag *ppbag, *ppbagEnd;
670
                struct tsf_region globalRegion;
670
                struct tsf_region globalRegion;
671
                for (otherphdr = hydra->phdrs; otherphdr != pphdrMax; otherphdr++)
671
                for (otherphdr = hydra->phdrs; otherphdr != pphdrMax; otherphdr++)
672
                {
672
                {
673
                        if (otherphdr == pphdr || otherphdr->bank > pphdr->bank) continue;
673
                        if (otherphdr == pphdr || otherphdr->bank > pphdr->bank) continue;
674
                        else if (otherphdr->bank < pphdr->bank) sortedIndex++;
674
                        else if (otherphdr->bank < pphdr->bank) sortedIndex++;
675
                        else if (otherphdr->preset > pphdr->preset) continue;
675
                        else if (otherphdr->preset > pphdr->preset) continue;
676
                        else if (otherphdr->preset < pphdr->preset) sortedIndex++;
676
                        else if (otherphdr->preset < pphdr->preset) sortedIndex++;
677
                        else if (otherphdr < pphdr) sortedIndex++;
677
                        else if (otherphdr < pphdr) sortedIndex++;
678
                }
678
                }
679
679
680
                preset = &res->presets[sortedIndex];
680
                preset = &res->presets[sortedIndex];
681
                TSF_MEMCPY(preset->presetName, pphdr->presetName, sizeof(preset->presetName));
681
                TSF_MEMCPY(preset->presetName, pphdr->presetName, sizeof(preset->presetName));
682
                preset->presetName[sizeof(preset->presetName)-1] = '\0'; //should be zero terminated in source file but make sure
682
                preset->presetName[sizeof(preset->presetName)-1] = '\0'; //should be zero terminated in source file but make sure
683
                preset->bank = pphdr->bank;
683
                preset->bank = pphdr->bank;
684
                preset->preset = pphdr->preset;
684
                preset->preset = pphdr->preset;
685
                preset->regionNum = 0;
685
                preset->regionNum = 0;
686
686
687
                //count regions covered by this preset
687
                //count regions covered by this preset
688
                for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
688
                for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
689
                {
689
                {
690
                        unsigned char plokey = 0, phikey = 127, plovel = 0, phivel = 127;
690
                        unsigned char plokey = 0, phikey = 127, plovel = 0, phivel = 127;
691
                        struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
691
                        struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
692
                        for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
692
                        for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
693
                        {
693
                        {
694
                                if (ppgen->genOper == GenKeyRange) { plokey = ppgen->genAmount.range.lo; phikey = ppgen->genAmount.range.hi; continue; }
694
                                if (ppgen->genOper == GenKeyRange) { plokey = ppgen->genAmount.range.lo; phikey = ppgen->genAmount.range.hi; continue; }
695
                                if (ppgen->genOper == GenVelRange) { plovel = ppgen->genAmount.range.lo; phivel = ppgen->genAmount.range.hi; continue; }
695
                                if (ppgen->genOper == GenVelRange) { plovel = ppgen->genAmount.range.lo; phivel = ppgen->genAmount.range.hi; continue; }
696
                                if (ppgen->genOper != GenInstrument) continue;
696
                                if (ppgen->genOper != GenInstrument) continue;
697
                                if (ppgen->genAmount.wordAmount >= hydra->instNum) continue;
697
                                if (ppgen->genAmount.wordAmount >= hydra->instNum) continue;
698
                                pinst = hydra->insts + ppgen->genAmount.wordAmount;
698
                                pinst = hydra->insts + ppgen->genAmount.wordAmount;
699
                                for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
699
                                for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
700
                                {
700
                                {
701
                                        unsigned char ilokey = 0, ihikey = 127, ilovel = 0, ihivel = 127;
701
                                        unsigned char ilokey = 0, ihikey = 127, ilovel = 0, ihivel = 127;
702
                                        for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
702
                                        for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
703
                                        {
703
                                        {
704
                                                if (pigen->genOper == GenKeyRange) { ilokey = pigen->genAmount.range.lo; ihikey = pigen->genAmount.range.hi; continue; }
704
                                                if (pigen->genOper == GenKeyRange) { ilokey = pigen->genAmount.range.lo; ihikey = pigen->genAmount.range.hi; continue; }
705
                                                if (pigen->genOper == GenVelRange) { ilovel = pigen->genAmount.range.lo; ihivel = pigen->genAmount.range.hi; continue; }
705
                                                if (pigen->genOper == GenVelRange) { ilovel = pigen->genAmount.range.lo; ihivel = pigen->genAmount.range.hi; continue; }
706
                                                if (pigen->genOper == GenSampleID && ihikey >= plokey && ilokey <= phikey && ihivel >= plovel && ilovel <= phivel) preset->regionNum++;
706
                                                if (pigen->genOper == GenSampleID && ihikey >= plokey && ilokey <= phikey && ihivel >= plovel && ilovel <= phivel) preset->regionNum++;
707
                                        }
707
                                        }
708
                                }
708
                                }
709
                        }
709
                        }
710
                }
710
                }
711
711
712
                preset->regions = (struct tsf_region*)TSF_MALLOC(preset->regionNum * sizeof(struct tsf_region));
712
                preset->regions = (struct tsf_region*)TSF_MALLOC(preset->regionNum * sizeof(struct tsf_region));
713
                tsf_region_clear(&globalRegion, TSF_TRUE);
713
                tsf_region_clear(&globalRegion, TSF_TRUE);
714
714
715
                // Zones.
715
                // Zones.
716
                for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
716
                for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
717
                {
717
                {
718
                        struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
718
                        struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
719
                        struct tsf_region presetRegion = globalRegion;
719
                        struct tsf_region presetRegion = globalRegion;
720
                        int hadGenInstrument = 0;
720
                        int hadGenInstrument = 0;
721
721
722
                        // Generators.
722
                        // Generators.
723
                        for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
723
                        for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
724
                        {
724
                        {
725
                                // Instrument.
725
                                // Instrument.
726
                                if (ppgen->genOper == GenInstrument)
726
                                if (ppgen->genOper == GenInstrument)
727
                                {
727
                                {
728
                                        struct tsf_region instRegion;
728
                                        struct tsf_region instRegion;
729
                                        tsf_u16 whichInst = ppgen->genAmount.wordAmount;
729
                                        tsf_u16 whichInst = ppgen->genAmount.wordAmount;
730
                                        if (whichInst >= hydra->instNum) continue;
730
                                        if (whichInst >= hydra->instNum) continue;
731
731
732
                                        tsf_region_clear(&instRegion, TSF_FALSE);
732
                                        tsf_region_clear(&instRegion, TSF_FALSE);
733
                                        pinst = &hydra->insts[whichInst];
733
                                        pinst = &hydra->insts[whichInst];
734
                                        for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
734
                                        for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
735
                                        {
735
                                        {
736
                                                // Generators.
736
                                                // Generators.
737
                                                struct tsf_region zoneRegion = instRegion;
737
                                                struct tsf_region zoneRegion = instRegion;
738
                                                int hadSampleID = 0;
738
                                                int hadSampleID = 0;
739
                                                for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
739
                                                for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
740
                                                {
740
                                                {
741
                                                        if (pigen->genOper == GenSampleID)
741
                                                        if (pigen->genOper == GenSampleID)
742
                                                        {
742
                                                        {
743
                                                                struct tsf_hydra_shdr* pshdr;
743
                                                                struct tsf_hydra_shdr* pshdr;
744
744
745
                                                                //preset region key and vel ranges are a filter for the zone regions
745
                                                                //preset region key and vel ranges are a filter for the zone regions
746
                                                                if (zoneRegion.hikey < presetRegion.lokey || zoneRegion.lokey > presetRegion.hikey) continue;
746
                                                                if (zoneRegion.hikey < presetRegion.lokey || zoneRegion.lokey > presetRegion.hikey) continue;
747
                                                                if (zoneRegion.hivel < presetRegion.lovel || zoneRegion.lovel > presetRegion.hivel) continue;
747
                                                                if (zoneRegion.hivel < presetRegion.lovel || zoneRegion.lovel > presetRegion.hivel) continue;
748
                                                                if (presetRegion.lokey > zoneRegion.lokey) zoneRegion.lokey = presetRegion.lokey;
748
                                                                if (presetRegion.lokey > zoneRegion.lokey) zoneRegion.lokey = presetRegion.lokey;
749
                                                                if (presetRegion.hikey < zoneRegion.hikey) zoneRegion.hikey = presetRegion.hikey;
749
                                                                if (presetRegion.hikey < zoneRegion.hikey) zoneRegion.hikey = presetRegion.hikey;
750
                                                                if (presetRegion.lovel > zoneRegion.lovel) zoneRegion.lovel = presetRegion.lovel;
750
                                                                if (presetRegion.lovel > zoneRegion.lovel) zoneRegion.lovel = presetRegion.lovel;
751
                                                                if (presetRegion.hivel < zoneRegion.hivel) zoneRegion.hivel = presetRegion.hivel;
751
                                                                if (presetRegion.hivel < zoneRegion.hivel) zoneRegion.hivel = presetRegion.hivel;
752
752
753
                                                                //sum regions
753
                                                                //sum regions
754
                                                                tsf_region_operator(&zoneRegion, 0, TSF_NULL, &presetRegion);
754
                                                                tsf_region_operator(&zoneRegion, 0, TSF_NULL, &presetRegion);
755
755
756
                                                                // EG times need to be converted from timecents to seconds.
756
                                                                // EG times need to be converted from timecents to seconds.
757
                                                                tsf_region_envtosecs(&zoneRegion.ampenv, TSF_TRUE);
757
                                                                tsf_region_envtosecs(&zoneRegion.ampenv, TSF_TRUE);
758
                                                                tsf_region_envtosecs(&zoneRegion.modenv, TSF_FALSE);
758
                                                                tsf_region_envtosecs(&zoneRegion.modenv, TSF_FALSE);
759
759
760
                                                                // LFO times need to be converted from timecents to seconds.
760
                                                                // LFO times need to be converted from timecents to seconds.
761
                                                                zoneRegion.delayModLFO = (zoneRegion.delayModLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayModLFO));
761
                                                                zoneRegion.delayModLFO = (zoneRegion.delayModLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayModLFO));
762
                                                                zoneRegion.delayVibLFO = (zoneRegion.delayVibLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayVibLFO));
762
                                                                zoneRegion.delayVibLFO = (zoneRegion.delayVibLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayVibLFO));
763
763
764
                                                                // Fixup sample positions
764
                                                                // Fixup sample positions
765
                                                                pshdr = &hydra->shdrs[pigen->genAmount.wordAmount];
765
                                                                pshdr = &hydra->shdrs[pigen->genAmount.wordAmount];
766
                                                                zoneRegion.offset += pshdr->start;
766
                                                                zoneRegion.offset += pshdr->start;
767
                                                                zoneRegion.end += pshdr->end;
767
                                                                zoneRegion.end += pshdr->end;
768
                                                                zoneRegion.loop_start += pshdr->startLoop;
768
                                                                zoneRegion.loop_start += pshdr->startLoop;
769
                                                                zoneRegion.loop_end += pshdr->endLoop;
769
                                                                zoneRegion.loop_end += pshdr->endLoop;
770
                                                                if (pshdr->endLoop > 0) zoneRegion.loop_end -= 1;
770
                                                                if (pshdr->endLoop > 0) zoneRegion.loop_end -= 1;
771
                                                                if (zoneRegion.pitch_keycenter == -1) zoneRegion.pitch_keycenter = pshdr->originalPitch;
771
                                                                if (zoneRegion.pitch_keycenter == -1) zoneRegion.pitch_keycenter = pshdr->originalPitch;
772
                                                                zoneRegion.tune += pshdr->pitchCorrection;
772
                                                                zoneRegion.tune += pshdr->pitchCorrection;
773
                                                                zoneRegion.sample_rate = pshdr->sampleRate;
773
                                                                zoneRegion.sample_rate = pshdr->sampleRate;
774
                                                                if (zoneRegion.end && zoneRegion.end < fontSampleCount) zoneRegion.end++;
774
                                                                if (zoneRegion.end && zoneRegion.end < fontSampleCount) zoneRegion.end++;
775
                                                                else zoneRegion.end = fontSampleCount;
775
                                                                else zoneRegion.end = fontSampleCount;
776
776
777
                                                                preset->regions[region_index] = zoneRegion;
777
                                                                preset->regions[region_index] = zoneRegion;
778
                                                                region_index++;
778
                                                                region_index++;
779
                                                                hadSampleID = 1;
779
                                                                hadSampleID = 1;
780
                                                        }
780
                                                        }
781
                                                        else tsf_region_operator(&zoneRegion, pigen->genOper, &pigen->genAmount, TSF_NULL);
781
                                                        else tsf_region_operator(&zoneRegion, pigen->genOper, &pigen->genAmount, TSF_NULL);
782
                                                }
782
                                                }
783
783
784
                                                // Handle instrument's global zone.
784
                                                // Handle instrument's global zone.
785
                                                if (pibag == hydra->ibags + pinst->instBagNdx && !hadSampleID)
785
                                                if (pibag == hydra->ibags + pinst->instBagNdx && !hadSampleID)
786
                                                        instRegion = zoneRegion;
786
                                                        instRegion = zoneRegion;
787
787
788
                                                // Modulators (TODO)
788
                                                // Modulators (TODO)
789
                                                //if (ibag->instModNdx < ibag[1].instModNdx) addUnsupportedOpcode("any modulator");
789
                                                //if (ibag->instModNdx < ibag[1].instModNdx) addUnsupportedOpcode("any modulator");
790
                                        }
790
                                        }
791
                                        hadGenInstrument = 1;
791
                                        hadGenInstrument = 1;
792
                                }
792
                                }
793
                                else tsf_region_operator(&presetRegion, ppgen->genOper, &ppgen->genAmount, TSF_NULL);
793
                                else tsf_region_operator(&presetRegion, ppgen->genOper, &ppgen->genAmount, TSF_NULL);
794
                        }
794
                        }
795
795
796
                        // Modulators (TODO)
796
                        // Modulators (TODO)
797
                        //if (pbag->modNdx < pbag[1].modNdx) addUnsupportedOpcode("any modulator");
797
                        //if (pbag->modNdx < pbag[1].modNdx) addUnsupportedOpcode("any modulator");
798
798
799
                        // Handle preset's global zone.
799
                        // Handle preset's global zone.
800
                        if (ppbag == hydra->pbags + pphdr->presetBagNdx && !hadGenInstrument)
800
                        if (ppbag == hydra->pbags + pphdr->presetBagNdx && !hadGenInstrument)
801
                                globalRegion = presetRegion;
801
                                globalRegion = presetRegion;
802
                }
802
                }
803
        }
803
        }
804
}
804
}
805
805
806
static void tsf_load_samples(float** fontSamples, unsigned int* fontSampleCount, struct tsf_riffchunk *chunkSmpl, struct tsf_stream* stream)
806
static void tsf_load_samples(float** fontSamples, unsigned int* fontSampleCount, struct tsf_riffchunk *chunkSmpl, struct tsf_stream* stream)
807
{
807
{
808
        // Read sample data into float format buffer.
808
        // Read sample data into float format buffer.
809
        float* out; unsigned int samplesLeft, samplesToRead, samplesToConvert;
809
        float* out; unsigned int samplesLeft, samplesToRead, samplesToConvert;
810
        samplesLeft = *fontSampleCount = chunkSmpl->size / sizeof(short);
810
        samplesLeft = *fontSampleCount = chunkSmpl->size / sizeof(short);
811
        out = *fontSamples = (float*)TSF_MALLOC(samplesLeft * sizeof(float));
811
        out = *fontSamples = (float*)TSF_MALLOC(samplesLeft * sizeof(float));
812
        for (; samplesLeft; samplesLeft -= samplesToRead)
812
        for (; samplesLeft; samplesLeft -= samplesToRead)
813
        {
813
        {
814
                short sampleBuffer[1024], *in = sampleBuffer;;
814
                short sampleBuffer[1024], *in = sampleBuffer;;
815
                samplesToRead = (samplesLeft > 1024 ? 1024 : samplesLeft);
815
                samplesToRead = (samplesLeft > 1024 ? 1024 : samplesLeft);
816
                stream->read(stream->data, sampleBuffer, samplesToRead * sizeof(short));
816
                stream->read(stream->data, sampleBuffer, samplesToRead * sizeof(short));
817
817
818
                // Convert from signed 16-bit to float.
818
                // Convert from signed 16-bit to float.
819
                for (samplesToConvert = samplesToRead; samplesToConvert > 0; --samplesToConvert)
819
                for (samplesToConvert = samplesToRead; samplesToConvert > 0; --samplesToConvert)
820
                        // If we ever need to compile for big-endian platforms, we'll need to byte-swap here.
820
                        // If we ever need to compile for big-endian platforms, we'll need to byte-swap here.
821
                        *out++ = (float)(*in++ / 32767.0);
821
                        *out++ = (float)(*in++ / 32767.0);
822
        }
822
        }
823
}
823
}
824
824
825
static void tsf_voice_envelope_nextsegment(struct tsf_voice_envelope* e, short active_segment, float outSampleRate)
825
static void tsf_voice_envelope_nextsegment(struct tsf_voice_envelope* e, short active_segment, float outSampleRate)
826
{
826
{
827
        switch (active_segment)
827
        switch (active_segment)
828
        {
828
        {
829
                case TSF_SEGMENT_NONE:
829
                case TSF_SEGMENT_NONE:
830
                        e->samplesUntilNextSegment = (int)(e->parameters.delay * outSampleRate);
830
                        e->samplesUntilNextSegment = (int)(e->parameters.delay * outSampleRate);
831
                        if (e->samplesUntilNextSegment > 0)
831
                        if (e->samplesUntilNextSegment > 0)
832
                        {
832
                        {
833
                                e->segment = TSF_SEGMENT_DELAY;
833
                                e->segment = TSF_SEGMENT_DELAY;
834
                                e->segmentIsExponential = TSF_FALSE;
834
                                e->segmentIsExponential = TSF_FALSE;
835
                                e->level = 0.0;
835
                                e->level = 0.0;
836
                                e->slope = 0.0;
836
                                e->slope = 0.0;
837
                                return;
837
                                return;
838
                        }
838
                        }
839
                        /* fall through */
839
                        /* fall through */
840
                case TSF_SEGMENT_DELAY:
840
                case TSF_SEGMENT_DELAY:
841
                        e->samplesUntilNextSegment = (int)(e->parameters.attack * outSampleRate);
841
                        e->samplesUntilNextSegment = (int)(e->parameters.attack * outSampleRate);
842
                        if (e->samplesUntilNextSegment > 0)
842
                        if (e->samplesUntilNextSegment > 0)
843
                        {
843
                        {
844
                                if (!e->isAmpEnv)
844
                                if (!e->isAmpEnv)
845
                                {
845
                                {
846
                                        //mod env attack duration scales with velocity (velocity of 1 is full duration, max velocity is 0.125 times duration)
846
                                        //mod env attack duration scales with velocity (velocity of 1 is full duration, max velocity is 0.125 times duration)
847
                                        e->samplesUntilNextSegment = (int)(e->parameters.attack * ((145 - e->midiVelocity) / 144.0f) * outSampleRate);
847
                                        e->samplesUntilNextSegment = (int)(e->parameters.attack * ((145 - e->midiVelocity) / 144.0f) * outSampleRate);
848
                                }
848
                                }
849
                                e->segment = TSF_SEGMENT_ATTACK;
849
                                e->segment = TSF_SEGMENT_ATTACK;
850
                                e->segmentIsExponential = TSF_FALSE;
850
                                e->segmentIsExponential = TSF_FALSE;
851
                                e->level = 0.0f;
851
                                e->level = 0.0f;
852
                                e->slope = 1.0f / e->samplesUntilNextSegment;
852
                                e->slope = 1.0f / e->samplesUntilNextSegment;
853
                                return;
853
                                return;
854
                        }
854
                        }
855
                        /* fall through */
855
                        /* fall through */
856
                case TSF_SEGMENT_ATTACK:
856
                case TSF_SEGMENT_ATTACK:
857
                        e->samplesUntilNextSegment = (int)(e->parameters.hold * outSampleRate);
857
                        e->samplesUntilNextSegment = (int)(e->parameters.hold * outSampleRate);
858
                        if (e->samplesUntilNextSegment > 0)
858
                        if (e->samplesUntilNextSegment > 0)
859
                        {
859
                        {
860
                                e->segment = TSF_SEGMENT_HOLD;
860
                                e->segment = TSF_SEGMENT_HOLD;
861
                                e->segmentIsExponential = TSF_FALSE;
861
                                e->segmentIsExponential = TSF_FALSE;
862
                                e->level = 1.0f;
862
                                e->level = 1.0f;
863
                                e->slope = 0.0f;
863
                                e->slope = 0.0f;
864
                                return;
864
                                return;
865
                        }
865
                        }
866
                        /* fall through */
866
                        /* fall through */
867
                case TSF_SEGMENT_HOLD:
867
                case TSF_SEGMENT_HOLD:
868
                        e->samplesUntilNextSegment = (int)(e->parameters.decay * outSampleRate);
868
                        e->samplesUntilNextSegment = (int)(e->parameters.decay * outSampleRate);
869
                        if (e->samplesUntilNextSegment > 0)
869
                        if (e->samplesUntilNextSegment > 0)
870
                        {
870
                        {
871
                                e->segment = TSF_SEGMENT_DECAY;
871
                                e->segment = TSF_SEGMENT_DECAY;
872
                                e->level = 1.0f;
872
                                e->level = 1.0f;
873
                                if (e->isAmpEnv)
873
                                if (e->isAmpEnv)
874
                                {
874
                                {
875
                                        // I don't truly understand this; just following what LinuxSampler does.
875
                                        // I don't truly understand this; just following what LinuxSampler does.
876
                                        float mysterySlope = -9.226f / e->samplesUntilNextSegment;
876
                                        float mysterySlope = -9.226f / e->samplesUntilNextSegment;
877
                                        e->slope = TSF_EXPF(mysterySlope);
877
                                        e->slope = TSF_EXPF(mysterySlope);
878
                                        e->segmentIsExponential = TSF_TRUE;
878
                                        e->segmentIsExponential = TSF_TRUE;
879
                                        if (e->parameters.sustain > 0.0f)
879
                                        if (e->parameters.sustain > 0.0f)
880
                                        {
880
                                        {
881
                                                // Again, this is following LinuxSampler's example, which is similar to
881
                                                // Again, this is following LinuxSampler's example, which is similar to
882
                                                // SF2-style decay, where "decay" specifies the time it would take to
882
                                                // SF2-style decay, where "decay" specifies the time it would take to
883
                                                // get to zero, not to the sustain level.  The SFZ spec is not that
883
                                                // get to zero, not to the sustain level.  The SFZ spec is not that
884
                                                // specific about what "decay" means, so perhaps it's really supposed
884
                                                // specific about what "decay" means, so perhaps it's really supposed
885
                                                // to specify the time to reach the sustain level.
885
                                                // to specify the time to reach the sustain level.
886
                                                e->samplesUntilNextSegment = (int)(TSF_LOG(e->parameters.sustain) / mysterySlope);
886
                                                e->samplesUntilNextSegment = (int)(TSF_LOG(e->parameters.sustain) / mysterySlope);
887
                                        }
887
                                        }
888
                                }
888
                                }
889
                                else
889
                                else
890
                                {
890
                                {
891
                                        e->slope = -1.0f / e->samplesUntilNextSegment;
891
                                        e->slope = -1.0f / e->samplesUntilNextSegment;
892
                                        e->samplesUntilNextSegment = (int)(e->parameters.decay * (1.0f - e->parameters.sustain) * outSampleRate);
892
                                        e->samplesUntilNextSegment = (int)(e->parameters.decay * (1.0f - e->parameters.sustain) * outSampleRate);
893
                                        e->segmentIsExponential = TSF_FALSE;
893
                                        e->segmentIsExponential = TSF_FALSE;
894
                                }
894
                                }
895
                                return;
895
                                return;
896
                        }
896
                        }
897
                        /* fall through */
897
                        /* fall through */
898
                case TSF_SEGMENT_DECAY:
898
                case TSF_SEGMENT_DECAY:
899
                        e->segment = TSF_SEGMENT_SUSTAIN;
899
                        e->segment = TSF_SEGMENT_SUSTAIN;
900
                        e->level = e->parameters.sustain;
900
                        e->level = e->parameters.sustain;
901
                        e->slope = 0.0f;
901
                        e->slope = 0.0f;
902
                        e->samplesUntilNextSegment = 0x7FFFFFFF;
902
                        e->samplesUntilNextSegment = 0x7FFFFFFF;
903
                        e->segmentIsExponential = TSF_FALSE;
903
                        e->segmentIsExponential = TSF_FALSE;
904
                        return;
904
                        return;
905
                case TSF_SEGMENT_SUSTAIN:
905
                case TSF_SEGMENT_SUSTAIN:
906
                        e->segment = TSF_SEGMENT_RELEASE;
906
                        e->segment = TSF_SEGMENT_RELEASE;
907
                        e->samplesUntilNextSegment = (int)((e->parameters.release <= 0 ? TSF_FASTRELEASETIME : e->parameters.release) * outSampleRate);
907
                        e->samplesUntilNextSegment = (int)((e->parameters.release <= 0 ? TSF_FASTRELEASETIME : e->parameters.release) * outSampleRate);
908
                        if (e->isAmpEnv)
908
                        if (e->isAmpEnv)
909
                        {
909
                        {
910
                                // I don't truly understand this; just following what LinuxSampler does.
910
                                // I don't truly understand this; just following what LinuxSampler does.
911
                                float mysterySlope = -9.226f / e->samplesUntilNextSegment;
911
                                float mysterySlope = -9.226f / e->samplesUntilNextSegment;
912
                                e->slope = TSF_EXPF(mysterySlope);
912
                                e->slope = TSF_EXPF(mysterySlope);
913
                                e->segmentIsExponential = TSF_TRUE;
913
                                e->segmentIsExponential = TSF_TRUE;
914
                        }
914
                        }
915
                        else
915
                        else
916
                        {
916
                        {
917
                                e->slope = -e->level / e->samplesUntilNextSegment;
917
                                e->slope = -e->level / e->samplesUntilNextSegment;
918
                                e->segmentIsExponential = TSF_FALSE;
918
                                e->segmentIsExponential = TSF_FALSE;
919
                        }
919
                        }
920
                        return;
920
                        return;
921
                case TSF_SEGMENT_RELEASE:
921
                case TSF_SEGMENT_RELEASE:
922
                default:
922
                default:
923
                        e->segment = TSF_SEGMENT_DONE;
923
                        e->segment = TSF_SEGMENT_DONE;
924
                        e->segmentIsExponential = TSF_FALSE;
924
                        e->segmentIsExponential = TSF_FALSE;
925
                        e->level = e->slope = 0.0f;
925
                        e->level = e->slope = 0.0f;
926
                        e->samplesUntilNextSegment = 0x7FFFFFF;
926
                        e->samplesUntilNextSegment = 0x7FFFFFF;
927
        }
927
        }
928
}
928
}
929
929
930
static void tsf_voice_envelope_setup(struct tsf_voice_envelope* e, struct tsf_envelope* new_parameters, int midiNoteNumber, short midiVelocity, TSF_BOOL isAmpEnv, float outSampleRate)
930
static void tsf_voice_envelope_setup(struct tsf_voice_envelope* e, struct tsf_envelope* new_parameters, int midiNoteNumber, short midiVelocity, TSF_BOOL isAmpEnv, float outSampleRate)
931
{
931
{
932
        e->parameters = *new_parameters;
932
        e->parameters = *new_parameters;
933
        if (e->parameters.keynumToHold)
933
        if (e->parameters.keynumToHold)
934
        {
934
        {
935
                e->parameters.hold += e->parameters.keynumToHold * (60.0f - midiNoteNumber);
935
                e->parameters.hold += e->parameters.keynumToHold * (60.0f - midiNoteNumber);
936
                e->parameters.hold = (e->parameters.hold < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.hold));
936
                e->parameters.hold = (e->parameters.hold < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.hold));
937
        }
937
        }
938
        if (e->parameters.keynumToDecay)
938
        if (e->parameters.keynumToDecay)
939
        {
939
        {
940
                e->parameters.decay += e->parameters.keynumToDecay * (60.0f - midiNoteNumber);
940
                e->parameters.decay += e->parameters.keynumToDecay * (60.0f - midiNoteNumber);
941
                e->parameters.decay = (e->parameters.decay < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.decay));
941
                e->parameters.decay = (e->parameters.decay < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.decay));
942
        }
942
        }
943
        e->midiVelocity = midiVelocity;
943
        e->midiVelocity = midiVelocity;
944
        e->isAmpEnv = isAmpEnv;
944
        e->isAmpEnv = isAmpEnv;
945
        tsf_voice_envelope_nextsegment(e, TSF_SEGMENT_NONE, outSampleRate);
945
        tsf_voice_envelope_nextsegment(e, TSF_SEGMENT_NONE, outSampleRate);
946
}
946
}
947
947
948
static void tsf_voice_envelope_process(struct tsf_voice_envelope* e, int numSamples, float outSampleRate)
948
static void tsf_voice_envelope_process(struct tsf_voice_envelope* e, int numSamples, float outSampleRate)
949
{
949
{
950
        if (e->slope)
950
        if (e->slope)
951
        {
951
        {
952
                if (e->segmentIsExponential) e->level *= TSF_POWF(e->slope, (float)numSamples);
952
                if (e->segmentIsExponential) e->level *= TSF_POWF(e->slope, (float)numSamples);
953
                else e->level += (e->slope * numSamples);
953
                else e->level += (e->slope * numSamples);
954
        }
954
        }
955
        if ((e->samplesUntilNextSegment -= numSamples) <= 0)
955
        if ((e->samplesUntilNextSegment -= numSamples) <= 0)
956
                tsf_voice_envelope_nextsegment(e, e->segment, outSampleRate);
956
                tsf_voice_envelope_nextsegment(e, e->segment, outSampleRate);
957
}
957
}
958
958
959
static void tsf_voice_lowpass_setup(struct tsf_voice_lowpass* e, float Fc)
959
static void tsf_voice_lowpass_setup(struct tsf_voice_lowpass* e, float Fc)
960
{
960
{
961
        // Lowpass filter from http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
961
        // Lowpass filter from http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
962
        double K = TSF_TAN(TSF_PI * Fc), KK = K * K;
962
        double K = TSF_TAN(TSF_PI * Fc), KK = K * K;
963
        double norm = 1 / (1 + K * e->QInv + KK);
963
        double norm = 1 / (1 + K * e->QInv + KK);
964
        e->a0 = KK * norm;
964
        e->a0 = KK * norm;
965
        e->a1 = 2 * e->a0;
965
        e->a1 = 2 * e->a0;
966
        e->b1 = 2 * (KK - 1) * norm;
966
        e->b1 = 2 * (KK - 1) * norm;
967
        e->b2 = (1 - K * e->QInv + KK) * norm;
967
        e->b2 = (1 - K * e->QInv + KK) * norm;
968
}
968
}
969
969
970
static float tsf_voice_lowpass_process(struct tsf_voice_lowpass* e, double In)
970
static float tsf_voice_lowpass_process(struct tsf_voice_lowpass* e, double In)
971
{
971
{
972
        double Out = In * e->a0 + e->z1; e->z1 = In * e->a1 + e->z2 - e->b1 * Out; e->z2 = In * e->a0 - e->b2 * Out; return (float)Out;
972
        double Out = In * e->a0 + e->z1; e->z1 = In * e->a1 + e->z2 - e->b1 * Out; e->z2 = In * e->a0 - e->b2 * Out; return (float)Out;
973
}
973
}
974
974
975
static void tsf_voice_lfo_setup(struct tsf_voice_lfo* e, float delay, int freqCents, float outSampleRate)
975
static void tsf_voice_lfo_setup(struct tsf_voice_lfo* e, float delay, int freqCents, float outSampleRate)
976
{
976
{
977
        e->samplesUntil = (int)(delay * outSampleRate);
977
        e->samplesUntil = (int)(delay * outSampleRate);
978
        e->delta = (4.0f * tsf_cents2Hertz((float)freqCents) / outSampleRate);
978
        e->delta = (4.0f * tsf_cents2Hertz((float)freqCents) / outSampleRate);
979
        e->level = 0;
979
        e->level = 0;
980
}
980
}
981
981
982
static void tsf_voice_lfo_process(struct tsf_voice_lfo* e, int blockSamples)
982
static void tsf_voice_lfo_process(struct tsf_voice_lfo* e, int blockSamples)
983
{
983
{
984
        if (e->samplesUntil > blockSamples) { e->samplesUntil -= blockSamples; return; }
984
        if (e->samplesUntil > blockSamples) { e->samplesUntil -= blockSamples; return; }
985
        e->level += e->delta * blockSamples;
985
        e->level += e->delta * blockSamples;
986
        if      (e->level >  1.0f) { e->delta = -e->delta; e->level =  2.0f - e->level; }
986
        if      (e->level >  1.0f) { e->delta = -e->delta; e->level =  2.0f - e->level; }
987
        else if (e->level < -1.0f) { e->delta = -e->delta; e->level = -2.0f - e->level; }
987
        else if (e->level < -1.0f) { e->delta = -e->delta; e->level = -2.0f - e->level; }
988
}
988
}
989
989
990
static void tsf_voice_kill(struct tsf_voice* v)
990
static void tsf_voice_kill(struct tsf_voice* v)
991
{
991
{
992
        v->playingPreset = -1;
992
        v->playingPreset = -1;
993
}
993
}
994
994
995
static void tsf_voice_end(struct tsf_voice* v, float outSampleRate)
995
static void tsf_voice_end(struct tsf_voice* v, float outSampleRate)
996
{
996
{
997
        tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
997
        tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
998
        tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
998
        tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
999
        if (v->region->loop_mode == TSF_LOOPMODE_SUSTAIN)
999
        if (v->region->loop_mode == TSF_LOOPMODE_SUSTAIN)
1000
        {
1000
        {
1001
                // Continue playing, but stop looping.
1001
                // Continue playing, but stop looping.
1002
                v->loopEnd = v->loopStart;
1002
                v->loopEnd = v->loopStart;
1003
        }
1003
        }
1004
}
1004
}
1005
1005
1006
static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate)
1006
static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate)
1007
{
1007
{
1008
        v->ampenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
1008
        v->ampenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
1009
        v->modenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
1009
        v->modenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
1010
}
1010
}
1011
1011
1012
static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate)
1012
static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate)
1013
{
1013
{
1014
        double note = v->playingKey + v->region->transpose + v->region->tune / 100.0;
1014
        double note = v->playingKey + v->region->transpose + v->region->tune / 100.0;
1015
        double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0);
1015
        double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0);
1016
        if (pitchShift) adjustedPitch += pitchShift;
1016
        if (pitchShift) adjustedPitch += pitchShift;
1017
        v->pitchInputTimecents = adjustedPitch * 100.0;
1017
        v->pitchInputTimecents = adjustedPitch * 100.0;
1018
        v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate);
1018
        v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate);
1019
}
1019
}
1020
1020
1021
static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples)
1021
static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples)
1022
{
1022
{
1023
        struct tsf_region* region = v->region;
1023
        struct tsf_region* region = v->region;
1024
        float* input = f->fontSamples;
1024
        float* input = f->fontSamples;
1025
        float* outL = outputBuffer;
1025
        float* outL = outputBuffer;
1026
        float* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL);
1026
        float* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL);
1027
1027
1028
        // Cache some values, to give them at least some chance of ending up in registers.
1028
        // Cache some values, to give them at least some chance of ending up in registers.
1029
        TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc);
1029
        TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc);
1030
        TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume));
1030
        TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume));
1031
        TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch));
1031
        TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch));
1032
        TSF_BOOL isLooping    = (v->loopStart < v->loopEnd);
1032
        TSF_BOOL isLooping    = (v->loopStart < v->loopEnd);
1033
        unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd;
1033
        unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd;
1034
        double tmpSampleEndDbl = (double)region->end, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0;
1034
        double tmpSampleEndDbl = (double)region->end, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0;
1035
        double tmpSourceSamplePosition = v->sourceSamplePosition;
1035
        double tmpSourceSamplePosition = v->sourceSamplePosition;
1036
        struct tsf_voice_lowpass tmpLowpass = v->lowpass;
1036
        struct tsf_voice_lowpass tmpLowpass = v->lowpass;
1037
1037
1038
        TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc);
1038
        TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc);
1039
        float tmpSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc;
1039
        float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc;
1040
1040
1041
        TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch);
1041
        TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch);
1042
        double pitchRatio;
1042
        double pitchRatio;
1043
        float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch;
1043
        float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch;
1044
1044
1045
        TSF_BOOL dynamicGain = (region->modLfoToVolume != 0);
1045
        TSF_BOOL dynamicGain = (region->modLfoToVolume != 0);
1046
        float noteGain = 0, tmpModLfoToVolume;
1046
        float noteGain = 0, tmpModLfoToVolume;
1047
1047
1048
        if (dynamicLowpass) tmpSampleRate = f->outSampleRate, tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc;
1048
        if (dynamicLowpass) tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc;
1049
        else tmpSampleRate = 0, tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0;
1049
        else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0;
1050
1050
1051
        if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
1051
        if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
1052
        else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
1052
        else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
1053
1053
1054
        if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
1054
        if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
1055
        else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0;
1055
        else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0;
1056
1056
1057
        while (numSamples)
1057
        while (numSamples)
1058
        {
1058
        {
1059
                float gainMono, gainLeft, gainRight;
1059
                float gainMono, gainLeft, gainRight;
1060
                int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples);
1060
                int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples);
1061
                numSamples -= blockSamples;
1061
                numSamples -= blockSamples;
1062
1062
1063
                if (dynamicLowpass)
1063
                if (dynamicLowpass)
1064
                {
1064
                {
1065
                        float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc;
1065
                        float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc;
1066
                        float lowpassFc = (fres <= 13500 ? tsf_cents2Hertz(fres) / tmpSampleRate : 1.0f);
1066
                        float lowpassFc = (fres <= 13500 ? tsf_cents2Hertz(fres) / tmpSampleRate : 1.0f);
1067
                        tmpLowpass.active = (lowpassFc < 0.499f);
1067
                        tmpLowpass.active = (lowpassFc < 0.499f);
1068
                        if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, lowpassFc);
1068
                        if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, lowpassFc);
1069
                }
1069
                }
1070
1070
1071
                if (dynamicPitchRatio)
1071
                if (dynamicPitchRatio)
1072
                        pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor;
1072
                        pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor;
1073
1073
1074
                if (dynamicGain)
1074
                if (dynamicGain)
1075
                        noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume));
1075
                        noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume));
1076
1076
1077
                gainMono = noteGain * v->ampenv.level;
1077
                gainMono = noteGain * v->ampenv.level;
1078
1078
1079
                // Update EG.
1079
                // Update EG.
1080
                tsf_voice_envelope_process(&v->ampenv, blockSamples, tmpSampleRate);
1080
                tsf_voice_envelope_process(&v->ampenv, blockSamples, tmpSampleRate);
1081
                if (updateModEnv) tsf_voice_envelope_process(&v->modenv, blockSamples, tmpSampleRate);
1081
                if (updateModEnv) tsf_voice_envelope_process(&v->modenv, blockSamples, tmpSampleRate);
1082
1082
1083
                // Update LFOs.
1083
                // Update LFOs.
1084
                if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples);
1084
                if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples);
1085
                if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples);
1085
                if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples);
1086
1086
1087
                switch (f->outputmode)
1087
                switch (f->outputmode)
1088
                {
1088
                {
1089
                        case TSF_STEREO_INTERLEAVED:
1089
                        case TSF_STEREO_INTERLEAVED:
1090
                                gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1090
                                gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1091
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1091
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1092
                                {
1092
                                {
1093
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1093
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1094
1094
1095
                                        // Simple linear interpolation.
1095
                                        // Simple linear interpolation.
1096
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1096
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1097
1097
1098
                                        // Low-pass filter.
1098
                                        // Low-pass filter.
1099
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1099
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1100
1100
1101
                                        *outL++ += val * gainLeft;
1101
                                        *outL++ += val * gainLeft;
1102
                                        *outL++ += val * gainRight;
1102
                                        *outL++ += val * gainRight;
1103
1103
1104
                                        // Next sample.
1104
                                        // Next sample.
1105
                                        tmpSourceSamplePosition += pitchRatio;
1105
                                        tmpSourceSamplePosition += pitchRatio;
1106
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1106
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1107
                                }
1107
                                }
1108
                                break;
1108
                                break;
1109
1109
1110
                        case TSF_STEREO_UNWEAVED:
1110
                        case TSF_STEREO_UNWEAVED:
1111
                                gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1111
                                gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1112
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1112
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1113
                                {
1113
                                {
1114
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1114
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1115
1115
1116
                                        // Simple linear interpolation.
1116
                                        // Simple linear interpolation.
1117
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1117
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1118
1118
1119
                                        // Low-pass filter.
1119
                                        // Low-pass filter.
1120
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1120
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1121
1121
1122
                                        *outL++ += val * gainLeft;
1122
                                        *outL++ += val * gainLeft;
1123
                                        *outR++ += val * gainRight;
1123
                                        *outR++ += val * gainRight;
1124
1124
1125
                                        // Next sample.
1125
                                        // Next sample.
1126
                                        tmpSourceSamplePosition += pitchRatio;
1126
                                        tmpSourceSamplePosition += pitchRatio;
1127
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1127
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1128
                                }
1128
                                }
1129
                                break;
1129
                                break;
1130
1130
1131
                        case TSF_MONO:
1131
                        case TSF_MONO:
1132
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1132
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1133
                                {
1133
                                {
1134
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1134
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1135
1135
1136
                                        // Simple linear interpolation.
1136
                                        // Simple linear interpolation.
1137
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1137
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1138
1138
1139
                                        // Low-pass filter.
1139
                                        // Low-pass filter.
1140
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1140
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1141
1141
1142
                                        *outL++ += val * gainMono;
1142
                                        *outL++ += val * gainMono;
1143
1143
1144
                                        // Next sample.
1144
                                        // Next sample.
1145
                                        tmpSourceSamplePosition += pitchRatio;
1145
                                        tmpSourceSamplePosition += pitchRatio;
1146
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1146
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1147
                                }
1147
                                }
1148
                                break;
1148
                                break;
1149
                }
1149
                }
1150
1150
1151
                if (tmpSourceSamplePosition >= tmpSampleEndDbl || v->ampenv.segment == TSF_SEGMENT_DONE)
1151
                if (tmpSourceSamplePosition >= tmpSampleEndDbl || v->ampenv.segment == TSF_SEGMENT_DONE)
1152
                {
1152
                {
1153
                        tsf_voice_kill(v);
1153
                        tsf_voice_kill(v);
1154
                        return;
1154
                        return;
1155
                }
1155
                }
1156
        }
1156
        }
1157
1157
1158
        v->sourceSamplePosition = tmpSourceSamplePosition;
1158
        v->sourceSamplePosition = tmpSourceSamplePosition;
1159
        if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass;
1159
        if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass;
1160
}
1160
}
1161
1161
1162
TSFDEF tsf* tsf_load(struct tsf_stream* stream)
1162
TSFDEF tsf* tsf_load(struct tsf_stream* stream)
1163
{
1163
{
1164
        tsf* res = TSF_NULL;
1164
        tsf* res = TSF_NULL;
1165
        struct tsf_riffchunk chunkHead;
1165
        struct tsf_riffchunk chunkHead;
1166
        struct tsf_riffchunk chunkList;
1166
        struct tsf_riffchunk chunkList;
1167
        struct tsf_hydra hydra;
1167
        struct tsf_hydra hydra;
1168
        float* fontSamples = TSF_NULL;
1168
        float* fontSamples = TSF_NULL;
1169
        unsigned int fontSampleCount = 0;
1169
        unsigned int fontSampleCount = 0;
1170
1170
1171
        if (!tsf_riffchunk_read(TSF_NULL, &chunkHead, stream) || !TSF_FourCCEquals(chunkHead.id, "sfbk"))
1171
        if (!tsf_riffchunk_read(TSF_NULL, &chunkHead, stream) || !TSF_FourCCEquals(chunkHead.id, "sfbk"))
1172
        {
1172
        {
1173
                //if (e) *e = TSF_INVALID_NOSF2HEADER;
1173
                //if (e) *e = TSF_INVALID_NOSF2HEADER;
1174
                return res;
1174
                return res;
1175
        }
1175
        }
1176
1176
1177
        // Read hydra and locate sample data.
1177
        // Read hydra and locate sample data.
1178
        TSF_MEMSET(&hydra, 0, sizeof(hydra));
1178
        TSF_MEMSET(&hydra, 0, sizeof(hydra));
1179
        while (tsf_riffchunk_read(&chunkHead, &chunkList, stream))
1179
        while (tsf_riffchunk_read(&chunkHead, &chunkList, stream))
1180
        {
1180
        {
1181
                struct tsf_riffchunk chunk;
1181
                struct tsf_riffchunk chunk;
1182
                if (TSF_FourCCEquals(chunkList.id, "pdta"))
1182
                if (TSF_FourCCEquals(chunkList.id, "pdta"))
1183
                {
1183
                {
1184
                        while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1184
                        while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1185
                        {
1185
                        {
1186
                                #define HandleChunk(chunkName) (TSF_FourCCEquals(chunk.id, #chunkName) && !(chunk.size % chunkName##SizeInFile)) \
1186
                                #define HandleChunk(chunkName) (TSF_FourCCEquals(chunk.id, #chunkName) && !(chunk.size % chunkName##SizeInFile)) \
1187
                                        { \
1187
                                        { \
1188
                                                int num = chunk.size / chunkName##SizeInFile, i; \
1188
                                                int num = chunk.size / chunkName##SizeInFile, i; \
1189
                                                hydra.chunkName##Num = num; \
1189
                                                hydra.chunkName##Num = num; \
1190
                                                hydra.chunkName##s = (struct tsf_hydra_##chunkName*)TSF_MALLOC(num * sizeof(struct tsf_hydra_##chunkName)); \
1190
                                                hydra.chunkName##s = (struct tsf_hydra_##chunkName*)TSF_MALLOC(num * sizeof(struct tsf_hydra_##chunkName)); \
1191
                                                for (i = 0; i < num; ++i) tsf_hydra_read_##chunkName(&hydra.chunkName##s[i], stream); \
1191
                                                for (i = 0; i < num; ++i) tsf_hydra_read_##chunkName(&hydra.chunkName##s[i], stream); \
1192
                                        }
1192
                                        }
1193
                                enum
1193
                                enum
1194
                                {
1194
                                {
1195
                                        phdrSizeInFile = 38, pbagSizeInFile =  4, pmodSizeInFile = 10,
1195
                                        phdrSizeInFile = 38, pbagSizeInFile =  4, pmodSizeInFile = 10,
1196
                                        pgenSizeInFile =  4, instSizeInFile = 22, ibagSizeInFile =  4,
1196
                                        pgenSizeInFile =  4, instSizeInFile = 22, ibagSizeInFile =  4,
1197
                                        imodSizeInFile = 10, igenSizeInFile =  4, shdrSizeInFile = 46
1197
                                        imodSizeInFile = 10, igenSizeInFile =  4, shdrSizeInFile = 46
1198
                                };
1198
                                };
1199
                                if      HandleChunk(phdr) else if HandleChunk(pbag) else if HandleChunk(pmod)
1199
                                if      HandleChunk(phdr) else if HandleChunk(pbag) else if HandleChunk(pmod)
1200
                                else if HandleChunk(pgen) else if HandleChunk(inst) else if HandleChunk(ibag)
1200
                                else if HandleChunk(pgen) else if HandleChunk(inst) else if HandleChunk(ibag)
1201
                                else if HandleChunk(imod) else if HandleChunk(igen) else if HandleChunk(shdr)
1201
                                else if HandleChunk(imod) else if HandleChunk(igen) else if HandleChunk(shdr)
1202
                                else stream->skip(stream->data, chunk.size);
1202
                                else stream->skip(stream->data, chunk.size);
1203
                                #undef HandleChunk
1203
                                #undef HandleChunk
1204
                        }
1204
                        }
1205
                }
1205
                }
1206
                else if (TSF_FourCCEquals(chunkList.id, "sdta"))
1206
                else if (TSF_FourCCEquals(chunkList.id, "sdta"))
1207
                {
1207
                {
1208
                        while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1208
                        while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1209
                        {
1209
                        {
1210
                                if (TSF_FourCCEquals(chunk.id, "smpl"))
1210
                                if (TSF_FourCCEquals(chunk.id, "smpl"))
1211
                                {
1211
                                {
1212
                                        tsf_load_samples(&fontSamples, &fontSampleCount, &chunk, stream);
1212
                                        tsf_load_samples(&fontSamples, &fontSampleCount, &chunk, stream);
1213
                                }
1213
                                }
1214
                                else stream->skip(stream->data, chunk.size);
1214
                                else stream->skip(stream->data, chunk.size);
1215
                        }
1215
                        }
1216
                }
1216
                }
1217
                else stream->skip(stream->data, chunkList.size);
1217
                else stream->skip(stream->data, chunkList.size);
1218
        }
1218
        }
1219
        if (!hydra.phdrs || !hydra.pbags || !hydra.pmods || !hydra.pgens || !hydra.insts || !hydra.ibags || !hydra.imods || !hydra.igens || !hydra.shdrs)
1219
        if (!hydra.phdrs || !hydra.pbags || !hydra.pmods || !hydra.pgens || !hydra.insts || !hydra.ibags || !hydra.imods || !hydra.igens || !hydra.shdrs)
1220
        {
1220
        {
1221
                //if (e) *e = TSF_INVALID_INCOMPLETE;
1221
                //if (e) *e = TSF_INVALID_INCOMPLETE;
1222
        }
1222
        }
1223
        else if (fontSamples == TSF_NULL)
1223
        else if (fontSamples == TSF_NULL)
1224
        {
1224
        {
1225
                //if (e) *e = TSF_INVALID_NOSAMPLEDATA;
1225
                //if (e) *e = TSF_INVALID_NOSAMPLEDATA;
1226
        }
1226
        }
1227
        else
1227
        else
1228
        {
1228
        {
1229
                res = (tsf*)TSF_MALLOC(sizeof(tsf));
1229
                res = (tsf*)TSF_MALLOC(sizeof(tsf));
1230
                TSF_MEMSET(res, 0, sizeof(tsf));
1230
                TSF_MEMSET(res, 0, sizeof(tsf));
1231
                res->presetNum = hydra.phdrNum - 1;
1231
                res->presetNum = hydra.phdrNum - 1;
1232
                res->presets = (struct tsf_preset*)TSF_MALLOC(res->presetNum * sizeof(struct tsf_preset));
1232
                res->presets = (struct tsf_preset*)TSF_MALLOC(res->presetNum * sizeof(struct tsf_preset));
1233
                res->fontSamples = fontSamples;
1233
                res->fontSamples = fontSamples;
1234
                res->outSampleRate = 44100.0f;
1234
                res->outSampleRate = 44100.0f;
1235
                fontSamples = TSF_NULL; //don't free below
1235
                fontSamples = TSF_NULL; //don't free below
1236
                tsf_load_presets(res, &hydra, fontSampleCount);
1236
                tsf_load_presets(res, &hydra, fontSampleCount);
1237
        }
1237
        }
1238
        TSF_FREE(hydra.phdrs); TSF_FREE(hydra.pbags); TSF_FREE(hydra.pmods);
1238
        TSF_FREE(hydra.phdrs); TSF_FREE(hydra.pbags); TSF_FREE(hydra.pmods);
1239
        TSF_FREE(hydra.pgens); TSF_FREE(hydra.insts); TSF_FREE(hydra.ibags);
1239
        TSF_FREE(hydra.pgens); TSF_FREE(hydra.insts); TSF_FREE(hydra.ibags);
1240
        TSF_FREE(hydra.imods); TSF_FREE(hydra.igens); TSF_FREE(hydra.shdrs);
1240
        TSF_FREE(hydra.imods); TSF_FREE(hydra.igens); TSF_FREE(hydra.shdrs);
1241
        TSF_FREE(fontSamples);
1241
        TSF_FREE(fontSamples);
1242
        return res;
1242
        return res;
1243
}
1243
}
1244
1244
1245
TSFDEF void tsf_close(tsf* f)
1245
TSFDEF void tsf_close(tsf* f)
1246
{
1246
{
1247
        struct tsf_preset *preset, *presetEnd;
1247
        struct tsf_preset *preset, *presetEnd;
1248
        if (!f) return;
1248
        if (!f) return;
1249
        for (preset = f->presets, presetEnd = preset + f->presetNum; preset != presetEnd; preset++)
1249
        for (preset = f->presets, presetEnd = preset + f->presetNum; preset != presetEnd; preset++)
1250
                TSF_FREE(preset->regions);
1250
                TSF_FREE(preset->regions);
1251
        TSF_FREE(f->presets);
1251
        TSF_FREE(f->presets);
1252
        TSF_FREE(f->fontSamples);
1252
        TSF_FREE(f->fontSamples);
1253
        TSF_FREE(f->voices);
1253
        TSF_FREE(f->voices);
1254
        if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); }
1254
        if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); }
1255
        TSF_FREE(f->outputSamples);
1255
        TSF_FREE(f->outputSamples);
1256
        TSF_FREE(f);
1256
        TSF_FREE(f);
1257
}
1257
}
1258
1258
1259
TSFDEF void tsf_reset(tsf* f)
1259
TSFDEF void tsf_reset(tsf* f)
1260
{
1260
{
1261
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1261
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1262
        for (; v != vEnd; v++)
1262
        for (; v != vEnd; v++)
1263
                if (v->playingPreset != -1 && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release))
1263
                if (v->playingPreset != -1 && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release))
1264
                        tsf_voice_endquick(v, f->outSampleRate);
1264
                        tsf_voice_endquick(v, f->outSampleRate);
1265
        if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); f->channels = TSF_NULL; }
1265
        if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); f->channels = TSF_NULL; }
1266
}
1266
}
1267
1267
1268
TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number)
1268
TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number)
1269
{
1269
{
1270
        const struct tsf_preset *presets;
1270
        const struct tsf_preset *presets;
1271
        int i, iMax;
1271
        int i, iMax;
1272
        for (presets = f->presets, i = 0, iMax = f->presetNum; i < iMax; i++)
1272
        for (presets = f->presets, i = 0, iMax = f->presetNum; i < iMax; i++)
1273
                if (presets[i].preset == preset_number && presets[i].bank == bank)
1273
                if (presets[i].preset == preset_number && presets[i].bank == bank)
1274
                        return i;
1274
                        return i;
1275
        return -1;
1275
        return -1;
1276
}
1276
}
1277
1277
1278
TSFDEF int tsf_get_presetcount(const tsf* f)
1278
TSFDEF int tsf_get_presetcount(const tsf* f)
1279
{
1279
{
1280
        return f->presetNum;
1280
        return f->presetNum;
1281
}
1281
}
1282
1282
1283
TSFDEF const char* tsf_get_presetname(const tsf* f, int preset)
1283
TSFDEF const char* tsf_get_presetname(const tsf* f, int preset)
1284
{
1284
{
1285
        return (preset < 0 || preset >= f->presetNum ? TSF_NULL : f->presets[preset].presetName);
1285
        return (preset < 0 || preset >= f->presetNum ? TSF_NULL : f->presets[preset].presetName);
1286
}
1286
}
1287
1287
1288
TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number)
1288
TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number)
1289
{
1289
{
1290
        return tsf_get_presetname(f, tsf_get_presetindex(f, bank, preset_number));
1290
        return tsf_get_presetname(f, tsf_get_presetindex(f, bank, preset_number));
1291
}
1291
}
1292
1292
1293
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db)
1293
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db)
1294
{
1294
{
1295
        f->outputmode = outputmode;
1295
        f->outputmode = outputmode;
1296
        f->outSampleRate = (float)(samplerate >= 1 ? samplerate : 44100.0f);
1296
        f->outSampleRate = (float)(samplerate >= 1 ? samplerate : 44100.0f);
1297
        f->globalGainDB = global_gain_db;
1297
        f->globalGainDB = global_gain_db;
1298
}
1298
}
1299
1299
1300
TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
1300
TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
1301
{
1301
{
1302
        short midiVelocity = (short)(vel * 127);
1302
        short midiVelocity = (short)(vel * 127);
1303
        int voicePlayIndex;
1303
        int voicePlayIndex;
1304
        struct tsf_region *region, *regionEnd;
1304
        struct tsf_region *region, *regionEnd;
1305
1305
1306
        if (preset_index < 0 || preset_index >= f->presetNum) return;
1306
        if (preset_index < 0 || preset_index >= f->presetNum) return;
1307
        if (vel <= 0.0f) { tsf_note_off(f, preset_index, key); return; }
1307
        if (vel <= 0.0f) { tsf_note_off(f, preset_index, key); return; }
1308
1308
1309
        // Play all matching regions.
1309
        // Play all matching regions.
1310
        voicePlayIndex = f->voicePlayIndex++;
1310
        voicePlayIndex = f->voicePlayIndex++;
1311
        for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++)
1311
        for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++)
1312
        {
1312
        {
1313
                struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; float lowpassFilterQDB, lowpassFc;
1313
                struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; float lowpassFilterQDB, lowpassFc;
1314
                if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue;
1314
                if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue;
1315
1315
1316
                voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum;
1316
                voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum;
1317
                if (region->group)
1317
                if (region->group)
1318
                {
1318
                {
1319
                        for (; v != vEnd; v++)
1319
                        for (; v != vEnd; v++)
1320
                                if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(v, f->outSampleRate);
1320
                                if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(v, f->outSampleRate);
1321
                                else if (v->playingPreset == -1 && !voice) voice = v;
1321
                                else if (v->playingPreset == -1 && !voice) voice = v;
1322
                }
1322
                }
1323
                else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; }
1323
                else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; }
1324
1324
1325
                if (!voice)
1325
                if (!voice)
1326
                {
1326
                {
1327
                        f->voiceNum += 4;
1327
                        f->voiceNum += 4;
1328
                        f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice));
1328
                        f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice));
1329
                        voice = &f->voices[f->voiceNum - 4];
1329
                        voice = &f->voices[f->voiceNum - 4];
1330
                        voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1;
1330
                        voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1;
1331
                }
1331
                }
1332
1332
1333
                voice->region = region;
1333
                voice->region = region;
1334
                voice->playingPreset = preset_index;
1334
                voice->playingPreset = preset_index;
1335
                voice->playingKey = key;
1335
                voice->playingKey = key;
1336
                voice->playIndex = voicePlayIndex;
1336
                voice->playIndex = voicePlayIndex;
1337
                voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel);
1337
                voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel);
1338
1338
1339
                if (f->channels)
1339
                if (f->channels)
1340
                {
1340
                {
1341
                        f->channels->setupVoice(f, voice);
1341
                        f->channels->setupVoice(f, voice);
1342
                }
1342
                }
1343
                else
1343
                else
1344
                {
1344
                {
1345
                        tsf_voice_calcpitchratio(voice, 0, f->outSampleRate);
1345
                        tsf_voice_calcpitchratio(voice, 0, f->outSampleRate);
1346
                        // The SFZ spec is silent about the pan curve, but a 3dB pan law seems common. This sqrt() curve matches what Dimension LE does; Alchemy Free seems closer to sin(adjustedPan * pi/2).
1346
                        // The SFZ spec is silent about the pan curve, but a 3dB pan law seems common. This sqrt() curve matches what Dimension LE does; Alchemy Free seems closer to sin(adjustedPan * pi/2).
1347
                        voice->panFactorLeft  = TSF_SQRTF(0.5f - region->pan);
1347
                        voice->panFactorLeft  = TSF_SQRTF(0.5f - region->pan);
1348
                        voice->panFactorRight = TSF_SQRTF(0.5f + region->pan);
1348
                        voice->panFactorRight = TSF_SQRTF(0.5f + region->pan);
1349
                }
1349
                }
1350
1350
1351
                // Offset/end.
1351
                // Offset/end.
1352
                voice->sourceSamplePosition = region->offset;
1352
                voice->sourceSamplePosition = region->offset;
1353
1353
1354
                // Loop.
1354
                // Loop.
1355
                doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end);
1355
                doLoop = (region->loop_mode != TSF_LOOPMODE_NONE