Giter VIP home page Giter VIP logo

tinysoundfont's Introduction

TinySoundFont

SoundFont2 synthesizer library in a single C/C++ file

Overview

TinySoundFont is a software synthesizer using SoundFont2 sound bank files.

The library is a single C header file so it is extremely simple to integrate in your C/C++ projects.

#define TSF_IMPLEMENTATION
#include "tsf.h"

...

tsf* TinySoundFont = tsf_load_filename("soundfont.sf2");
tsf_set_output(TinySoundFont, TSF_MONO, 44100, 0); //sample rate
tsf_note_on(TinySoundFont, 0, 60, 1.0f); //preset 0, middle C
short HalfSecond[22050]; //synthesize 0.5 seconds
tsf_render_short(TinySoundFont, HalfSecond, 22050, 0);

The library code is based on SFZero by Steve Folta.

Documentation

The API documentation can be found on top of the library source code.

There are also examples available which come with a sample SoundFont file and build and play sound on Win32, Win64, Linux and MacOSX with no further dependencies.

Dependencies

C standard libraries for fopen, math and malloc (can be removed by providing custom functions with #defines).

License

TinySoundFont is available under the MIT license.

tinysoundfont's People

Contributors

drubinstein avatar ell1e avatar jacqueslorentz avatar kavika13 avatar misterhat avatar nicholascioli avatar reputeless avatar schellingb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinysoundfont's Issues

Incompatibility with ISO C++

tml.h:91:24: warning: ISO C++ prohibits anonymous structs [-Wpedantic]
   91 |                 struct { union { char key, control, program, channel_pressure; }; union { char velocity, key_pressure, control_value; }; };
      |                        ^

Goddamn annoying that they haven't updated to C99 compatibility in even C++20, apparently.

Trouble playing general midi file percussion

Two problems I've run into so far:

  1. The example3 app mapped all channels to 0, whereas GM seems (from my limited understanding) to map channel 10 (index 9 in this library's case) to a special percussion sound set. My understanding is coming from this page: https://www.midi.org/specifications/item/gm-level-1-sound-set
  2. When I manually mapped channel 10 to the right bank/program for my sound font, it seems it wasn't playing just the percussion sound that it should have been. As far as I can tell, it was hitting multiple notes at once - both what sounded like the right crash cymbal (49) and some sort of cowbell sound. This might partly be an artifact of the sound font I was using for testing, which is called GeneralUser GS MuseScore v1.442.sf2

I can provide a sample midi file if that helps. I looked at the binary of the midi in a hex editor with midi template support, and ran the sample code through the debugger. There's no program specification on that channel at all, and no bank switching. It seems the midi file is relying on mapping to the GM standard.

I can just manually map to solve problem 1, but problem 2 I don't fully get how to work around. I tried playing just "note 49" by hard coding it in the sample program, and it still played the extra note.

Not muting playing notes

Hi again! Playing a single note (note_on, note_off) quickly results in sharp reverb cut off. I found a temporary hack which fixed this (maybe not ideal but works)

tsf.h commit 7f29067 line 1160 onwards:

	for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++)
	{
		if (v->playingPreset != preset_index) continue;
		#ifndef SET_LOSSLESS
		if (v->playingKey == key) tsf_voice_endquick(v, f->outSampleRate);
		if (v->region->group) haveGroupedNotesPlaying = TSF_TRUE;
		#endif
	}

You can hear the difference here: https://soundcloud.com/martin-minovski/tsf-test
Ignore the buffer underruns. If I pre-render the samples instead, it sounds perfect with the hack enabled.

Could be nice to have that as a setting variable which can change during runtime. 👍

Cheers

Martin

get bank and presetnumber from presetindex

hi,
it works wonderfull in tcltk. Now, I Need a function to get the bank and preset number from presetindex of a sound. is it possible to make reversing function of tsf_get_presetindex?

// Returns the preset index from a bank and preset number, or -1 if it does not exist in the loaded SoundFont
TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number);

thx and greetings - kmatze

Effects per preset

Hello again. So I want to apply e. g. a compressor to a single instrument (preset) in a sound font. I can't do it at the tsf_render_float level because that would have a mix of many instruments at that point.

