File Coverage

TinySoundFont/tsf.h
Criterion Covered Total %
statement 438 827 52.9
branch 383 926 41.3
condition n/a
subroutine n/a
pod n/a
total 821 1753 46.8


line stmt bran cond sub pod time code
1             /* TinySoundFont - v0.9 - 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-2023 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             // Copy a tsf instance from an existing one, use tsf_close to close it as well.
93             // All copied tsf instances and their original instance are linked, and share the underlying soundfont.
94             // This allows loading a soundfont only once, but using it for multiple independent playbacks.
95             // (This function isn't thread-safe without locking.)
96             TSFDEF tsf* tsf_copy(tsf* f);
97            
98             // Free the memory related to this tsf instance
99             TSFDEF void tsf_close(tsf* f);
100            
101             // Stop all playing notes immediately and reset all channel parameters
102             TSFDEF void tsf_reset(tsf* f);
103            
104             // Returns the preset index from a bank and preset number, or -1 if it does not exist in the loaded SoundFont
105             TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number);
106            
107             // Returns the number of presets in the loaded SoundFont
108             TSFDEF int tsf_get_presetcount(const tsf* f);
109            
110             // Returns the name of a preset index >= 0 and < tsf_get_presetcount()
111             TSFDEF const char* tsf_get_presetname(const tsf* f, int preset_index);
112            
113             // Returns the name of a preset by bank and preset number
114             TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number);
115            
116             // Supported output modes by the render methods
117             enum TSFOutputMode
118             {
119             // Two channels with single left/right samples one after another
120             TSF_STEREO_INTERLEAVED,
121             // Two channels with all samples for the left channel first then right
122             TSF_STEREO_UNWEAVED,
123             // A single channel (stereo instruments are mixed into center)
124             TSF_MONO
125             };
126            
127             // Thread safety:
128             //
129             // 1. Rendering / voices:
130             //
131             // Your audio output which calls the tsf_render* functions will most likely
132             // run on a different thread than where the playback tsf_note* functions
133             // are called. In which case some sort of concurrency control like a
134             // mutex needs to be used so they are not called at the same time.
135             // Alternatively, you can pre-allocate a maximum number of voices that can
136             // play simultaneously by calling tsf_set_max_voices after loading.
137             // That way memory re-allocation will not happen during tsf_note_on and
138             // TSF should become mostly thread safe.
139             // There is a theoretical chance that ending notes would negatively influence
140             // a voice that is rendering at the time but it is hard to say.
141             // Also be aware, this has not been tested much.
142             //
143             // 2. Channels:
144             //
145             // Calls to tsf_channel_set_... functions may allocate new channels
146             // if no channel with that number was previously used. Make sure to
147             // create all channels at the beginning as required if you call tsf_render*
148             // from a different thread.
149            
150             // Setup the parameters for the voice render methods
151             // outputmode: if mono or stereo and how stereo channel data is ordered
152             // samplerate: the number of samples per second (output frequency)
153             // global_gain_db: volume gain in decibels (>0 means higher, <0 means lower)
154             TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db CPP_DEFAULT0);
155            
156             // Set the global gain as a volume factor
157             // global_gain: the desired volume where 1.0 is 100%
158             TSFDEF void tsf_set_volume(tsf* f, float global_gain);
159            
160             // Set the maximum number of voices to play simultaneously
161             // Depending on the soundfond, one note can cause many new voices to be started,
162             // so don't keep this number too low or otherwise sounds may not play.
163             // max_voices: maximum number to pre-allocate and set the limit to
164             // (tsf_set_max_voices returns 0 if allocation failed, otherwise 1)
165             TSFDEF int tsf_set_max_voices(tsf* f, int max_voices);
166            
167             // Start playing a note
168             // preset_index: preset index >= 0 and < tsf_get_presetcount()
169             // key: note value between 0 and 127 (60 being middle C)
170             // vel: velocity as a float between 0.0 (equal to note off) and 1.0 (full)
171             // bank: instrument bank number (alternative to preset_index)
172             // preset_number: preset number (alternative to preset_index)
173             // (tsf_note_on returns 0 if the allocation of a new voice failed, otherwise 1)
174             // (tsf_bank_note_on returns 0 if preset does not exist or allocation failed, otherwise 1)
175             TSFDEF int tsf_note_on(tsf* f, int preset_index, int key, float vel);
176             TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel);
177            
178             // Stop playing a note
179             // (bank_note_off returns 0 if preset does not exist, otherwise 1)
180             TSFDEF void tsf_note_off(tsf* f, int preset_index, int key);
181             TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key);
182            
183             // Stop playing all notes (end with sustain and release)
184             TSFDEF void tsf_note_off_all(tsf* f);
185            
186             // Returns the number of active voices
187             TSFDEF int tsf_active_voice_count(tsf* f);
188            
189             // Render output samples into a buffer
190             // You can either render as signed 16-bit values (tsf_render_short) or
191             // as 32-bit float values (tsf_render_float)
192             // buffer: target buffer of size samples * output_channels * sizeof(type)
193             // samples: number of samples to render
194             // flag_mixing: if 0 clear the buffer first, otherwise mix into existing data
195             TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing CPP_DEFAULT0);
196             TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing CPP_DEFAULT0);
197            
198             // Higher level channel based functions, set up channel parameters
199             // channel: channel number
200             // preset_index: preset index >= 0 and < tsf_get_presetcount()
201             // preset_number: preset number (alternative to preset_index)
202             // flag_mididrums: 0 for normal channels, otherwise apply MIDI drum channel rules
203             // bank: instrument bank number (alternative to preset_index)
204             // pan: stereo panning value from 0.0 (left) to 1.0 (right) (default 0.5 center)
205             // volume: linear volume scale factor (default 1.0 full)
206             // pitch_wheel: pitch wheel position 0 to 16383 (default 8192 unpitched)
207             // pitch_range: range of the pitch wheel in semitones (default 2.0, total +/- 2 semitones)
208             // tuning: tuning of all playing voices in semitones (default 0.0, standard (A440) tuning)
209             // (tsf_set_preset_number and set_bank_preset return 0 if preset does not exist, otherwise 1)
210             // (tsf_channel_set_... return 0 if a new channel needed allocation and that failed, otherwise 1)
211             TSFDEF int tsf_channel_set_presetindex(tsf* f, int channel, int preset_index);
212             TSFDEF int tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums CPP_DEFAULT0);
213             TSFDEF int tsf_channel_set_bank(tsf* f, int channel, int bank);
214             TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number);
215             TSFDEF int tsf_channel_set_pan(tsf* f, int channel, float pan);
216             TSFDEF int tsf_channel_set_volume(tsf* f, int channel, float volume);
217             TSFDEF int tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel);
218             TSFDEF int tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range);
219             TSFDEF int tsf_channel_set_tuning(tsf* f, int channel, float tuning);
220            
221             // Start or stop playing notes on a channel (needs channel preset to be set)
222             // channel: channel number
223             // key: note value between 0 and 127 (60 being middle C)
224             // vel: velocity as a float between 0.0 (equal to note off) and 1.0 (full)
225             // (tsf_channel_note_on returns 0 on allocation failure of new voice, otherwise 1)
226             TSFDEF int tsf_channel_note_on(tsf* f, int channel, int key, float vel);
227             TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key);
228             TSFDEF void tsf_channel_note_off_all(tsf* f, int channel); //end with sustain and release
229             TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel); //end immediately
230            
231             // Apply a MIDI control change to the channel (not all controllers are supported!)
232             // (tsf_channel_midi_control returns 0 on allocation failure of new channel, otherwise 1)
233             TSFDEF int tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value);
234            
235             // Get current values set on the channels
236             TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel);
237             TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel);
238             TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel);
239             TSFDEF float tsf_channel_get_pan(tsf* f, int channel);
240             TSFDEF float tsf_channel_get_volume(tsf* f, int channel);
241             TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel);
242             TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel);
243             TSFDEF float tsf_channel_get_tuning(tsf* f, int channel);
244            
245             #ifdef __cplusplus
246             # undef CPP_DEFAULT0
247             }
248             #endif
249            
250             // end header
251             // ---------------------------------------------------------------------------------------------------------
252             #endif //TSF_INCLUDE_TSF_INL
253            
254             #ifdef TSF_IMPLEMENTATION
255             #undef TSF_IMPLEMENTATION
256            
257             // The lower this block size is the more accurate the effects are.
258             // Increasing the value significantly lowers the CPU usage of the voice rendering.
259             // If LFO affects the low-pass filter it can be hearable even as low as 8.
260             #ifndef TSF_RENDER_EFFECTSAMPLEBLOCK
261             #define TSF_RENDER_EFFECTSAMPLEBLOCK 64
262             #endif
263            
264             // When using tsf_render_short, to do the conversion a buffer of a fixed size is
265             // allocated on the stack. On low memory platforms this could be made smaller.
266             // Increasing this above 512 should not have a significant impact on performance.
267             // The value should be a multiple of TSF_RENDER_EFFECTSAMPLEBLOCK.
268             #ifndef TSF_RENDER_SHORTBUFFERBLOCK
269             #define TSF_RENDER_SHORTBUFFERBLOCK 512
270             #endif
271            
272             // Grace release time for quick voice off (avoid clicking noise)
273             #define TSF_FASTRELEASETIME 0.01f
274            
275             #if !defined(TSF_MALLOC) || !defined(TSF_FREE) || !defined(TSF_REALLOC)
276             # include
277             # define TSF_MALLOC malloc
278             # define TSF_FREE free
279             # define TSF_REALLOC realloc
280             #endif
281            
282             #if !defined(TSF_MEMCPY) || !defined(TSF_MEMSET)
283             # include
284             # define TSF_MEMCPY memcpy
285             # define TSF_MEMSET memset
286             #endif
287            
288             #if !defined(TSF_POW) || !defined(TSF_POWF) || !defined(TSF_EXPF) || !defined(TSF_LOG) || !defined(TSF_TAN) || !defined(TSF_LOG10) || !defined(TSF_SQRT)
289             # include
290             # if !defined(__cplusplus) && !defined(NAN) && !defined(powf) && !defined(expf) && !defined(sqrtf)
291             # define powf (float)pow // deal with old math.h
292             # define expf (float)exp // files that come without
293             # define sqrtf (float)sqrt // powf, expf and sqrtf
294             # endif
295             # define TSF_POW pow
296             # define TSF_POWF powf
297             # define TSF_EXPF expf
298             # define TSF_LOG log
299             # define TSF_TAN tan
300             # define TSF_LOG10 log10
301             # define TSF_SQRTF sqrtf
302             #endif
303            
304             #ifndef TSF_NO_STDIO
305             # include
306             #endif
307            
308             #define TSF_TRUE 1
309             #define TSF_FALSE 0
310             #define TSF_BOOL char
311             #define TSF_PI 3.14159265358979323846264338327950288
312             #define TSF_NULL 0
313            
314             #ifdef __cplusplus
315             extern "C" {
316             #endif
317            
318             typedef char tsf_fourcc[4];
319             typedef signed char tsf_s8;
320             typedef unsigned char tsf_u8;
321             typedef unsigned short tsf_u16;
322             typedef signed short tsf_s16;
323             typedef unsigned int tsf_u32;
324             typedef char tsf_char20[20];
325            
326             #define TSF_FourCCEquals(value1, value2) (value1[0] == value2[0] && value1[1] == value2[1] && value1[2] == value2[2] && value1[3] == value2[3])
327            
328             struct tsf
329             {
330             struct tsf_preset* presets;
331             float* fontSamples;
332             struct tsf_voice* voices;
333             struct tsf_channels* channels;
334            
335             int presetNum;
336             int voiceNum;
337             int maxVoiceNum;
338             unsigned int voicePlayIndex;
339            
340             enum TSFOutputMode outputmode;
341             float outSampleRate;
342             float globalGainDB;
343             int* refCount;
344             };
345            
346             #ifndef TSF_NO_STDIO
347 1102           static int tsf_stream_stdio_read(FILE* f, void* ptr, unsigned int size) { return (int)fread(ptr, 1, size, f); }
348 10           static int tsf_stream_stdio_skip(FILE* f, unsigned int count) { return !fseek(f, count, SEEK_CUR); }
349 11           TSFDEF tsf* tsf_load_filename(const char* filename)
350             {
351             tsf* res;
352 11           struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_stdio_read, (int(*)(void*,unsigned int))&tsf_stream_stdio_skip };
353             #if __STDC_WANT_SECURE_LIB__
354             FILE* f = TSF_NULL; fopen_s(&f, filename, "rb");
355             #else
356 11           FILE* f = fopen(filename, "rb");
357             #endif
358 11 50         if (!f)
359             {
360             //if (e) *e = TSF_FILENOTFOUND;
361 0           return TSF_NULL;
362             }
363 11           stream.data = f;
364 11           res = tsf_load(&stream);
365 11           fclose(f);
366 11           return res;
367             }
368             #endif
369            
370             struct tsf_stream_memory { const char* buffer; unsigned int total, pos; };
371 0 0         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; }
372 0 0         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; }
373 0           TSFDEF tsf* tsf_load_memory(const void* buffer, int size)
374             {
375 0           struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_memory_read, (int(*)(void*,unsigned int))&tsf_stream_memory_skip };
376 0           struct tsf_stream_memory f = { 0, 0, 0 };
377 0           f.buffer = (const char*)buffer;
378 0           f.total = size;
379 0           stream.data = &f;
380 0           return tsf_load(&stream);
381             }
382            
383             enum { TSF_LOOPMODE_NONE, TSF_LOOPMODE_CONTINUOUS, TSF_LOOPMODE_SUSTAIN };
384            
385             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 };
386            
387             struct tsf_hydra
388             {
389             struct tsf_hydra_phdr *phdrs; struct tsf_hydra_pbag *pbags; struct tsf_hydra_pmod *pmods;
390             struct tsf_hydra_pgen *pgens; struct tsf_hydra_inst *insts; struct tsf_hydra_ibag *ibags;
391             struct tsf_hydra_imod *imods; struct tsf_hydra_igen *igens; struct tsf_hydra_shdr *shdrs;
392             int phdrNum, pbagNum, pmodNum, pgenNum, instNum, ibagNum, imodNum, igenNum, shdrNum;
393             };
394            
395             union tsf_hydra_genamount { struct { tsf_u8 lo, hi; } range; tsf_s16 shortAmount; tsf_u16 wordAmount; };
396             struct tsf_hydra_phdr { tsf_char20 presetName; tsf_u16 preset, bank, presetBagNdx; tsf_u32 library, genre, morphology; };
397             struct tsf_hydra_pbag { tsf_u16 genNdx, modNdx; };
398             struct tsf_hydra_pmod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; };
399             struct tsf_hydra_pgen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; };
400             struct tsf_hydra_inst { tsf_char20 instName; tsf_u16 instBagNdx; };
401             struct tsf_hydra_ibag { tsf_u16 instGenNdx, instModNdx; };
402             struct tsf_hydra_imod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; };
403             struct tsf_hydra_igen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; };
404             struct tsf_hydra_shdr { tsf_char20 sampleName; tsf_u32 start, end, startLoop, endLoop, sampleRate; tsf_u8 originalPitch; tsf_s8 pitchCorrection; tsf_u16 sampleLink, sampleType; };
405            
406             #define TSFR(FIELD) stream->read(stream->data, &i->FIELD, sizeof(i->FIELD));
407 39           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) }
408 39           static void tsf_hydra_read_pbag(struct tsf_hydra_pbag* i, struct tsf_stream* stream) { TSFR(genNdx) TSFR(modNdx) }
409 13           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) }
410 39           static void tsf_hydra_read_pgen(struct tsf_hydra_pgen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) }
411 26           static void tsf_hydra_read_inst(struct tsf_hydra_inst* i, struct tsf_stream* stream) { TSFR(instName) TSFR(instBagNdx) }
412 26           static void tsf_hydra_read_ibag(struct tsf_hydra_ibag* i, struct tsf_stream* stream) { TSFR(instGenNdx) TSFR(instModNdx) }
413 13           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) }
414 39           static void tsf_hydra_read_igen(struct tsf_hydra_igen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) }
415 26           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) }
416             #undef TSFR
417            
418             struct tsf_riffchunk { tsf_fourcc id; tsf_u32 size; };
419             struct tsf_envelope { float delay, attack, hold, decay, sustain, release, keynumToHold, keynumToDecay; };
420             struct tsf_voice_envelope { float level, slope; int samplesUntilNextSegment; short segment, midiVelocity; struct tsf_envelope parameters; TSF_BOOL segmentIsExponential, isAmpEnv; };
421             struct tsf_voice_lowpass { double QInv, a0, a1, b1, b2, z1, z2; TSF_BOOL active; };
422             struct tsf_voice_lfo { int samplesUntil; float level, delta; };
423            
424             struct tsf_region
425             {
426             int loop_mode;
427             unsigned int sample_rate;
428             unsigned char lokey, hikey, lovel, hivel;
429             unsigned int group, offset, end, loop_start, loop_end;
430             int transpose, tune, pitch_keycenter, pitch_keytrack;
431             float attenuation, pan;
432             struct tsf_envelope ampenv, modenv;
433             int initialFilterQ, initialFilterFc;
434             int modEnvToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume;
435             float delayModLFO;
436             int freqModLFO, modLfoToPitch;
437             float delayVibLFO;
438             int freqVibLFO, vibLfoToPitch;
439             };
440            
441             struct tsf_preset
442             {
443             tsf_char20 presetName;
444             tsf_u16 preset, bank;
445             struct tsf_region* regions;
446             int regionNum;
447             };
448            
449             struct tsf_voice
450             {
451             int playingPreset, playingKey, playingChannel;
452             struct tsf_region* region;
453             double pitchInputTimecents, pitchOutputFactor;
454             double sourceSamplePosition;
455             float noteGainDB, panFactorLeft, panFactorRight;
456             unsigned int playIndex, loopStart, loopEnd;
457             struct tsf_voice_envelope ampenv, modenv;
458             struct tsf_voice_lowpass lowpass;
459             struct tsf_voice_lfo modlfo, viblfo;
460             };
461            
462             struct tsf_channel
463             {
464             unsigned short presetIndex, bank, pitchWheel, midiPan, midiVolume, midiExpression, midiRPN, midiData;
465             float panOffset, gainDB, pitchRange, tuning;
466             };
467            
468             struct tsf_channels
469             {
470             void (*setupVoice)(tsf* f, struct tsf_voice* voice);
471             int channelNum, activeChannel;
472             struct tsf_channel channels[1];
473             };
474            
475 4921           static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); }
476 0           static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); }
477 165           static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); }
478 4892 100         static float tsf_decibelsToGain(float db) { return (db > -100.f ? TSF_POWF(10.0f, db * 0.05f) : 0); }
479 105 50         static float tsf_gainToDecibels(float gain) { return (gain <= .00001f ? -100.f : (float)(20.0 * TSF_LOG10(gain))); }
480            
481 223           static TSF_BOOL tsf_riffchunk_read(struct tsf_riffchunk* parent, struct tsf_riffchunk* chunk, struct tsf_stream* stream)
482             {
483             TSF_BOOL IsRiff, IsList;
484 223 100         if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) > parent->size) return TSF_FALSE;
    100          
485 184 100         if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE;
    50          
    50          
486 183 50         if (!stream->read(stream->data, &chunk->size, sizeof(tsf_u32))) return TSF_FALSE;
487 183 100         if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size > parent->size) return TSF_FALSE;
    50          
488 183 100         if (parent) parent->size -= sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size;
489 183 100         IsRiff = TSF_FourCCEquals(chunk->id, "RIFF"), IsList = TSF_FourCCEquals(chunk->id, "LIST");
    50          
    50          
    50          
    100          
    50          
    50          
    50          
490 183 100         if (IsRiff && parent) return TSF_FALSE; //not allowed
    50          
491 183 100         if (!IsRiff && !IsList) return TSF_TRUE; //custom type without sub type
    100          
492 52 50         if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE;
    50          
    50          
493 52           chunk->size -= sizeof(tsf_fourcc);
494 52           return TSF_TRUE;
495             }
496            
497 52           static void tsf_region_clear(struct tsf_region* i, TSF_BOOL for_relative)
498             {
499 52           TSF_MEMSET(i, 0, sizeof(struct tsf_region));
500 52           i->hikey = i->hivel = 127;
501 52           i->pitch_keycenter = 60; // C4
502 52 100         if (for_relative) return;
503            
504 26           i->pitch_keytrack = 100;
505            
506 26           i->pitch_keycenter = -1;
507            
508             // SF2 defaults in timecents.
509 26           i->ampenv.delay = i->ampenv.attack = i->ampenv.hold = i->ampenv.decay = i->ampenv.release = -12000.0f;
510 26           i->modenv.delay = i->modenv.attack = i->modenv.hold = i->modenv.decay = i->modenv.release = -12000.0f;
511            
512 26           i->initialFilterFc = 13500;
513            
514 26           i->delayModLFO = -12000.0f;
515 26           i->delayVibLFO = -12000.0f;
516             }
517            
518 52           static void tsf_region_operator(struct tsf_region* region, tsf_u16 genOper, union tsf_hydra_genamount* amount, struct tsf_region* merge_region)
519             {
520             enum
521             {
522             _GEN_TYPE_MASK = 0x0F,
523             GEN_FLOAT = 0x01,
524             GEN_INT = 0x02,
525             GEN_UINT_ADD = 0x03,
526             GEN_UINT_ADD15 = 0x04,
527             GEN_KEYRANGE = 0x05,
528             GEN_VELRANGE = 0x06,
529             GEN_LOOPMODE = 0x07,
530             GEN_GROUP = 0x08,
531             GEN_KEYCENTER = 0x09,
532            
533             _GEN_LIMIT_MASK = 0xF0,
534             GEN_INT_LIMIT12K = 0x10, //min -12000, max 12000
535             GEN_INT_LIMITFC = 0x20, //min 1500, max 13500
536             GEN_INT_LIMITQ = 0x30, //min 0, max 960
537             GEN_INT_LIMIT960 = 0x40, //min -960, max 960
538             GEN_INT_LIMIT16K4500 = 0x50, //min -16000, max 4500
539             GEN_FLOAT_LIMIT12K5K = 0x60, //min -12000, max 5000
540             GEN_FLOAT_LIMIT12K8K = 0x70, //min -12000, max 8000
541             GEN_FLOAT_LIMIT1200 = 0x80, //min -1200, max 1200
542             GEN_FLOAT_LIMITPAN = 0x90, //* .001f, min -.5f, max .5f,
543             GEN_FLOAT_LIMITATTN = 0xA0, //* .1f, min 0, max 144.0
544             GEN_FLOAT_MAX1000 = 0xB0, //min 0, max 1000
545             GEN_FLOAT_MAX1440 = 0xC0, //min 0, max 1440
546            
547             _GEN_MAX = 59
548             };
549             #define _TSFREGIONOFFSET(TYPE, FIELD) (unsigned char)(((TYPE*)&((struct tsf_region*)0)->FIELD) - (TYPE*)0)
550             #define _TSFREGIONENVOFFSET(TYPE, ENV, FIELD) (unsigned char)(((TYPE*)&((&(((struct tsf_region*)0)->ENV))->FIELD)) - (TYPE*)0)
551             static const struct { unsigned char mode, offset; } genMetas[_GEN_MAX] =
552             {
553             { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, offset ) }, // 0 StartAddrsOffset
554             { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, end ) }, // 1 EndAddrsOffset
555             { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, loop_start ) }, // 2 StartloopAddrsOffset
556             { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, loop_end ) }, // 3 EndloopAddrsOffset
557             { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, offset ) }, // 4 StartAddrsCoarseOffset
558             { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modLfoToPitch ) }, // 5 ModLfoToPitch
559             { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, vibLfoToPitch ) }, // 6 VibLfoToPitch
560             { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modEnvToPitch ) }, // 7 ModEnvToPitch
561             { GEN_INT | GEN_INT_LIMITFC , _TSFREGIONOFFSET( int, initialFilterFc ) }, // 8 InitialFilterFc
562             { GEN_INT | GEN_INT_LIMITQ , _TSFREGIONOFFSET( int, initialFilterQ ) }, // 9 InitialFilterQ
563             { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modLfoToFilterFc ) }, //10 ModLfoToFilterFc
564             { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modEnvToFilterFc ) }, //11 ModEnvToFilterFc
565             { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, end ) }, //12 EndAddrsCoarseOffset
566             { GEN_INT | GEN_INT_LIMIT960 , _TSFREGIONOFFSET( int, modLfoToVolume ) }, //13 ModLfoToVolume
567             { 0 , (0 ) }, // Unused
568             { 0 , (0 ) }, //15 ChorusEffectsSend (unsupported)
569             { 0 , (0 ) }, //16 ReverbEffectsSend (unsupported)
570             { GEN_FLOAT | GEN_FLOAT_LIMITPAN , _TSFREGIONOFFSET( float, pan ) }, //17 Pan
571             { 0 , (0 ) }, // Unused
572             { 0 , (0 ) }, // Unused
573             { 0 , (0 ) }, // Unused
574             { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET( float, delayModLFO ) }, //21 DelayModLFO
575             { GEN_INT | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET( int, freqModLFO ) }, //22 FreqModLFO
576             { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET( float, delayVibLFO ) }, //23 DelayVibLFO
577             { GEN_INT | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET( int, freqVibLFO ) }, //24 FreqVibLFO
578             { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, modenv, delay ) }, //25 DelayModEnv
579             { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, modenv, attack ) }, //26 AttackModEnv
580             { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, modenv, hold ) }, //27 HoldModEnv
581             { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, modenv, decay ) }, //28 DecayModEnv
582             { GEN_FLOAT | GEN_FLOAT_MAX1000 , _TSFREGIONENVOFFSET( float, modenv, sustain ) }, //29 SustainModEnv
583             { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, modenv, release ) }, //30 ReleaseModEnv
584             { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, modenv, keynumToHold ) }, //31 KeynumToModEnvHold
585             { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, modenv, keynumToDecay) }, //32 KeynumToModEnvDecay
586             { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, ampenv, delay ) }, //33 DelayVolEnv
587             { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, ampenv, attack ) }, //34 AttackVolEnv
588             { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, ampenv, hold ) }, //35 HoldVolEnv
589             { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, ampenv, decay ) }, //36 DecayVolEnv
590             { GEN_FLOAT | GEN_FLOAT_MAX1440 , _TSFREGIONENVOFFSET( float, ampenv, sustain ) }, //37 SustainVolEnv
591             { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, ampenv, release ) }, //38 ReleaseVolEnv
592             { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, ampenv, keynumToHold ) }, //39 KeynumToVolEnvHold
593             { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, ampenv, keynumToDecay) }, //40 KeynumToVolEnvDecay
594             { 0 , (0 ) }, // Instrument (special)
595             { 0 , (0 ) }, // Reserved
596             { GEN_KEYRANGE , (0 ) }, //43 KeyRange
597             { GEN_VELRANGE , (0 ) }, //44 VelRange
598             { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, loop_start ) }, //45 StartloopAddrsCoarseOffset
599             { 0 , (0 ) }, //46 Keynum (special)
600             { 0 , (0 ) }, //47 Velocity (special)
601             { GEN_FLOAT | GEN_FLOAT_LIMITATTN , _TSFREGIONOFFSET( float, attenuation ) }, //48 InitialAttenuation
602             { 0 , (0 ) }, // Reserved
603             { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, loop_end ) }, //50 EndloopAddrsCoarseOffset
604             { GEN_INT , _TSFREGIONOFFSET( int, transpose ) }, //51 CoarseTune
605             { GEN_INT , _TSFREGIONOFFSET( int, tune ) }, //52 FineTune
606             { 0 , (0 ) }, // SampleID (special)
607             { GEN_LOOPMODE , _TSFREGIONOFFSET( int, loop_mode ) }, //54 SampleModes
608             { 0 , (0 ) }, // Reserved
609             { GEN_INT , _TSFREGIONOFFSET( int, pitch_keytrack ) }, //56 ScaleTuning
610             { GEN_GROUP , _TSFREGIONOFFSET(unsigned int, group ) }, //57 ExclusiveClass
611             { GEN_KEYCENTER , _TSFREGIONOFFSET( int, pitch_keycenter ) }, //58 OverridingRootKey
612             };
613             #undef _TSFREGIONOFFSET
614             #undef _TSFREGIONENVOFFSET
615 52 100         if (amount)
616             {
617             int offset;
618 26 50         if (genOper >= _GEN_MAX) return;
619 26           offset = genMetas[genOper].offset;
620 26           switch (genMetas[genOper].mode & _GEN_TYPE_MASK)
621             {
622 0           case GEN_FLOAT: (( float*)region)[offset] = amount->shortAmount; return;
623 0           case GEN_INT: (( int*)region)[offset] = amount->shortAmount; return;
624 0           case GEN_UINT_ADD: ((unsigned int*)region)[offset] += amount->shortAmount; return;
625 0           case GEN_UINT_ADD15: ((unsigned int*)region)[offset] += amount->shortAmount<<15; return;
626 0           case GEN_KEYRANGE: region->lokey = amount->range.lo; region->hikey = amount->range.hi; return;
627 0           case GEN_VELRANGE: region->lovel = amount->range.lo; region->hivel = amount->range.hi; return;
628 26 50         case GEN_LOOPMODE: region->loop_mode = ((amount->wordAmount&3) == 3 ? TSF_LOOPMODE_SUSTAIN : ((amount->wordAmount&3) == 1 ? TSF_LOOPMODE_CONTINUOUS : TSF_LOOPMODE_NONE)); return;
629 0           case GEN_GROUP: region->group = amount->wordAmount; return;
630 0           case GEN_KEYCENTER: region->pitch_keycenter = amount->shortAmount; return;
631             }
632             }
633             else //merge regions and clamp values
634             {
635 1560 100         for (genOper = 0; genOper != _GEN_MAX; genOper++)
636             {
637 1534           int offset = genMetas[genOper].offset;
638 1534           switch (genMetas[genOper].mode & _GEN_TYPE_MASK)
639             {
640 520           case GEN_FLOAT:
641 520           {
642 520           float *val = &((float*)region)[offset], vfactor, vmin, vmax;
643 520           *val += ((float*)merge_region)[offset];
644 520           switch (genMetas[genOper].mode & _GEN_LIMIT_MASK)
645             {
646 156           case GEN_FLOAT_LIMIT12K5K: vfactor = 1.0f; vmin = -12000.0f; vmax = 5000.0f; break;
647 156           case GEN_FLOAT_LIMIT12K8K: vfactor = 1.0f; vmin = -12000.0f; vmax = 8000.0f; break;
648 104           case GEN_FLOAT_LIMIT1200: vfactor = 1.0f; vmin = -1200.0f; vmax = 1200.0f; break;
649 26           case GEN_FLOAT_LIMITPAN: vfactor = 0.001f; vmin = -0.5f; vmax = 0.5f; break;
650 26           case GEN_FLOAT_LIMITATTN: vfactor = 0.1f; vmin = 0.0f; vmax = 144.0f; break;
651 26           case GEN_FLOAT_MAX1000: vfactor = 1.0f; vmin = 0.0f; vmax = 1000.0f; break;
652 26           case GEN_FLOAT_MAX1440: vfactor = 1.0f; vmin = 0.0f; vmax = 1440.0f; break;
653 0           default: continue;
654             }
655 520           *val *= vfactor;
656 520 50         if (*val < vmin) *val = vmin;
657 520 50         else if (*val > vmax) *val = vmax;
658 520           continue;
659             }
660 338           case GEN_INT:
661 260           {
662 338           int *val = &((int*)region)[offset], vmin, vmax;
663 338           *val += ((int*)merge_region)[offset];
664 338           switch (genMetas[genOper].mode & _GEN_LIMIT_MASK)
665             {
666 130           case GEN_INT_LIMIT12K: vmin = -12000; vmax = 12000; break;
667 26           case GEN_INT_LIMITFC: vmin = 1500; vmax = 13500; break;
668 26           case GEN_INT_LIMITQ: vmin = 0; vmax = 960; break;
669 26           case GEN_INT_LIMIT960: vmin = -960; vmax = 960; break;
670 52           case GEN_INT_LIMIT16K4500: vmin = -16000; vmax = 4500; break;
671 78           default: continue;
672             }
673 260 50         if (*val < vmin) *val = vmin;
674 260 50         else if (*val > vmax) *val = vmax;
675 260           continue;
676             }
677 104           case GEN_UINT_ADD:
678             {
679 104           ((unsigned int*)region)[offset] += ((unsigned int*)merge_region)[offset];
680 104           continue;
681             }
682             }
683             }
684             }
685             }
686            
687 52           static void tsf_region_envtosecs(struct tsf_envelope* p, TSF_BOOL sustainIsGain)
688             {
689             // EG times need to be converted from timecents to seconds.
690             // Pin very short EG segments. Timecents don't get to zero, and our EG is
691             // happier with zero values.
692 52 50         p->delay = (p->delay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->delay));
693 52 50         p->attack = (p->attack < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->attack));
694 52 50         p->release = (p->release < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->release));
695            
696             // If we have dynamic hold or decay times depending on key number we need
697             // to keep the values in timecents so we can calculate it during startNote
698 52 50         if (!p->keynumToHold) p->hold = (p->hold < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->hold));
    50          
699 52 50         if (!p->keynumToDecay) p->decay = (p->decay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->decay));
    50          
700            
701 52 50         if (p->sustain < 0.0f) p->sustain = 0.0f;
702 52 100         else if (sustainIsGain) p->sustain = tsf_decibelsToGain(-p->sustain / 10.0f);
703 26           else p->sustain = 1.0f - (p->sustain / 1000.0f);
704 52           }
705            
706 13           static int tsf_load_presets(tsf* res, struct tsf_hydra *hydra, unsigned int fontSampleCount)
707             {
708             enum { GenInstrument = 41, GenKeyRange = 43, GenVelRange = 44, GenSampleID = 53 };
709             // Read each preset.
710             struct tsf_hydra_phdr *pphdr, *pphdrMax;
711 13           res->presetNum = hydra->phdrNum - 1;
712 13           res->presets = (struct tsf_preset*)TSF_MALLOC(res->presetNum * sizeof(struct tsf_preset));
713 13 50         if (!res->presets) return 0;
714 39 100         else { int i; for (i = 0; i != res->presetNum; i++) res->presets[i].regions = TSF_NULL; }
715 39 100         for (pphdr = hydra->phdrs, pphdrMax = pphdr + hydra->phdrNum - 1; pphdr != pphdrMax; pphdr++)
716             {
717 26           int sortedIndex = 0, region_index = 0;
718             struct tsf_hydra_phdr *otherphdr;
719             struct tsf_preset* preset;
720             struct tsf_hydra_pbag *ppbag, *ppbagEnd;
721             struct tsf_region globalRegion;
722 78 100         for (otherphdr = hydra->phdrs; otherphdr != pphdrMax; otherphdr++)
723             {
724 52 100         if (otherphdr == pphdr || otherphdr->bank > pphdr->bank) continue;
    50          
725 26 50         else if (otherphdr->bank < pphdr->bank) sortedIndex++;
726 26 50         else if (otherphdr->preset > pphdr->preset) continue;
727 26 50         else if (otherphdr->preset < pphdr->preset) sortedIndex++;
728 26 100         else if (otherphdr < pphdr) sortedIndex++;
729             }
730            
731 26           preset = &res->presets[sortedIndex];
732 26           TSF_MEMCPY(preset->presetName, pphdr->presetName, sizeof(preset->presetName));
733 26           preset->presetName[sizeof(preset->presetName)-1] = '\0'; //should be zero terminated in source file but make sure
734 26           preset->bank = pphdr->bank;
735 26           preset->preset = pphdr->preset;
736 26           preset->regionNum = 0;
737            
738             //count regions covered by this preset
739 52 100         for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
740             {
741 26           unsigned char plokey = 0, phikey = 127, plovel = 0, phivel = 127;
742             struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
743 52 100         for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
744             {
745 26 50         if (ppgen->genOper == GenKeyRange) { plokey = ppgen->genAmount.range.lo; phikey = ppgen->genAmount.range.hi; continue; }
746 26 50         if (ppgen->genOper == GenVelRange) { plovel = ppgen->genAmount.range.lo; phivel = ppgen->genAmount.range.hi; continue; }
747 26 50         if (ppgen->genOper != GenInstrument) continue;
748 26 50         if (ppgen->genAmount.wordAmount >= hydra->instNum) continue;
749 26           pinst = hydra->insts + ppgen->genAmount.wordAmount;
750 52 100         for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
751             {
752 26           unsigned char ilokey = 0, ihikey = 127, ilovel = 0, ihivel = 127;
753 78 100         for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
754             {
755 52 50         if (pigen->genOper == GenKeyRange) { ilokey = pigen->genAmount.range.lo; ihikey = pigen->genAmount.range.hi; continue; }
756 52 50         if (pigen->genOper == GenVelRange) { ilovel = pigen->genAmount.range.lo; ihivel = pigen->genAmount.range.hi; continue; }
757 52 100         if (pigen->genOper == GenSampleID && ihikey >= plokey && ilokey <= phikey && ihivel >= plovel && ilovel <= phivel) preset->regionNum++;
    50          
    50          
    50          
    50          
758             }
759             }
760             }
761             }
762            
763 26           preset->regions = (struct tsf_region*)TSF_MALLOC(preset->regionNum * sizeof(struct tsf_region));
764 26 50         if (!preset->regions)
765             {
766 0 0         int i; for (i = 0; i != res->presetNum; i++) TSF_FREE(res->presets[i].regions);
767 0           TSF_FREE(res->presets);
768 0           return 0;
769             }
770 26           tsf_region_clear(&globalRegion, TSF_TRUE);
771            
772             // Zones.
773 52 100         for (ppbag = hydra->pbags + pphdr->presetBagNdx, ppbagEnd = hydra->pbags + pphdr[1].presetBagNdx; ppbag != ppbagEnd; ppbag++)
774             {
775             struct tsf_hydra_pgen *ppgen, *ppgenEnd; struct tsf_hydra_inst *pinst; struct tsf_hydra_ibag *pibag, *pibagEnd; struct tsf_hydra_igen *pigen, *pigenEnd;
776 26           struct tsf_region presetRegion = globalRegion;
777 26           int hadGenInstrument = 0;
778            
779             // Generators.
780 52 100         for (ppgen = hydra->pgens + ppbag->genNdx, ppgenEnd = hydra->pgens + ppbag[1].genNdx; ppgen != ppgenEnd; ppgen++)
781             {
782             // Instrument.
783 26 50         if (ppgen->genOper == GenInstrument)
784             {
785             struct tsf_region instRegion;
786 26           tsf_u16 whichInst = ppgen->genAmount.wordAmount;
787 26 50         if (whichInst >= hydra->instNum) continue;
788            
789 26           tsf_region_clear(&instRegion, TSF_FALSE);
790 26           pinst = &hydra->insts[whichInst];
791 52 100         for (pibag = hydra->ibags + pinst->instBagNdx, pibagEnd = hydra->ibags + pinst[1].instBagNdx; pibag != pibagEnd; pibag++)
792             {
793             // Generators.
794 26           struct tsf_region zoneRegion = instRegion;
795 26           int hadSampleID = 0;
796 78 100         for (pigen = hydra->igens + pibag->instGenNdx, pigenEnd = hydra->igens + pibag[1].instGenNdx; pigen != pigenEnd; pigen++)
797             {
798 52 100         if (pigen->genOper == GenSampleID)
799             {
800             struct tsf_hydra_shdr* pshdr;
801            
802             //preset region key and vel ranges are a filter for the zone regions
803 26 50         if (zoneRegion.hikey < presetRegion.lokey || zoneRegion.lokey > presetRegion.hikey) continue;
    50          
804 26 50         if (zoneRegion.hivel < presetRegion.lovel || zoneRegion.lovel > presetRegion.hivel) continue;
    50          
805 26 50         if (presetRegion.lokey > zoneRegion.lokey) zoneRegion.lokey = presetRegion.lokey;
806 26 50         if (presetRegion.hikey < zoneRegion.hikey) zoneRegion.hikey = presetRegion.hikey;
807 26 50         if (presetRegion.lovel > zoneRegion.lovel) zoneRegion.lovel = presetRegion.lovel;
808 26 50         if (presetRegion.hivel < zoneRegion.hivel) zoneRegion.hivel = presetRegion.hivel;
809            
810             //sum regions
811 26           tsf_region_operator(&zoneRegion, 0, TSF_NULL, &presetRegion);
812            
813             // EG times need to be converted from timecents to seconds.
814 26           tsf_region_envtosecs(&zoneRegion.ampenv, TSF_TRUE);
815 26           tsf_region_envtosecs(&zoneRegion.modenv, TSF_FALSE);
816            
817             // LFO times need to be converted from timecents to seconds.
818 26 50         zoneRegion.delayModLFO = (zoneRegion.delayModLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayModLFO));
819 26 50         zoneRegion.delayVibLFO = (zoneRegion.delayVibLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayVibLFO));
820            
821             // Fixup sample positions
822 26           pshdr = &hydra->shdrs[pigen->genAmount.wordAmount];
823 26           zoneRegion.offset += pshdr->start;
824 26           zoneRegion.end += pshdr->end;
825 26           zoneRegion.loop_start += pshdr->startLoop;
826 26           zoneRegion.loop_end += pshdr->endLoop;
827 26 50         if (pshdr->endLoop > 0) zoneRegion.loop_end -= 1;
828 26 50         if (zoneRegion.loop_end > fontSampleCount) zoneRegion.loop_end = fontSampleCount;
829 26 50         if (zoneRegion.pitch_keycenter == -1) zoneRegion.pitch_keycenter = pshdr->originalPitch;
830 26           zoneRegion.tune += pshdr->pitchCorrection;
831 26           zoneRegion.sample_rate = pshdr->sampleRate;
832 26 50         if (zoneRegion.end && zoneRegion.end < fontSampleCount) zoneRegion.end++;
    50          
833 26           else zoneRegion.end = fontSampleCount;
834            
835 26           preset->regions[region_index] = zoneRegion;
836 26           region_index++;
837 26           hadSampleID = 1;
838             }
839 26           else tsf_region_operator(&zoneRegion, pigen->genOper, &pigen->genAmount, TSF_NULL);
840             }
841            
842             // Handle instrument's global zone.
843 26 50         if (pibag == hydra->ibags + pinst->instBagNdx && !hadSampleID)
    50          
844 0           instRegion = zoneRegion;
845            
846             // Modulators (TODO)
847             //if (ibag->instModNdx < ibag[1].instModNdx) addUnsupportedOpcode("any modulator");
848             }
849 26           hadGenInstrument = 1;
850             }
851 0           else tsf_region_operator(&presetRegion, ppgen->genOper, &ppgen->genAmount, TSF_NULL);
852             }
853            
854             // Modulators (TODO)
855             //if (pbag->modNdx < pbag[1].modNdx) addUnsupportedOpcode("any modulator");
856            
857             // Handle preset's global zone.
858 26 50         if (ppbag == hydra->pbags + pphdr->presetBagNdx && !hadGenInstrument)
    50          
859 0           globalRegion = presetRegion;
860             }
861             }
862 13           return 1;
863             }
864            
865             #ifdef STB_VORBIS_INCLUDE_STB_VORBIS_H
866             static int tsf_decode_ogg(const tsf_u8 *pSmpl, const tsf_u8 *pSmplEnd, float** pRes, tsf_u32* pResNum, tsf_u32* pResMax, tsf_u32 resInitial)
867             {
868             float *res = *pRes, *oldres; tsf_u32 resNum = *pResNum; tsf_u32 resMax = *pResMax; stb_vorbis *v;
869            
870             // Use whatever stb_vorbis API that is available (either pull or push)
871             #if !defined(STB_VORBIS_NO_PULLDATA_API) && !defined(STB_VORBIS_NO_FROMMEMORY)
872             v = stb_vorbis_open_memory(pSmpl, (int)(pSmplEnd - pSmpl), TSF_NULL, TSF_NULL);
873             #else
874             { int use, err; v = stb_vorbis_open_pushdata(pSmpl, (int)(pSmplEnd - pSmpl), &use, &err, TSF_NULL); pSmpl += use; }
875             #endif
876             if (v == TSF_NULL) return 0;
877            
878             for (;;)
879             {
880             float** outputs; int n_samples;
881            
882             // Decode one frame of vorbis samples with whatever stb_vorbis API that is available
883             #if !defined(STB_VORBIS_NO_PULLDATA_API) && !defined(STB_VORBIS_NO_FROMMEMORY)
884             n_samples = stb_vorbis_get_frame_float(v, TSF_NULL, &outputs);
885             if (!n_samples) break;
886             #else
887             if (pSmpl >= pSmplEnd) break;
888             { int use = stb_vorbis_decode_frame_pushdata(v, pSmpl, (int)(pSmplEnd - pSmpl), TSF_NULL, &outputs, &n_samples); pSmpl += use; }
889             if (!n_samples) continue;
890             #endif
891            
892             // Expand our output buffer if necessary then copy over the decoded frame samples
893             resNum += n_samples;
894             if (resNum > resMax)
895             {
896             do { resMax += (resMax ? (resMax < 1048576 ? resMax : 1048576) : resInitial); } while (resNum > resMax);
897             res = (float*)TSF_REALLOC((oldres = res), resMax * sizeof(float));
898             if (!res) { TSF_FREE(oldres); stb_vorbis_close(v); return 0; }
899             }
900             TSF_MEMCPY(res + resNum - n_samples, outputs[0], n_samples * sizeof(float));
901             }
902             stb_vorbis_close(v);
903             *pRes = res; *pResNum = resNum; *pResMax = resMax;
904             return 1;
905             }
906            
907             static int tsf_decode_sf3_samples(const void* rawBuffer, float** pFloatBuffer, unsigned int* pSmplCount, struct tsf_hydra *hydra)
908             {
909             const tsf_u8* smplBuffer = (const tsf_u8*)rawBuffer;
910             tsf_u32 smplLength = *pSmplCount, resNum = 0, resMax = 0, resInitial = (smplLength > 0x100000 ? (smplLength & ~0xFFFFF) : 65536);
911             float *res = TSF_NULL, *oldres;
912             int i, shdrLast = hydra->shdrNum - 1, is_sf3 = 0;
913             for (i = 0; i <= shdrLast; i++)
914             {
915             struct tsf_hydra_shdr *shdr = &hydra->shdrs[i];
916             if (shdr->sampleType & 0x30) // compression flags (sometimes Vorbis flag)
917             {
918             const tsf_u8 *pSmpl = smplBuffer + shdr->start, *pSmplEnd = smplBuffer + shdr->end;
919             if (pSmpl + 4 > pSmplEnd || !TSF_FourCCEquals(pSmpl, "OggS"))
920             {
921             shdr->start = shdr->end = shdr->startLoop = shdr->endLoop = 0;
922             continue;
923             }
924            
925             // Fix up sample indices in shdr (end index is set after decoding)
926             shdr->start = resNum;
927             shdr->startLoop += resNum;
928             shdr->endLoop += resNum;
929             if (!tsf_decode_ogg(pSmpl, pSmplEnd, &res, &resNum, &resMax, resInitial)) { TSF_FREE(res); return 0; }
930             shdr->end = resNum;
931             is_sf3 = 1;
932             }
933             else // raw PCM sample
934             {
935             float *out; short *in = (short*)smplBuffer + resNum, *inEnd; tsf_u32 oldResNum = resNum;
936             if (is_sf3) // Fix up sample indices in shdr
937             {
938             tsf_u32 fix_offset = resNum - shdr->start;
939             in -= fix_offset;
940             shdr->start = resNum;
941             shdr->end += fix_offset;
942             shdr->startLoop += fix_offset;
943             shdr->endLoop += fix_offset;
944             }
945             inEnd = in + ((shdr->end >= shdr->endLoop ? shdr->end : shdr->endLoop) - resNum);
946             if (i == shdrLast || (tsf_u8*)inEnd > (smplBuffer + smplLength)) inEnd = (short*)(smplBuffer + smplLength);
947             if (inEnd <= in) continue;
948            
949             // expand our output buffer if necessary then convert the PCM data from short to float
950             resNum += (tsf_u32)(inEnd - in);
951             if (resNum > resMax)
952             {
953             do { resMax += (resMax ? (resMax < 1048576 ? resMax : 1048576) : resInitial); } while (resNum > resMax);
954             res = (float*)TSF_REALLOC((oldres = res), resMax * sizeof(float));
955             if (!res) { TSF_FREE(oldres); return 0; }
956             }
957            
958             // Convert the samples from short to float
959             for (out = res + oldResNum; in < inEnd;)
960             *(out++) = (float)(*(in++) / 32767.0);
961             }
962             }
963            
964             // Trim the sample buffer down then return success (unless out of memory)
965             if (!(*pFloatBuffer = (float*)TSF_REALLOC(res, resNum * sizeof(float)))) *pFloatBuffer = res;
966             *pFloatBuffer = res;
967             *pSmplCount = resNum;
968             return (res ? 1 : 0);
969             }
970             #endif
971            
972 13           static int tsf_load_samples(void** pRawBuffer, float** pFloatBuffer, unsigned int* pSmplCount, struct tsf_riffchunk *chunkSmpl, struct tsf_stream* stream)
973             {
974             #ifdef STB_VORBIS_INCLUDE_STB_VORBIS_H
975             // With OGG Vorbis support we cannot pre-allocate the memory for tsf_decode_sf3_samples
976             tsf_u32 resNum, resMax; float* oldres;
977             *pSmplCount = chunkSmpl->size;
978             *pRawBuffer = (void*)TSF_MALLOC(*pSmplCount);
979             if (!*pRawBuffer || !stream->read(stream->data, *pRawBuffer, chunkSmpl->size)) return 0;
980             if (chunkSmpl->id[3] != 'o') return 1;
981            
982             // Decode custom .sfo 'smpo' format where all samples are in a single ogg stream
983             resNum = resMax = 0;
984             if (!tsf_decode_ogg((tsf_u8*)*pRawBuffer, (tsf_u8*)*pRawBuffer + chunkSmpl->size, pFloatBuffer, &resNum, &resMax, 65536)) return 0;
985             if (!(*pFloatBuffer = (float*)TSF_REALLOC((oldres = *pFloatBuffer), resNum * sizeof(float)))) *pFloatBuffer = oldres;
986             *pSmplCount = resNum;
987             return (*pFloatBuffer ? 1 : 0);
988             #else
989             // Inline convert the samples from short to float
990             float *res, *out; const short *in;
991 13           *pSmplCount = chunkSmpl->size / (unsigned int)sizeof(short);
992 13           *pFloatBuffer = (float*)TSF_MALLOC(*pSmplCount * sizeof(float));
993 13 50         if (!*pFloatBuffer || !stream->read(stream->data, *pFloatBuffer, chunkSmpl->size)) return 0;
    50          
994 663 100         for (res = *pFloatBuffer, out = res + *pSmplCount, in = (short*)res + *pSmplCount; out != res;)
995 650           *(--out) = (float)(*(--in) / 32767.0);
996 13           return 1;
997             #endif
998             }
999            
1000 106           static int tsf_voice_envelope_release_samples(struct tsf_voice_envelope* e, float outSampleRate)
1001             {
1002 106 50         return (int)((e->parameters.release <= 0 ? TSF_FASTRELEASETIME : e->parameters.release) * outSampleRate);
1003             }
1004            
1005 269           static void tsf_voice_envelope_nextsegment(struct tsf_voice_envelope* e, short active_segment, float outSampleRate)
1006             {
1007 269           switch (active_segment)
1008             {
1009 110           case TSF_SEGMENT_NONE:
1010 110           e->samplesUntilNextSegment = (int)(e->parameters.delay * outSampleRate);
1011 110 50         if (e->samplesUntilNextSegment > 0)
1012             {
1013 0           e->segment = TSF_SEGMENT_DELAY;
1014 0           e->segmentIsExponential = TSF_FALSE;
1015 0           e->level = 0.0;
1016 0           e->slope = 0.0;
1017 0           return;
1018             }
1019             /* fall through */
1020             case TSF_SEGMENT_DELAY:
1021 110           e->samplesUntilNextSegment = (int)(e->parameters.attack * outSampleRate);
1022 110 50         if (e->samplesUntilNextSegment > 0)
1023             {
1024 0 0         if (!e->isAmpEnv)
1025             {
1026             //mod env attack duration scales with velocity (velocity of 1 is full duration, max velocity is 0.125 times duration)
1027 0           e->samplesUntilNextSegment = (int)(e->parameters.attack * ((145 - e->midiVelocity) / 144.0f) * outSampleRate);
1028             }
1029 0           e->segment = TSF_SEGMENT_ATTACK;
1030 0           e->segmentIsExponential = TSF_FALSE;
1031 0           e->level = 0.0f;
1032 0           e->slope = 1.0f / e->samplesUntilNextSegment;
1033 0           return;
1034             }
1035             /* fall through */
1036             case TSF_SEGMENT_ATTACK:
1037 110           e->samplesUntilNextSegment = (int)(e->parameters.hold * outSampleRate);
1038 110 50         if (e->samplesUntilNextSegment > 0)
1039             {
1040 0           e->segment = TSF_SEGMENT_HOLD;
1041 0           e->segmentIsExponential = TSF_FALSE;
1042 0           e->level = 1.0f;
1043 0           e->slope = 0.0f;
1044 0           return;
1045             }
1046             /* fall through */
1047             case TSF_SEGMENT_HOLD:
1048 110           e->samplesUntilNextSegment = (int)(e->parameters.decay * outSampleRate);
1049 110 50         if (e->samplesUntilNextSegment > 0)
1050             {
1051 0           e->segment = TSF_SEGMENT_DECAY;
1052 0           e->level = 1.0f;
1053 0 0         if (e->isAmpEnv)
1054             {
1055             // I don't truly understand this; just following what LinuxSampler does.
1056 0           float mysterySlope = -9.226f / e->samplesUntilNextSegment;
1057 0           e->slope = TSF_EXPF(mysterySlope);
1058 0           e->segmentIsExponential = TSF_TRUE;
1059 0 0         if (e->parameters.sustain > 0.0f)
1060             {
1061             // Again, this is following LinuxSampler's example, which is similar to
1062             // SF2-style decay, where "decay" specifies the time it would take to
1063             // get to zero, not to the sustain level. The SFZ spec is not that
1064             // specific about what "decay" means, so perhaps it's really supposed
1065             // to specify the time to reach the sustain level.
1066 0           e->samplesUntilNextSegment = (int)(TSF_LOG(e->parameters.sustain) / mysterySlope);
1067             }
1068             }
1069             else
1070             {
1071 0           e->slope = -1.0f / e->samplesUntilNextSegment;
1072 0           e->samplesUntilNextSegment = (int)(e->parameters.decay * (1.0f - e->parameters.sustain) * outSampleRate);
1073 0           e->segmentIsExponential = TSF_FALSE;
1074             }
1075 0           return;
1076             }
1077             /* fall through */
1078             case TSF_SEGMENT_DECAY:
1079 110           e->segment = TSF_SEGMENT_SUSTAIN;
1080 110           e->level = e->parameters.sustain;
1081 110           e->slope = 0.0f;
1082 110           e->samplesUntilNextSegment = 0x7FFFFFFF;
1083 110           e->segmentIsExponential = TSF_FALSE;
1084 110           return;
1085 106           case TSF_SEGMENT_SUSTAIN:
1086 106           e->segment = TSF_SEGMENT_RELEASE;
1087 106           e->samplesUntilNextSegment = tsf_voice_envelope_release_samples(e, outSampleRate);
1088 106 100         if (e->isAmpEnv)
1089             {
1090             // I don't truly understand this; just following what LinuxSampler does.
1091 53           float mysterySlope = -9.226f / e->samplesUntilNextSegment;
1092 53           e->slope = TSF_EXPF(mysterySlope);
1093 53           e->segmentIsExponential = TSF_TRUE;
1094             }
1095             else
1096             {
1097 53           e->slope = -e->level / e->samplesUntilNextSegment;
1098 53           e->segmentIsExponential = TSF_FALSE;
1099             }
1100 106           return;
1101 53           case TSF_SEGMENT_RELEASE:
1102             default:
1103 53           e->segment = TSF_SEGMENT_DONE;
1104 53           e->segmentIsExponential = TSF_FALSE;
1105 53           e->level = e->slope = 0.0f;
1106 53           e->samplesUntilNextSegment = 0x7FFFFFF;
1107             }
1108             }
1109            
1110 110           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)
1111             {
1112 110           e->parameters = *new_parameters;
1113 110 50         if (e->parameters.keynumToHold)
1114             {
1115 0           e->parameters.hold += e->parameters.keynumToHold * (60.0f - midiNoteNumber);
1116 0 0         e->parameters.hold = (e->parameters.hold < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.hold));
1117             }
1118 110 50         if (e->parameters.keynumToDecay)
1119             {
1120 0           e->parameters.decay += e->parameters.keynumToDecay * (60.0f - midiNoteNumber);
1121 0 0         e->parameters.decay = (e->parameters.decay < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.decay));
1122             }
1123 110           e->midiVelocity = midiVelocity;
1124 110           e->isAmpEnv = isAmpEnv;
1125 110           tsf_voice_envelope_nextsegment(e, TSF_SEGMENT_NONE, outSampleRate);
1126 110           }
1127            
1128 38649           static void tsf_voice_envelope_process(struct tsf_voice_envelope* e, int numSamples, float outSampleRate)
1129             {
1130 38649 100         if (e->slope)
1131             {
1132 371 50         if (e->segmentIsExponential) e->level *= TSF_POWF(e->slope, (float)numSamples);
1133 0           else e->level += (e->slope * numSamples);
1134             }
1135 38649 100         if ((e->samplesUntilNextSegment -= numSamples) <= 0)
1136 53           tsf_voice_envelope_nextsegment(e, e->segment, outSampleRate);
1137 38649           }
1138            
1139 55           static void tsf_voice_lowpass_setup(struct tsf_voice_lowpass* e, float Fc)
1140             {
1141             // Lowpass filter from http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
1142 55           double K = TSF_TAN(TSF_PI * Fc), KK = K * K;
1143 55           double norm = 1 / (1 + K * e->QInv + KK);
1144 55           e->a0 = KK * norm;
1145 55           e->a1 = 2 * e->a0;
1146 55           e->b1 = 2 * (KK - 1) * norm;
1147 55           e->b2 = (1 - K * e->QInv + KK) * norm;
1148 55           }
1149            
1150 2471294           static float tsf_voice_lowpass_process(struct tsf_voice_lowpass* e, double In)
1151             {
1152 2471294           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;
1153             }
1154            
1155 110           static void tsf_voice_lfo_setup(struct tsf_voice_lfo* e, float delay, int freqCents, float outSampleRate)
1156             {
1157 110           e->samplesUntil = (int)(delay * outSampleRate);
1158 110           e->delta = (4.0f * tsf_cents2Hertz((float)freqCents) / outSampleRate);
1159 110           e->level = 0;
1160 110           }
1161            
1162 0           static void tsf_voice_lfo_process(struct tsf_voice_lfo* e, int blockSamples)
1163             {
1164 0 0         if (e->samplesUntil > blockSamples) { e->samplesUntil -= blockSamples; return; }
1165 0           e->level += e->delta * blockSamples;
1166 0 0         if (e->level > 1.0f) { e->delta = -e->delta; e->level = 2.0f - e->level; }
1167 0 0         else if (e->level < -1.0f) { e->delta = -e->delta; e->level = -2.0f - e->level; }
1168             }
1169            
1170 53           static void tsf_voice_kill(struct tsf_voice* v)
1171             {
1172 53           v->playingPreset = -1;
1173 53           }
1174            
1175 53           static void tsf_voice_end(tsf* f, struct tsf_voice* v)
1176             {
1177             // if maxVoiceNum is set, assume that voice rendering and note queuing are on separate threads
1178             // so to minimize the chance that voice rendering would advance the segment at the same time
1179             // we just do it twice here and hope that it sticks
1180 53 50         int repeats = (f->maxVoiceNum ? 2 : 1);
1181 106 100         while (repeats--)
1182             {
1183 53           tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, f->outSampleRate);
1184 53           tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, f->outSampleRate);
1185 53 50         if (v->region->loop_mode == TSF_LOOPMODE_SUSTAIN)
1186             {
1187             // Continue playing, but stop looping.
1188 0           v->loopEnd = v->loopStart;
1189             }
1190             }
1191 53           }
1192            
1193 0           static void tsf_voice_endquick(tsf* f, struct tsf_voice* v)
1194             {
1195             // if maxVoiceNum is set, assume that voice rendering and note queuing are on separate threads
1196             // so to minimize the chance that voice rendering would advance the segment at the same time
1197             // we just do it twice here and hope that it sticks
1198 0 0         int repeats = (f->maxVoiceNum ? 2 : 1);
1199 0 0         while (repeats--)
1200             {
1201 0           v->ampenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, f->outSampleRate);
1202 0           v->modenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, f->outSampleRate);
1203             }
1204 0           }
1205            
1206 55           static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate)
1207             {
1208 55           double note = v->playingKey + v->region->transpose + v->region->tune / 100.0;
1209 55           double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0);
1210 55 50         if (pitchShift) adjustedPitch += pitchShift;
1211 55           v->pitchInputTimecents = adjustedPitch * 100.0;
1212 55           v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate);
1213 55           }
1214            
1215 4866           static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples)
1216             {
1217 4866           struct tsf_region* region = v->region;
1218 4866           float* input = f->fontSamples;
1219 4866           float* outL = outputBuffer;
1220 4866 50         float* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL);
1221            
1222             // Cache some values, to give them at least some chance of ending up in registers.
1223 4866 50         TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc);
    50          
