Subversion Repositories eduke32

Rev

Rev 8754 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8752 terminx 1
/* TinySoundFont - v0.8 - SoundFont2 synthesizer - https://github.com/schellingb/TinySoundFont
2
                                     no warranty implied; use at your own risk
3
   Do this:
4
      #define TSF_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:
7
   #include ...
8
   #include ...
9
   #define TSF_IMPLEMENTATION
10
   #include "tsf.h"
11
 
12
   [OPTIONAL] #define TSF_NO_STDIO to remove stdio dependency
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
15
   [OPTIONAL] #define TSF_POW, TSF_POWF, TSF_EXPF, TSF_LOG, TSF_TAN, TSF_LOG10, TSF_SQRT to avoid math.h
16
 
17
   NOT YET IMPLEMENTED
18
     - Support for ChorusEffectsSend and ReverbEffectsSend generators
19
     - Better low-pass filter without lowering performance too much
20
     - Support for modulators
21
 
22
   LICENSE (MIT)
23
 
24
   Copyright (C) 2017, 2018 Bernhard Schelling
25
   Based on SFZero, Copyright (C) 2012 Steve Folta (https://github.com/stevefolta/SFZero)
26
 
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
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
31
   to whom the Software is furnished to do so, subject to the following conditions:
32
 
33
   The above copyright notice and this permission notice shall be included in all
34
   copies or substantial portions of the Software.
35
 
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
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,
40
   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
41
   USE OR OTHER DEALINGS IN THE SOFTWARE.
42
 
43
*/
44
 
45
#ifndef TSF_INCLUDE_TSF_INL
46
#define TSF_INCLUDE_TSF_INL
47
 
48
#ifdef __cplusplus
49
extern "C" {
50
#  define CPP_DEFAULT0 = 0
51
#else
52
#  define CPP_DEFAULT0
53
#endif
54
 
55
//define this if you want the API functions to be static
56
#ifdef TSF_STATIC
57
#define TSFDEF static
58
#else
59
#define TSFDEF extern
60
#endif
61
 
62
// The load functions will return a pointer to a struct tsf which all functions
63
// thereafter take as the first parameter.
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).
66
typedef struct tsf tsf;
67
 
68
#ifndef TSF_NO_STDIO
69
// Directly load a SoundFont from a .sf2 file path
70
TSFDEF tsf* tsf_load_filename(const char* filename);
71
#endif
72
 
73
// Load a SoundFont from a block of memory
74
TSFDEF tsf* tsf_load_memory(const void* buffer, int size);
75
 
76
// Stream structure for the generic loading
77
struct tsf_stream
78
{
79
        // Custom data given to the functions as the first parameter
80
        void* data;
81
 
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);
84
 
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);
87
};
88
 
89
// Generic SoundFont loading method using the stream structure above
90
TSFDEF tsf* tsf_load(struct tsf_stream* stream);
91
 
92
// Free the memory related to this tsf instance
93
TSFDEF void tsf_close(tsf* f);
94
 
95
// Stop all playing notes immediatly and reset all channel parameters
96
TSFDEF void tsf_reset(tsf* f);
97
 
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);
100
 
101
// Returns the number of presets in the loaded SoundFont
102
TSFDEF int tsf_get_presetcount(const tsf* f);
103
 
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);
106
 
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);
109
 
110
// Supported output modes by the render methods
111
enum TSFOutputMode
112
{
113
        // Two channels with single left/right samples one after another
114
        TSF_STEREO_INTERLEAVED,
115
        // Two channels with all samples for the left channel first then right
116
        TSF_STEREO_UNWEAVED,
117
        // A single channel (stereo instruments are mixed into center)
118
        TSF_MONO,
119
};
120
 
121
// Thread safety:
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
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.
126
 
127
// Setup the parameters for the voice render methods
128
//   outputmode: if mono or stereo and how stereo channel data is ordered
129
//   samplerate: the number of samples per second (output frequency)
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);
132
 
133
// Start playing a note
134
//   preset_index: preset index >= 0 and < tsf_get_presetcount()
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)
137
//   bank: instrument bank 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)
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);
142
 
143
// Stop playing a note
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);
146
TSFDEF int  tsf_bank_note_off(tsf* f, int bank, int preset_number, int key);
147
 
148
// Stop playing all notes (end with sustain and release)
149
TSFDEF void tsf_note_off_all(tsf* f);
150
 
151
// Returns the number of active voices
152
TSFDEF int tsf_active_voice_count(tsf* f);
153
 
154
// Render output samples into a buffer
155
// You can either render as signed 16-bit values (tsf_render_short) or
156
// as 32-bit float values (tsf_render_float)
157
//   buffer: target buffer of size samples * output_channels * sizeof(type)
158
//   samples: number of samples to render
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);
161
TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing CPP_DEFAULT0);
162
 
163
// Higher level channel based functions, set up channel parameters
164
//   channel: channel number
165
//   preset_index: preset index >= 0 and < tsf_get_presetcount()
166
//   preset_number: preset number (alternative to preset_index)
167
//   flag_mididrums: 0 for normal channels, otherwise apply MIDI drum channel rules
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)
170
//   volume: linear volume scale factor (default 1.0 full)
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)
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)
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);
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);
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);
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);
183
TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning);
184
 
185
// Start or stop playing notes on a channel (needs channel preset to be set)
186
//   channel: channel number
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)
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);
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
193
 
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);
196
 
197
// Get current values set on the channels
198
TSFDEF int tsf_channel_get_preset_index(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);
201
TSFDEF float tsf_channel_get_pan(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);
204
TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel);
205
TSFDEF float tsf_channel_get_tuning(tsf* f, int channel);
206
 
207
#ifdef __cplusplus
208
#  undef CPP_DEFAULT0
209
}
210
#endif
211
 
212
// end header
213
// ---------------------------------------------------------------------------------------------------------
214
#endif //TSF_INCLUDE_TSF_INL
215
 
216
#ifdef TSF_IMPLEMENTATION
217
 
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.
220
// If LFO affects the low-pass filter it can be hearable even as low as 8.
221
#ifndef TSF_RENDER_EFFECTSAMPLEBLOCK
222
#define TSF_RENDER_EFFECTSAMPLEBLOCK 64
223
#endif
224
 
225
// Grace release time for quick voice off (avoid clicking noise)
226
#define TSF_FASTRELEASETIME 0.01f
227
 
228
#if !defined(TSF_MALLOC) || !defined(TSF_FREE) || !defined(TSF_REALLOC)
229
#  include <stdlib.h>
230
#  define TSF_MALLOC  malloc
231
#  define TSF_FREE    free
232
#  define TSF_REALLOC realloc
233
#endif
234
 
235
#if !defined(TSF_MEMCPY) || !defined(TSF_MEMSET)
236
#  include <string.h>
237
#  define TSF_MEMCPY  memcpy
238
#  define TSF_MEMSET  memset
239
#endif
240
 
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>
243
#  if !defined(__cplusplus) && !defined(NAN) && !defined(powf) && !defined(expf) && !defined(sqrtf)
244
#    define powf (float)pow // deal with old math.h
245
#    define expf (float)exp // files that come without
246
#    define sqrtf (float)sqrt // powf, expf and sqrtf
247
#  endif
248
#  define TSF_POW     pow
249
#  define TSF_POWF    powf
250
#  define TSF_EXPF    expf
251
#  define TSF_LOG     log
252
#  define TSF_TAN     tan
253
#  define TSF_LOG10   log10
254
#  define TSF_SQRTF   sqrtf
255
#endif
256
 
257
#ifndef TSF_NO_STDIO
258
#  include <stdio.h>
259
#endif
260
 
261
#define TSF_TRUE 1
262
#define TSF_FALSE 0
263
#define TSF_BOOL char
264
#define TSF_PI 3.14159265358979323846264338327950288
265
#define TSF_NULL 0
266
 
267
#ifdef __cplusplus
268
extern "C" {
269
#endif
270
 
271
typedef char tsf_fourcc[4];
272
typedef signed char tsf_s8;
273
typedef unsigned char tsf_u8;
274
typedef unsigned short tsf_u16;
275
typedef signed short tsf_s16;
276
typedef unsigned int tsf_u32;
277
typedef char tsf_char20[20];
278
 
279
#define TSF_FourCCEquals(value1, value2) (value1[0] == value2[0] && value1[1] == value2[1] && value1[2] == value2[2] && value1[3] == value2[3])
280
 
281
struct tsf
282
{
283
        struct tsf_preset* presets;
284
        float* fontSamples;
285
        struct tsf_voice* voices;
286
        struct tsf_channels* channels;
287
        float* outputSamples;
288
 
289
        int presetNum;
290
        int voiceNum;
291
        int outputSampleSize;
292
        unsigned int voicePlayIndex;
293
 
294
        enum TSFOutputMode outputmode;
295
        float outSampleRate;
296
        float globalGainDB;
297
};
298
 
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); }
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)
303
{
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 };
306
        #if __STDC_WANT_SECURE_LIB__
307
        FILE* f = TSF_NULL; fopen_s(&f, filename, "rb");
308
        #else
309
        FILE* f = fopen(filename, "rb");
310
        #endif
311
        if (!f)
