File Coverage

TinySoundFont/tsf.h
Criterion Covered Total %
statement 422 751 56.1
branch 360 834 43.1
condition n/a
subroutine n/a
pod n/a
total 782 1585 49.3


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