1224 4866 50         TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume));
    50          
    50          
    50          
1225 4866 50         TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch));
    50          
1226 4866           TSF_BOOL isLooping = (v->loopStart < v->loopEnd);
1227 4866           unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd;
1228 4866           double tmpSampleEndDbl = (double)region->end, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0;
1229 4866           double tmpSourceSamplePosition = v->sourceSamplePosition;
1230 4866           struct tsf_voice_lowpass tmpLowpass = v->lowpass;
1231            
1232 4866 50         TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc);
    50          
1233 4866           float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc;
1234            
1235 4866 50         TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch);
    50          
    50          
1236             double pitchRatio;
1237             float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch;
1238            
1239 4866           TSF_BOOL dynamicGain = (region->modLfoToVolume != 0);
1240 4866           float noteGain = 0, tmpModLfoToVolume;
1241            
1242 4866 50         if (dynamicLowpass) tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc;
1243 4866           else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0;
1244            
1245 4866 50         if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch;
1246 4866           else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0;
1247            
1248 4866 50         if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f;
1249 4866           else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0;
1250            
1251 43462 100         while (numSamples)
1252             {
1253             float gainMono, gainLeft, gainRight;
1254 38649           int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples);
1255 38649           numSamples -= blockSamples;
1256            
1257 38649 50         if (dynamicLowpass)
1258             {
1259 0           float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc;
1260 0 0         float lowpassFc = (fres <= 13500 ? tsf_cents2Hertz(fres) / tmpSampleRate : 1.0f);
1261 0           tmpLowpass.active = (lowpassFc < 0.499f);
1262 0 0         if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, lowpassFc);
1263             }
1264            
1265 38649 50         if (dynamicPitchRatio)
1266 0           pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor;
1267            
1268 38649 50         if (dynamicGain)
1269 0           noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume));
1270            
1271 38649           gainMono = noteGain * v->ampenv.level;
1272            
1273             // Update EG.
1274 38649           tsf_voice_envelope_process(&v->ampenv, blockSamples, tmpSampleRate);
1275 38649 50         if (updateModEnv) tsf_voice_envelope_process(&v->modenv, blockSamples, tmpSampleRate);
1276            
1277             // Update LFOs.
1278 38649 50         if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples);
1279 38649 50         if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples);
1280            
1281 38649           switch (f->outputmode)
1282             {
1283 0           case TSF_STEREO_INTERLEAVED:
1284 0           gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1285 0 0         while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
    0          
1286             {
1287 0 0         unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
    0          
1288            
1289             // Simple linear interpolation.
1290 0           float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1291            
1292             // Low-pass filter.
1293 0 0         if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1294            
1295 0           *outL++ += val * gainLeft;
1296 0           *outL++ += val * gainRight;
1297            
1298             // Next sample.
1299 0           tmpSourceSamplePosition += pitchRatio;
1300 0 0         if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
    0          
1301             }
1302 0           break;
1303            
1304 0           case TSF_STEREO_UNWEAVED:
1305 0           gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight;
1306 0 0         while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
    0          
1307             {
1308 0 0         unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
    0          
1309            
1310             // Simple linear interpolation.
1311 0           float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1312            
1313             // Low-pass filter.
1314 0 0         if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1315            
1316 0           *outL++ += val * gainLeft;
1317 0           *outR++ += val * gainRight;
1318            
1319             // Next sample.
1320 0           tmpSourceSamplePosition += pitchRatio;
1321 0 0         if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
    0          
1322             }
1323 0           break;
1324            
1325 38649           case TSF_MONO:
1326 2509943 100         while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl)
    50          