312
        {
313
                //if (e) *e = TSF_FILENOTFOUND;
314
                return TSF_NULL;
315
        }
316
        stream.data = f;
317
        res = tsf_load(&stream);
318
        fclose(f);
319
        return res;
320
}
321
#endif
322
 
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; }
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)
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 };
329
        struct tsf_stream_memory f = { 0, 0, 0 };
330
        f.buffer = (const char*)buffer;
331
        f.total = size;
332
        stream.data = &f;
333
        return tsf_load(&stream);
334
}
335
 
336
enum { TSF_LOOPMODE_NONE, TSF_LOOPMODE_CONTINUOUS, TSF_LOOPMODE_SUSTAIN };
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 };
339
 
340
struct tsf_hydra
341
{
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;
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;
346
};
347
 
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; };
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; };
352
struct tsf_hydra_pgen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; };
353
struct tsf_hydra_inst { tsf_char20 instName; tsf_u16 instBagNdx; };
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; };
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; };
358
 
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) }
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) }
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) }
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) }
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) }
369
#undef TSFR
370
 
371
struct tsf_riffchunk { tsf_fourcc id; tsf_u32 size; };
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; };
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; };
376
 
377
struct tsf_region
378
{
379
        int loop_mode;
380
        unsigned int sample_rate;
381
        unsigned char lokey, hikey, lovel, hivel;
382
        unsigned int group, offset, end, loop_start, loop_end;
383
        int transpose, tune, pitch_keycenter, pitch_keytrack;
384
        float attenuation, pan;
385
        struct tsf_envelope ampenv, modenv;
386
        int initialFilterQ, initialFilterFc;
387
        int modEnvToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume;
388
        float delayModLFO;
389
        int freqModLFO, modLfoToPitch;
390
        float delayVibLFO;
391
        int freqVibLFO, vibLfoToPitch;
392
};
393
 
394
struct tsf_preset
395
{
396
        tsf_char20 presetName;
397
        tsf_u16 preset, bank;
398
        struct tsf_region* regions;
399
        int regionNum;
400
};
401
 
402
struct tsf_voice
403
{
404
        int playingPreset, playingKey, playingChannel;
405
        struct tsf_region* region;
406
        double pitchInputTimecents, pitchOutputFactor;
407
        double sourceSamplePosition;
408
        float  noteGainDB, panFactorLeft, panFactorRight;
409
        unsigned int playIndex, loopStart, loopEnd;
410
        struct tsf_voice_envelope ampenv, modenv;
411
        struct tsf_voice_lowpass lowpass;
412
        struct tsf_voice_lfo modlfo, viblfo;
413
};
414
 
415
struct tsf_channel
416
{
417
        unsigned short presetIndex, bank, pitchWheel, midiPan, midiVolume, midiExpression, midiRPN, midiData;
418
        float panOffset, gainDB, pitchRange, tuning;
419
};
420
 
421
struct tsf_channels
422
{
423
        void (*setupVoice)(tsf* f, struct tsf_voice* voice);
424
        struct tsf_channel* channels;
425
        int channelNum, activeChannel;
426
};
427
 
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); }
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); }
432
static float tsf_gainToDecibels(float gain) { return (gain <= .00001f ? -100.f : (float)(20.0 * TSF_LOG10(gain))); }
433
 
434
static TSF_BOOL tsf_riffchunk_read(struct tsf_riffchunk* parent, struct tsf_riffchunk* chunk, struct tsf_stream* stream)
435
{
436
        TSF_BOOL IsRiff, IsList;
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;
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;
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");
443
        if (IsRiff && parent) return TSF_FALSE; //not allowed
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;
446
        chunk->size -= sizeof(tsf_fourcc);
447
        return TSF_TRUE;
448
}
449
 
450
static void tsf_region_clear(struct tsf_region* i, TSF_BOOL for_relative)
451
{
452
        TSF_MEMSET(i, 0, sizeof(struct tsf_region));
453
        i->hikey = i->hivel = 127;
454
        i->pitch_keycenter = 60; // C4
455
        if (for_relative) return;
456
 
457
        i->pitch_keytrack = 100;
458
 
459
        i->pitch_keycenter = -1;
460
 
461
        // SF2 defaults in timecents.
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;
464
 
465
        i->initialFilterFc = 13500;
466
 
467
        i->delayModLFO = -12000.0f;
468
        i->delayVibLFO = -12000.0f;
469
}
470
 
471
static void tsf_region_operator(struct tsf_region* region, tsf_u16 genOper, union tsf_hydra_genamount* amount)
472
{
473
        enum
474
        {
475
                StartAddrsOffset, EndAddrsOffset, StartloopAddrsOffset, EndloopAddrsOffset, StartAddrsCoarseOffset, ModLfoToPitch, VibLfoToPitch, ModEnvToPitch,
476
                InitialFilterFc, InitialFilterQ, ModLfoToFilterFc, ModEnvToFilterFc, EndAddrsCoarseOffset, ModLfoToVolume, Unused1, ChorusEffectsSend,
477
                ReverbEffectsSend, Pan, Unused2, Unused3, Unused4, DelayModLFO, FreqModLFO, DelayVibLFO, FreqVibLFO, DelayModEnv, AttackModEnv, HoldModEnv,
478
                DecayModEnv, SustainModEnv, ReleaseModEnv, KeynumToModEnvHold, KeynumToModEnvDecay, DelayVolEnv, AttackVolEnv, HoldVolEnv, DecayVolEnv,
479
                SustainVolEnv, ReleaseVolEnv, KeynumToVolEnvHold, KeynumToVolEnvDecay, Instrument, Reserved1, KeyRange, VelRange, StartloopAddrsCoarseOffset,
480
                Keynum, Velocity, InitialAttenuation, Reserved2, EndloopAddrsCoarseOffset, CoarseTune, FineTune, SampleID, SampleModes, Reserved3, ScaleTuning,
481
                ExclusiveClass, OverridingRootKey, Unused5, EndOper
482
        };
483
        switch (genOper)
484
        {
485
                case StartAddrsOffset:           region->offset += amount->shortAmount; break;
486
                case EndAddrsOffset:             region->end += amount->shortAmount; break;
487
                case StartloopAddrsOffset:       region->loop_start += amount->shortAmount; break;
488
                case EndloopAddrsOffset:         region->loop_end += amount->shortAmount; break;
489
                case StartAddrsCoarseOffset:     region->offset += amount->shortAmount * 32768; break;
490
                case ModLfoToPitch:              region->modLfoToPitch = amount->shortAmount; break;
491
                case VibLfoToPitch:              region->vibLfoToPitch = amount->shortAmount; break;
492
                case ModEnvToPitch:              region->modEnvToPitch = amount->shortAmount; break;
493
                case InitialFilterFc:            region->initialFilterFc = amount->shortAmount; break;
494
                case InitialFilterQ:             region->initialFilterQ = amount->shortAmount; break;
495
                case ModLfoToFilterFc:           region->modLfoToFilterFc = amount->shortAmount; break;
496
                case ModEnvToFilterFc:           region->modEnvToFilterFc = amount->shortAmount; break;
497
                case EndAddrsCoarseOffset:       region->end += amount->shortAmount * 32768; break;
498
                case ModLfoToVolume:             region->modLfoToVolume = amount->shortAmount; break;
499
                case Pan:                        region->pan = amount->shortAmount / 1000.0f; break;
500
                case DelayModLFO:                region->delayModLFO = amount->shortAmount; break;
501
                case FreqModLFO:                 region->freqModLFO = amount->shortAmount; break;
502
                case DelayVibLFO:                region->delayVibLFO = amount->shortAmount; break;
503
                case FreqVibLFO:                 region->freqVibLFO = amount->shortAmount; break;
504
                case DelayModEnv:                region->modenv.delay = amount->shortAmount; break;
505
                case AttackModEnv:               region->modenv.attack = amount->shortAmount; break;
506
                case HoldModEnv:                 region->modenv.hold = amount->shortAmount; break;
507
                case DecayModEnv:                region->modenv.decay = amount->shortAmount; break;
508
                case SustainModEnv:              region->modenv.sustain = amount->shortAmount; break;
509
                case ReleaseModEnv:              region->modenv.release = amount->shortAmount; break;
510
                case KeynumToModEnvHold:         region->modenv.keynumToHold = amount->shortAmount; break;
511
                case KeynumToModEnvDecay:        region->modenv.keynumToDecay = amount->shortAmount; break;
512
                case DelayVolEnv:                region->ampenv.delay = amount->shortAmount; break;
513
                case AttackVolEnv:               region->ampenv.attack = amount->shortAmount; break;
514
                case HoldVolEnv:                 region->ampenv.hold = amount->shortAmount; break;
515
                case DecayVolEnv:                region->ampenv.decay = amount->shortAmount; break;
516
                case SustainVolEnv:              region->ampenv.sustain = amount->shortAmount; break;
517
                case ReleaseVolEnv:              region->ampenv.release = amount->shortAmount; break;
518
                case KeynumToVolEnvHold:         region->ampenv.keynumToHold = amount->shortAmount; break;
519
                case KeynumToVolEnvDecay:        region->ampenv.keynumToDecay = amount->shortAmount; break;
520
                case KeyRange:                   region->lokey = amount->range.lo; region->hikey = amount->range.hi; break;
521
                case VelRange:                   region->lovel = amount->range.lo; region->hivel = amount->range.hi; break;
522
                case StartloopAddrsCoarseOffset: region->loop_start += amount->shortAmount * 32768; break;
523
                case InitialAttenuation:         region->attenuation += amount->shortAmount * 0.1f; break;
524
                case EndloopAddrsCoarseOffset:   region->loop_end += amount->shortAmount * 32768; break;
525
                case CoarseTune:                 region->transpose += amount->shortAmount; break;
526
                case FineTune:                   region->tune += amount->shortAmount; break;
527
                case SampleModes:                region->loop_mode = ((amount->wordAmount&3) == 3 ? TSF_LOOPMODE_SUSTAIN : ((amount->wordAmount&3) == 1 ? TSF_LOOPMODE_CONTINUOUS : TSF_LOOPMODE_NONE)); break;
528
                case ScaleTuning:                region->pitch_keytrack = amount->shortAmount; break;
529
                case ExclusiveClass:             region->group = amount->wordAmount; break;
530
                case OverridingRootKey:          region->pitch_keycenter = amount->shortAmount; break;
531
                //case gen_endOper: break; // Ignore.
532
                //default: addUnsupportedOpcode(generator_name);
533
        }
534
}
535
 