It would be nice if tsf would have a callback that allows the source sound to be modified before mixing it to the float buffer.

Until then, which function can be hooked?

Best,

Feature request: Fix whatever is breaking this sf/midi combo?

I'm sorry, this request is fairly vague :| It is sort of testing the limit of my sf/midi knowledge and debugging skills!

Playback is much better with most soundfonts w/ your previous 5 or 6 commits (🎈), but now I'm trying to find a small soundfont I can legally distribute w/ an open source game I'm porting.

I'm having a problem with this combo:

Other soundfonts are working fine w/ this track in the example3 player, and this sound font is working fine with this track in a different bassmidi-based player.

The problem is on track 12, when using Lead 6 Voice (85). The track has long held notes, modulation, and aftertouch. The result of playback in example3 is like someone trying to do rapid notes on an instrument with a very long attack, so it barely plays or doesn't sound at all.

I'd just use a different working soundfont, since other ones are working just fine with your lib, but they're either too big, or of dubious legality. I am working on a FOSS game port, so I'd rather not try anything on-the-sly!

Set panning for each note_on

Hi there! Would it be possible to assign panning factor for each individual note (voice)? I noticed you're setting some panning values for each voice in the note_on function, but I don't want to break anything there ;)

Great piece of lib, keep it up!

Cheers

Martin

white noise unexpected sound when playing the files

Hello!

Thanks for this interesting library. It's really compact and for sure can be used in many projects.
I had some strange problem when trying to run the examples on my old tv box, an allwinner a10 armhf system.
The example1 works fine there.
examples 2 and 3 do play the notes, but also some quite loud white noise plays in the background.
I have also tried to use the tinysoundfont implementation from esp8266audio and got a similar problem there. A background whooshing sound goes together with every note played.
On a regular x86_64 system it works perfectly.
Any hints to solve this? thanks again...

Pitch bend

Would it be feasible to add pitch bend control for each note (defined by preset and pitch)?

Thanks

Martin

Is it possible to use this library with SDL_mixer?

My project uses SDL_mixer and I saw your examples and it seems to use SDL audio directly.
The thing is that SDL_mixer can't be used at the same time so when I try it my app crashes.
Do you know if it's possible to use TinySoundFont with the SDL_mixer?

I tried to look for examples but I couldn't find it how.

Thank you!

(I think your library is amazing by the way, thanks for sharing this)

quickpick

engine for palm mute check

use combination of resonator, bcf, and energy analysis to dial it in

maybe run faster than 1024 buffer

Using with Android via Oboe - threading question

Hi there,

I'm trying to use TinySoundFont to render sound to Android using https://github.com/google/oboe/.

I'm having trouble marrying these two bits of documentation:

Any ideas of what I can do? For what it's worth, running without mutexes seems to work fine, and adding mutexes adds only very slight audio glitches here and there, so maybe I can just not include mutexes, but that feels dangerous.

Ability to grab track metadata (tempo change messages?)

I'm converting an old DirectMusic application to use TML. I need to seek/loop to a specific part of the song, but the application I am using has the time stamps encoded in MUSIC_TIME (which is relative to tempo). In order to determine the actual milliseconds offset within the song, I need to seek from the beginning and see all tempo changes.

If the midi header has tempo data, it would also be useful to have that available, in case no change tempo messages are in the stream.

Other audio library examples

Any interest in seeing examples of use with other audio libraries/frameworks?

A few random suggestions:

  • OpenAL
  • MiniAL
  • Using system DirectSound/CoreAudio/ALSA directly
  • ?

I found several bigger/high level libraries as well. They would be pretty hard to set up a build for, compared to your stripped down SDL example. However for projects already using another audio lib that don't have good sound font synthesis/midi loading and playback this library might still be a useful option.

Missing sample in every buffer window

I tried with different soundfont libraries, as well as on different platforms (BeagleBone+Bela, Windows 10 + standard soundcard [examples/example2.c]), but there is a persistent clicking noise - its frequency is correlated with the buffer length. Recorded the output, here's how it looks like:

https://pasteboard.co/GM3rN13.png

Looks almost as if there is one missing sample for each buffer window i.e. tsf_render_float and tsf_render_short producing less samples than defined in the the function argument? Any ideas whether it's something obvious?