1327             {
1328 2471294 100         unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1);
    50          
1329            
1330             // Simple linear interpolation.
1331 2471294           float alpha = (float)(tmpSourceSamplePosition - pos), val = (input[pos] * (1.0f - alpha) + input[nextPos] * alpha);
1332            
1333             // Low-pass filter.
1334 2471294 50         if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val);
1335            
1336 2471294           *outL++ += val * gainMono;
1337            
1338             // Next sample.
1339 2471294           tmpSourceSamplePosition += pitchRatio;
1340 2471294 100         if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0);
    50          
1341             }
1342 38649           break;
1343             }
1344            
1345 38649 50         if (tmpSourceSamplePosition >= tmpSampleEndDbl || v->ampenv.segment == TSF_SEGMENT_DONE)
    100          
1346             {
1347 53           tsf_voice_kill(v);
1348 53           return;
1349             }
1350             }
1351            
1352 4813           v->sourceSamplePosition = tmpSourceSamplePosition;
1353 4813 50         if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass;
    0          
1354             }
1355            
1356 15           TSFDEF tsf* tsf_load(struct tsf_stream* stream)
1357             {
1358 15           tsf* res = TSF_NULL;
1359             struct tsf_riffchunk chunkHead;
1360             struct tsf_riffchunk chunkList;
1361             struct tsf_hydra hydra;
1362 15           void* rawBuffer = TSF_NULL;
1363 15           float* floatBuffer = TSF_NULL;
1364 15           tsf_u32 smplCount = 0;
1365            
1366 15 100         if (!tsf_riffchunk_read(TSF_NULL, &chunkHead, stream) || !TSF_FourCCEquals(chunkHead.id, "sfbk"))
    100          
    50          
    50          
    50          
1367             {
1368             //if (e) *e = TSF_INVALID_NOSF2HEADER;
1369 2           return res;
1370             }
1371            
1372             // Read hydra and locate sample data.
1373 13           TSF_MEMSET(&hydra, 0, sizeof(hydra));
1374 52 100         while (tsf_riffchunk_read(&chunkHead, &chunkList, stream))
1375             {
1376             struct tsf_riffchunk chunk;
1377 39 100         if (TSF_FourCCEquals(chunkList.id, "pdta"))
    50          
    50          
    50          
1378             {
1379 130 100         while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1380             {
1381             #define HandleChunk(chunkName) (TSF_FourCCEquals(chunk.id, #chunkName) && !(chunk.size % chunkName##SizeInFile)) \
1382             { \
1383             int num = chunk.size / chunkName##SizeInFile, i; \
1384             hydra.chunkName##Num = num; \
1385             hydra.chunkName##s = (struct tsf_hydra_##chunkName*)TSF_MALLOC(num * sizeof(struct tsf_hydra_##chunkName)); \
1386             if (!hydra.chunkName##s) goto out_of_memory; \
1387             for (i = 0; i < num; ++i) tsf_hydra_read_##chunkName(&hydra.chunkName##s[i], stream); \
1388             }
1389             enum
1390             {
1391             phdrSizeInFile = 38, pbagSizeInFile = 4, pmodSizeInFile = 10,
1392             pgenSizeInFile = 4, instSizeInFile = 22, ibagSizeInFile = 4,
1393             imodSizeInFile = 10, igenSizeInFile = 4, shdrSizeInFile = 46
1394             };
1395 208 100         if HandleChunk(phdr) else if HandleChunk(pbag) else if HandleChunk(pmod)
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
1396 169 100         else if HandleChunk(pgen) else if HandleChunk(inst) else if HandleChunk(ibag)
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
1397 117 100         else if HandleChunk(imod) else if HandleChunk(igen) else if HandleChunk(shdr)
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
1398 0           else stream->skip(stream->data, chunk.size);
1399             #undef HandleChunk
1400             }
1401             }
1402 26 100         else if (TSF_FourCCEquals(chunkList.id, "sdta"))
    50          
    50          
    50          
1403             {
1404 26 100         while (tsf_riffchunk_read(&chunkList, &chunk, stream))
1405             {
1406 13 50         if ((TSF_FourCCEquals(chunk.id, "smpl")
    50          
    50          
    50          
1407             #ifdef STB_VORBIS_INCLUDE_STB_VORBIS_H
1408             || TSF_FourCCEquals(chunk.id, "smpo")
1409             #endif
1410 13 50         ) && !rawBuffer && !floatBuffer && chunk.size >= sizeof(short))
    50          
    50          
1411             {
1412 13 50         if (!tsf_load_samples(&rawBuffer, &floatBuffer, &smplCount, &chunk, stream)) goto out_of_memory;
1413             }
1414 0           else stream->skip(stream->data, chunk.size);
1415             }
1416             }
1417 13           else stream->skip(stream->data, chunkList.size);
1418             }
1419 13 50         if (!hydra.phdrs || !hydra.pbags || !hydra.pmods || !hydra.pgens || !hydra.insts || !hydra.ibags || !hydra.imods || !hydra.igens || !hydra.shdrs)
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
1420             {
1421             //if (e) *e = TSF_INVALID_INCOMPLETE;
1422             }
1423 13 50         else if (!rawBuffer && !floatBuffer)
    50          
1424             {
1425             //if (e) *e = TSF_INVALID_NOSAMPLEDATA;
1426             }
1427             else
1428             {
1429             #ifdef STB_VORBIS_INCLUDE_STB_VORBIS_H
1430             if (!floatBuffer && !tsf_decode_sf3_samples(rawBuffer, &floatBuffer, &smplCount, &hydra)) goto out_of_memory;
1431             #endif
1432 13           res = (tsf*)TSF_MALLOC(sizeof(tsf));
1433 13 50         if (res) TSF_MEMSET(res, 0, sizeof(tsf));
1434 13 50         if (!res || !tsf_load_presets(res, &hydra, smplCount)) goto out_of_memory;
    50          
1435 13           res->outSampleRate = 44100.0f;
1436 13           res->fontSamples = floatBuffer;
1437 13           floatBuffer = TSF_NULL; // don't free below
1438             }
1439             if (0)
1440             {
1441 0           out_of_memory:
1442 0           TSF_FREE(res);
1443 0           res = TSF_NULL;
1444             //if (e) *e = TSF_OUT_OF_MEMORY;
1445             }
1446 13           TSF_FREE(hydra.phdrs); TSF_FREE(hydra.pbags); TSF_FREE(hydra.pmods);
1447 13           TSF_FREE(hydra.pgens); TSF_FREE(hydra.insts); TSF_FREE(hydra.ibags);
1448 13           TSF_FREE(hydra.imods); TSF_FREE(hydra.igens); TSF_FREE(hydra.shdrs);
1449 13           TSF_FREE(rawBuffer); TSF_FREE(floatBuffer);
1450 13           return res;
1451             }
1452            
1453 0           TSFDEF tsf* tsf_copy(tsf* f)
1454             {
1455             tsf* res;
1456 0 0         if (!f) return TSF_NULL;
1457 0 0         if (!f->refCount)
1458             {
1459 0           f->refCount = (int*)TSF_MALLOC(sizeof(int));
1460 0 0         if (!f->refCount) return TSF_NULL;
1461 0           *f->refCount = 1;
1462             }
1463 0           res = (tsf*)TSF_MALLOC(sizeof(tsf));
1464 0 0         if (!res) return TSF_NULL;
1465 0           TSF_MEMCPY(res, f, sizeof(tsf));
1466 0           res->voices = TSF_NULL;
1467 0           res->voiceNum = 0;
1468 0           res->channels = TSF_NULL;
1469 0           (*res->refCount)++;
1470 0           return res;
1471             }
1472            
1473 0           TSFDEF void tsf_close(tsf* f)
1474             {
1475 0 0         if (!f) return;
1476 0 0         if (!f->refCount || !--(*f->refCount))
    0          
1477             {
1478 0           struct tsf_preset *preset = f->presets, *presetEnd = preset + f->presetNum;
1479 0 0         for (; preset != presetEnd; preset++) TSF_FREE(preset->regions);
1480 0           TSF_FREE(f->presets);
1481 0           TSF_FREE(f->fontSamples);
1482 0           TSF_FREE(f->refCount);
1483             }
1484 0           TSF_FREE(f->channels);
1485 0           TSF_FREE(f->voices);
1486 0           TSF_FREE(f);
1487             }
1488            
1489 0           TSFDEF void tsf_reset(tsf* f)
1490             {
1491 0           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1492 0 0         for (; v != vEnd; v++)
1493 0 0         if (v->playingPreset != -1 && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release))
    0          
    0          
1494 0           tsf_voice_endquick(f, v);
1495 0 0         if (f->channels) { TSF_FREE(f->channels); f->channels = TSF_NULL; }
1496 0           }
1497            
1498 0           TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number)
1499             {
1500             const struct tsf_preset *presets;
1501             int i, iMax;
1502 0 0         for (presets = f->presets, i = 0, iMax = f->presetNum; i < iMax; i++)
1503 0 0         if (presets[i].preset == preset_number && presets[i].bank == bank)
    0          
1504 0           return i;
1505 0           return -1;
1506             }
1507            
1508 12           TSFDEF int tsf_get_presetcount(const tsf* f)
1509             {
1510 12           return f->presetNum;
1511             }
1512            
1513 39           TSFDEF const char* tsf_get_presetname(const tsf* f, int preset)
1514             {
1515 39 50         return (preset < 0 || preset >= f->presetNum ? TSF_NULL : f->presets[preset].presetName);
    100          
1516             }
1517            
1518 0           TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number)
1519             {
1520 0           return tsf_get_presetname(f, tsf_get_presetindex(f, bank, preset_number));
1521             }
1522            
1523 13           TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db)
1524             {
1525 13           f->outputmode = outputmode;
1526 13 50         f->outSampleRate = (float)(samplerate >= 1 ? samplerate : 44100.0f);
1527 13           f->globalGainDB = global_gain_db;
1528 13           }
1529            
1530 57           TSFDEF void tsf_set_volume(tsf* f, float global_volume)
1531             {
1532 57 100         f->globalGainDB = (global_volume == 1.0f ? 0 : -tsf_gainToDecibels(1.0f / global_volume));
1533 57           }
1534            
1535 0           TSFDEF int tsf_set_max_voices(tsf* f, int max_voices)
1536             {
1537 0           int i = f->voiceNum;
1538 0           int newVoiceNum = (f->voiceNum > max_voices ? f->voiceNum : max_voices);
1539 0           struct tsf_voice *newVoices = (struct tsf_voice*)TSF_REALLOC(f->voices, newVoiceNum * sizeof(struct tsf_voice));
1540 0 0         if (!newVoices) return 0;
1541 0           f->voices = newVoices;
1542 0           f->voiceNum = f->maxVoiceNum = newVoiceNum;
1543 0 0         for (; i < max_voices; i++)
1544 0           f->voices[i].playingPreset = -1;
1545 0           return 1;
1546             }
1547            
1548 57           TSFDEF int tsf_note_on(tsf* f, int preset_index, int key, float vel)
1549             {
1550 57           short midiVelocity = (short)(vel * 127);
1551             int voicePlayIndex;
1552             struct tsf_region *region, *regionEnd;
1553            
1554 57 50         if (preset_index < 0 || preset_index >= f->presetNum) return 1;
    50          
1555 57 100         if (vel <= 0.0f) { tsf_note_off(f, preset_index, key); return 1; }
1556            
1557             // Play all matching regions.
1558 55           voicePlayIndex = f->voicePlayIndex++;
1559 110 100         for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++)
1560             {
1561             struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; float lowpassFilterQDB, lowpassFc;
1562 55 50         if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue;
    50          
    50          
    50          
1563            
1564 55           voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum;
1565 55 50         if (region->group)
1566             {
1567 0 0         for (; v != vEnd; v++)
1568 0 0         if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(f, v);
    0          
1569 0 0         else if (v->playingPreset == -1 && !voice) voice = v;
    0          
1570             }
1571 59 100         else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; }
    100          