536
static void tsf_region_envtosecs(struct tsf_envelope* p, TSF_BOOL sustainIsGain)
537
{
538
        // EG times need to be converted from timecents to seconds.
539
        // Pin very short EG segments.  Timecents don't get to zero, and our EG is
540
        // happier with zero values.
541
        p->delay   = (p->delay   < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->delay));
542
        p->attack  = (p->attack  < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->attack));
543
        p->release = (p->release < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->release));
544
 
545
        // If we have dynamic hold or decay times depending on key number we need
546
        // to keep the values in timecents so we can calculate it during startNote
547
        if (!p->keynumToHold)  p->hold  = (p->hold  < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->hold));
548
        if (!p->keynumToDecay) p->decay = (p->decay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->decay));
549
 
550
        if (p->sustain < 0.0f) p->sustain = 0.0f;
551
        else if (sustainIsGain) p->sustain = tsf_decibelsToGain(-p->sustain / 10.0f);
552
        else p->sustain = 1.0f - (p->sustain / 1000.0f);
553
}
554
 
555
static void tsf_load_presets(tsf* res, struct tsf_hydra *hydra, unsigned int fontSampleCount)
556
{
557
        enum { GenInstrument = 41, GenKeyRange = 43, GenVelRange = 44, GenSampleID = 53 };
558
        // Read each preset.
559
        struct tsf_hydra_phdr *pphdr, *pphdrMax;
560
        for (pphdr = hydra->phdrs, pphdrMax = pphdr + hydra->phdrNum - 1; pphdr != pphdrMax; pphdr++)
561
        {
562
                int sortedIndex = 0, region_index = 0;
563
                struct tsf_hydra_phdr *otherphdr;
564
                struct tsf_preset* preset;
565
                struct tsf_hydra_pbag *ppbag, *ppbagEnd;
566
                struct tsf_region globalRegion;
567
                for (otherphdr = hydra->phdrs; otherphdr != pphdrMax; otherphdr++)
568
                {
569
                        if (otherphdr == pphdr || otherphdr->bank > pphdr->bank) continue;
570
                        else if (otherphdr->bank < pphdr->bank) sortedIndex++;
571
                        else if (otherphdr->preset > pphdr->preset) continue;
572
                        else if (otherphdr->preset < pphdr->preset) sortedIndex++;
573
                        else if (otherphdr < pphdr) sortedIndex++;
574
                }
575
 
576
                preset = &res->presets[sortedIndex];
577
                TSF_MEMCPY(preset->presetName, pphdr->presetName, sizeof(preset->presetName));
578
                preset->presetName[sizeof(preset->presetName)-1] = '\0'; //should be zero terminated in source file but make sure
579
                preset->bank = pphdr->bank;
580
                preset->preset = pphdr->preset;
581
                preset->regionNum = 0;
582
 
583
                //count regions covered by this preset
584
                for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
585
                {
586
                        unsigned char plokey = 0, phikey = 127, plovel = 0, phivel = 127;
587
                        struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
588
                        for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
589
                        {
590
                                if (ppgen->genOper == GenKeyRange) { plokey = ppgen->genAmount.range.lo; phikey = ppgen->genAmount.range.hi; continue; }
591
                                if (ppgen->genOper == GenVelRange) { plovel = ppgen->genAmount.range.lo; phivel = ppgen->genAmount.range.hi; continue; }
592
                                if (ppgen->genOper != GenInstrument) continue;
593
                                if (ppgen->genAmount.wordAmount >= hydra->instNum) continue;
594
                                pinst = hydra->insts + ppgen->genAmount.wordAmount;
595
                                for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
596
                                {
597
                                        unsigned char ilokey = 0, ihikey = 127, ilovel = 0, ihivel = 127;
598
                                        for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
599
                                        {
600
                                                if (pigen->genOper == GenKeyRange) { ilokey = pigen->genAmount.range.lo; ihikey = pigen->genAmount.range.hi; continue; }
601
                                                if (pigen->genOper == GenVelRange) { ilovel = pigen->genAmount.range.lo; ihivel = pigen->genAmount.range.hi; continue; }
602
                                                if (pigen->genOper == GenSampleID && ihikey >= plokey && ilokey <= phikey && ihivel >= plovel && ilovel <= phivel) preset->regionNum++;
603
                                        }
604
                                }
605
                        }
606
                }
607
 
608
                preset->regions = (struct tsf_region*)TSF_MALLOC(preset->regionNum * sizeof(struct tsf_region));
609
                tsf_region_clear(&globalRegion, TSF_TRUE);
610
 
611
                // Zones.
612
                for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
613
                {
614
                        struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
615
                        struct tsf_region presetRegion = globalRegion;
616
                        int hadGenInstrument = 0;
617
 
618
                        // Generators.
619
                        for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
620
                        {
621
                                // Instrument.
622
                                if (ppgen->genOper == GenInstrument)
623
                                {
624
                                        struct tsf_region instRegion;
625
                                        tsf_u16 whichInst = ppgen->genAmount.wordAmount;
626
                                        if (whichInst >= hydra->instNum) continue;
627
 
628
                                        tsf_region_clear(&instRegion, TSF_FALSE);
629
                                        pinst = &hydra->insts[whichInst];
630
                                        for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
631
                                        {
632
                                                // Generators.
633
                                                struct tsf_region zoneRegion = instRegion;
634
                                                int hadSampleID = 0;
635
                                                for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
636
                                                {
637
                                                        if (pigen->genOper == GenSampleID)
638
                                                        {
639
                                                                struct tsf_hydra_shdr* pshdr;
640
 
641
                                                                //preset region key and vel ranges are a filter for the zone regions
642
                                                                if (zoneRegion.hikey < presetRegion.lokey || zoneRegion.lokey > presetRegion.hikey) continue;
643
                                                                if (zoneRegion.hivel < presetRegion.lovel || zoneRegion.lovel > presetRegion.hivel) continue;
644
                                                                if (presetRegion.lokey > zoneRegion.lokey) zoneRegion.lokey = presetRegion.lokey;
645
                                                                if (presetRegion.hikey < zoneRegion.hikey) zoneRegion.hikey = presetRegion.hikey;
646
                                                                if (presetRegion.lovel > zoneRegion.lovel) zoneRegion.lovel = presetRegion.lovel;
647
                                                                if (presetRegion.hivel < zoneRegion.hivel) zoneRegion.hivel = presetRegion.hivel;
648
 
649
                                                                //sum regions
650
                                                                zoneRegion.offset += presetRegion.offset;
651
                                                                zoneRegion.end += presetRegion.end;
652
                                                                zoneRegion.loop_start += presetRegion.loop_start;
653
                                                                zoneRegion.loop_end += presetRegion.loop_end;
654
                                                                zoneRegion.transpose += presetRegion.transpose;
655
                                                                zoneRegion.tune += presetRegion.tune;
656
                                                                zoneRegion.pitch_keytrack += presetRegion.pitch_keytrack;
657
                                                                zoneRegion.attenuation += presetRegion.attenuation;
658
                                                                zoneRegion.pan += presetRegion.pan;
659
                                                                zoneRegion.ampenv.delay += presetRegion.ampenv.delay;
660
                                                                zoneRegion.ampenv.attack += presetRegion.ampenv.attack;
661
                                                                zoneRegion.ampenv.hold += presetRegion.ampenv.hold;
662
                                                                zoneRegion.ampenv.decay += presetRegion.ampenv.decay;
663
                                                                zoneRegion.ampenv.sustain += presetRegion.ampenv.sustain;
664
                                                                zoneRegion.ampenv.release += presetRegion.ampenv.release;
665
                                                                zoneRegion.modenv.delay += presetRegion.modenv.delay;
666
                                                                zoneRegion.modenv.attack += presetRegion.modenv.attack;
667
                                                                zoneRegion.modenv.hold += presetRegion.modenv.hold;
668
                                                                zoneRegion.modenv.decay += presetRegion.modenv.decay;
669
                                                                zoneRegion.modenv.sustain += presetRegion.modenv.sustain;
670
                                                                zoneRegion.modenv.release += presetRegion.modenv.release;
671
                                                                zoneRegion.initialFilterQ += presetRegion.initialFilterQ;
672
                                                                zoneRegion.initialFilterFc += presetRegion.initialFilterFc;
673
                                                                zoneRegion.modEnvToPitch += presetRegion.modEnvToPitch;
674
                                                                zoneRegion.modEnvToFilterFc += presetRegion.modEnvToFilterFc;
675
                                                                zoneRegion.delayModLFO += presetRegion.delayModLFO;
676
                                                                zoneRegion.freqModLFO += presetRegion.freqModLFO;
677
                                                                zoneRegion.modLfoToPitch += presetRegion.modLfoToPitch;
678
                                                                zoneRegion.modLfoToFilterFc += presetRegion.modLfoToFilterFc;
679
                                                                zoneRegion.modLfoToVolume += presetRegion.modLfoToVolume;
680
                                                                zoneRegion.delayVibLFO += presetRegion.delayVibLFO;
681
                                                                zoneRegion.freqVibLFO += presetRegion.freqVibLFO;
682
                                                                zoneRegion.vibLfoToPitch += presetRegion.vibLfoToPitch;
683
 
684
                                                                // EG times need to be converted from timecents to seconds.
685
                                                                tsf_region_envtosecs(&zoneRegion.ampenv, TSF_TRUE);
686
                                                                tsf_region_envtosecs(&zoneRegion.modenv, TSF_FALSE);
687
 
688
                                                                // LFO times need to be converted from timecents to seconds.
689
                                                                zoneRegion.delayModLFO = (zoneRegion.delayModLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayModLFO));
690
                                                                zoneRegion.delayVibLFO = (zoneRegion.delayVibLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayVibLFO));
691
 
692
                                                                // Pin values to their ranges.
693
                                                                if (zoneRegion.pan < -0.5f) zoneRegion.pan = -0.5f;
694
                                                                else if (zoneRegion.pan > 0.5f) zoneRegion.pan = 0.5f;
695
                                                                if (zoneRegion.initialFilterQ < 1500 || zoneRegion.initialFilterQ > 13500) zoneRegion.initialFilterQ = 0;
696
 
697
                                                                pshdr = &hydra->shdrs[pigen->genAmount.wordAmount];
698
                                                                zoneRegion.offset += pshdr->start;
699
                                                                zoneRegion.end += pshdr->end;
700
                                                                zoneRegion.loop_start += pshdr->startLoop;
701
                                                                zoneRegion.loop_end += pshdr->endLoop;
702
                                                                if (pshdr->endLoop > 0) zoneRegion.loop_end -= 1;
703
                                                                if (zoneRegion.pitch_keycenter == -1) zoneRegion.pitch_keycenter = pshdr->originalPitch;
704
                                                                zoneRegion.tune += pshdr->pitchCorrection;
705
                                                                zoneRegion.sample_rate = pshdr->sampleRate;
706
                                                                if (zoneRegion.end && zoneRegion.end < fontSampleCount) zoneRegion.end++;
707
                                                                else zoneRegion.end = fontSampleCount;
708
 
709
                                                                preset->regions[region_index] = zoneRegion;
710
                                                                region_index++;
711
                                                                hadSampleID = 1;
712
                                                        }
713
                                                        else tsf_region_operator(&zoneRegion, pigen->genOper, &pigen->genAmount);
714
                                                }
715
 
716
                                                // Handle instrument's global zone.
717
                                                if (pibag == hydra->ibags + pinst->instBagNdx && !hadSampleID)
718
                                                        instRegion = zoneRegion;
719
 
720
                                                // Modulators (TODO)
721
                                                //if (ibag->instModNdx < ibag[1].instModNdx) addUnsupportedOpcode("any modulator");
722
                                        }
723
                                        hadGenInstrument = 1;
724
                                }
725
                                else tsf_region_operator(&presetRegion, ppgen->genOper, &ppgen->genAmount);
726
                        }
727
 
728
                        // Modulators (TODO)
729
                        //if (pbag->modNdx < pbag[1].modNdx) addUnsupportedOpcode("any modulator");
730
 
731
                        // Handle preset's global zone.
732
                        if (ppbag == hydra->pbags + pphdr->presetBagNdx && !hadGenInstrument)
733
                                globalRegion = presetRegion;
734
                }