Thanks!

Stuck instrument with Windows XP onestop.mid

When playing onestop.mid from Windows XP a note gets stuck after the first "verse" of the song, and continues through the rest of the song.

I'm trying to figure out what's going on but it's a hard one to debug.

"conversion may change the value [-Werror=conversion]" compilation errors on MCST lcc compiler

When compiling TinySoundFont library as part of OpenGothic project (https://github.com/Try/OpenGothic), I get the following compilation errors on the MCST lcc compiler:

lcc: "/root/dev/r-a-sattarov/OpenGothic/lib/TinySoundFont/tsf.h", line 829: error #2463:
conversion may change the value [-Werror=conversion]
samplesLeft = *fontSampleCount = chunkSmpl->size / sizeof(short);

lcc: "/root/dev/r-a-sattarov/OpenGothic/lib/TinySoundFont/tsf.h", line 835: error #2463:
conversion may change the value [-Werror=conversion]
stream->read(stream->data, sampleBuffer, samplesToRead * sizeof(short));

lcc: "/root/dev/r-a-sattarov/OpenGothic/lib/TinySoundFont/tsf.h", line 1483: error #2463:
conversion may change the value [-Werror=conversion]
int channelSamples = (f->outputmode == TSF_MONO ? 1 : 2) * samples, floatBufferSize = channelSamples * sizeof(float);

log: TinySoundFont-OpenGothic_lcc_compile_err.log

original issue Try/OpenGothic#91

TinySoundFont fails to render a specific combination of .sf2 and .mid

Here are the files we're having trouble with: tsfbug.zip

We were able to get that particular .sf2 working by clamping the sustain in tsf_region_envtosecs() and clamping region->attenuation where voice->noteGainDB is calculated in tsf_note_on(), but we were hoping to ditch the hacky workaround for a real fix since you were so responsive to the previous issue I reported.

Thanks in advance for taking a look at it and for a great single-file library.

Porting to .net

Hi there.

tl;dr: Would you be fine for you, if I port your library to C# and merge it into my music notation library I am developing? I will try to retain the original copyright notice as good as possible but the borders between my library and yours will likely become quite fuzzy over time.

Long Version:

First of all thanks for this great library. Most of the synthesizer libraries out there are really heavyweight and consist of thousands of lines of code but your library is really slim and produces great results. The best and most complete ones out there, are still FluidSynth and Gervill (part of the JDK) but with simple soundfonts you can hardly here a difference (beside the missing effects #24 ). FluidSynth is quite heavyweight and hard to port to other languages due to its C-nature, huge codebase and tons of capabilities. Gervill with it's GPL license and Oracle in the back, I can already forget to use it outside of the Java world.

I am the author of alphaTab, a web (and .net) based music notation software with playback capabilities. I already have a soundfont based synthesis library where I generate raw audio samples based on a given midi input to play it via the audio interface available on the platform. TinySoundFont has a way smaller footprint and produces more accurate results than my current one and I'm considering to replace my synth library partly with yours.

In general the MIT license would not prevent me to port your library to another language, but I prefer to talk to the original authors of libraries before doing so to get official permission. Especially as it will not remain a simple 1:1 port of the original library.

My plan is to port the library to C# and then further cross compile it to JavaScript and Kotlin using a home-made compiler/transpiler. Actually I already finished the porting and it runs already on .net 😉. Unfortunately I will not be able to use the library as-it-is and I will need to make further extensions for my API and the need of SoundFont 3 (Ogg Vorbis) support. So I will need to rip apart the structure a bit and introduce new functionality here and there. Also my library currently is released under LGPL which would be then more restrictive.

Of course I will add to all synthesizer related classes your name, and refer to your project as well to maintain the original copyright notice but somehow TinySoundFont will likely be hidden within my library.

I'm also looking forward to implement certain missing parts of the synthesizer on top of my port. I compared several midi file/soundfont combinations between TinySoundFont and Gervill and often they sound quite different. I hope to eliminate those differences.

I'm looking forward to get your permission to adopt your library and integrate it with mine.

Kind Regards
Daniel

Reverb and Chorus

How hard would it be to get reverb and chorus going? :)

These effects can be implemented in a tiny amount of code. I was poking around FluidSynth and they are using a 4 allpass + 8 comb filter network for reverb. I believe it is based on Freeverb.

My thoughts are that there's no reference implementation for these FX, so might as well make them sound as good as possible. There might be better options than Freeverb. Thoughts?

Line 59 of tsf.h

Hi, Our team was trying to build a C++ project using tsf.h and GNU's g++ and kept getting linking errors that the functions in tsf.h were multiply defined. We traced the problem to line 59 of tsf.h:

#define TSFDEF extern

as the functions being flagged were all fully defined internally within tsf.h, not declared in tsf.h and then defined externally. We were able to fix the problem by revising line 59 as follows:

#define TSFDEF inline

Cheers,

-Joel.

[Question] Can it be used as replacement for Fluidsynth?

Hi.
First of all, really sorry to bother you with this poor question.

I just want to ask, are these libraries especially tml.h can be used to play Standard MIDI Files (.mid) replacing other libraries, such as Timidity++ or Fluidsynth?

If yes, how complete the support for MIDI specifications? Are there limitations?

Thank you so much for reading this.

Hard to tell when the final note is actually over

This is regarding TML and not the TSF side of things.

I'm not sure if I'm doing things incorrectly, but tml_get_info seems to return the begin timestamp of the last note in out_time_length, and not include the lingering time. If I stop playback at exactly this time, then the final note gets cut off in the particular song I'm playing. I'm also not sure if it's cutting off on-tempo or not.

Is there some mechanism I've missed, or work-around that I can do? There are a couple I thought of ("just wait a bit longer" and "double-output so I can sample the volume"), but they don't seem ideal. I am planning on specifying a mid-song loop point, running to the end, and looping back to that point, so I think I need to get that last note to be the correct length for the tempo.

I might be able to get enough info if I had a way of determining "final" tempo, and got info from the midi header, but as far as I can tell, those are buried inside the implementation right now. Easy enough to hack around (esp if that's what you suggest), but I think it might also be nice to have functions to handle it for me :) Maybe return both a header struct as well as the message list from tml_load_filename? If this sounds like a good direction, then I think I could make a PR for that.

Edit: Or maybe I'm thinking about this wrong... I am guessing most midi tracks are going to have their last message be a "note off". At least, the "track length" solution seems to assume something along those lines. So maybe looping isn't a problem? Properly sustaining the last note before unhooking the midi sample generator callback is all I'm looking for, then. Maybe this is best served with a hard-coded pause, or maybe getting the header info/tempo would still be useful. Would like some thoughts on that at least :)

Memory duplicate

It's really great, I use it for my sequencer. However I have an issue, for simultaneous processing.
Say I have two tracks that use the same channel and loaded SF file, then simultaneous processing cannot be with TSF.

  1. Is there a way to have simultaneous processing within the same TSF object?
  2. If not, is there a way to "mirror" the samples from another TSF object? Currently I use tsf_load_memory to load a SF, but although the memory is the same, TSF duplicates it in their own structures. Is there a way to avoid duplication of the same samples?

Best regards,

Setting maximum voices.

So, now I have a working TSF on my Bela. As the device has 'limited' performance .. I'd like to set a limit on the number of playable voices and see where that leads - this may give me some headroom to implement multiple outs and reverb / chorus. Is there a way currently to set a voice limit (I've had a look through the examples and couldn't see anything obvious, nor in SFZero or every the SF architecture - before I go digging where I don't belong :)

Kind regards

Adrian

Pitch Modulation

So I'm going to attack adding Pitch Modulation from the Mod Wheel (well, vibrato) to my Bela implementation and wondered if anyone had already had a crack at this.

I presume that I'll have to implement controller ID #1 in tsf_channel_midi_control and link it to mod or vibLfoToPitch. Anyway, I'll start digging.

tsf_voice_kill not being called for all Voices

It is possible for voice->playingPreset to be set to -1 during tsf_note_on before completion. This is caused by tsf_voice_kill altering the voice during render (assuming a multithreaded call) as soon as voice initialisation begins. This means that the voice pool grows over time. I've added an active flag (in my local code) around tsf_voice to protect it until it is fully set.

Volume curve

I've been looking into volume curves recently, because my implementation of a MIDI player using TSF didn't sound quite right. In the end I was using a linear curve to map MIDI velocity (0-127) to the velocity (0-1) in tsf_note_on. It turns out that a quadratic curve is a better fit.

This led me to do some maths that a) I'd like to share in case anyone else is worrying about this, and b) I think it would be useful to use a quadratic curve in your examples (e.g. here), and also here.