1572            
1573 55 100         if (!voice)
1574             {
1575 7 50         if (f->maxVoiceNum)
1576             {
1577             // Voices have been pre-allocated and limited to a maximum, try to kill a voice off in its release envelope
1578 0           int bestKillReleaseSamplePos = -999999999;
1579 0 0         for (v = f->voices; v != vEnd; v++)
1580             {
1581 0 0         if (v->ampenv.segment == TSF_SEGMENT_RELEASE)
1582             {
1583             // We're looking for the voice furthest into its release
1584 0           int releaseSamplesDone = tsf_voice_envelope_release_samples(&v->ampenv, f->outSampleRate) - v->ampenv.samplesUntilNextSegment;
1585 0 0         if (releaseSamplesDone > bestKillReleaseSamplePos)
1586             {
1587 0           bestKillReleaseSamplePos = releaseSamplesDone;
1588 0           voice = v;
1589             }
1590             }
1591             }
1592 0 0         if (!voice)
1593 0           continue;
1594 0           tsf_voice_kill(voice);
1595             }
1596             else
1597             {
1598             // Allocate more voices so we don't need to kill one off.
1599             struct tsf_voice* newVoices;
1600 7           f->voiceNum += 4;
1601 7           newVoices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice));
1602 7 50         if (!newVoices) return 0;
1603 7           f->voices = newVoices;
1604 7           voice = &f->voices[f->voiceNum - 4];
1605 7           voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1;
1606             }
1607             }
1608            
1609 55           voice->region = region;
1610 55           voice->playingPreset = preset_index;
1611 55           voice->playingKey = key;
1612 55           voice->playIndex = voicePlayIndex;
1613 55           voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel);
1614            
1615 55 50         if (f->channels)
1616             {
1617 0           f->channels->setupVoice(f, voice);
1618             }
1619             else
1620             {
1621 55           tsf_voice_calcpitchratio(voice, 0, f->outSampleRate);
1622             // 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).
1623 55           voice->panFactorLeft = TSF_SQRTF(0.5f - region->pan);
1624 55           voice->panFactorRight = TSF_SQRTF(0.5f + region->pan);
1625             }
1626            
1627             // Offset/end.
1628 55           voice->sourceSamplePosition = region->offset;
1629            
1630             // Loop.
1631 55 50         doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end);
    50          