735
        }
736
}
737
 
738
static void tsf_load_samples(float** fontSamples, unsigned int* fontSampleCount, struct tsf_riffchunk *chunkSmpl, struct tsf_stream* stream)
739
{
740
        // Read sample data into float format buffer.
741
        float* out; unsigned int samplesLeft, samplesToRead, samplesToConvert;
742
        samplesLeft = *fontSampleCount = chunkSmpl->size / sizeof(short);
743
        out = *fontSamples = (float*)TSF_MALLOC(samplesLeft * sizeof(float));
744
        for (; samplesLeft; samplesLeft -= samplesToRead)
745
        {
746
                short sampleBuffer[1024], *in = sampleBuffer;;
747
                samplesToRead = (samplesLeft > 1024 ? 1024 : samplesLeft);
748
                stream->read(stream->data, sampleBuffer, samplesToRead * sizeof(short));
749
 
750
                // Convert from signed 16-bit to float.
751
                for (samplesToConvert = samplesToRead; samplesToConvert > 0; --samplesToConvert)
752
                        // If we ever need to compile for big-endian platforms, we'll need to byte-swap here.
753
                        *out++ = (float)(*in++ / 32767.0);
754
        }
755
}
756
 
757
static void tsf_voice_envelope_nextsegment(struct tsf_voice_envelope* e, short active_segment, float outSampleRate)
758
{
759
        switch (active_segment)
760
        {
761
                case TSF_SEGMENT_NONE:
762
                        e->samplesUntilNextSegment = (int)(e->parameters.delay * outSampleRate);
763
                        if (e->samplesUntilNextSegment > 0)
764
                        {
765
                                e->segment = TSF_SEGMENT_DELAY;
766
                                e->segmentIsExponential = TSF_FALSE;
767
                                e->level = 0.0;
768
                                e->slope = 0.0;
769
                                return;
770
                        }
771
                        /* fall through */
772
                case TSF_SEGMENT_DELAY:
773
                        e->samplesUntilNextSegment = (int)(e->parameters.attack * outSampleRate);
774
                        if (e->samplesUntilNextSegment > 0)
775
                        {
776
                                if (!e->isAmpEnv)
777
                                {
778
                                        //mod env attack duration scales with velocity (velocity of 1 is full duration, max velocity is 0.125 times duration)
779
                                        e->samplesUntilNextSegment = (int)(e->parameters.attack * ((145 - e->midiVelocity) / 144.0f) * outSampleRate);
780
                                }
781
                                e->segment = TSF_SEGMENT_ATTACK;
782
                                e->segmentIsExponential = TSF_FALSE;
783
                                e->level = 0.0f;
784
                                e->slope = 1.0f / e->samplesUntilNextSegment;
785
                                return;
786
                        }
787
                        /* fall through */
788
                case TSF_SEGMENT_ATTACK:
789
                        e->samplesUntilNextSegment = (int)(e->parameters.hold * outSampleRate);
790
                        if (e->samplesUntilNextSegment > 0)
791
                        {
792
                                e->segment = TSF_SEGMENT_HOLD;
793
                                e->segmentIsExponential = TSF_FALSE;
794
                                e->level = 1.0f;
795
                                e->slope = 0.0f;
796
                                return;
797
                        }
798
                        /* fall through */
799
                case TSF_SEGMENT_HOLD:
800
                        e->samplesUntilNextSegment = (int)(e->parameters.decay * outSampleRate);
801
                        if (e->samplesUntilNextSegment > 0)
802
                        {
803
                                e->segment = TSF_SEGMENT_DECAY;
804
                                e->level = 1.0f;
805
                                if (e->isAmpEnv)
806
                                {
807
                                        // I don't truly understand this; just following what LinuxSampler does.
808
                                        float mysterySlope = -9.226f / e->samplesUntilNextSegment;
809
                                        e->slope = TSF_EXPF(mysterySlope);
810
                                        e->segmentIsExponential = TSF_TRUE;
811
                                        if (e->parameters.sustain > 0.0f)
812
                                        {
813
                                                // Again, this is following LinuxSampler's example, which is similar to
814
                                                // SF2-style decay, where "decay" specifies the time it would take to
815
                                                // get to zero, not to the sustain level.  The SFZ spec is not that
816
                                                // specific about what "decay" means, so perhaps it's really supposed
817
                                                // to specify the time to reach the sustain level.
818
                                                e->samplesUntilNextSegment = (int)(TSF_LOG(e->parameters.sustain) / mysterySlope);
819
                                        }
820
                                }
821
                                else
822
                                {
823
                                        e->slope = -1.0f / e->samplesUntilNextSegment;
824
                                        e->samplesUntilNextSegment = (int)(e->parameters.decay * (1.0f - e->parameters.sustain) * outSampleRate);
825
                                        e->segmentIsExponential = TSF_FALSE;
826
                                }
827
                                return;
828
                        }
829
                        /* fall through */
830
                case TSF_SEGMENT_DECAY:
831
                        e->segment = TSF_SEGMENT_SUSTAIN;
832
                        e->level = e->parameters.sustain;
833
                        e->slope = 0.0f;
834
                        e->samplesUntilNextSegment = 0x7FFFFFFF;
835
                        e->segmentIsExponential = TSF_FALSE;
836
                        return;
837
                case TSF_SEGMENT_SUSTAIN:
838
                        e->segment = TSF_SEGMENT_RELEASE;
839
                        e->samplesUntilNextSegment = (int)((e->parameters.release <= 0 ? TSF_FASTRELEASETIME : e->parameters.release) * outSampleRate);
840
                        if (e->isAmpEnv)
841
                        {
842
                                // I don't truly understand this; just following what LinuxSampler does.
843
                                float mysterySlope = -9.226f / e->samplesUntilNextSegment;
844
                                e->slope = TSF_EXPF(mysterySlope);
845
                                e->segmentIsExponential = TSF_TRUE;
846
                        }
847
                        else
848
                        {
849
                                e->slope = -e->level / e->samplesUntilNextSegment;
850
                                e->segmentIsExponential = TSF_FALSE;
851
                        }
852
                        return;
853
                case TSF_SEGMENT_RELEASE:
854
                default:
855
                        e->segment = TSF_SEGMENT_DONE;
856
                        e->segmentIsExponential = TSF_FALSE;
857
                        e->level = e->slope = 0.0f;
858
                        e->samplesUntilNextSegment = 0x7FFFFFF;
859
        }
860
}
861
 