A MIDI note has a velocity v between 0 and 127 (int).
TSF asks for a velocity x between 0 and 1 (float).
In the final output, we get a volume L measured in decibels between -∞ and 0 (this is the difference in decibels from full volume, i.e. 0dB is full volume).

According to the GM recommendations (bottom of page 9) the recommendation is to map between v and L by L = 40 log (v/127).

From looking at TSF's code, it maps between x and L by L = 20 log (x) (see tsf_gainToDecibels).

It's the user of TSF's job to implement the map between v and x. If we want to conform to the GM recommendations, we need 40 log (v/127) = 20 log (x), i.e. x = (v/127)^2.

Therefore, I recommend that people using TSF use the mapping x = (v/127)^2 when calling tsf_note_on or similar functions. It makes sense to me to default to conforming to the GM recommendations.

I think it would be good to update the examples to use this map, rather than x = v/127 (which I see in example3.c). Also, I wonder if you should use a quadratic map rather than the cubic map x = (v/16383)^3 in TCMC_SET_VOLUME (here v is between 0 and 16383).

Can TSF work without the SDL

Hello,

I am participating in this year's Google Summer of Code, for which i'll be integrating MIDI support in a game engine called Godot. So far TinySoundFont looks like the best option and i was wondering what are the conditions to using TSF in an already existing project?
I've studied the example files and if i understand correctly, I should be able to replace the SDL parts with another audio library and in theory it should work right?
Thanks

