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