862
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)
863
{
864
        e->parameters = *new_parameters;
865
        if (e->parameters.keynumToHold)
866
        {
867
                e->parameters.hold += e->parameters.keynumToHold * (60.0f - midiNoteNumber);
868
                e->parameters.hold = (e->parameters.hold < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.hold));
869
        }
870
        if (e->parameters.keynumToDecay)
871
        {
872
                e->parameters.decay += e->parameters.keynumToDecay * (60.0f - midiNoteNumber);
873
                e->parameters.decay = (e->parameters.decay < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.decay));
874
        }
875
        e->midiVelocity = midiVelocity;
876
        e->isAmpEnv = isAmpEnv;
877
        tsf_voice_envelope_nextsegment(e, TSF_SEGMENT_NONE, outSampleRate);
878
}
879
 
880
static void tsf_voice_envelope_process(struct tsf_voice_envelope* e, int numSamples, float outSampleRate)
881
{
882
        if (e->slope)
883
        {
884
                if (e->segmentIsExponential) e->level *= TSF_POWF(e->slope, (float)numSamples);
885
                else e->level += (e->slope * numSamples);
886
        }
887
        if ((e->samplesUntilNextSegment -= numSamples) <= 0)
888
                tsf_voice_envelope_nextsegment(e, e->segment, outSampleRate);
889
}
890
 
891
static void tsf_voice_lowpass_setup(struct tsf_voice_lowpass* e, float Fc)
892
{
893
        // Lowpass filter from http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
894
        double K = TSF_TAN(TSF_PI * Fc), KK = K * K;
895
        double norm = 1 / (1 + K * e->QInv + KK);
896
        e->a0 = KK * norm;
897
        e->a1 = 2 * e->a0;
898
        e->b1 = 2 * (KK - 1) * norm;
899
        e->b2 = (1 - K * e->QInv + KK) * norm;
900
}
901
 
902
static float tsf_voice_lowpass_process(struct tsf_voice_lowpass* e, double In)
903
{
904
        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;
905
}
906
 
907
static void tsf_voice_lfo_setup(struct tsf_voice_lfo* e, float delay, int freqCents, float outSampleRate)
908
{
909
        e->samplesUntil = (int)(delay * outSampleRate);
910
        e->delta = (4.0f * tsf_cents2Hertz((float)freqCents) / outSampleRate);
911
        e->level = 0;
912
}
913
 
914
static void tsf_voice_lfo_process(struct tsf_voice_lfo* e, int blockSamples)
915
{
916
        if (e->samplesUntil > blockSamples) { e->samplesUntil -= blockSamples; return; }
917
        e->level += e->delta * blockSamples;
918
        if      (e->level >  1.0f) { e->delta = -e->delta; e->level =  2.0f - e->level; }
919
        else if (e->level < -1.0f) { e->delta = -e->delta; e->level = -2.0f - e->level; }
920
}
921
 
922
static void tsf_voice_kill(struct tsf_voice* v)
923
{
924
        v->playingPreset = -1;
925
}
926
 
927
static void tsf_voice_end(struct tsf_voice* v, float outSampleRate)
928
{
929
        tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
930
        tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
931
        if (v->region->loop_mode == TSF_LOOPMODE_SUSTAIN)
932
        {
933
                // Continue playing, but stop looping.
934
                v->loopEnd = v->loopStart;
935
        }
936
}
937
 
938
static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate)
939
{
940
        v->ampenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
941
        v->modenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate);
942
}
943
 
944
static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate)
945
{
946
        double note = v->playingKey + v->region->transpose + v->region->tune / 100.0;
947
        double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0);
948
        if (pitchShift) adjustedPitch += pitchShift;
949
        v->pitchInputTimecents = adjustedPitch * 100.0;
950
        v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate);
951
}
952
 
953
static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples)
954
{
955
        struct tsf_region* region = v->region;
956
        float* input = f->fontSamples;
957
        float* outL = outputBuffer;
958
        float* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL);
959
 
960
        // Cache some values, to give them at least some chance of ending up in registers.
961
        TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc);
962
        TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume));
963
        TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch));
964
        TSF_BOOL isLooping    = (v->loopStart < v->loopEnd);
965
        unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd;
966
        double tmpSampleEndDbl = (double)region->end, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0;
967
        double tmpSourceSamplePosition = v->sourceSamplePosition;
968
        struct tsf_voice_lowpass tmpLowpass = v->lowpass;
969
 
970
        TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc);
971
        float tmpSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc;
972
 
973
        TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch);
974
        double pitchRatio;
975
        float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch;
976
 
977
        TSF_BOOL dynamicGain = (region->modLfoToVolume != 0);
978
        float noteGain = 0, tmpModLfoToVolume;
979
 
980
        if (dynamicLowpass) tmpSampleRate = f->outSampleRate, tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc;
981
        else tmpSampleRate = 0, tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0;
982
 
983
        if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
984
        else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
985
 
986
        if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
987
        else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0;
988
 
989
        while (numSamples)
990
        {
991
                float gainMono, gainLeft, gainRight;
992
                int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples);
993
                numSamples -= blockSamples;
994
 
995
                if (dynamicLowpass)
996
                {
997
                        float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc;
998
                        tmpLowpass.active = (fres <= 13500.0f);
999
                        if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, tsf_cents2Hertz(fres) / tmpSampleRate);
1000
                }
1001
 
1002
                if (dynamicPitchRatio)
1003
                        pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor;
1004
 
1005
                if (dynamicGain)
1006
                        noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume));
1007
 
1008
                gainMono = noteGain * v->ampenv.level;
1009
 
1010
                // Update EG.
1011
                tsf_voice_envelope_process(&v->ampenv, blockSamples, f->outSampleRate);
1012
                if (updateModEnv) tsf_voice_envelope_process(&v->modenv, blockSamples, f->outSampleRate);
1013
 
1014
                // Update LFOs.
1015
                if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples);
1016
                if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples);
1017
 
1018
                switch (f->outputmode)
1019
                {
1020
                        case TSF_STEREO_INTERLEAVED:
1021
                                gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1022
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1023
                                {
1024
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1025
 
1026
                                        // Simple linear interpolation.
1027
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1028
 
1029
                                        // Low-pass filter.
1030
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1031
 
1032
                                        *outL++ += val * gainLeft;
1033
                                        *outL++ += val * gainRight;
1034
 
1035
                                        // Next sample.
1036
                                        tmpSourceSamplePosition += pitchRatio;
1037
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1038
                                }
1039
                                break;
1040
 
1041
                        case TSF_STEREO_UNWEAVED:
1042
                                gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1043
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1044
                                {
1045
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1046
 
1047
                                        // Simple linear interpolation.
1048
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1049
 
1050
                                        // Low-pass filter.
1051
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1052
 
1053
                                        *outL++ += val * gainLeft;
1054
                                        *outR++ += val * gainRight;
1055
 
1056
                                        // Next sample.
1057
                                        tmpSourceSamplePosition += pitchRatio;
1058
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1059
                                }
1060
                                break;
1061
 
1062
                        case TSF_MONO:
1063
                                while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
1064
                                {
1065
                                        unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
1066
 
1067
                                        // Simple linear interpolation.
1068
                                        float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1069
 
1070
                                        // Low-pass filter.
1071
                                        if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1072
 
1073
                                        *outL++ += val * gainMono;
1074
 
1075
                                        // Next sample.
1076
                                        tmpSourceSamplePosition += pitchRatio;
1077
                                        if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
1078
                                }
1079
                                break;
1080
                }
1081
 
1082
                if (tmpSourceSamplePosition >= tmpSampleEndDbl || v->ampenv.segment == TSF_SEGMENT_DONE)