this library wrote 3300 seconds of PCM audio in 4.9 seconds. (nice work)

i ran this script https://github.com/yishengjiang99/ssr-bach/blob/master/install.c 15 times (from note js) to compile 15 different instruments for keys 21-109 and it finished in 6.9 (first 2.0 were spent parsing some midi file)

`yishengs-macbook-pro:ssr-bach yisheng$ ts-node /Users/yisheng/Documents/GitHub/ssr-bach/src/install.ts
2.097498536
2.354698177
2.598045037
2.869136001
3.104193877
3.445881478
3.699593748
4.207481075
4.661177624
5.084969839
5.513516307
5.797124318
6.230779299
6.492082309
6.922956223``

TinySoundFont does not work with sampling frequencies lower than 44100Hz

This can be verified by changing the output frequency in any of the example programs. 44100Hz and 48000Hz seem to work fine, but 22050Hz, 11025Hz, etc are all broken. I've verified the breakage both with the example programs and with a separate integration of TinySoundFont into an existing project.

How many channels does this support?

In the MIDI spec, a channel MIDI message (e.g. note on, note off, program changed, etc.) has a channel represented by 4 bits (i.e. 0-15). However, that's only a limitation of the MIDI messages. Since TSF uses functions as its interface, not MIDI messages, does it still have this restriction of only 16 channels? (Having searched the code for the number 16, I think the answer is "no", which is good, but it's safer to check with you!)

The reason I ask is because we're looking at trying to support >16 channels in our MIDI player. As far as I can tell, normally these are encoded by choosing which MIDI device to send the event to, with the assumption that each MIDI device handles just 16 channels. So channels 0-15 go to MIDI device 0, 16-31 go to MIDI device 1, 32-47 go to MIDI device 2, etc. You would configure this on your MIDI software. To record this concept in a Standard MIDI files, this is usually done by telling each track which MIDI device to use with a 0x21 (port name) or 0x9 (device name) meta-event.

Taken literally, this would mean spinning up multiple TSF instances, since TSF takes the role of an output MIDI device. However, if TSF can handle more than 16 channels, it would be far easier just to have a shim layer in front of TSF that simply receives a MIDI event for MIDI device D for channel C, and maps that to channel 16*D+C on TSF. This way we need just one instance of TSF, one audio stream connecting TSF to an audio device, etc.

Midi

Hi,
i try to write a wrapper/package for tcl/tk in c. I created a function
"play soundfont midifile"
(similar tu exemple3.c) but i dont know how to split the different functions in seperate c functions.

My Goal is to seperate These steps in tcl commands

  • initialize the audio System
  • load soundfont
  • load midi file
  • play (in Background)
  • pause, resume and stop
  • get actual information
  • load new midi file and soundfont (and re-initialized the audiosystem?)
  • shutdown the System.

The other think is how can i read the playing Information (whole length, actual Position etc.)?

thx a lot - kmatze

tinysoundfont with Arduino IDE and ESP32

Hi Bernhard,
I'd like to make use of your tinysoundfont-library with ESP32 (128MBit) and Arduino IDE.
Can you give a small example of how this could work. I only want to play midi note-on and midi note-off with different instruments on different midi-channels.
Audio-out: I2S DAC
Possible with your library?
Any idea about latency?

I would like you to answer to: [email protected]

Thank you very much for a quick answer!

Michael

SFZ not working in SFZero

Hi,

This is actually a report against your fork of SFZero, but there's no issue tracker currently for that repo so I'm posting here.

SF2 works fine in your SFZero, however SFZ just produces silence (or at least some very low level noise).

I will look into this myself, but I'm asking here in case you're aware of anything obvious that may be causing the problem

The original stevefolta SFZ works fine, so this is definitely a regression.

segfault on `tsf_set_output`

Hello! Excellent library!

I've had no problems with it when calling from a static context that loads a file immediately, but I'm getting a lot of segfaults when I try to load a second file, or when I call tsf_set_output a second time after loading another file. Is there something special that I need to do to prevent these crashes happening?

how to build it on c4droid or on mingw's msys.bat?

I tried both but in vain.
Error says:
example1.c: func main: undefined reference to SDL_Delay
minisdl_audio.c: func SDL_Audio_LockDevice_Default: undefined reference to SDL_ThreadID ……
makefile:

NDK_ROOT=F:/COD/NVPACK/android-ndk-r12b
sysroot=$(NDK_ROOT)/platforms/android-23/arch-arm
TOOLCHAINS_ROOT=$(NDK_ROOT)/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/4.9.x/include-fixed
PLATFROM_ROOT=$(NDK_ROOT)/platforms/android-23/arch-arm
PLATFROM_INCLUDE=$(PLATFROM_ROOT)/usr/include
PLATFROM_LIB=$(PLATFROM_ROOT)/usr/lib
FLAGSMY=-I$(TOOLCHAINS_INCLUDE)\
	-I$(PLATFROM_INCLUDE)\
	-L$(PLATFROM_LIB)\
	-lgcc\
	-Bdynamic\
	-lc\
	-fPIC

all:ha
.PHONY : all
ha:
	$(TOOLCHAINS_PREFIX)-gcc $(FLAGSMY) -Wall  example1.c minisdl_audio.c -lm -ldl  -o libexample1.so --sysroot=$(sysroot)

clean:
	$(RM) *.o

Sustain and release issue

If I call tsf_channel_note_on(soundFont, channel, key, 0); internally the library call tsf_note_off(f, preset_index, key); which causes the notes for the channel to go off, but applying sustain (some kind of fading out I think).

I'm using that first call as a way to mute the music of my game, is there any way the sustain and release doesn't get applied? Or should I approach the muting of the music in another way?

I also have this problem when I change the music, say Music 1 is playing and the I as a player change it to Music 2, you can hear the fading out of Music 1 while the Music 2 starts to play.

Am I doing something wrong, using the library wrong or something?

pitchRatio is twice the value it should be...

Not sure if this is an issue specific to the soundfonts I've tried, but I've found that TSF is playing samples at circa double the speed they should be played at. This can be quite noticeable for soundfonts where the sound changes dramatically over different octaves...

I haven't got stuck into the details, but my fix has been to scale pitchRatio by 0.5 on line #L978... Otherwise I always see pitchRatio values between ~1.5 and ~2.5, i.e. samples are being played at twice the speed they should be...

This might also apply to dynamic pitch ratio calculations - I haven't been able to check yet though...

Hope that makes sense and thanks for the great library!

Duplicate Symbols

Hiya, this might be a dumb question, but I want to include tsf.h in a header file, then include that header in main, and its giving me 40 duplicate symbols when I do (I see you said to include it in one file, I've tried pragma onceing it etc etc and its still showing duplicates, any ways around this?

tml.h depends on struct tsf_stream definition

Hello,

I'm currently working on a project in which I use TinyMidiLoader as a standalone lib (thanks!), and I'm encountering some problems with gcc complaining about tml_load_tsf_stream, here's the related output:

In file included from rbncli.c:9:
tml.h:469:48: warning: ‘struct tsf_stream’ declared inside parameter list will not be visible outside of this definition or declaration
 TMLDEF tml_message* tml_load_tsf_stream(struct tsf_stream* stream)
                                                ^~~~~~~~~~
tml.h:469:21: error: conflicting types for ‘tml_load_tsf_stream’
 TMLDEF tml_message* tml_load_tsf_stream(struct tsf_stream* stream)
                     ^~~~~~~~~~~~~~~~~~~
In file included from rbncli.h:7,
                 from rbncli.c:1:
tml.h:141:21: note: previous declaration of ‘tml_load_tsf_stream’ was here
 TMLDEF tml_message* tml_load_tsf_stream(struct tsf_stream* stream);
                     ^~~~~~~~~~~~~~~~~~~

struct tsf_stream doesn't seem to be declared in TinyMidiLoader and is assumed to have been declared earlier in tsf.h.
I figure to fix this problem you could move it out of tml.h (or remove it, considering it's only a simple cast) or you could compile it conditionally (from tsf.h defines).
I could define a dummy struct tsf_stream in my code to avoid the problem or remove the code from your lib, but it's client-side friction probably best avoided.
Do you have any other suggestion? Thanks again for your work!

Default tempo constant is set incorrectly

I think the constant 480000 in tml_load, for the default tempo value is incorrect.

This is supposed to be defined as microseconds per tick, and the default BPM is supposed to be 120, which means a value of 500000.

This is the line of code that I think needs to be changed:

double ticks2time = 480000 / (1000.0 * division); //milliseconds per tick

Repro steps:

  1. Grab this midi file that sets the BPM to 120 via SET_TEMPO messages, and never wavers from that tempo: this midi file here - TITLE.zip
  2. Playback the file and get the track length value: tml_get_info(tiny_midi_loader, NULL, NULL, NULL, NULL, &time_length);
  3. Commented out the Set Tempo code in tml.h (inside tml_load):
if (Msg->type == TML_SET_TEMPO)
{
    //unsigned char* Tempo = ((struct tml_tempomsg*)Msg)->Tempo;
    //ticks2time = ((Tempo[0]<<16)|(Tempo[1]<<8)|Tempo[2])/(1000.0 * division);
    //tempo_msec = msec;
    //tempo_ticks = ticks;
}
  1. Playback the same track with that code commented out, and get the track length value again

Expected:
The times in step 1 and step 3 should be equal

Actual:
The times are off by a factor of exactly 0.96 (480000 / 500000)

How I can stop a note by fading the volume?

So when I turn off a note the sound stops completely, this is very abrupt and I will like it to stop it smoothly.

Is this possible?

I was thinking I could turn off the volume gradually until it reaches zero, is there something already built in for this on the library?

I tried to change the volume of a note by calling tsf_note_on with a lower velocity but it resets the note to the beginning.

Is it possible to have different notes with different volumes and fade them away after some time?

TinySoundFont HTML5 MIDI Player doesn't work in Microsoft Edge

Hi, Mr. Bernhard Schelling .

When I tried your TinySoundFont HTML5 MIDI Player at https://schellingb.github.io/TinySoundFont/CustomSoundFont.html using Microsoft Edge, I cannot hear any sound from my browser. But when using another browser, it works perfectly.
Are there any issue that can be fixed there? Because I want to ask somebody to make HTML5 game script that support MIDI and your library is the best for it and I want to use your HTML 5 MIDI Player as reference.

Thank you very much for your attention.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.