1632 55 50         voice->loopStart = (doLoop ? region->loop_start : 0);
1633 55 50         voice->loopEnd = (doLoop ? region->loop_end : 0);
1634            
1635             // Setup envelopes.
1636 55           tsf_voice_envelope_setup(&voice->ampenv, ®ion->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate);
1637 55           tsf_voice_envelope_setup(&voice->modenv, ®ion->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate);
1638            
1639             // Setup lowpass filter.
1640 55 50         lowpassFc = (region->initialFilterFc <= 13500 ? tsf_cents2Hertz((float)region->initialFilterFc) / f->outSampleRate : 1.0f);
1641 55           lowpassFilterQDB = region->initialFilterQ / 10.0f;
1642 55           voice->lowpass.QInv = 1.0 / TSF_POW(10.0, (lowpassFilterQDB / 20.0));
1643 55           voice->lowpass.z1 = voice->lowpass.z2 = 0;
1644 55           voice->lowpass.active = (lowpassFc < 0.499f);
1645 55 50         if (voice->lowpass.active) tsf_voice_lowpass_setup(&voice->lowpass, lowpassFc);
1646            
1647             // Setup LFO filters.
1648 55           tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate);
1649 55           tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate);
1650             }
1651 55           return 1;
1652             }
1653            
1654 0           TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel)
1655             {
1656 0           int preset_index = tsf_get_presetindex(f, bank, preset_number);
1657 0 0         if (preset_index == -1) return 0;
1658 0           return tsf_note_on(f, preset_index, key, vel);
1659             }
1660            
1661 57           TSFDEF void tsf_note_off(tsf* f, int preset_index, int key)
1662             {
1663 57           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL;
1664 285 100         for (; v != vEnd; v++)
1665             {
1666             //Find the first and last entry in the voices list with matching preset, key and look up the smallest play index
1667 228 100         if (v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) continue;
    100          
    50          
1668 53 50         else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) vMatchFirst = vMatchLast = v;
    0          
1669 0 0         else if (v->playIndex == vMatchFirst->playIndex) vMatchLast = v;
1670             }
1671 57 100         if (!vMatchFirst) return;
1672 106 100         for (v = vMatchFirst; v <= vMatchLast; v++)
1673             {
1674             //Stop all voices with matching preset, key and the smallest play index which was enumerated above
1675 53 50         if (v != vMatchFirst && v != vMatchLast &&
    0          
1676 0 0         (v->playIndex != vMatchFirst->playIndex || v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) continue;
    0          
    0          
    0          
1677 53           tsf_voice_end(f, v);
1678             }
1679             }
1680            
1681 0           TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key)
1682             {
1683 0           int preset_index = tsf_get_presetindex(f, bank, preset_number);
1684 0 0         if (preset_index == -1) return 0;
1685 0           tsf_note_off(f, preset_index, key);
1686 0           return 1;
1687             }
1688            
1689 0           TSFDEF void tsf_note_off_all(tsf* f)
1690             {
1691 0           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1692 0 0         for (; v != vEnd; v++) if (v->playingPreset != -1 && v->ampenv.segment < TSF_SEGMENT_RELEASE)
    0          
    0          
1693 0           tsf_voice_end(f, v);
1694 0           }
1695            
1696 121           TSFDEF int tsf_active_voice_count(tsf* f)
1697             {
1698 121           int count = 0;
1699 121           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1700 585 100         for (; v != vEnd; v++) if (v->playingPreset != -1) count++;
    100          
1701 121           return count;
1702             }
1703            
1704 90           TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing)
1705             {
1706             float outputSamples[TSF_RENDER_SHORTBUFFERBLOCK];
1707 90 50         int channels = (f->outputmode == TSF_MONO ? 1 : 2), maxChannelSamples = TSF_RENDER_SHORTBUFFERBLOCK / channels;
1708 7642 100         while (samples > 0)
1709             {
1710 7552           int channelSamples = (samples > maxChannelSamples ? maxChannelSamples : samples);
1711 7552           short* bufferEnd = buffer + channelSamples * channels;
1712 7552           float *floatSamples = outputSamples;
1713 7552           tsf_render_float(f, floatSamples, channelSamples, TSF_FALSE);
1714 7552           samples -= channelSamples;
1715            
1716 7552 50         if (flag_mixing)
1717 0 0         while (buffer != bufferEnd)
1718             {
1719 0           float v = *floatSamples++;
1720 0 0         int vi = *buffer + (v < -1.00004566f ? (int)-32768 : (v > 1.00001514f ? (int)32767 : (int)(v * 32767.5f)));
    0          
1721 0 0         *buffer++ = (vi < -32768 ? (short)-32768 : (vi > 32767 ? (short)32767 : (short)vi));
    0          
1722             }
1723             else
1724 3851216 100         while (buffer != bufferEnd)
1725             {
1726 3843664           float v = *floatSamples++;
1727 3843664 50         *buffer++ = (v < -1.00004566f ? (short)-32768 : (v > 1.00001514f ? (short)32767 : (short)(v * 32767.5f)));
    50          
1728             }
1729             }
1730 90           }
1731            
1732 7552           TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing)
1733             {
1734 7552           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1735 7552 50         if (!flag_mixing) TSF_MEMSET(buffer, 0, (f->outputmode == TSF_MONO ? 1 : 2) * sizeof(float) * samples);
    50          
1736 37760 100         for (; v != vEnd; v++)
1737 30208 100         if (v->playingPreset != -1)
1738 4866           tsf_voice_render(f, v, buffer, samples);
1739 7552           }
1740            
1741 0           static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v)
1742             {
1743 0           struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel];
1744 0           float newpan = v->region->pan + c->panOffset;
1745 0           v->playingChannel = f->channels->activeChannel;
1746 0           v->noteGainDB += c->gainDB;
1747 0 0         tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate);
1748 0 0         if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; }
1749 0 0         else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; }
1750 0           else { v->panFactorLeft = TSF_SQRTF(0.5f - newpan); v->panFactorRight = TSF_SQRTF(0.5f + newpan); }
1751 0           }
1752            
1753 0           static struct tsf_channel* tsf_channel_init(tsf* f, int channel)
1754             {
1755             int i;
1756 0 0         if (f->channels && channel < f->channels->channelNum) return &f->channels->channels[channel];
    0          
1757 0 0         if (!f->channels)
1758             {
1759 0           f->channels = (struct tsf_channels*)TSF_MALLOC(sizeof(struct tsf_channels) + sizeof(struct tsf_channel) * channel);
1760 0 0         if (!f->channels) return TSF_NULL;
1761 0           f->channels->setupVoice = &tsf_channel_setup_voice;
1762 0           f->channels->channelNum = 0;
1763 0           f->channels->activeChannel = 0;
1764             }
1765             else
1766             {
1767 0           struct tsf_channels *newChannels = (struct tsf_channels*)TSF_REALLOC(f->channels, sizeof(struct tsf_channels) + sizeof(struct tsf_channel) * channel);
1768 0 0         if (!newChannels) return TSF_NULL;
1769 0           f->channels = newChannels;
1770             }
1771 0           i = f->channels->channelNum;
1772 0           f->channels->channelNum = channel + 1;
1773 0 0         for (; i <= channel; i++)
1774             {
1775 0           struct tsf_channel* c = &f->channels->channels[i];
1776 0           c->presetIndex = c->bank = 0;
1777 0           c->pitchWheel = c->midiPan = 8192;
1778 0           c->midiVolume = c->midiExpression = 16383;
1779 0           c->midiRPN = 0xFFFF;
1780 0           c->midiData = 0;
1781 0           c->panOffset = 0.0f;
1782 0           c->gainDB = 0.0f;
1783 0           c->pitchRange = 2.0f;
1784 0           c->tuning = 0.0f;
1785             }
1786 0           return &f->channels->channels[channel];
1787             }
1788            
1789 0           static void tsf_channel_applypitch(tsf* f, int channel, struct tsf_channel* c)
1790             {
1791             struct tsf_voice *v, *vEnd;
1792 0 0         float pitchShift = (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning));
1793 0 0         for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
1794 0 0         if (v->playingPreset != -1 && v->playingChannel == channel)
    0          