1083
                {
1084
                        tsf_voice_kill(v);
1085
                        return;
1086
                }
1087
        }
1088
 
1089
        v->sourceSamplePosition = tmpSourceSamplePosition;
1090
        if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass;
1091
}
1092
 
1093
TSFDEF tsf* tsf_load(struct tsf_stream* stream)
1094
{
1095
        tsf* res = TSF_NULL;
1096
        struct tsf_riffchunk chunkHead;
1097
        struct tsf_riffchunk chunkList;
1098
        struct tsf_hydra hydra;
1099
        float* fontSamples = TSF_NULL;
1100
        unsigned int fontSampleCount = 0;
1101
 
1102
        if (!tsf_riffchunk_read(TSF_NULL, &chunkHead, stream) || !TSF_FourCCEquals(chunkHead.id, "sfbk"))
1103
        {
1104
                //if (e) *e = TSF_INVALID_NOSF2HEADER;
1105
                return res;
1106
        }
1107
 
1108
        // Read hydra and locate sample data.
1109
        TSF_MEMSET(&hydra, 0, sizeof(hydra));
1110
        while (tsf_riffchunk_read(&chunkHead, &chunkList, stream))
1111
        {
1112
                struct tsf_riffchunk chunk;
1113
                if (TSF_FourCCEquals(chunkList.id, "pdta"))
1114
                {
1115
                        while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1116
                        {
1117
                                #define HandleChunk(chunkName) (TSF_FourCCEquals(chunk.id, #chunkName) && !(chunk.size % chunkName##SizeInFile)) \
1118
                                        { \
1119
                                                int num = chunk.size / chunkName##SizeInFile, i; \
1120
                                                hydra.chunkName##Num = num; \
1121
                                                hydra.chunkName##s = (struct tsf_hydra_##chunkName*)TSF_MALLOC(num * sizeof(struct tsf_hydra_##chunkName)); \
1122
                                                for (i = 0; i < num; ++i) tsf_hydra_read_##chunkName(&hydra.chunkName##s[i], stream); \
1123
                                        }
1124
                                enum
1125
                                {
1126
                                        phdrSizeInFile = 38, pbagSizeInFile =  4, pmodSizeInFile = 10,
1127
                                        pgenSizeInFile =  4, instSizeInFile = 22, ibagSizeInFile =  4,
1128
                                        imodSizeInFile = 10, igenSizeInFile =  4, shdrSizeInFile = 46
1129
                                };
1130
                                if      HandleChunk(phdr) else if HandleChunk(pbag) else if HandleChunk(pmod)
1131
                                else if HandleChunk(pgen) else if HandleChunk(inst) else if HandleChunk(ibag)
1132
                                else if HandleChunk(imod) else if HandleChunk(igen) else if HandleChunk(shdr)
1133
                                else stream->skip(stream->data, chunk.size);
1134
                                #undef HandleChunk
1135
                        }
1136
                }
1137
                else if (TSF_FourCCEquals(chunkList.id, "sdta"))
1138
                {
1139
                        while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1140
                        {
1141
                                if (TSF_FourCCEquals(chunk.id, "smpl"))
1142
                                {
1143
                                        tsf_load_samples(&fontSamples, &fontSampleCount, &chunk, stream);
1144
                                }
1145
                                else stream->skip(stream->data, chunk.size);
1146
                        }
1147
                }
1148
                else stream->skip(stream->data, chunkList.size);
1149
        }
1150
        if (!hydra.phdrs || !hydra.pbags || !hydra.pmods || !hydra.pgens || !hydra.insts || !hydra.ibags || !hydra.imods || !hydra.igens || !hydra.shdrs)
1151
        {
1152
                //if (e) *e = TSF_INVALID_INCOMPLETE;
1153
        }
1154
        else if (fontSamples == TSF_NULL)
1155
        {
1156
                //if (e) *e = TSF_INVALID_NOSAMPLEDATA;
1157
        }
1158
        else
1159
        {
1160
                res = (tsf*)TSF_MALLOC(sizeof(tsf));
1161
                TSF_MEMSET(res, 0, sizeof(tsf));
1162
                res->presetNum = hydra.phdrNum - 1;
1163
                res->presets = (struct tsf_preset*)TSF_MALLOC(res->presetNum * sizeof(struct tsf_preset));
1164
                res->fontSamples = fontSamples;
1165
                res->outSampleRate = 44100.0f;
1166
                fontSamples = TSF_NULL; //don't free below
1167
                tsf_load_presets(res, &hydra, fontSampleCount);
1168
        }
1169
        TSF_FREE(hydra.phdrs); TSF_FREE(hydra.pbags); TSF_FREE(hydra.pmods);
1170
        TSF_FREE(hydra.pgens); TSF_FREE(hydra.insts); TSF_FREE(hydra.ibags);
1171
        TSF_FREE(hydra.imods); TSF_FREE(hydra.igens); TSF_FREE(hydra.shdrs);
1172
        TSF_FREE(fontSamples);
1173
        return res;
1174
}
1175
 
1176
TSFDEF void tsf_close(tsf* f)
1177
{
1178
        struct tsf_preset *preset, *presetEnd;
1179
        if (!f) return;
1180
        for (preset = f->presets, presetEnd = preset + f->presetNum; preset != presetEnd; preset++)
1181
                TSF_FREE(preset->regions);
1182
        TSF_FREE(f->presets);
1183
        TSF_FREE(f->fontSamples);
1184
        TSF_FREE(f->voices);
1185
        if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); }
1186
        TSF_FREE(f->outputSamples);
1187
        TSF_FREE(f);
1188
}
1189
 
1190
TSFDEF void tsf_reset(tsf* f)
1191
{
1192
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1193
        for (; v != vEnd; v++)
1194
                if (v->playingPreset != -1 && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release))
1195
                        tsf_voice_endquick(v, f->outSampleRate);
1196
        if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); f->channels = TSF_NULL; }
1197
}
1198
 
1199
TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number)
1200
{
1201
        const struct tsf_preset *presets;
1202
        int i, iMax;
1203
        for (presets = f->presets, i = 0, iMax = f->presetNum; i < iMax; i++)
1204
                if (presets[i].preset == preset_number && presets[i].bank == bank)
1205
                        return i;
1206
        return -1;
1207
}
1208
 
1209
TSFDEF int tsf_get_presetcount(const tsf* f)
1210
{
1211
        return f->presetNum;
1212
}
1213
 
1214
TSFDEF const char* tsf_get_presetname(const tsf* f, int preset)
1215
{
1216
        return (preset < 0 || preset >= f->presetNum ? TSF_NULL : f->presets[preset].presetName);
1217
}
1218
 
1219
TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number)
1220
{
1221
        return tsf_get_presetname(f, tsf_get_presetindex(f, bank, preset_number));
1222
}
1223
 
1224
TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db)
1225
{
1226
        f->outputmode = outputmode;
1227
        f->outSampleRate = (float)(samplerate >= 1 ? samplerate : 44100.0f);
1228
        f->globalGainDB = global_gain_db;
1229
}
1230
 
1231
TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel)
1232
{
1233
        short midiVelocity = (short)(vel * 127);
1234
        int voicePlayIndex;
1235
        struct tsf_region *region, *regionEnd;
1236
 
1237
        if (preset_index < 0 || preset_index >= f->presetNum) return;
1238
        if (vel <= 0.0f) { tsf_note_off(f, preset_index, key); return; }
1239
 
1240
        // Play all matching regions.
1241
        voicePlayIndex = f->voicePlayIndex++;
1242
        for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++)
1243
        {
1244
                struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; float filterQDB;
1245
                if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue;
1246
 
1247
                voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum;
1248
                if (region->group)
1249
                {
1250
                        for (; v != vEnd; v++)
1251
                                if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(v, f->outSampleRate);
1252
                                else if (v->playingPreset == -1 && !voice) voice = v;
1253
                }
1254
                else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; }
1255
 
1256
                if (!voice)
1257
                {
1258
                        f->voiceNum += 4;
1259
                        f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice));
1260
                        voice = &f->voices[f->voiceNum - 4];
1261
                        voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1;
1262
                }
1263
 
1264
                voice->region = region;
1265
                voice->playingPreset = preset_index;
1266
                voice->playingKey = key;
1267
                voice->playIndex = voicePlayIndex;
1268
                voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel);
1269
 
1270
                if (f->channels)
1271
                {
1272
                        f->channels->setupVoice(f, voice);
1273
                }
1274
                else
1275
                {
1276
                        tsf_voice_calcpitchratio(voice, 0, f->outSampleRate);
1277
                        // 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).
1278
                        voice->panFactorLeft  = TSF_SQRTF(0.5f - region->pan);
1279
                        voice->panFactorRight = TSF_SQRTF(0.5f + region->pan);
1280
                }
1281
 
1282
                // Offset/end.
1283
                voice->sourceSamplePosition = region->offset;
1284
 
1285
                // Loop.
1286
                doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end);
1287
                voice->loopStart = (doLoop ? region->loop_start : 0);
1288
                voice->loopEnd = (doLoop ? region->loop_end : 0);
1289
 
1290
                // Setup envelopes.
1291
                tsf_voice_envelope_setup(&voice->ampenv, &region->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate);
1292
                tsf_voice_envelope_setup(&voice->modenv, &region->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate);
1293
 
1294
                // Setup lowpass filter.
1295
                filterQDB = region->initialFilterQ / 10.0f;
1296
                voice->lowpass.QInv = 1.0 / TSF_POW(10.0, (filterQDB / 20.0));
1297
                voice->lowpass.z1 = voice->lowpass.z2 = 0;
1298
                voice->lowpass.active = (region->initialFilterFc <= 13500);
1299
                if (voice->lowpass.active) tsf_voice_lowpass_setup(&voice->lowpass, tsf_cents2Hertz((float)region->initialFilterFc) / f->outSampleRate);
1300
 
1301
                // Setup LFO filters.
1302
                tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate);
1303
                tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate);
1304
        }
1305
}
1306
 
1307
TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel)
1308
{
1309
        int preset_index = tsf_get_presetindex(f, bank, preset_number);
1310
        if (preset_index == -1) return 0;
1311
        tsf_note_on(f, preset_index, key, vel);
1312
        return 1;
1313
}
1314
 
1315
TSFDEF void tsf_note_off(tsf* f, int preset_index, int key)
1316
{
1317
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL;
1318
        for (; v != vEnd; v++)
1319
        {
1320
                //Find the first and last entry in the voices list with matching preset, key and look up the smallest play index
1321
                if (v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) continue;
1322
                else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) vMatchFirst = vMatchLast = v;
1323
                else if (v->playIndex == vMatchFirst->playIndex) vMatchLast = v;
1324
        }
1325
        if (!vMatchFirst) return;
1326
        for (v = vMatchFirst; v <= vMatchLast; v++)
1327
        {
1328
                //Stop all voices with matching preset, key and the smallest play index which was enumerated above
1329
                if (v != vMatchFirst && v != vMatchLast &&
1330
                        (v->playIndex != vMatchFirst->playIndex || v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) continue;
1331
                tsf_voice_end(v, f->outSampleRate);
1332
        }
1333
}
1334
 
1335
TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key)
1336
{
1337
        int preset_index = tsf_get_presetindex(f, bank, preset_number);
1338
        if (preset_index == -1) return 0;
1339
        tsf_note_off(f, preset_index, key);
1340
        return 1;
1341
}
1342
 
1343
TSFDEF void tsf_note_off_all(tsf* f)
1344
{
1345
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1346
        for (; v != vEnd; v++) if (v->playingPreset != -1 && v->ampenv.segment < TSF_SEGMENT_RELEASE)
1347
                tsf_voice_end(v, f->outSampleRate);
1348
}
1349
 
1350
TSFDEF int tsf_active_voice_count(tsf* f)
1351
{
1352
        int count = 0;
1353
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1354
        for (; v != vEnd; v++) if (v->playingPreset != -1) count++;
1355
        return count;
1356
}
1357
 
1358
TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing)
1359
{
1360
        float *floatSamples;
1361
        int channelSamples = (f->outputmode == TSF_MONO ? 1 : 2) * samples, floatBufferSize = channelSamples * sizeof(float);
1362
        short* bufferEnd = buffer + channelSamples;
1363
        if (floatBufferSize > f->outputSampleSize)
1364
        {
1365
                TSF_FREE(f->outputSamples);
1366
                f->outputSamples = (float*)TSF_MALLOC(floatBufferSize);
1367
                f->outputSampleSize = floatBufferSize;
1368
        }
1369
 
1370
        tsf_render_float(f, f->outputSamples, samples, TSF_FALSE);
1371
 
1372
        floatSamples = f->outputSamples;
1373
        if (flag_mixing)
1374
                while (buffer != bufferEnd)
1375
                {
1376
                        float v = *floatSamples++;
1377
                        int vi = *buffer + (v < -1.00004566f ? (int)-32768 : (v > 1.00001514f ? (int)32767 : (int)(v * 32767.5f)));
1378
                        *buffer++ = (vi < -32768 ? (short)-32768 : (vi > 32767 ? (short)32767 : (short)vi));
1379
                }
1380
        else
1381
                while (buffer != bufferEnd)
1382
                {
1383
                        float v = *floatSamples++;
1384
                        *buffer++ = (v < -1.00004566f ? (short)-32768 : (v > 1.00001514f ? (short)32767 : (short)(v * 32767.5f)));
1385
                }
1386
}
1387
 
1388
TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing)
1389
{
1390
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1391
        if (!flag_mixing) TSF_MEMSET(buffer, 0, (f->outputmode == TSF_MONO ? 1 : 2) * sizeof(float) * samples);
1392
        for (; v != vEnd; v++)
1393
                if (v->playingPreset != -1)
1394
                        tsf_voice_render(f, v, buffer, samples);
1395
}
1396
 
1397
static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v)
1398
{
1399
        struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel];
1400
        float newpan = v->region->pan + c->panOffset;
1401
        v->playingChannel = f->channels->activeChannel;
1402
        v->noteGainDB += c->gainDB;
1403
        tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate);
1404
        if      (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; }
1405
        else if (newpan >=  0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; }
1406
        else { v->panFactorLeft = TSF_SQRTF(0.5f - newpan); v->panFactorRight = TSF_SQRTF(0.5f + newpan); }
1407
}
1408
 
1409
static struct tsf_channel* tsf_channel_init(tsf* f, int channel)
1410
{
1411
        int i;
1412
        if (f->channels && channel < f->channels->channelNum) return &f->channels->channels[channel];
1413
        if (!f->channels)
1414
        {
1415
                f->channels = (struct tsf_channels*)TSF_MALLOC(sizeof(struct tsf_channels));
1416
                f->channels->setupVoice = &tsf_channel_setup_voice;
1417
                f->channels->channels = NULL;
1418
                f->channels->channelNum = 0;
1419
                f->channels->activeChannel = 0;
1420
        }
1421
        i = f->channels->channelNum;
1422
        f->channels->channelNum = channel + 1;
1423
        f->channels->channels = (struct tsf_channel*)TSF_REALLOC(f->channels->channels, f->channels->channelNum * sizeof(struct tsf_channel));
1424
        for (; i <= channel; i++)
1425
        {
1426
                struct tsf_channel* c = &f->channels->channels[i];
1427
                c->presetIndex = c->bank = 0;
1428
                c->pitchWheel = c->midiPan = 8192;
1429
                c->midiVolume = c->midiExpression = 16383;
1430
                c->midiRPN = 0xFFFF;
1431
                c->midiData = 0;
1432
                c->panOffset = 0.0f;
1433
                c->gainDB = 0.0f;
1434
                c->pitchRange = 2.0f;
1435
                c->tuning = 0.0f;
1436
        }
1437
        return &f->channels->channels[channel];
1438
}
1439
 
1440
static void tsf_channel_applypitch(tsf* f, int channel, struct tsf_channel* c)
1441
{
1442
        struct tsf_voice *v, *vEnd;
1443
        float pitchShift = (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning));
1444
        for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
1445
                if (v->playingChannel == channel && v->playingPreset != -1)
1446
                        tsf_voice_calcpitchratio(v, pitchShift, f->outSampleRate);
1447
}
1448
 
1449
TSFDEF void tsf_channel_set_presetindex(tsf* f, int channel, int preset_index)
1450
{
1451
        tsf_channel_init(f, channel)->presetIndex = (unsigned short)preset_index;
1452
}
1453
 
1454
TSFDEF int tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums)
1455
{
1456
        struct tsf_channel *c = tsf_channel_init(f, channel);
1457
        int preset_index;
1458
        if (flag_mididrums)
1459
        {
1460
                preset_index = tsf_get_presetindex(f, 128 | (c->bank & 0x7FFF), preset_number);
1461
                if (preset_index == -1) preset_index = tsf_get_presetindex(f, 128, preset_number);
1462
                if (preset_index == -1) preset_index = tsf_get_presetindex(f, 128, 0);
1463
                if (preset_index == -1) preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number);
1464
        }
1465
        else preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number);
1466
        if (preset_index == -1) preset_index = tsf_get_presetindex(f, 0, preset_number);
1467
        if (preset_index != -1)
1468
        {
1469
                c->presetIndex = (unsigned short)preset_index;
1470
                return 1;
1471
        }
1472
        return 0;
1473
}
1474
 
1475
TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank)
1476
{
1477
        tsf_channel_init(f, channel)->bank = (unsigned short)bank;
1478
}
1479
 
1480
TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number)
1481
{
1482
        struct tsf_channel *c = tsf_channel_init(f, channel);
1483
        int preset_index = tsf_get_presetindex(f, bank, preset_number);
1484
        if (preset_index == -1) return 0;
1485
        c->presetIndex = (unsigned short)preset_index;
1486
        c->bank = (unsigned short)bank;
1487
        return 1;
1488
}
1489
 
1490
TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan)
1491
{
1492
        struct tsf_voice *v, *vEnd;
1493
        for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
1494
                if (v->playingChannel == channel && v->playingPreset != -1)
1495
                {
1496
                        float newpan = v->region->pan + pan - 0.5f;
1497
                        if      (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; }
1498
                        else if (newpan >=  0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; }
1499
                        else { v->panFactorLeft = TSF_SQRTF(0.5f - newpan); v->panFactorRight = TSF_SQRTF(0.5f + newpan); }
1500
                }
1501
        tsf_channel_init(f, channel)->panOffset = pan - 0.5f;
1502
}
1503
 