1795 0           tsf_voice_calcpitchratio(v, pitchShift, f->outSampleRate);
1796 0           }
1797            
1798 0           TSFDEF int tsf_channel_set_presetindex(tsf* f, int channel, int preset_index)
1799             {
1800 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1801 0 0         if (!c) return 0;
1802 0           c->presetIndex = (unsigned short)preset_index;
1803 0           return 1;
1804             }
1805            
1806 0           TSFDEF int tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums)
1807             {
1808             int preset_index;
1809 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1810 0 0         if (!c) return 0;
1811 0 0         if (flag_mididrums)
1812             {
1813 0           preset_index = tsf_get_presetindex(f, 128 | (c->bank & 0x7FFF), preset_number);
1814 0 0         if (preset_index == -1) preset_index = tsf_get_presetindex(f, 128, preset_number);
1815 0 0         if (preset_index == -1) preset_index = tsf_get_presetindex(f, 128, 0);
1816 0 0         if (preset_index == -1) preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number);
1817             }
1818 0           else preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number);
1819 0 0         if (preset_index == -1) preset_index = tsf_get_presetindex(f, 0, preset_number);
1820 0 0         if (preset_index != -1)
1821             {
1822 0           c->presetIndex = (unsigned short)preset_index;
1823 0           return 1;
1824             }
1825 0           return 0;
1826             }
1827            
1828 0           TSFDEF int tsf_channel_set_bank(tsf* f, int channel, int bank)
1829             {
1830 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1831 0 0         if (!c) return 0;
1832 0           c->bank = (unsigned short)bank;
1833 0           return 1;
1834             }
1835            
1836 0           TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number)
1837             {
1838             int preset_index;
1839 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1840 0 0         if (!c) return 0;
1841 0           preset_index = tsf_get_presetindex(f, bank, preset_number);
1842 0 0         if (preset_index == -1) return 0;
1843 0           c->presetIndex = (unsigned short)preset_index;
1844 0           c->bank = (unsigned short)bank;
1845 0           return 1;
1846             }
1847            
1848 0           TSFDEF int tsf_channel_set_pan(tsf* f, int channel, float pan)
1849             {
1850             struct tsf_voice *v, *vEnd;
1851 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1852 0 0         if (!c) return 0;
1853 0 0         for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
1854 0 0         if (v->playingChannel == channel && v->playingPreset != -1)
    0          
1855             {
1856 0           float newpan = v->region->pan + pan - 0.5f;
1857 0 0         if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; }
1858 0 0         else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; }
1859 0           else { v->panFactorLeft = TSF_SQRTF(0.5f - newpan); v->panFactorRight = TSF_SQRTF(0.5f + newpan); }
1860             }
1861 0           c->panOffset = pan - 0.5f;
1862 0           return 1;
1863             }
1864            
1865 0           TSFDEF int tsf_channel_set_volume(tsf* f, int channel, float volume)
1866             {
1867 0           float gainDB = tsf_gainToDecibels(volume), gainDBChange;
1868             struct tsf_voice *v, *vEnd;
1869 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1870 0 0         if (!c) return 0;
1871 0 0         if (gainDB == c->gainDB) return 1;
1872 0 0         for (v = f->voices, vEnd = v + f->voiceNum, gainDBChange = gainDB - c->gainDB; v != vEnd; v++)
1873 0 0         if (v->playingPreset != -1 && v->playingChannel == channel)
    0          
1874 0           v->noteGainDB += gainDBChange;
1875 0           c->gainDB = gainDB;
1876 0           return 1;
1877             }
1878            
1879 0           TSFDEF int tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel)
1880             {
1881 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1882 0 0         if (!c) return 0;
1883 0 0         if (c->pitchWheel == pitch_wheel) return 1;
1884 0           c->pitchWheel = (unsigned short)pitch_wheel;
1885 0           tsf_channel_applypitch(f, channel, c);
1886 0           return 1;
1887             }
1888            
1889 0           TSFDEF int tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range)
1890             {
1891 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1892 0 0         if (!c) return 0;
1893 0 0         if (c->pitchRange == pitch_range) return 1;
1894 0           c->pitchRange = pitch_range;
1895 0 0         if (c->pitchWheel != 8192) tsf_channel_applypitch(f, channel, c);
1896 0           return 1;
1897             }
1898            
1899 0           TSFDEF int tsf_channel_set_tuning(tsf* f, int channel, float tuning)
1900             {
1901 0           struct tsf_channel *c = tsf_channel_init(f, channel);
1902 0 0         if (!c) return 0;
1903 0 0         if (c->tuning == tuning) return 1;
1904 0           c->tuning = tuning;
1905 0           tsf_channel_applypitch(f, channel, c);
1906 0           return 1;
1907             }
1908            
1909 0           TSFDEF int tsf_channel_note_on(tsf* f, int channel, int key, float vel)
1910             {
1911 0 0         if (!f->channels || channel >= f->channels->channelNum) return 1;
    0          
1912 0           f->channels->activeChannel = channel;
1913 0           return tsf_note_on(f, f->channels->channels[channel].presetIndex, key, vel);
1914             }
1915            
1916 0           TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key)
1917             {
1918 0           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL;
1919 0 0         for (; v != vEnd; v++)
1920             {
1921             //Find the first and last entry in the voices list with matching channel, key and look up the smallest play index
1922 0 0         if (v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) continue;
    0          
    0          
    0          
1923 0 0         else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) vMatchFirst = vMatchLast = v;
    0          
1924 0 0         else if (v->playIndex == vMatchFirst->playIndex) vMatchLast = v;
1925             }
1926 0 0         if (!vMatchFirst) return;
1927 0 0         for (v = vMatchFirst; v <= vMatchLast; v++)
1928             {
1929             //Stop all voices with matching channel, key and the smallest play index which was enumerated above
1930 0 0         if (v != vMatchFirst && v != vMatchLast &&
    0          
1931 0 0         (v->playIndex != vMatchFirst->playIndex || v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) continue;
    0          
    0          
    0          
    0          
1932 0           tsf_voice_end(f, v);
1933             }
1934             }
1935            
1936 0           TSFDEF void tsf_channel_note_off_all(tsf* f, int channel)
1937             {
1938 0           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1939 0 0         for (; v != vEnd; v++)
1940 0 0         if (v->playingPreset != -1 && v->playingChannel == channel && v->ampenv.segment < TSF_SEGMENT_RELEASE)
    0          
    0          
1941 0           tsf_voice_end(f, v);
1942 0           }
1943            
1944 0           TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel)
1945             {
1946 0           struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum;
1947 0 0         for (; v != vEnd; v++)
1948 0 0         if (v->playingPreset != -1 && v->playingChannel == channel && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release))
    0          
    0          
    0          