1504
TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume)
1505
{
1506
        struct tsf_channel *c = tsf_channel_init(f, channel);
1507
        float gainDB = tsf_gainToDecibels(volume), gainDBChange = gainDB - c->gainDB;
1508
        struct tsf_voice *v, *vEnd;
1509
        if (gainDBChange == 0) return;
1510
        for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
1511
                if (v->playingChannel == channel && v->playingPreset != -1)
1512
                        v->noteGainDB += gainDBChange;
1513
        c->gainDB = gainDB;
1514
}
1515
 
1516
TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel)
1517
{
1518
        struct tsf_channel *c = tsf_channel_init(f, channel);
1519
        if (c->pitchWheel == pitch_wheel) return;
1520
        c->pitchWheel = (unsigned short)pitch_wheel;
1521
        tsf_channel_applypitch(f, channel, c);
1522
}
1523
 
1524
TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range)
1525
{
1526
        struct tsf_channel *c = tsf_channel_init(f, channel);
1527
        if (c->pitchRange == pitch_range) return;
1528
        c->pitchRange = pitch_range;
1529
        if (c->pitchWheel != 8192) tsf_channel_applypitch(f, channel, c);
1530
}
1531
 
1532
TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning)
1533
{
1534
        struct tsf_channel *c = tsf_channel_init(f, channel);
1535
        if (c->tuning == tuning) return;
1536
        c->tuning = tuning;
1537
        tsf_channel_applypitch(f, channel, c);
1538
}
1539
 
1540
TSFDEF void tsf_channel_note_on(tsf* f, int channel, int key, float vel)
1541
{
1542
        if (!f->channels || channel >= f->channels->channelNum) return;
1543
        f->channels->activeChannel = channel;
1544
        tsf_note_on(f, f->channels->channels[channel].presetIndex, key, vel);
1545
}
1546
 
1547
TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key)
1548
{
1549
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL;
1550
        for (; v != vEnd; v++)
1551
        {
1552
                //Find the first and last entry in the voices list with matching channel, key and look up the smallest play index
1553
                if (v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) continue;
1554
                else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) vMatchFirst = vMatchLast = v;
1555
                else if (v->playIndex == vMatchFirst->playIndex) vMatchLast = v;
1556
        }
1557
        if (!vMatchFirst) return;
1558
        for (v = vMatchFirst; v <= vMatchLast; v++)
1559
        {
1560
                //Stop all voices with matching channel, key and the smallest play index which was enumerated above
1561
                if (v != vMatchFirst && v != vMatchLast &&
1562
                        (v->playIndex != vMatchFirst->playIndex || v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) continue;
1563
                tsf_voice_end(v, f->outSampleRate);
1564
        }
1565
}
1566
 
1567
TSFDEF void tsf_channel_note_off_all(tsf* f, int channel)
1568
{
1569
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1570
        for (; v != vEnd; v++)
1571
                if (v->playingPreset != -1 && v->playingChannel == channel && v->ampenv.segment < TSF_SEGMENT_RELEASE)
1572
                        tsf_voice_end(v, f->outSampleRate);
1573
}
1574
 
1575
TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel)
1576
{
1577
        struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1578
        for (; v != vEnd; v++)
1579
                if (v->playingPreset != -1 && v->playingChannel == channel && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release))
1580
                        tsf_voice_endquick(v, f->outSampleRate);
1581
}
1582
 
1583
TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value)
1584
{
1585
        struct tsf_channel* c = tsf_channel_init(f, channel);
1586
        switch (controller)
1587
        {
1588
                case   7 /*VOLUME_MSB*/      : c->midiVolume     = (unsigned short)((c->midiVolume     & 0x7F  ) | (control_value << 7)); goto TCMC_SET_VOLUME;
1589
                case  39 /*VOLUME_LSB*/      : c->midiVolume     = (unsigned short)((c->midiVolume     & 0x3F80) |  control_value);       goto TCMC_SET_VOLUME;
1590
                case  11 /*EXPRESSION_MSB*/  : c->midiExpression = (unsigned short)((c->midiExpression & 0x7F  ) | (control_value << 7)); goto TCMC_SET_VOLUME;
1591
                case  43 /*EXPRESSION_LSB*/  : c->midiExpression = (unsigned short)((c->midiExpression & 0x3F80) |  control_value);       goto TCMC_SET_VOLUME;
1592
                case  10 /*PAN_MSB*/         : c->midiPan        = (unsigned short)((c->midiPan        & 0x7F  ) | (control_value << 7)); goto TCMC_SET_PAN;
1593
                case  42 /*PAN_LSB*/         : c->midiPan        = (unsigned short)((c->midiPan        & 0x3F80) |  control_value);       goto TCMC_SET_PAN;
1594
                case   6 /*DATA_ENTRY_MSB*/  : c->midiData       = (unsigned short)((c->midiData       & 0x7F)   | (control_value << 7)); goto TCMC_SET_DATA;
1595
                case  38 /*DATA_ENTRY_LSB*/  : c->midiData       = (unsigned short)((c->midiData       & 0x3F80) |  control_value);       goto TCMC_SET_DATA;
1596
                case   0 /*BANK_SELECT_MSB*/ : c->bank = (unsigned short)(0x8000 | control_value); return; //bank select MSB alone acts like LSB
1597
                case  32 /*BANK_SELECT_LSB*/ : c->bank = (unsigned short)((c->bank & 0x8000 ? ((c->bank & 0x7F) << 7) : 0) | control_value); return;
1598
                case 101 /*RPN_MSB*/         : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x7F  ) | (control_value << 7)); return;
1599
                case 100 /*RPN_LSB*/         : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x3F80) |  control_value); return;
1600
                case  98 /*NRPN_LSB*/        : c->midiRPN = 0xFFFF; return;
1601
                case  99 /*NRPN_MSB*/        : c->midiRPN = 0xFFFF; return;
1602
                case 120 /*ALL_SOUND_OFF*/   : tsf_channel_sounds_off_all(f, channel); return;
1603
                case 123 /*ALL_NOTES_OFF*/   : tsf_channel_note_off_all(f, channel);   return;
1604
                case 121 /*ALL_CTRL_OFF*/    :
1605
                        c->midiVolume = c->midiExpression = 16383;
1606
                        c->midiPan = 8192;
1607
                        c->bank = 0;
1608
                        tsf_channel_set_volume(f, channel, 1.0f);
1609
                        tsf_channel_set_pan(f, channel, 0.5f);
1610
                        tsf_channel_set_pitchrange(f, channel, 2.0f);
1611
                        return;
1612
        }
1613
        return;
1614
TCMC_SET_VOLUME:
1615
        //Raising to the power of 3 seems to result in a decent sounding volume curve for MIDI
1616
        tsf_channel_set_volume(f, channel, TSF_POWF((c->midiVolume / 16383.0f) * (c->midiExpression / 16383.0f), 3.0f));
1617
        return;
1618
TCMC_SET_PAN:
1619
        tsf_channel_set_pan(f, channel, c->midiPan / 16383.0f);
1620
        return;
1621
TCMC_SET_DATA:
1622
        if      (c->midiRPN == 0) tsf_channel_set_pitchrange(f, channel, (c->midiData >> 7) + 0.01f * (c->midiData & 0x7F));
1623
        else if (c->midiRPN == 1) tsf_channel_set_tuning(f, channel, (int)c->tuning + ((float)c->midiData - 8192.0f) / 8192.0f); //fine tune
1624
        else if (c->midiRPN == 2 && controller == 6) tsf_channel_set_tuning(f, channel, ((float)control_value - 64.0f) + (c->tuning - (int)c->tuning)); //coarse tune
1625
        return;
1626
}
1627
 
1628
TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel)
1629
{
1630
        return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].presetIndex : 0);
1631
}
1632
 
1633
TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel)
1634
{
1635
        return (f->channels && channel < f->channels->channelNum ? (f->channels->channels[channel].bank & 0x7FFF) : 0);
1636
}
1637
 
1638
TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel)
1639
{
1640
        return (f->channels && channel < f->channels->channelNum ? f->presets[f->channels->channels[channel].presetIndex].preset : 0);
1641
}
1642
 
1643
TSFDEF float tsf_channel_get_pan(tsf* f, int channel)
1644
{
1645
        return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].panOffset - 0.5f : 0.5f);
1646
}
1647
 
1648
TSFDEF float tsf_channel_get_volume(tsf* f, int channel)
1649
{
1650
        return (f->channels && channel < f->channels->channelNum ? tsf_decibelsToGain(f->channels->channels[channel].gainDB) : 1.0f);
1651
}
1652
 
1653
TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel)
1654
{
1655
        return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchWheel : 8192);
1656
}
1657
 
1658
TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel)
1659
{
1660
        return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchRange : 2.0f);
1661
}
1662
 
1663
TSFDEF float tsf_channel_get_tuning(tsf* f, int channel)
1664
{
1665
        return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].tuning : 0.0f);
1666
}
1667
 
1668
#ifdef __cplusplus
1669
}
1670
#endif
1671
 
1672
#endif //TSF_IMPLEMENTATION