1949 0           tsf_voice_endquick(f, v);
1950 0           }
1951            
1952 0           TSFDEF int tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value)
1953             {
1954 0           struct tsf_channel* c = tsf_channel_init(f, channel);
1955 0 0         if (!c) return 0;
1956 0           switch (controller)
1957             {
1958 0           case 7 /*VOLUME_MSB*/ : c->midiVolume = (unsigned short)((c->midiVolume & 0x7F ) | (control_value << 7)); goto TCMC_SET_VOLUME;
1959 0           case 39 /*VOLUME_LSB*/ : c->midiVolume = (unsigned short)((c->midiVolume & 0x3F80) | control_value); goto TCMC_SET_VOLUME;
1960 0           case 11 /*EXPRESSION_MSB*/ : c->midiExpression = (unsigned short)((c->midiExpression & 0x7F ) | (control_value << 7)); goto TCMC_SET_VOLUME;
1961 0           case 43 /*EXPRESSION_LSB*/ : c->midiExpression = (unsigned short)((c->midiExpression & 0x3F80) | control_value); goto TCMC_SET_VOLUME;
1962 0           case 10 /*PAN_MSB*/ : c->midiPan = (unsigned short)((c->midiPan & 0x7F ) | (control_value << 7)); goto TCMC_SET_PAN;
1963 0           case 42 /*PAN_LSB*/ : c->midiPan = (unsigned short)((c->midiPan & 0x3F80) | control_value); goto TCMC_SET_PAN;
1964 0           case 6 /*DATA_ENTRY_MSB*/ : c->midiData = (unsigned short)((c->midiData & 0x7F) | (control_value << 7)); goto TCMC_SET_DATA;
1965 0           case 38 /*DATA_ENTRY_LSB*/ : c->midiData = (unsigned short)((c->midiData & 0x3F80) | control_value); goto TCMC_SET_DATA;
1966 0           case 0 /*BANK_SELECT_MSB*/ : c->bank = (unsigned short)(0x8000 | control_value); return 1; //bank select MSB alone acts like LSB
1967 0 0         case 32 /*BANK_SELECT_LSB*/ : c->bank = (unsigned short)((c->bank & 0x8000 ? ((c->bank & 0x7F) << 7) : 0) | control_value); return 1;
1968 0 0         case 101 /*RPN_MSB*/ : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x7F ) | (control_value << 7)); return 1;
1969 0 0         case 100 /*RPN_LSB*/ : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x3F80) | control_value); return 1;
1970 0           case 98 /*NRPN_LSB*/ : c->midiRPN = 0xFFFF; return 1;
1971 0           case 99 /*NRPN_MSB*/ : c->midiRPN = 0xFFFF; return 1;
1972 0           case 120 /*ALL_SOUND_OFF*/ : tsf_channel_sounds_off_all(f, channel); return 1;
1973 0           case 123 /*ALL_NOTES_OFF*/ : tsf_channel_note_off_all(f, channel); return 1;
1974 0           case 121 /*ALL_CTRL_OFF*/ :
1975 0           c->midiVolume = c->midiExpression = 16383;
1976 0           c->midiPan = 8192;
1977 0           c->bank = 0;
1978 0           c->midiRPN = 0xFFFF;
1979 0           c->midiData = 0;
1980 0           tsf_channel_set_volume(f, channel, 1.0f);
1981 0           tsf_channel_set_pan(f, channel, 0.5f);
1982 0           tsf_channel_set_pitchrange(f, channel, 2.0f);
1983 0           tsf_channel_set_tuning(f, channel, 0);
1984 0           return 1;
1985             }
1986 0           return 1;
1987 0           TCMC_SET_VOLUME:
1988             //Raising to the power of 3 seems to result in a decent sounding volume curve for MIDI
1989 0           tsf_channel_set_volume(f, channel, TSF_POWF((c->midiVolume / 16383.0f) * (c->midiExpression / 16383.0f), 3.0f));
1990 0           return 1;
1991 0           TCMC_SET_PAN:
1992 0           tsf_channel_set_pan(f, channel, c->midiPan / 16383.0f);
1993 0           return 1;
1994 0           TCMC_SET_DATA:
1995 0 0         if (c->midiRPN == 0) tsf_channel_set_pitchrange(f, channel, (c->midiData >> 7) + 0.01f * (c->midiData & 0x7F));
1996 0 0         else if (c->midiRPN == 1) tsf_channel_set_tuning(f, channel, (int)c->tuning + ((float)c->midiData - 8192.0f) / 8192.0f); //fine tune
1997 0 0         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
    0          
1998 0           return 1;
1999             }
2000            
2001 0           TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel)
2002             {
2003 0 0         return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].presetIndex : 0);
    0          
2004             }
2005            
2006 0           TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel)
2007             {
2008 0 0         return (f->channels && channel < f->channels->channelNum ? (f->channels->channels[channel].bank & 0x7FFF) : 0);
    0          
2009             }
2010            
2011 0           TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel)
2012             {
2013 0 0         return (f->channels && channel < f->channels->channelNum ? f->presets[f->channels->channels[channel].presetIndex].preset : 0);
    0          
2014             }
2015            
2016 0           TSFDEF float tsf_channel_get_pan(tsf* f, int channel)
2017             {
2018 0 0         return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].panOffset - 0.5f : 0.5f);
    0          
2019             }
2020            
2021 0           TSFDEF float tsf_channel_get_volume(tsf* f, int channel)
2022             {
2023 0 0         return (f->channels && channel < f->channels->channelNum ? tsf_decibelsToGain(f->channels->channels[channel].gainDB) : 1.0f);
    0          
2024             }
2025            
2026 0           TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel)
2027             {
2028 0 0         return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchWheel : 8192);
    0          
2029             }
2030            
2031 0           TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel)
2032             {
2033 0 0         return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchRange : 2.0f);
    0          
2034             }
2035            
2036 0           TSFDEF float tsf_channel_get_tuning(tsf* f, int channel)
2037             {
2038 0 0         return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].tuning : 0.0f);
    0          
2039             }
2040            
2041             #ifdef __cplusplus
2042             }
2043             #endif
2044            
2045             #endif //TSF_IMPLEMENTATION