MIDI: Replaced BASSMIDI with FluidSynth
parent
a60d6daed8
commit
4cf76dd7e3
|
@ -494,6 +494,10 @@ void* kAppControllerContext = &kAppControllerContext;
|
|||
if ([brokenFeedURLs containsObject:feedURL]) {
|
||||
[[NSUserDefaults standardUserDefaults] setValue:feedURLdefault forKey:@"SUFeedURL"];
|
||||
}
|
||||
|
||||
if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"] isEqualToString:@"BASSMIDI"]) {
|
||||
[[NSUserDefaults standardUserDefaults] setValue:@"FluidSynth" forKey:@"midi.plugin"];
|
||||
}
|
||||
}
|
||||
|
||||
/* Unassign previous handler first, so dealloc can unregister it from the global map before the new instances are assigned */
|
||||
|
|
|
@ -7,9 +7,21 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
830C94D11D171B65000E404F /* sflist.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C94CB1D171B65000E404F /* sflist.c */; };
|
||||
830C94D21D171B65000E404F /* json-builder.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C94CD1D171B65000E404F /* json-builder.c */; };
|
||||
830C94D31D171B65000E404F /* json.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C94CF1D171B65000E404F /* json.c */; };
|
||||
8309220B2640D0B8005855C1 /* SFPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8309220A2640D0B8005855C1 /* SFPlayer.cpp */; };
|
||||
8309220C2640D3CD005855C1 /* libFLAC.8.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830921FD2640CC16005855C1 /* libFLAC.8.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
8309220D2640D3CF005855C1 /* libfluidsynth.2.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830921FB2640CC16005855C1 /* libfluidsynth.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
8309220E2640D3D3005855C1 /* libglib-2.0.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922022640CC16005855C1 /* libglib-2.0.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
8309220F2640D3D8005855C1 /* libgthread-2.0.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830921FF2640CC16005855C1 /* libgthread-2.0.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922102640D3E4005855C1 /* libintl.8.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922042640CC16005855C1 /* libintl.8.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922112640D3E8005855C1 /* libogg.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922062640CC16005855C1 /* libogg.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922122640D3EC005855C1 /* libopus.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922052640CC16005855C1 /* libopus.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922132640D3F1005855C1 /* libpcre.1.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922012640CC16005855C1 /* libpcre.1.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922142640D3F4005855C1 /* libportaudio.2.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922032640CC16005855C1 /* libportaudio.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922152640D3F7005855C1 /* libreadline.8.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830921FE2640CC16005855C1 /* libreadline.8.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922162640D3FD005855C1 /* libsndfile.1.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922002640CC16005855C1 /* libsndfile.1.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922172640D400005855C1 /* libvorbis.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830922072640CC16005855C1 /* libvorbis.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922182640D40D005855C1 /* libvorbisenc.2.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830921FC2640CC16005855C1 /* libvorbisenc.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
830922192640D45D005855C1 /* libfluidsynth.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 830921FB2640CC16005855C1 /* libfluidsynth.2.dylib */; };
|
||||
834BE91B1DE407CB00A07DCD /* resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 834BE9191DE407CB00A07DCD /* resampler.c */; };
|
||||
83686AAC1C5C69D400671C7A /* AUPlayerView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83686AAB1C5C69D400671C7A /* AUPlayerView.mm */; };
|
||||
83686AB11C5C783000671C7A /* CoreAudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83686AB01C5C783000671C7A /* CoreAudioKit.framework */; };
|
||||
|
@ -24,15 +36,6 @@
|
|||
83B06695180D5668008E3612 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 83B06693180D5668008E3612 /* InfoPlist.strings */; };
|
||||
83B06701180D5747008E3612 /* midi_processing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83B066E0180D56BA008E3612 /* midi_processing.framework */; };
|
||||
83B06709180D64DA008E3612 /* MIDIPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B06708180D64DA008E3612 /* MIDIPlayer.cpp */; };
|
||||
83B0670C180D6665008E3612 /* BMPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B0670A180D6665008E3612 /* BMPlayer.cpp */; };
|
||||
83B0670F180D6F7F008E3612 /* libbass.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83B0670D180D6F7F008E3612 /* libbass.dylib */; };
|
||||
83B06710180D6F7F008E3612 /* libbassmidi.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83B0670E180D6F7F008E3612 /* libbassmidi.dylib */; };
|
||||
83B06712180D6FAA008E3612 /* libbass.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B0670D180D6F7F008E3612 /* libbass.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
83B06713180D6FAA008E3612 /* libbassmidi.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B0670E180D6F7F008E3612 /* libbassmidi.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
83B0671C180D6FD8008E3612 /* libbass_mpc.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B06714180D6FC8008E3612 /* libbass_mpc.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
83B0671D180D6FD8008E3612 /* libbassflac.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B06715180D6FC8008E3612 /* libbassflac.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
83B0671E180D6FD8008E3612 /* libbassopus.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B06716180D6FC8008E3612 /* libbassopus.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
83B0671F180D6FD8008E3612 /* libbasswv.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B06717180D6FC8008E3612 /* libbasswv.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
83B06722180D70FE008E3612 /* MIDIDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83B06721180D70FE008E3612 /* MIDIDecoder.mm */; };
|
||||
83C35702180EDB74007E9DF0 /* MIDIContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83C35700180EDB74007E9DF0 /* MIDIContainer.mm */; };
|
||||
83C35705180EDD1C007E9DF0 /* MIDIMetadataReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83C35703180EDD1C007E9DF0 /* MIDIMetadataReader.mm */; };
|
||||
|
@ -75,24 +78,40 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 6;
|
||||
files = (
|
||||
83B0671C180D6FD8008E3612 /* libbass_mpc.dylib in CopyFiles */,
|
||||
83B0671D180D6FD8008E3612 /* libbassflac.dylib in CopyFiles */,
|
||||
83B0671E180D6FD8008E3612 /* libbassopus.dylib in CopyFiles */,
|
||||
83B0671F180D6FD8008E3612 /* libbasswv.dylib in CopyFiles */,
|
||||
83B06712180D6FAA008E3612 /* libbass.dylib in CopyFiles */,
|
||||
83B06713180D6FAA008E3612 /* libbassmidi.dylib in CopyFiles */,
|
||||
8309220C2640D3CD005855C1 /* libFLAC.8.dylib in CopyFiles */,
|
||||
8309220D2640D3CF005855C1 /* libfluidsynth.2.dylib in CopyFiles */,
|
||||
8309220F2640D3D8005855C1 /* libgthread-2.0.0.dylib in CopyFiles */,
|
||||
8309220E2640D3D3005855C1 /* libglib-2.0.0.dylib in CopyFiles */,
|
||||
830922102640D3E4005855C1 /* libintl.8.dylib in CopyFiles */,
|
||||
830922112640D3E8005855C1 /* libogg.0.dylib in CopyFiles */,
|
||||
830922122640D3EC005855C1 /* libopus.0.dylib in CopyFiles */,
|
||||
830922132640D3F1005855C1 /* libpcre.1.dylib in CopyFiles */,
|
||||
830922142640D3F4005855C1 /* libportaudio.2.dylib in CopyFiles */,
|
||||
830922152640D3F7005855C1 /* libreadline.8.dylib in CopyFiles */,
|
||||
830922162640D3FD005855C1 /* libsndfile.1.dylib in CopyFiles */,
|
||||
830922172640D400005855C1 /* libvorbis.0.dylib in CopyFiles */,
|
||||
830922182640D40D005855C1 /* libvorbisenc.2.dylib in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
830C94CB1D171B65000E404F /* sflist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sflist.c; path = ../../../ThirdParty/BASS/sflist.c; sourceTree = "<group>"; };
|
||||
830C94CC1D171B65000E404F /* sflist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sflist.h; path = ../../../ThirdParty/BASS/sflist.h; sourceTree = "<group>"; };
|
||||
830C94CD1D171B65000E404F /* json-builder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "json-builder.c"; path = "../../../ThirdParty/json/json-builder.c"; sourceTree = "<group>"; };
|
||||
830C94CE1D171B65000E404F /* json-builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "json-builder.h"; path = "../../../ThirdParty/json/json-builder.h"; sourceTree = "<group>"; };
|
||||
830C94CF1D171B65000E404F /* json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = json.c; path = ../../../ThirdParty/json/json.c; sourceTree = "<group>"; };
|
||||
830C94D01D171B65000E404F /* json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = json.h; path = ../../../ThirdParty/json/json.h; sourceTree = "<group>"; };
|
||||
830921FA2640CBBD005855C1 /* SFPlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFPlayer.h; sourceTree = "<group>"; };
|
||||
830921FB2640CC16005855C1 /* libfluidsynth.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfluidsynth.2.dylib; path = ../../ThirdParty/FluidSynth/libfluidsynth.2.dylib; sourceTree = "<group>"; };
|
||||
830921FC2640CC16005855C1 /* libvorbisenc.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbisenc.2.dylib; path = ../../ThirdParty/FluidSynth/libvorbisenc.2.dylib; sourceTree = "<group>"; };
|
||||
830921FD2640CC16005855C1 /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libFLAC.8.dylib; path = ../../ThirdParty/FluidSynth/libFLAC.8.dylib; sourceTree = "<group>"; };
|
||||
830921FE2640CC16005855C1 /* libreadline.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libreadline.8.dylib; path = ../../ThirdParty/FluidSynth/libreadline.8.dylib; sourceTree = "<group>"; };
|
||||
830921FF2640CC16005855C1 /* libgthread-2.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libgthread-2.0.0.dylib"; path = "../../ThirdParty/FluidSynth/libgthread-2.0.0.dylib"; sourceTree = "<group>"; };
|
||||
830922002640CC16005855C1 /* libsndfile.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsndfile.1.dylib; path = ../../ThirdParty/FluidSynth/libsndfile.1.dylib; sourceTree = "<group>"; };
|
||||
830922012640CC16005855C1 /* libpcre.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpcre.1.dylib; path = ../../ThirdParty/FluidSynth/libpcre.1.dylib; sourceTree = "<group>"; };
|
||||
830922022640CC16005855C1 /* libglib-2.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libglib-2.0.0.dylib"; path = "../../ThirdParty/FluidSynth/libglib-2.0.0.dylib"; sourceTree = "<group>"; };
|
||||
830922032640CC16005855C1 /* libportaudio.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libportaudio.2.dylib; path = ../../ThirdParty/FluidSynth/libportaudio.2.dylib; sourceTree = "<group>"; };
|
||||
830922042640CC16005855C1 /* libintl.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libintl.8.dylib; path = ../../ThirdParty/FluidSynth/libintl.8.dylib; sourceTree = "<group>"; };
|
||||
830922052640CC16005855C1 /* libopus.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libopus.0.dylib; path = ../../ThirdParty/FluidSynth/libopus.0.dylib; sourceTree = "<group>"; };
|
||||
830922062640CC16005855C1 /* libogg.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libogg.0.dylib; path = ../../ThirdParty/FluidSynth/libogg.0.dylib; sourceTree = "<group>"; };
|
||||
830922072640CC16005855C1 /* libvorbis.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbis.0.dylib; path = ../../ThirdParty/FluidSynth/libvorbis.0.dylib; sourceTree = "<group>"; };
|
||||
8309220A2640D0B8005855C1 /* SFPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SFPlayer.cpp; sourceTree = "<group>"; };
|
||||
833F68431CDBCABE00AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
834BE9191DE407CB00A07DCD /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = "<group>"; };
|
||||
834BE91A1DE407CB00A07DCD /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = "<group>"; };
|
||||
|
@ -131,14 +150,6 @@
|
|||
83B066DA180D56B9008E3612 /* midi_processing.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = midi_processing.xcodeproj; path = ../../Frameworks/midi_processing/midi_processing.xcodeproj; sourceTree = "<group>"; };
|
||||
83B06706180D6471008E3612 /* MIDIPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIPlayer.h; sourceTree = "<group>"; };
|
||||
83B06708180D64DA008E3612 /* MIDIPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MIDIPlayer.cpp; sourceTree = "<group>"; };
|
||||
83B0670A180D6665008E3612 /* BMPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMPlayer.cpp; sourceTree = "<group>"; };
|
||||
83B0670B180D6665008E3612 /* BMPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMPlayer.h; sourceTree = "<group>"; };
|
||||
83B0670D180D6F7F008E3612 /* libbass.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbass.dylib; path = ../../ThirdParty/BASS/libbass.dylib; sourceTree = "<group>"; };
|
||||
83B0670E180D6F7F008E3612 /* libbassmidi.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbassmidi.dylib; path = ../../ThirdParty/BASS/libbassmidi.dylib; sourceTree = "<group>"; };
|
||||
83B06714180D6FC8008E3612 /* libbass_mpc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbass_mpc.dylib; path = ../../ThirdParty/BASS/libbass_mpc.dylib; sourceTree = "<group>"; };
|
||||
83B06715180D6FC8008E3612 /* libbassflac.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbassflac.dylib; path = ../../ThirdParty/BASS/libbassflac.dylib; sourceTree = "<group>"; };
|
||||
83B06716180D6FC8008E3612 /* libbassopus.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbassopus.dylib; path = ../../ThirdParty/BASS/libbassopus.dylib; sourceTree = "<group>"; };
|
||||
83B06717180D6FC8008E3612 /* libbasswv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbasswv.dylib; path = ../../ThirdParty/BASS/libbasswv.dylib; sourceTree = "<group>"; };
|
||||
83B06720180D70FE008E3612 /* MIDIDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIDecoder.h; sourceTree = "<group>"; };
|
||||
83B06721180D70FE008E3612 /* MIDIDecoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MIDIDecoder.mm; sourceTree = "<group>"; };
|
||||
83B06723180D714F008E3612 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../../Audio/Plugin.h; sourceTree = "<group>"; };
|
||||
|
@ -163,29 +174,15 @@
|
|||
files = (
|
||||
83686AB11C5C783000671C7A /* CoreAudioKit.framework in Frameworks */,
|
||||
8398F2E01C438C7D00EB9639 /* AudioUnit.framework in Frameworks */,
|
||||
83B0670F180D6F7F008E3612 /* libbass.dylib in Frameworks */,
|
||||
83B06701180D5747008E3612 /* midi_processing.framework in Frameworks */,
|
||||
83B06710180D6F7F008E3612 /* libbassmidi.dylib in Frameworks */,
|
||||
83B0668B180D5668008E3612 /* Cocoa.framework in Frameworks */,
|
||||
830922192640D45D005855C1 /* libfluidsynth.2.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
830C94CA1D171B30000E404F /* sflist */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
830C94CB1D171B65000E404F /* sflist.c */,
|
||||
830C94CC1D171B65000E404F /* sflist.h */,
|
||||
830C94CD1D171B65000E404F /* json-builder.c */,
|
||||
830C94CE1D171B65000E404F /* json-builder.h */,
|
||||
830C94CF1D171B65000E404F /* json.c */,
|
||||
830C94D01D171B65000E404F /* json.h */,
|
||||
);
|
||||
name = sflist;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83A09F551CFA83F2001E7D2D /* synthlib_doom */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -254,12 +251,6 @@
|
|||
83686AB01C5C783000671C7A /* CoreAudioKit.framework */,
|
||||
83686AAE1C5C780500671C7A /* AudioToolbox.framework */,
|
||||
8398F2DF1C438C7D00EB9639 /* AudioUnit.framework */,
|
||||
83B06714180D6FC8008E3612 /* libbass_mpc.dylib */,
|
||||
83B06715180D6FC8008E3612 /* libbassflac.dylib */,
|
||||
83B06716180D6FC8008E3612 /* libbassopus.dylib */,
|
||||
83B06717180D6FC8008E3612 /* libbasswv.dylib */,
|
||||
83B0670D180D6F7F008E3612 /* libbass.dylib */,
|
||||
83B0670E180D6F7F008E3612 /* libbassmidi.dylib */,
|
||||
83B0668A180D5668008E3612 /* Cocoa.framework */,
|
||||
83B0668C180D5668008E3612 /* Other Frameworks */,
|
||||
83B066DA180D56B9008E3612 /* midi_processing.xcodeproj */,
|
||||
|
@ -270,6 +261,19 @@
|
|||
83B0668C180D5668008E3612 /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
830921FD2640CC16005855C1 /* libFLAC.8.dylib */,
|
||||
830921FB2640CC16005855C1 /* libfluidsynth.2.dylib */,
|
||||
830922022640CC16005855C1 /* libglib-2.0.0.dylib */,
|
||||
830921FF2640CC16005855C1 /* libgthread-2.0.0.dylib */,
|
||||
830922042640CC16005855C1 /* libintl.8.dylib */,
|
||||
830922062640CC16005855C1 /* libogg.0.dylib */,
|
||||
830922052640CC16005855C1 /* libopus.0.dylib */,
|
||||
830922012640CC16005855C1 /* libpcre.1.dylib */,
|
||||
830922032640CC16005855C1 /* libportaudio.2.dylib */,
|
||||
830921FE2640CC16005855C1 /* libreadline.8.dylib */,
|
||||
830922002640CC16005855C1 /* libsndfile.1.dylib */,
|
||||
830922072640CC16005855C1 /* libvorbis.0.dylib */,
|
||||
830921FC2640CC16005855C1 /* libvorbisenc.2.dylib */,
|
||||
83B0668D180D5668008E3612 /* Foundation.framework */,
|
||||
83B0668E180D5668008E3612 /* CoreData.framework */,
|
||||
83B0668F180D5668008E3612 /* AppKit.framework */,
|
||||
|
@ -280,7 +284,8 @@
|
|||
83B06690180D5668008E3612 /* MIDI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
830C94CA1D171B30000E404F /* sflist */,
|
||||
8309220A2640D0B8005855C1 /* SFPlayer.cpp */,
|
||||
830921FA2640CBBD005855C1 /* SFPlayer.h */,
|
||||
83A09F6E1CFA8D6B001E7D2D /* MSPlayer.cpp */,
|
||||
83A09F6D1CFA8D6B001E7D2D /* MSPlayer.h */,
|
||||
83A09F661CFA883D001E7D2D /* interface.h */,
|
||||
|
@ -306,8 +311,6 @@
|
|||
83B06723180D714F008E3612 /* Plugin.h */,
|
||||
83B06720180D70FE008E3612 /* MIDIDecoder.h */,
|
||||
83B06721180D70FE008E3612 /* MIDIDecoder.mm */,
|
||||
83B0670A180D6665008E3612 /* BMPlayer.cpp */,
|
||||
83B0670B180D6665008E3612 /* BMPlayer.h */,
|
||||
83B06708180D64DA008E3612 /* MIDIPlayer.cpp */,
|
||||
83B06706180D6471008E3612 /* MIDIPlayer.h */,
|
||||
83B06691180D5668008E3612 /* Supporting Files */,
|
||||
|
@ -424,7 +427,6 @@
|
|||
files = (
|
||||
83E973471C4378880007F413 /* AUPlayer.mm in Sources */,
|
||||
83686AAC1C5C69D400671C7A /* AUPlayerView.mm in Sources */,
|
||||
830C94D31D171B65000E404F /* json.c in Sources */,
|
||||
83DFEA071CBC87BB00BCC565 /* SCCore.cpp in Sources */,
|
||||
83A09F621CFA83F2001E7D2D /* i_oplmusic.cpp in Sources */,
|
||||
83B06709180D64DA008E3612 /* MIDIPlayer.cpp in Sources */,
|
||||
|
@ -433,13 +435,11 @@
|
|||
83B06722180D70FE008E3612 /* MIDIDecoder.mm in Sources */,
|
||||
83A09F6F1CFA8D6B001E7D2D /* MSPlayer.cpp in Sources */,
|
||||
83C35702180EDB74007E9DF0 /* MIDIContainer.mm in Sources */,
|
||||
83B0670C180D6665008E3612 /* BMPlayer.cpp in Sources */,
|
||||
83A09F651CFA83F2001E7D2D /* opl3class.cpp in Sources */,
|
||||
83C35705180EDD1C007E9DF0 /* MIDIMetadataReader.mm in Sources */,
|
||||
830C94D21D171B65000E404F /* json-builder.c in Sources */,
|
||||
834BE91B1DE407CB00A07DCD /* resampler.c in Sources */,
|
||||
830C94D11D171B65000E404F /* sflist.c in Sources */,
|
||||
83A09F641CFA83F2001E7D2D /* opl3.cpp in Sources */,
|
||||
8309220B2640D0B8005855C1 /* SFPlayer.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -577,14 +577,14 @@
|
|||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "MIDI/MIDI-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(SRCROOT)/../../ThirdParty/BASS",
|
||||
"$(SRCROOT)/../../ThirdParty/FluidSynth/include",
|
||||
"$(SRCROOT)/../../ThirdParty/json",
|
||||
);
|
||||
INFOPLIST_FILE = "MIDI/MIDI-Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/../../ThirdParty/BASS",
|
||||
"$(PROJECT_DIR)/../../ThirdParty/FluidSynth",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.midi;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -605,14 +605,14 @@
|
|||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "MIDI/MIDI-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(SRCROOT)/../../ThirdParty/BASS",
|
||||
"$(SRCROOT)/../../ThirdParty/FluidSynth/include",
|
||||
"$(SRCROOT)/../../ThirdParty/json",
|
||||
);
|
||||
INFOPLIST_FILE = "MIDI/MIDI-Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/../../ThirdParty/BASS",
|
||||
"$(PROJECT_DIR)/../../ThirdParty/FluidSynth",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.midi;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
#import "Plugin.h"
|
||||
|
||||
class AUPlayer;
|
||||
class BMPlayer;
|
||||
class SFPlayer;
|
||||
|
||||
@interface MIDIDecoder : NSObject <CogDecoder> {
|
||||
id<CogSource> source;
|
||||
int track_num;
|
||||
|
||||
BMPlayer* bmplayer;
|
||||
SFPlayer* sfplayer;
|
||||
AUPlayer* auplayer;
|
||||
MIDIPlayer* player;
|
||||
midi_container midi_file;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#import "MIDIDecoder.h"
|
||||
|
||||
#import "AUPlayer.h"
|
||||
#import "BMPlayer.h"
|
||||
#import "SFPlayer.h"
|
||||
#import "SCPlayer.h"
|
||||
#import "MSPlayer.h"
|
||||
|
||||
|
@ -153,22 +153,26 @@ static OSType getOSType(const char * in_)
|
|||
DLog(@"Track num: %i", track_num);
|
||||
|
||||
NSString * plugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"];
|
||||
if (!plugin || [plugin isEqualToString:@"BASSMIDI"])
|
||||
if (!plugin || [plugin isEqualToString:@"FluidSynth"])
|
||||
{
|
||||
bmplayer = new BMPlayer;
|
||||
sfplayer = new SFPlayer;
|
||||
|
||||
bool resampling_sinc = false;
|
||||
unsigned int resamplingQuality = 0;
|
||||
NSString * resampling = [[NSUserDefaults standardUserDefaults] stringForKey:@"resampling"];
|
||||
if ([resampling isEqualToString:@"sinc"])
|
||||
resampling_sinc = true;
|
||||
if ([resampling isEqualToString:@"linear"])
|
||||
resamplingQuality = 1;
|
||||
else if ([resampling isEqualToString:@"cubic"])
|
||||
resamplingQuality = 4;
|
||||
else if ([resampling isEqualToString:@"sinc"])
|
||||
resamplingQuality = 7;
|
||||
|
||||
bmplayer->setSincInterpolation( resampling_sinc );
|
||||
bmplayer->setSampleRate( 44100 );
|
||||
sfplayer->setInterpolationMethod(resamplingQuality);
|
||||
sfplayer->setSampleRate( 44100 );
|
||||
|
||||
if ( [soundFontPath length] )
|
||||
bmplayer->setFileSoundFont( [soundFontPath UTF8String] );
|
||||
sfplayer->setFileSoundFont( [soundFontPath UTF8String] );
|
||||
|
||||
player = bmplayer;
|
||||
player = sfplayer;
|
||||
}
|
||||
else if ([[plugin substringToIndex:4] isEqualToString:@"DOOM"])
|
||||
{
|
||||
|
@ -277,13 +281,13 @@ static OSType getOSType(const char * in_)
|
|||
if ( !repeatone && framesRead >= localTotalFrames )
|
||||
return 0;
|
||||
|
||||
if ( (bmplayer||auplayer) && !soundFontsAssigned ) {
|
||||
if ( (sfplayer||auplayer) && !soundFontsAssigned ) {
|
||||
NSString * soundFontPath = [[NSUserDefaults standardUserDefaults] stringForKey:@"soundFontPath"];
|
||||
if (soundFontPath == nil)
|
||||
return 0;
|
||||
|
||||
if (bmplayer)
|
||||
bmplayer->setSoundFont( [soundFontPath UTF8String] );
|
||||
if (sfplayer)
|
||||
sfplayer->setSoundFont( [soundFontPath UTF8String] );
|
||||
else if (auplayer)
|
||||
auplayer->setSoundFont( [soundFontPath UTF8String] );
|
||||
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
//
|
||||
// SFPlayer.cpp
|
||||
// MIDI
|
||||
//
|
||||
// Created by Christopher Snowhill on 5/3/21.
|
||||
// Copyright © 2021 Christopher Snowhill. All rights reserved.
|
||||
//
|
||||
|
||||
#include "SFPlayer.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define _countof(x) (sizeof((x))/sizeof(((x)[0])))
|
||||
|
||||
static const uint8_t sysex_gm_reset[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7 };
|
||||
static const uint8_t sysex_gm2_reset[]= { 0xF0, 0x7E, 0x7F, 0x09, 0x03, 0xF7 };
|
||||
static const uint8_t sysex_gs_reset[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7 };
|
||||
static const uint8_t sysex_xg_reset[] = { 0xF0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7 };
|
||||
|
||||
static bool is_gs_reset(const unsigned char * data, unsigned long size)
|
||||
{
|
||||
if ( size != _countof( sysex_gs_reset ) ) return false;
|
||||
|
||||
if ( memcmp( data, sysex_gs_reset, 5 ) != 0 ) return false;
|
||||
if ( memcmp( data + 7, sysex_gs_reset + 7, 2 ) != 0 ) return false;
|
||||
if ( ( ( data[ 5 ] + data[ 6 ] + 1 ) & 127 ) != data[ 9 ] ) return false;
|
||||
if ( data[ 10 ] != sysex_gs_reset[ 10 ] ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SFPlayer::SFPlayer() : MIDIPlayer()
|
||||
{
|
||||
_synth = 0;
|
||||
uInterpolationMethod = FLUID_INTERP_DEFAULT;
|
||||
|
||||
reset_drums();
|
||||
|
||||
synth_mode = mode_gm;
|
||||
|
||||
_settings = new_fluid_settings();
|
||||
|
||||
fluid_settings_setnum(_settings, "synth.gain", 1.0);
|
||||
fluid_settings_setnum(_settings, "synth.sample-rate", 44100);
|
||||
fluid_settings_setint(_settings, "synth.midi-channels", 48);
|
||||
}
|
||||
|
||||
SFPlayer::~SFPlayer()
|
||||
{
|
||||
if (_synth) delete_fluid_synth(_synth);
|
||||
if (_settings) delete_fluid_settings(_settings);
|
||||
}
|
||||
|
||||
void SFPlayer::setInterpolationMethod(unsigned method)
|
||||
{
|
||||
shutdown();
|
||||
uInterpolationMethod = method;
|
||||
if ( _synth ) fluid_synth_set_interp_method( _synth, -1, method );
|
||||
}
|
||||
|
||||
void SFPlayer::send_event(uint32_t b)
|
||||
{
|
||||
if (!(b & 0x80000000))
|
||||
{
|
||||
int param2 = (b >> 16) & 0xFF;
|
||||
int param1 = (b >> 8) & 0xFF;
|
||||
int cmd = b & 0xF0;
|
||||
int chan = b & 0x0F;
|
||||
int port = (b >> 24) & 0x7F;
|
||||
|
||||
if ( port && port < 3 )
|
||||
chan += port * 16;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case 0x80:
|
||||
fluid_synth_noteoff(_synth, chan, param1);
|
||||
break;
|
||||
case 0x90:
|
||||
fluid_synth_noteon(_synth, chan, param1, param2);
|
||||
break;
|
||||
case 0xA0:
|
||||
break;
|
||||
case 0xB0:
|
||||
fluid_synth_cc(_synth, chan, param1, param2);
|
||||
if ( param1 == 0 || param1 == 0x20 )
|
||||
{
|
||||
unsigned bank = channel_banks[ chan ];
|
||||
if ( param1 == 0x20 ) bank = ( bank & 0x3F80 ) | ( param2 & 0x7F );
|
||||
else bank = ( bank & 0x007F ) | ( ( param2 & 0x7F ) << 7 );
|
||||
channel_banks[ chan ] = bank;
|
||||
if ( synth_mode == mode_xg )
|
||||
{
|
||||
if ( bank == 16256 ) drum_channels [chan] = 1;
|
||||
else drum_channels [chan] = 0;
|
||||
}
|
||||
else if ( synth_mode == mode_gm2 )
|
||||
{
|
||||
if ( bank == 15360 )
|
||||
drum_channels [chan] = 1;
|
||||
else if ( bank == 15488 )
|
||||
drum_channels [chan] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xC0:
|
||||
if ( drum_channels [chan] ) fluid_synth_bank_select(_synth, chan, 16256 /*DRUM_INST_BANK*/);
|
||||
fluid_synth_program_change(_synth, chan, param1);
|
||||
break;
|
||||
case 0xD0:
|
||||
fluid_synth_channel_pressure(_synth, chan, param1);
|
||||
break;
|
||||
case 0xE0:
|
||||
fluid_synth_pitch_bend(_synth, chan, (param2 << 7) | param1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t n = b & 0xffffff;
|
||||
const uint8_t * data;
|
||||
size_t size, port;
|
||||
mSysexMap.get_entry( n, data, size, port );
|
||||
if (port >= 3)
|
||||
port = 0;
|
||||
if ( ( size == _countof( sysex_gm_reset ) && !memcmp( data, sysex_gm_reset, _countof( sysex_gm_reset ) ) ) ||
|
||||
( size == _countof( sysex_gm2_reset ) && !memcmp( data, sysex_gm2_reset, _countof( sysex_gm2_reset ) ) ) ||
|
||||
is_gs_reset( data, size ) ||
|
||||
( size == _countof( sysex_xg_reset ) && !memcmp( data, sysex_xg_reset, _countof( sysex_xg_reset ) ) ) )
|
||||
{
|
||||
fluid_synth_system_reset( _synth );
|
||||
reset_drums();
|
||||
synth_mode = ( size == _countof( sysex_xg_reset ) ) ? mode_xg :
|
||||
( size == _countof( sysex_gs_reset ) ) ? mode_gs :
|
||||
( data [4] == 0x01 ) ? mode_gm :
|
||||
mode_gm2;
|
||||
}
|
||||
else if ( synth_mode == mode_gs && size == 11 &&
|
||||
data [0] == 0xF0 && data [1] == 0x41 && data [3] == 0x42 &&
|
||||
data [4] == 0x12 && data [5] == 0x40 && (data [6] & 0xF0) == 0x10 &&
|
||||
data [10] == 0xF7)
|
||||
{
|
||||
if (data [7] == 2)
|
||||
{
|
||||
// GS MIDI channel to part assign
|
||||
gs_part_to_ch [ ( port * 16 ) + ( data [6] & 15 ) ] = data [8];
|
||||
}
|
||||
else if ( data [7] == 0x15 )
|
||||
{
|
||||
// GS part to rhythm allocation
|
||||
unsigned int drum_channel = gs_part_to_ch [ ( port * 16 ) + ( data [6] & 15 ) ];
|
||||
if ( drum_channel < 16 )
|
||||
{
|
||||
drum_channels [ ( port * 16 ) + drum_channel ] = data [8];
|
||||
if ( port == 0 )
|
||||
{
|
||||
drum_channels [ 16 + drum_channel ] = data [8];
|
||||
drum_channels [ 32 + drum_channel ] = data [8];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SFPlayer::render(float * out, unsigned long count)
|
||||
{
|
||||
fluid_synth_write_float(_synth, count, out, 0, 2, out, 1, 2);
|
||||
}
|
||||
|
||||
void SFPlayer::setSoundFont( const char * in )
|
||||
{
|
||||
sSoundFontName = in;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void SFPlayer::setFileSoundFont( const char * in )
|
||||
{
|
||||
sFileSoundFontName = in;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void SFPlayer::shutdown()
|
||||
{
|
||||
if (_synth) delete_fluid_synth(_synth);
|
||||
_synth = 0;
|
||||
}
|
||||
|
||||
bool SFPlayer::startup()
|
||||
{
|
||||
if ( _synth ) return true;
|
||||
|
||||
fluid_settings_setnum(_settings, "synth.sample-rate", uSampleRate);
|
||||
|
||||
_synth = new_fluid_synth(_settings);
|
||||
if (!_synth)
|
||||
{
|
||||
_last_error = "Out of memory";
|
||||
return false;
|
||||
}
|
||||
fluid_synth_set_interp_method( _synth, -1, uInterpolationMethod );
|
||||
reset_drums();
|
||||
synth_mode = mode_gm;
|
||||
if (sSoundFontName.length())
|
||||
{
|
||||
std::string ext;
|
||||
size_t dot = sSoundFontName.find_last_of( '.' );
|
||||
if ( dot != std::string::npos )
|
||||
ext.assign( sSoundFontName.begin() + dot + 1, sSoundFontName.end() );
|
||||
if ( !strcasecmp( ext.c_str(), "sf2" ) )
|
||||
{
|
||||
if ( FLUID_FAILED == fluid_synth_sfload( _synth, sSoundFontName.c_str(), 1) )
|
||||
{
|
||||
shutdown();
|
||||
_last_error = "Failed to load SoundFont bank: ";
|
||||
_last_error += sSoundFontName;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !strcasecmp( ext.c_str(), "sflist" ) )
|
||||
{
|
||||
FILE * fl = fopen( sSoundFontName.c_str(), "r" );
|
||||
if ( fl )
|
||||
{
|
||||
std::string path, temp;
|
||||
char name[32768];
|
||||
size_t slash = sSoundFontName.find_last_of( '\\' );
|
||||
if ( slash != std::string::npos )
|
||||
path.assign( sSoundFontName.begin(), sSoundFontName.begin() + slash + 1 );
|
||||
while ( !feof( fl ) )
|
||||
{
|
||||
if ( !fgets( name, 32767, fl ) ) break;
|
||||
name[32767] = 0;
|
||||
char * cr = strchr( name, '\n' );
|
||||
if ( cr ) *cr = 0;
|
||||
cr = strchr( name, '\r' );
|
||||
if ( cr ) *cr = 0;
|
||||
if ( name[0] == '/' )
|
||||
{
|
||||
temp = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = path;
|
||||
temp += name;
|
||||
}
|
||||
if ( FLUID_FAILED == fluid_synth_sfload( _synth, temp.c_str(), 1 ) )
|
||||
{
|
||||
fclose( fl );
|
||||
shutdown();
|
||||
_last_error = "Failed to load SoundFont bank: ";
|
||||
_last_error += temp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fclose( fl );
|
||||
}
|
||||
else
|
||||
{
|
||||
_last_error = "Failed to open SoundFont list: ";
|
||||
_last_error += sSoundFontName;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( sFileSoundFontName.length() )
|
||||
{
|
||||
if ( FLUID_FAILED == fluid_synth_sfload(_synth, sFileSoundFontName.c_str(), 1) )
|
||||
{
|
||||
shutdown();
|
||||
_last_error = "Failed to load SoundFont bank: ";
|
||||
_last_error += sFileSoundFontName;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_last_error = "";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SFPlayer::reset_drums()
|
||||
{
|
||||
static const uint8_t part_to_ch[16] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15 };
|
||||
|
||||
memset( drum_channels, 0, sizeof( drum_channels ) );
|
||||
drum_channels [9] = 1;
|
||||
drum_channels [9+16] = 1;
|
||||
drum_channels [9+32] = 1;
|
||||
|
||||
memcpy( gs_part_to_ch, part_to_ch, sizeof( gs_part_to_ch ) );
|
||||
memcpy( gs_part_to_ch+16, part_to_ch, sizeof( gs_part_to_ch ) );
|
||||
memcpy( gs_part_to_ch+32, part_to_ch, sizeof( gs_part_to_ch ) );
|
||||
|
||||
memset( channel_banks, 0, sizeof( channel_banks ) );
|
||||
|
||||
if ( _synth )
|
||||
{
|
||||
for ( unsigned i = 0; i < 48; ++i )
|
||||
{
|
||||
if ( drum_channels [i] )
|
||||
{
|
||||
fluid_synth_bank_select( _synth, i, 16256 /*DRUM_INST_BANK*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char * SFPlayer::GetLastError() const
|
||||
{
|
||||
if ( _last_error.length() ) return _last_error.c_str();
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// SFPlayer.h
|
||||
// MIDI
|
||||
//
|
||||
// Created by Christopher Snowhill on 5/3/21.
|
||||
// Copyright © 2021 Christopher Snowhill. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SFPlayer_h
|
||||
#define SFPlayer_h
|
||||
|
||||
#include "MIDIPlayer.h"
|
||||
|
||||
#include <fluidsynth.h>
|
||||
|
||||
class SFPlayer : public MIDIPlayer
|
||||
{
|
||||
public:
|
||||
// zero variables
|
||||
SFPlayer();
|
||||
|
||||
// close, unload
|
||||
virtual ~SFPlayer();
|
||||
|
||||
// configuration
|
||||
void setSoundFont( const char * in );
|
||||
void setFileSoundFont( const char * in );
|
||||
void setInterpolationMethod(unsigned method);
|
||||
|
||||
const char * GetLastError() const;
|
||||
|
||||
private:
|
||||
virtual void send_event(uint32_t b);
|
||||
virtual void render(float * out, unsigned long count);
|
||||
|
||||
virtual void shutdown();
|
||||
virtual bool startup();
|
||||
|
||||
std::string _last_error;
|
||||
|
||||
fluid_settings_t * _settings;
|
||||
fluid_synth_t * _synth;
|
||||
std::string sSoundFontName;
|
||||
std::string sFileSoundFontName;
|
||||
|
||||
unsigned uInterpolationMethod;
|
||||
|
||||
enum
|
||||
{
|
||||
mode_gm = 0,
|
||||
mode_gm2,
|
||||
mode_gs,
|
||||
mode_xg
|
||||
}
|
||||
synth_mode;
|
||||
|
||||
void reset_drums();
|
||||
uint8_t drum_channels[48];
|
||||
uint8_t gs_part_to_ch[48];
|
||||
unsigned short channel_banks[48];
|
||||
};
|
||||
|
||||
#endif /* SFPlayer_h */
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
- (IBAction)setSoundFont:(id)sender
|
||||
{
|
||||
NSArray *fileTypes = @[@"sf2", @"sf2pack", @"sflist", @"json"];
|
||||
NSArray *fileTypes = @[@"sf3", @"sf2", @"sflist"];
|
||||
NSOpenPanel * panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setCanChooseDirectories:NO];
|
||||
|
|
|
@ -74,7 +74,7 @@ static void enumCallback(void *context, OSType uSubType, OSType uManufacturer, c
|
|||
|
||||
[self addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"BASSMIDI", @"name", @"BASSMIDI", @"preference", nil]];
|
||||
@"FluidSynth", @"name", @"FluidSynth", @"preference", nil]];
|
||||
|
||||
[self addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,380 +0,0 @@
|
|||
/*
|
||||
BASSMIDI 2.4 C/C++ header file
|
||||
Copyright (c) 2006-2020 Un4seen Developments Ltd.
|
||||
|
||||
See the BASSMIDI.CHM file for more detailed documentation
|
||||
*/
|
||||
|
||||
#ifndef BASSMIDI_H
|
||||
#define BASSMIDI_H
|
||||
|
||||
#include "bass.h"
|
||||
|
||||
#if BASSVERSION!=0x204
|
||||
#error conflicting BASS and BASSMIDI versions
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef BASSMIDIDEF
|
||||
#define BASSMIDIDEF(f) WINAPI f
|
||||
#endif
|
||||
|
||||
typedef DWORD HSOUNDFONT; // soundfont handle
|
||||
|
||||
// Additional error codes returned by BASS_ErrorGetCode
|
||||
#define BASS_ERROR_MIDI_INCLUDE 7000 // SFZ include file could not be opened
|
||||
|
||||
// Additional BASS_SetConfig options
|
||||
#define BASS_CONFIG_MIDI_COMPACT 0x10400
|
||||
#define BASS_CONFIG_MIDI_VOICES 0x10401
|
||||
#define BASS_CONFIG_MIDI_AUTOFONT 0x10402
|
||||
#define BASS_CONFIG_MIDI_IN_PORTS 0x10404
|
||||
#define BASS_CONFIG_MIDI_SAMPLETHREADS 0x10406
|
||||
#define BASS_CONFIG_MIDI_SAMPLEMEM 0x10407
|
||||
#define BASS_CONFIG_MIDI_SAMPLEREAD 0x10408
|
||||
|
||||
// Additional BASS_SetConfigPtr options
|
||||
#define BASS_CONFIG_MIDI_DEFFONT 0x10403
|
||||
#define BASS_CONFIG_MIDI_SFZHEAD 0x10408
|
||||
|
||||
// Additional sync types
|
||||
#define BASS_SYNC_MIDI_MARK 0x10000
|
||||
#define BASS_SYNC_MIDI_MARKER 0x10000
|
||||
#define BASS_SYNC_MIDI_CUE 0x10001
|
||||
#define BASS_SYNC_MIDI_LYRIC 0x10002
|
||||
#define BASS_SYNC_MIDI_TEXT 0x10003
|
||||
#define BASS_SYNC_MIDI_EVENT 0x10004
|
||||
#define BASS_SYNC_MIDI_TICK 0x10005
|
||||
#define BASS_SYNC_MIDI_TIMESIG 0x10006
|
||||
#define BASS_SYNC_MIDI_KEYSIG 0x10007
|
||||
|
||||
// Additional BASS_MIDI_StreamCreateFile/etc flags
|
||||
#define BASS_MIDI_NOSYSRESET 0x800
|
||||
#define BASS_MIDI_DECAYEND 0x1000
|
||||
#define BASS_MIDI_NOFX 0x2000
|
||||
#define BASS_MIDI_DECAYSEEK 0x4000
|
||||
#define BASS_MIDI_NOCROP 0x8000
|
||||
#define BASS_MIDI_NOTEOFF1 0x10000
|
||||
#define BASS_MIDI_SINCINTER 0x800000
|
||||
|
||||
// BASS_MIDI_FontInit flags
|
||||
#define BASS_MIDI_FONT_MEM 0x10000
|
||||
#define BASS_MIDI_FONT_MMAP 0x20000
|
||||
#define BASS_MIDI_FONT_XGDRUMS 0x40000
|
||||
#define BASS_MIDI_FONT_NOFX 0x80000
|
||||
#define BASS_MIDI_FONT_LINATTMOD 0x100000
|
||||
#define BASS_MIDI_FONT_LINDECVOL 0x200000
|
||||
#define BASS_MIDI_FONT_NORAMPIN 0x400000
|
||||
#define BASS_MIDI_FONT_NOLIMITS 0x800000
|
||||
|
||||
typedef struct {
|
||||
HSOUNDFONT font; // soundfont
|
||||
int preset; // preset number (-1=all)
|
||||
int bank;
|
||||
} BASS_MIDI_FONT;
|
||||
|
||||
typedef struct {
|
||||
HSOUNDFONT font; // soundfont
|
||||
int spreset; // source preset number
|
||||
int sbank; // source bank number
|
||||
int dpreset; // destination preset/program number
|
||||
int dbank; // destination bank number
|
||||
int dbanklsb; // destination bank number LSB
|
||||
} BASS_MIDI_FONTEX;
|
||||
|
||||
// BASS_MIDI_StreamSet/GetFonts flag
|
||||
#define BASS_MIDI_FONT_EX 0x1000000 // BASS_MIDI_FONTEX
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *copyright;
|
||||
const char *comment;
|
||||
DWORD presets; // number of presets/instruments
|
||||
DWORD samsize; // total size (in bytes) of the sample data
|
||||
DWORD samload; // amount of sample data currently loaded
|
||||
DWORD samtype; // sample format (CTYPE) if packed
|
||||
} BASS_MIDI_FONTINFO;
|
||||
|
||||
typedef struct {
|
||||
DWORD track; // track containing marker
|
||||
DWORD pos; // marker position
|
||||
const char *text; // marker text
|
||||
} BASS_MIDI_MARK;
|
||||
|
||||
// Marker types
|
||||
#define BASS_MIDI_MARK_MARKER 0 // marker
|
||||
#define BASS_MIDI_MARK_CUE 1 // cue point
|
||||
#define BASS_MIDI_MARK_LYRIC 2 // lyric
|
||||
#define BASS_MIDI_MARK_TEXT 3 // text
|
||||
#define BASS_MIDI_MARK_TIMESIG 4 // time signature
|
||||
#define BASS_MIDI_MARK_KEYSIG 5 // key signature
|
||||
#define BASS_MIDI_MARK_COPY 6 // copyright notice
|
||||
#define BASS_MIDI_MARK_TRACK 7 // track name
|
||||
#define BASS_MIDI_MARK_INST 8 // instrument name
|
||||
#define BASS_MIDI_MARK_TRACKSTART 9 // track start (SMF2)
|
||||
#define BASS_MIDI_MARK_TICK 0x10000 // flag: get position in ticks (otherwise bytes)
|
||||
|
||||
// MIDI events
|
||||
#define MIDI_EVENT_NOTE 1
|
||||
#define MIDI_EVENT_PROGRAM 2
|
||||
#define MIDI_EVENT_CHANPRES 3
|
||||
#define MIDI_EVENT_PITCH 4
|
||||
#define MIDI_EVENT_PITCHRANGE 5
|
||||
#define MIDI_EVENT_DRUMS 6
|
||||
#define MIDI_EVENT_FINETUNE 7
|
||||
#define MIDI_EVENT_COARSETUNE 8
|
||||
#define MIDI_EVENT_MASTERVOL 9
|
||||
#define MIDI_EVENT_BANK 10
|
||||
#define MIDI_EVENT_MODULATION 11
|
||||
#define MIDI_EVENT_VOLUME 12
|
||||
#define MIDI_EVENT_PAN 13
|
||||
#define MIDI_EVENT_EXPRESSION 14
|
||||
#define MIDI_EVENT_SUSTAIN 15
|
||||
#define MIDI_EVENT_SOUNDOFF 16
|
||||
#define MIDI_EVENT_RESET 17
|
||||
#define MIDI_EVENT_NOTESOFF 18
|
||||
#define MIDI_EVENT_PORTAMENTO 19
|
||||
#define MIDI_EVENT_PORTATIME 20
|
||||
#define MIDI_EVENT_PORTANOTE 21
|
||||
#define MIDI_EVENT_MODE 22
|
||||
#define MIDI_EVENT_REVERB 23
|
||||
#define MIDI_EVENT_CHORUS 24
|
||||
#define MIDI_EVENT_CUTOFF 25
|
||||
#define MIDI_EVENT_RESONANCE 26
|
||||
#define MIDI_EVENT_RELEASE 27
|
||||
#define MIDI_EVENT_ATTACK 28
|
||||
#define MIDI_EVENT_DECAY 29
|
||||
#define MIDI_EVENT_REVERB_MACRO 30
|
||||
#define MIDI_EVENT_CHORUS_MACRO 31
|
||||
#define MIDI_EVENT_REVERB_TIME 32
|
||||
#define MIDI_EVENT_REVERB_DELAY 33
|
||||
#define MIDI_EVENT_REVERB_LOCUTOFF 34
|
||||
#define MIDI_EVENT_REVERB_HICUTOFF 35
|
||||
#define MIDI_EVENT_REVERB_LEVEL 36
|
||||
#define MIDI_EVENT_CHORUS_DELAY 37
|
||||
#define MIDI_EVENT_CHORUS_DEPTH 38
|
||||
#define MIDI_EVENT_CHORUS_RATE 39
|
||||
#define MIDI_EVENT_CHORUS_FEEDBACK 40
|
||||
#define MIDI_EVENT_CHORUS_LEVEL 41
|
||||
#define MIDI_EVENT_CHORUS_REVERB 42
|
||||
#define MIDI_EVENT_USERFX 43
|
||||
#define MIDI_EVENT_USERFX_LEVEL 44
|
||||
#define MIDI_EVENT_USERFX_REVERB 45
|
||||
#define MIDI_EVENT_USERFX_CHORUS 46
|
||||
#define MIDI_EVENT_DRUM_FINETUNE 50
|
||||
#define MIDI_EVENT_DRUM_COARSETUNE 51
|
||||
#define MIDI_EVENT_DRUM_PAN 52
|
||||
#define MIDI_EVENT_DRUM_REVERB 53
|
||||
#define MIDI_EVENT_DRUM_CHORUS 54
|
||||
#define MIDI_EVENT_DRUM_CUTOFF 55
|
||||
#define MIDI_EVENT_DRUM_RESONANCE 56
|
||||
#define MIDI_EVENT_DRUM_LEVEL 57
|
||||
#define MIDI_EVENT_DRUM_USERFX 58
|
||||
#define MIDI_EVENT_SOFT 60
|
||||
#define MIDI_EVENT_SYSTEM 61
|
||||
#define MIDI_EVENT_TEMPO 62
|
||||
#define MIDI_EVENT_SCALETUNING 63
|
||||
#define MIDI_EVENT_CONTROL 64
|
||||
#define MIDI_EVENT_CHANPRES_VIBRATO 65
|
||||
#define MIDI_EVENT_CHANPRES_PITCH 66
|
||||
#define MIDI_EVENT_CHANPRES_FILTER 67
|
||||
#define MIDI_EVENT_CHANPRES_VOLUME 68
|
||||
#define MIDI_EVENT_MOD_VIBRATO 69
|
||||
#define MIDI_EVENT_MODRANGE 69
|
||||
#define MIDI_EVENT_BANK_LSB 70
|
||||
#define MIDI_EVENT_KEYPRES 71
|
||||
#define MIDI_EVENT_KEYPRES_VIBRATO 72
|
||||
#define MIDI_EVENT_KEYPRES_PITCH 73
|
||||
#define MIDI_EVENT_KEYPRES_FILTER 74
|
||||
#define MIDI_EVENT_KEYPRES_VOLUME 75
|
||||
#define MIDI_EVENT_SOSTENUTO 76
|
||||
#define MIDI_EVENT_MOD_PITCH 77
|
||||
#define MIDI_EVENT_MOD_FILTER 78
|
||||
#define MIDI_EVENT_MOD_VOLUME 79
|
||||
#define MIDI_EVENT_VIBRATO_RATE 80
|
||||
#define MIDI_EVENT_VIBRATO_DEPTH 81
|
||||
#define MIDI_EVENT_VIBRATO_DELAY 82
|
||||
#define MIDI_EVENT_MIXLEVEL 0x10000
|
||||
#define MIDI_EVENT_TRANSPOSE 0x10001
|
||||
#define MIDI_EVENT_SYSTEMEX 0x10002
|
||||
#define MIDI_EVENT_SPEED 0x10004
|
||||
|
||||
#define MIDI_EVENT_END 0
|
||||
#define MIDI_EVENT_END_TRACK 0x10003
|
||||
|
||||
#define MIDI_EVENT_NOTES 0x20000
|
||||
#define MIDI_EVENT_VOICES 0x20001
|
||||
|
||||
#define MIDI_SYSTEM_DEFAULT 0
|
||||
#define MIDI_SYSTEM_GM1 1
|
||||
#define MIDI_SYSTEM_GM2 2
|
||||
#define MIDI_SYSTEM_XG 3
|
||||
#define MIDI_SYSTEM_GS 4
|
||||
|
||||
typedef struct {
|
||||
DWORD event; // MIDI_EVENT_xxx
|
||||
DWORD param;
|
||||
DWORD chan;
|
||||
DWORD tick; // event position (ticks)
|
||||
DWORD pos; // event position (bytes)
|
||||
} BASS_MIDI_EVENT;
|
||||
|
||||
// BASS_MIDI_StreamEvents modes
|
||||
#define BASS_MIDI_EVENTS_STRUCT 0 // BASS_MIDI_EVENT structures
|
||||
#define BASS_MIDI_EVENTS_RAW 0x10000 // raw MIDI event data
|
||||
#define BASS_MIDI_EVENTS_SYNC 0x1000000 // flag: trigger event syncs
|
||||
#define BASS_MIDI_EVENTS_NORSTATUS 0x2000000 // flag: no running status
|
||||
#define BASS_MIDI_EVENTS_CANCEL 0x4000000 // flag: cancel pending events
|
||||
#define BASS_MIDI_EVENTS_TIME 0x8000000 // flag: delta-time info is present
|
||||
#define BASS_MIDI_EVENTS_ABSTIME 0x10000000 // flag: absolute time info is present
|
||||
|
||||
// BASS_MIDI_StreamGetChannel special channels
|
||||
#define BASS_MIDI_CHAN_CHORUS (DWORD)-1
|
||||
#define BASS_MIDI_CHAN_REVERB (DWORD)-2
|
||||
#define BASS_MIDI_CHAN_USERFX (DWORD)-3
|
||||
|
||||
// BASS_CHANNELINFO type
|
||||
#define BASS_CTYPE_STREAM_MIDI 0x10d00
|
||||
|
||||
// Additional attributes
|
||||
#define BASS_ATTRIB_MIDI_PPQN 0x12000
|
||||
#define BASS_ATTRIB_MIDI_CPU 0x12001
|
||||
#define BASS_ATTRIB_MIDI_CHANS 0x12002
|
||||
#define BASS_ATTRIB_MIDI_VOICES 0x12003
|
||||
#define BASS_ATTRIB_MIDI_VOICES_ACTIVE 0x12004
|
||||
#define BASS_ATTRIB_MIDI_STATE 0x12005
|
||||
#define BASS_ATTRIB_MIDI_SRC 0x12006
|
||||
#define BASS_ATTRIB_MIDI_KILL 0x12007
|
||||
#define BASS_ATTRIB_MIDI_SPEED 0x12008
|
||||
#define BASS_ATTRIB_MIDI_REVERB 0x12009
|
||||
#define BASS_ATTRIB_MIDI_VOL 0x1200a
|
||||
#define BASS_ATTRIB_MIDI_TRACK_VOL 0x12100 // + track #
|
||||
|
||||
// Additional tag type
|
||||
#define BASS_TAG_MIDI_TRACK 0x11000 // + track #, track text : array of null-terminated ANSI strings
|
||||
|
||||
// BASS_ChannelGetLength/GetPosition/SetPosition mode
|
||||
#define BASS_POS_MIDI_TICK 2 // tick position
|
||||
|
||||
typedef BOOL (CALLBACK MIDIFILTERPROC)(HSTREAM handle, DWORD track, BASS_MIDI_EVENT *event, BOOL seeking, void *user);
|
||||
/* Event filtering callback function.
|
||||
handle : MIDI stream handle
|
||||
track : Track containing the event
|
||||
event : The event
|
||||
seeking: TRUE = the event is being processed while seeking, FALSE = it is being played
|
||||
user : The 'user' parameter value given when calling BASS_MIDI_StreamSetFilter
|
||||
RETURN : TRUE = process the event, FALSE = drop the event */
|
||||
|
||||
// BASS_MIDI_FontLoadEx flags
|
||||
#define BASS_MIDI_FONTLOAD_NOWAIT 1 // don't want for the samples to load
|
||||
#define BASS_MIDI_FONTLOAD_COMPACT 2 // compact samples
|
||||
#define BASS_MIDI_FONTLOAD_NOLOAD 4 // don't load (only compact)
|
||||
#define BASS_MIDI_FONTLOAD_TIME 8 // length is in milliseconds
|
||||
#define BASS_MIDI_FONTLOAD_KEEPDEC 16 // keep decoders
|
||||
|
||||
// BASS_MIDI_FontPack flags
|
||||
#define BASS_MIDI_PACK_NOHEAD 1 // don't send a WAV header to the encoder
|
||||
#define BASS_MIDI_PACK_16BIT 2 // discard low 8 bits of 24-bit sample data
|
||||
#define BASS_MIDI_PACK_48KHZ 4 // set encoding rate to 48000 Hz (else 44100 Hz)
|
||||
|
||||
typedef struct {
|
||||
const char *name; // description
|
||||
DWORD id;
|
||||
DWORD flags;
|
||||
} BASS_MIDI_DEVICEINFO;
|
||||
|
||||
typedef void (CALLBACK MIDIINPROC)(DWORD device, double time, const BYTE *buffer, DWORD length, void *user);
|
||||
/* MIDI input callback function.
|
||||
device : MIDI input device
|
||||
time : Timestamp
|
||||
buffer : Buffer containing MIDI data
|
||||
length : Number of bytes of data
|
||||
user : The 'user' parameter value given when calling BASS_MIDI_InInit */
|
||||
|
||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreate)(DWORD channels, DWORD flags, DWORD freq);
|
||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags, DWORD freq);
|
||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq);
|
||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user, DWORD freq);
|
||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateEvents)(const BASS_MIDI_EVENT *events, DWORD ppqn, DWORD flags, DWORD freq);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamGetMark)(HSTREAM handle, DWORD type, DWORD index, BASS_MIDI_MARK *mark);
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetMarks)(HSTREAM handle, int track, DWORD type, BASS_MIDI_MARK *marks);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFonts)(HSTREAM handle, const void *fonts, DWORD count);
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetFonts)(HSTREAM handle, void *fonts, DWORD count);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamLoadSamples)(HSTREAM handle);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamEvent)(HSTREAM handle, DWORD chan, DWORD event, DWORD param);
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamEvents)(HSTREAM handle, DWORD mode, const void *events, DWORD length);
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvent)(HSTREAM handle, DWORD chan, DWORD event);
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvents)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events);
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEventsEx)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events, DWORD start, DWORD count);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamGetPreset)(HSTREAM handle, DWORD chan, BASS_MIDI_FONT *font);
|
||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamGetChannel)(HSTREAM handle, DWORD chan);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFilter)(HSTREAM handle, BOOL seeking, MIDIFILTERPROC *proc, void *user);
|
||||
|
||||
HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInit)(const void *file, DWORD flags);
|
||||
HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInitUser)(const BASS_FILEPROCS *procs, void *user, DWORD flags);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontFree)(HSOUNDFONT handle);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontGetInfo)(HSOUNDFONT handle, BASS_MIDI_FONTINFO *info);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontGetPresets)(HSOUNDFONT handle, DWORD *presets);
|
||||
const char *BASSMIDIDEF(BASS_MIDI_FontGetPreset)(HSOUNDFONT handle, int preset, int bank);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontLoad)(HSOUNDFONT handle, int preset, int bank);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontLoadEx)(HSOUNDFONT handle, int preset, int bank, DWORD length, DWORD flags);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontUnload)(HSOUNDFONT handle, int preset, int bank);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontCompact)(HSOUNDFONT handle);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontPack)(HSOUNDFONT handle, const void *outfile, const void *encoder, DWORD flags);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontUnpack)(HSOUNDFONT handle, const void *outfile, DWORD flags);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontSetVolume)(HSOUNDFONT handle, float volume);
|
||||
float BASSMIDIDEF(BASS_MIDI_FontGetVolume)(HSOUNDFONT handle);
|
||||
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_ConvertEvents)(const BYTE *data, DWORD length, BASS_MIDI_EVENT *events, DWORD count, DWORD flags);
|
||||
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_InGetDeviceInfo)(DWORD device, BASS_MIDI_DEVICEINFO *info);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_InInit)(DWORD device, MIDIINPROC *proc, void *user);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_InFree)(DWORD device);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_InStart)(DWORD device);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_InStop)(DWORD device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX *fonts, DWORD count)
|
||||
{
|
||||
return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count|BASS_MIDI_FONT_EX);
|
||||
}
|
||||
|
||||
static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX *fonts, DWORD count)
|
||||
{
|
||||
return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count|BASS_MIDI_FONT_EX);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static inline HSTREAM BASS_MIDI_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags, DWORD freq)
|
||||
{
|
||||
return BASS_MIDI_StreamCreateFile(mem, (const void*)file, offset, length, flags|BASS_UNICODE, freq);
|
||||
}
|
||||
|
||||
static inline HSTREAM BASS_MIDI_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq)
|
||||
{
|
||||
return BASS_MIDI_StreamCreateURL((const char*)url, offset, flags|BASS_UNICODE, proc, user, freq);
|
||||
}
|
||||
|
||||
static inline HSOUNDFONT BASS_MIDI_FontInit(const WCHAR *file, DWORD flags)
|
||||
{
|
||||
return BASS_MIDI_FontInit((const void*)file, flags|BASS_UNICODE);
|
||||
}
|
||||
|
||||
static inline BOOL BASS_MIDI_FontPack(HSOUNDFONT handle, const WCHAR *outfile, const WCHAR *encoder, DWORD flags)
|
||||
{
|
||||
return BASS_MIDI_FontPack(handle, (const void*)outfile, (const void*)encoder, flags|BASS_UNICODE);
|
||||
}
|
||||
|
||||
static inline BOOL BASS_MIDI_FontUnpack(HSOUNDFONT handle, const WCHAR *outfile, DWORD flags)
|
||||
{
|
||||
return BASS_MIDI_FontUnpack(handle, (const void*)outfile, flags|BASS_UNICODE);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,917 +0,0 @@
|
|||
/* vim: set et ts=3 sw=3 sts=3 ft=c:
|
||||
*
|
||||
* Copyright (C) 2021 Christopher Snowhill. All rights reserved.
|
||||
* https://github.com/kode54/sflist
|
||||
* https://gist.github.com/kode54/a7bb01a0db3f2e996145b77f0ca510d5
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <json-builder.h>
|
||||
|
||||
#include "sflist.h"
|
||||
|
||||
#ifndef PRId64
|
||||
#ifdef _MSC_VER
|
||||
#define PRId64 "I64d"
|
||||
#else
|
||||
#define PRId64 "lld"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Extras needed */
|
||||
|
||||
static int json_equal (const json_value * a, const json_value * b);
|
||||
|
||||
static int json_equal_array(const json_value * a, const json_value * b)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
if (a->u.array.length != b->u.array.length) return 0;
|
||||
|
||||
for (i = 0, j = a->u.array.length; i < j; ++i)
|
||||
{
|
||||
if (!json_equal(a->u.array.values[i], b->u.array.values[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int json_equal_object(const json_value * a, const json_value * b)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
if (a->u.object.length != b->u.object.length) return 0;
|
||||
|
||||
for (i = 0, j = a->u.object.length; i < j; ++i)
|
||||
{
|
||||
if (strcmp(a->u.object.values[i].name, b->u.object.values[i].name))
|
||||
return 0;
|
||||
if (!json_equal(a->u.object.values[i].value, b->u.object.values[i].value))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int json_equal (const json_value * a, const json_value * b)
|
||||
{
|
||||
if (a->type != b->type) return 0;
|
||||
|
||||
switch (a->type)
|
||||
{
|
||||
case json_none:
|
||||
case json_null:
|
||||
return 1;
|
||||
|
||||
case json_integer:
|
||||
return a->u.integer == b->u.integer;
|
||||
|
||||
case json_double:
|
||||
return a->u.dbl == b->u.dbl;
|
||||
|
||||
case json_boolean:
|
||||
return !a->u.boolean == !b->u.boolean;
|
||||
|
||||
case json_string:
|
||||
return !strcmp(a->u.string.ptr, b->u.string.ptr);
|
||||
|
||||
case json_array:
|
||||
return json_equal_array(a, b);
|
||||
|
||||
case json_object:
|
||||
return json_equal_object(a, b);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int json_signum (double val)
|
||||
{
|
||||
return (val > 0.0) - (val < 0.0);
|
||||
}
|
||||
|
||||
#define json_compare_invalid -1000
|
||||
|
||||
static int json_compare (const json_value * a, const json_value * b)
|
||||
{
|
||||
if (a->type != b->type) return json_compare_invalid;
|
||||
|
||||
switch (a->type)
|
||||
{
|
||||
case json_none:
|
||||
case json_null:
|
||||
return 0;
|
||||
|
||||
case json_integer:
|
||||
return (int)(a->u.integer - b->u.integer);
|
||||
|
||||
case json_double:
|
||||
return json_signum(a->u.dbl - b->u.dbl);
|
||||
|
||||
case json_boolean:
|
||||
return !!a->u.boolean - !!b->u.boolean;
|
||||
|
||||
case json_string:
|
||||
return strcmp(a->u.string.ptr, b->u.string.ptr);
|
||||
|
||||
case json_array:
|
||||
case json_object:
|
||||
return json_compare_invalid;
|
||||
}
|
||||
|
||||
return json_compare_invalid;
|
||||
}
|
||||
|
||||
static int json_array_contains_value (const json_value * array, const json_value * value)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = array->u.array.length; i < j; ++i)
|
||||
{
|
||||
if (json_equal(array->u.array.values[i], value))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
json_value * json_array_merge (json_value * arrayA, json_value * arrayB)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
if (arrayA->type != json_array || arrayB->type != json_array)
|
||||
return 0;
|
||||
|
||||
for (i = 0, j = arrayB->u.array.length; i < j; ++i)
|
||||
{
|
||||
if (!json_array_contains_value(arrayA, arrayB->u.array.values[i]))
|
||||
{
|
||||
json_array_push(arrayA, arrayB->u.array.values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
json_builder_free(arrayB);
|
||||
|
||||
return arrayA;
|
||||
}
|
||||
|
||||
static int json_compare_callback (const void * a, const void * b)
|
||||
{
|
||||
const json_value * aa = (const json_value *) a;
|
||||
const json_value * bb = (const json_value *) b;
|
||||
return json_compare(aa, bb);
|
||||
}
|
||||
|
||||
json_value * json_array_sort (json_value * array)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
json_type type;
|
||||
|
||||
if (array->type != json_array) return 0;
|
||||
|
||||
if (array->u.array.length < 2) return array;
|
||||
|
||||
type = array->u.array.values[0]->type;
|
||||
|
||||
for (i = 1, j = array->u.array.length; i < j; ++i)
|
||||
{
|
||||
if (array->u.array.values[i]->type != type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
qsort(array->u.array.values, j, sizeof(json_value *), json_compare_callback);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/* Processing begins */
|
||||
|
||||
static size_t sflist_parse_int(const char * in, const char ** end)
|
||||
{
|
||||
size_t rval = 0;
|
||||
while (in < *end) {
|
||||
if (isdigit(*in)) {
|
||||
rval = (rval * 10) + (*in - '0');
|
||||
}
|
||||
else break;
|
||||
++in;
|
||||
}
|
||||
*end = in;
|
||||
return rval;
|
||||
}
|
||||
|
||||
static double sflist_parse_float(const char * in, const char ** end)
|
||||
{
|
||||
size_t whole = 0;
|
||||
size_t decimal = 0;
|
||||
size_t decimal_places = 0;
|
||||
double sign = 1.0;
|
||||
const char * end_orig = *end;
|
||||
const char * ptr = in;
|
||||
if (*ptr == '-') {
|
||||
++ptr;
|
||||
sign = -1.0;
|
||||
}
|
||||
whole = sflist_parse_int(ptr, end);
|
||||
if (*end == ptr || (**end != '.' && *end < end_orig)) {
|
||||
*end = in;
|
||||
return 0.0;
|
||||
}
|
||||
if (*end < end_orig) {
|
||||
ptr = *end + 1;
|
||||
*end = end_orig;
|
||||
decimal = sflist_parse_int(ptr, end);
|
||||
if (*end == ptr || *end < end_orig) {
|
||||
*end = in;
|
||||
return 0.0;
|
||||
}
|
||||
decimal_places = *end - ptr;
|
||||
}
|
||||
return (((double)whole) + (((double)decimal) / pow(10.0, (double)decimal_places))) * sign;
|
||||
}
|
||||
|
||||
static json_value * sflist_load_v1(const char * sflist, size_t size, char * error_buf)
|
||||
{
|
||||
json_value * rval = 0;
|
||||
|
||||
json_value * arr = json_array_new(0);
|
||||
|
||||
json_value * channels = 0;
|
||||
json_value * patchMappings = 0;
|
||||
double gain = 0.0;
|
||||
|
||||
const char * ptr = sflist;
|
||||
const char * end = sflist + size;
|
||||
|
||||
unsigned int cur_line = 0;
|
||||
|
||||
while (ptr < end) {
|
||||
const char * line_start = ptr;
|
||||
json_value * obj = 0;
|
||||
const char * path = 0;
|
||||
const char * pipe = 0;
|
||||
const char * lend = ptr;
|
||||
++cur_line;
|
||||
while (lend < end && *lend && *lend != '\r' && *lend != '\n') {
|
||||
if (*lend == '|')
|
||||
pipe = lend;
|
||||
++lend;
|
||||
}
|
||||
if (pipe)
|
||||
path = pipe + 1;
|
||||
else
|
||||
path = ptr;
|
||||
if (pipe) {
|
||||
while (ptr < pipe) {
|
||||
char c;
|
||||
const char * fend = ptr;
|
||||
const char * vend;
|
||||
while (fend < pipe && *fend != '&') ++fend;
|
||||
vend = fend;
|
||||
switch (c = *ptr++) {
|
||||
case '&':
|
||||
continue;
|
||||
|
||||
case 'c': {
|
||||
json_value * this_channels;
|
||||
size_t channel_low = sflist_parse_int(ptr, &vend);
|
||||
size_t channel_high = 0;
|
||||
size_t i;
|
||||
if (vend == ptr || (*vend != '-' && *vend != '&' && *vend != '|')) {
|
||||
sprintf(error_buf, "Invalid channel number (%u:%u)", cur_line, (int)(vend - line_start + 1));
|
||||
goto error;
|
||||
}
|
||||
if (*vend != '-')
|
||||
channel_high = channel_low;
|
||||
else {
|
||||
ptr = vend + 1;
|
||||
vend = fend;
|
||||
channel_high = sflist_parse_int(ptr, &vend);
|
||||
if (vend == ptr || (*vend != '&' && *vend != '|')) {
|
||||
sprintf(error_buf, "Invalid channel range end value (%u:%u)", cur_line, (int)(vend - line_start + 1));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (!channels)
|
||||
channels = json_array_new(0);
|
||||
this_channels = json_array_new(0);
|
||||
for (i = channel_low; i <= channel_high; ++i)
|
||||
json_array_push(this_channels, json_integer_new(i));
|
||||
channels = json_array_merge(channels, this_channels);
|
||||
ptr = fend;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p': {
|
||||
json_value * mapping = 0;
|
||||
json_value * mapping_destination = 0;
|
||||
json_value * mapping_source = 0;
|
||||
|
||||
long source_bank = -1;
|
||||
long source_program = -1;
|
||||
long dest_bank = -1;
|
||||
long dest_program = -1;
|
||||
|
||||
size_t val = sflist_parse_int(ptr, &vend);
|
||||
if (vend == ptr || (*vend != '=' && *vend != ',' && *vend != '|')) {
|
||||
sprintf(error_buf, "Invalid preset number (%u:%u)", cur_line, (int)(vend - line_start + 1));
|
||||
goto error;
|
||||
}
|
||||
dest_program = val;
|
||||
if (*vend == ',') {
|
||||
dest_bank = val;
|
||||
ptr = vend + 1;
|
||||
vend = fend;
|
||||
val = sflist_parse_int(ptr, &vend);
|
||||
if (vend == ptr || (*vend != '=' && *vend != '|')) {
|
||||
sprintf(error_buf, "Invalid preset number (%u:%u)", cur_line, (int)(vend - line_start + 1));
|
||||
goto error;
|
||||
}
|
||||
dest_program = val;
|
||||
}
|
||||
if (*vend == '=') {
|
||||
ptr = vend + 1;
|
||||
vend = fend;
|
||||
val = sflist_parse_int(ptr, &vend);
|
||||
if (vend == ptr || (*vend != ',' && *vend != '|')) {
|
||||
sprintf(error_buf, "Invalid preset number (%u:%u)", cur_line, (int)(vend - line_start + 1));
|
||||
goto error;
|
||||
}
|
||||
source_program = val;
|
||||
if (*vend == ',') {
|
||||
source_bank = val;
|
||||
ptr = vend + 1;
|
||||
vend = fend;
|
||||
val = sflist_parse_int(ptr, &vend);
|
||||
if (vend == ptr || (*vend != '&' && *vend != '|')) {
|
||||
sprintf(error_buf, "Invalid preset number (%u:%u)", cur_line, (int)(vend - line_start + 1));
|
||||
goto error;
|
||||
}
|
||||
source_program = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (!patchMappings)
|
||||
patchMappings = json_array_new(0);
|
||||
mapping = json_object_new(0);
|
||||
mapping_destination = json_object_new(0);
|
||||
if (dest_bank != -1) {
|
||||
json_object_push(mapping_destination, "bank", json_integer_new(dest_bank));
|
||||
}
|
||||
json_object_push(mapping_destination, "program", json_integer_new(dest_program));
|
||||
json_object_push(mapping, "destination", mapping_destination);
|
||||
if (source_program != -1) {
|
||||
mapping_source = json_object_new(0);
|
||||
if (source_bank != -1) {
|
||||
json_object_push(mapping_source, "bank", json_integer_new(source_bank));
|
||||
}
|
||||
json_object_push(mapping_source, "program", json_integer_new(source_program));
|
||||
json_object_push(mapping, "source", mapping_source);
|
||||
}
|
||||
json_array_push(patchMappings, mapping);
|
||||
|
||||
ptr = fend;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g': {
|
||||
double val = sflist_parse_float(ptr, &vend);
|
||||
if (vend == ptr || vend < fend) {
|
||||
sprintf(error_buf, "Invalid gain value (%u:%u)", cur_line, (int)(vend - line_start + 1));
|
||||
goto error;
|
||||
}
|
||||
gain = val;
|
||||
ptr = fend;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(error_buf, "Invalid character in preset '%c' (%u:%u)", c, cur_line, (unsigned int)(ptr - line_start));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = json_object_new(0);
|
||||
json_object_push(obj, "fileName", json_string_new_length((unsigned int)(lend - path), path));
|
||||
if (gain != 0.0) {
|
||||
json_object_push(obj, "gain", json_double_new(gain));
|
||||
gain = 0.0;
|
||||
}
|
||||
if (channels) {
|
||||
channels = json_array_sort(channels);
|
||||
json_object_push(obj, "channels", channels);
|
||||
channels = 0;
|
||||
}
|
||||
if (patchMappings) {
|
||||
json_object_push(obj, "patchMappings", patchMappings);
|
||||
patchMappings = 0;
|
||||
}
|
||||
|
||||
json_array_push(arr, obj);
|
||||
|
||||
ptr = lend;
|
||||
|
||||
while (ptr < end && (*ptr == '\n' || *ptr == '\r')) ++ptr;
|
||||
}
|
||||
|
||||
rval = json_object_new(1);
|
||||
json_object_push(rval, "soundFonts", arr);
|
||||
|
||||
return rval;
|
||||
|
||||
error:
|
||||
if (channels) json_builder_free(channels);
|
||||
if (patchMappings) json_builder_free(patchMappings);
|
||||
if (arr) json_builder_free(arr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static json_value * sflist_load_v2(const char * sflist, size_t size, char * error)
|
||||
{
|
||||
json_value * rval = 0;
|
||||
|
||||
json_settings settings = { 0 };
|
||||
settings.value_extra = json_builder_extra;
|
||||
|
||||
rval = json_parse_ex( &settings, sflist, size, error);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static const json_value * json_object_item(const json_value * object, const char * name)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
if (object->type != json_object) return &json_value_none;
|
||||
|
||||
for (i = 0, j = object->u.object.length; i < j; ++i) {
|
||||
if (!strcmp(object->u.object.values[i].name, name))
|
||||
return object->u.object.values[i].value;
|
||||
}
|
||||
|
||||
return &json_value_none;
|
||||
}
|
||||
|
||||
static void sflist_process_patchmappings(BASS_MIDI_FONTEX * out, BASS_MIDI_FONTEX * fontex, const json_value * patchMappings, unsigned int channel)
|
||||
{
|
||||
unsigned int i, j;
|
||||
for (i = 0, j = patchMappings->u.array.length; i < j; ++i) {
|
||||
json_value * preset = patchMappings->u.array.values[i];
|
||||
const json_value * destination = json_object_item(preset, "destination");
|
||||
const json_value * source = json_object_item(preset, "source");
|
||||
const json_value * destination_bank = json_object_item(destination, "bank");
|
||||
const json_value * destination_program = json_object_item(destination, "program");
|
||||
const json_value * source_bank = json_object_item(source, "bank");
|
||||
const json_value * source_program = json_object_item(source, "program");
|
||||
fontex->spreset = (source_program->type == json_none) ? -1 : (int)source_program->u.integer;
|
||||
fontex->sbank = (source_bank->type == json_none) ? -1 : (int)source_bank->u.integer;
|
||||
fontex->dpreset = (destination_program->type == json_none) ? -1 : (int)destination_program->u.integer;
|
||||
fontex->dbank = (destination_bank->type == json_none) ? 0 : (int)destination_bank->u.integer;
|
||||
fontex->dbanklsb = channel;
|
||||
*out++ = *fontex;
|
||||
}
|
||||
}
|
||||
|
||||
static sflist_presets * sflist_process(const json_value * sflist, const char * base_path, char * error_buf)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
wchar_t path16[32768];
|
||||
#endif
|
||||
char path_temp[32768];
|
||||
const char * base_path_end = base_path + strlen(base_path) - 1;
|
||||
unsigned int presets_to_allocate = 0;
|
||||
sflist_presets * rval = calloc(1, sizeof(sflist_presets));
|
||||
json_value * arr;
|
||||
unsigned int i, j, k, l, preset_number;
|
||||
HSOUNDFONT hfont = 0;
|
||||
BASS_MIDI_FONTEX fontex;
|
||||
|
||||
if (!rval)
|
||||
{
|
||||
strcpy(error_buf, "Out of memory");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sflist->type != json_object || sflist->u.object.length != 1 ||
|
||||
strcmp(sflist->u.object.values[0].name, "soundFonts"))
|
||||
{
|
||||
if (sflist->type != json_object)
|
||||
strcpy(error_buf, "Base JSON item is not an object");
|
||||
else if (sflist->u.object.length != 1)
|
||||
sprintf(error_buf, "Base JSON object contains unexpected number of items (wanted 1, got %u)", sflist->u.object.length);
|
||||
else
|
||||
sprintf(error_buf, "Base JSON object contains '%s' object instead of 'soundFonts'", sflist->u.object.values[0].name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
arr = sflist->u.object.values[0].value;
|
||||
|
||||
if (arr->type != json_array)
|
||||
{
|
||||
strcpy(error_buf, "JSON 'soundFonts' object is not an array");
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0, j = arr->u.array.length; i < j; ++i) {
|
||||
const json_value * obj = arr->u.array.values[i];
|
||||
const json_value * path = 0;
|
||||
const json_value * gain = 0;
|
||||
const json_value * channels = 0;
|
||||
const json_value * patchMappings = 0;
|
||||
unsigned int patches_needed = 1;
|
||||
if (obj->type != json_object) {
|
||||
sprintf(error_buf, "soundFont item #%u is not an object", i + 1);
|
||||
goto error;
|
||||
}
|
||||
path = json_object_item(obj, "fileName");
|
||||
gain = json_object_item(obj, "gain");
|
||||
channels = json_object_item(obj, "channels");
|
||||
patchMappings = json_object_item(obj, "patchMappings");
|
||||
if (path->type == json_none) {
|
||||
sprintf(error_buf, "soundFont item #%u has no 'fileName'", i + 1);
|
||||
goto error;
|
||||
}
|
||||
if (path->type != json_string) {
|
||||
sprintf(error_buf, "soundFont item #%u 'fileName' is not a string", i + 1);
|
||||
goto error;
|
||||
}
|
||||
if (gain->type != json_none && gain->type != json_integer && gain->type != json_double) {
|
||||
sprintf(error_buf, "soundFont item #%u has an invalid gain value", i + 1);
|
||||
goto error;
|
||||
}
|
||||
if (channels->type != json_none) {
|
||||
if (channels->type != json_array) {
|
||||
sprintf(error_buf, "soundFont item #%u 'channels' is not an array", i + 1);
|
||||
goto error;
|
||||
}
|
||||
for (k = 0, l = channels->u.array.length; k < l; ++k) {
|
||||
json_value * channel = channels->u.array.values[k];
|
||||
if (channel->type != json_integer) {
|
||||
sprintf(error_buf, "soundFont item #%u 'channels' #%u is not an integer", i + 1, k + 1);
|
||||
goto error;
|
||||
}
|
||||
if (channel->u.integer < 1 || channel->u.integer > 48) {
|
||||
sprintf(error_buf, "soundFont item #%u 'channels' #%u is out of range (wanted 1-48, got %" PRId64 ")", i + 1, k + 1, channel->u.integer);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
patches_needed = l;
|
||||
}
|
||||
if (patchMappings->type != json_none) {
|
||||
if (patchMappings->type != json_array) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' is not an array", i + 1);
|
||||
goto error;
|
||||
}
|
||||
for (k = 0, l = patchMappings->u.array.length; k < l; ++k) {
|
||||
unsigned int m, n;
|
||||
unsigned int source_found = 0;
|
||||
unsigned int destination_found = 0;
|
||||
json_value * mapping = patchMappings->u.array.values[k];
|
||||
if (mapping->type != json_object) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u is not an object", i + 1, k + 1);
|
||||
goto error;
|
||||
}
|
||||
for (m = 0, n = mapping->u.object.length; m < n; ++m) {
|
||||
unsigned int o, p;
|
||||
json_value * item = mapping->u.object.values[m].value;
|
||||
const char * name = mapping->u.object.values[m].name;
|
||||
unsigned int bank_found = 0;
|
||||
unsigned int program_found = 0;
|
||||
if (strcmp(name, "source") && strcmp(name, "destination")) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u contains an invalid '%s' field", i + 1, k + 1, name);
|
||||
goto error;
|
||||
}
|
||||
if (item->type != json_object) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u '%s' is not an object", i + 1, k + 1, name);
|
||||
goto error;
|
||||
}
|
||||
if (!strcmp(name, "source"))
|
||||
++source_found;
|
||||
else
|
||||
++destination_found;
|
||||
for (o = 0, p = item->u.object.length; o < p; ++o) {
|
||||
int range_min = 0;
|
||||
int range_max = 128;
|
||||
json_value * item2 = item->u.object.values[o].value;
|
||||
const char * name2 = item->u.object.values[o].name;
|
||||
if (strcmp(name2, "bank") && strcmp(name2, "program")) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u '%s' contains an invalid '%s' field", i + 1, k + 1, name, name2);
|
||||
goto error;
|
||||
}
|
||||
if (item2->type != json_integer) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u '%s' '%s' is not an integer", i + 1, k + 1, name, name2);
|
||||
}
|
||||
if (!strcmp(name2, "program")) {
|
||||
if (!strcmp(name, "destination"))
|
||||
range_max = 65535;
|
||||
else
|
||||
range_max = 127;
|
||||
}
|
||||
if (item2->u.integer < range_min || item2->u.integer > range_max) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u '%s' '%s' is out of range (expected %d-%d, got %" PRId64 ")", i + 1, k + 1, name, name2, range_min, range_max, item->u.integer);
|
||||
goto error;
|
||||
}
|
||||
if (!strcmp(name2, "bank"))
|
||||
++bank_found;
|
||||
else
|
||||
++program_found;
|
||||
}
|
||||
if (!bank_found && !program_found) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u '%s' contains no 'bank' or 'program'", i + 1, k + 1, name);
|
||||
goto error;
|
||||
}
|
||||
if (bank_found > 1) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u '%s' contains more than one 'bank'", i + 1, k + 1, name);
|
||||
goto error;
|
||||
}
|
||||
if (program_found > 1) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u '%s' contains more than one 'program'", i + 1, k + 1, name);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (!destination_found) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u is missing 'destination'", i + 1, k + 1);
|
||||
goto error;
|
||||
}
|
||||
if (destination_found > 1) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u contains more than one 'destination'", i + 1, k + 1);
|
||||
goto error;
|
||||
}
|
||||
if (source_found > 1) {
|
||||
sprintf(error_buf, "soundFont item #%u 'patchMappings' #%u contains more than one 'source'", i + 1, k + 1);
|
||||
}
|
||||
}
|
||||
patches_needed *= l;
|
||||
}
|
||||
presets_to_allocate += patches_needed;
|
||||
}
|
||||
|
||||
rval->count = presets_to_allocate;
|
||||
rval->presets = calloc(sizeof(BASS_MIDI_FONTEX), rval->count);
|
||||
|
||||
if (!rval->presets) {
|
||||
strcpy(error_buf, "Out of memory");
|
||||
goto error;
|
||||
}
|
||||
|
||||
preset_number = 0;
|
||||
|
||||
for (i = arr->u.array.length, j = 0; i--; ++j) {
|
||||
const json_value * obj = arr->u.array.values[i];
|
||||
const json_value * path = json_object_item(obj, "fileName");
|
||||
const json_value * gain = json_object_item(obj, "gain");
|
||||
const json_value * channels = json_object_item(obj, "channels");
|
||||
const json_value * patchMappings = json_object_item(obj, "patchMappings");
|
||||
const void * bass_path;
|
||||
const char * path_ptr = path->u.string.ptr;
|
||||
unsigned int bass_flags = 0;
|
||||
#ifdef _WIN32
|
||||
if (!(isalpha(*path_ptr) && path_ptr[1] == ':')) {
|
||||
if (strlen(path_ptr) + (base_path_end - base_path + 2) > 32767) {
|
||||
strcpy(error_buf, "Base path plus SoundFont relative path is longer than 32767 characters");
|
||||
goto error;
|
||||
}
|
||||
strcpy(path_temp, base_path);
|
||||
if (*base_path_end != '\\' && *base_path_end != '/')
|
||||
strcat(path_temp, "\\");
|
||||
strcat(path_temp, path_ptr);
|
||||
path_ptr = path_temp;
|
||||
}
|
||||
MultiByteToWideChar(CP_UTF8, 0, path_ptr, -1, path16, 32767);
|
||||
path16[32767] = '\0';
|
||||
bass_path = (void *) path16;
|
||||
bass_flags = BASS_UNICODE;
|
||||
#else
|
||||
if (*path_ptr != '/') {
|
||||
if (strlen(path_ptr) + (base_path_end - base_path + 2) > 32767) {
|
||||
strcpy(error_buf, "Base path plus SoundFont relative path is longer than 32767 characters");
|
||||
goto error;
|
||||
}
|
||||
strcpy(path_temp, base_path);
|
||||
if (*base_path_end != '/')
|
||||
strcat(path_temp, "/");
|
||||
strcat(path_temp, path_ptr);
|
||||
path_ptr = path_temp;
|
||||
}
|
||||
bass_path = (void *) path_ptr;
|
||||
#endif
|
||||
hfont = BASS_MIDI_FontInit(bass_path, bass_flags);
|
||||
if (!hfont) {
|
||||
int error_code = BASS_ErrorGetCode();
|
||||
if (error_code == BASS_ERROR_FILEOPEN) {
|
||||
sprintf(error_buf, "Could not open SoundFont bank '%s'", path->u.string.ptr);
|
||||
goto error;
|
||||
}
|
||||
else if (error_code == BASS_ERROR_FILEFORM) {
|
||||
sprintf(error_buf, "SoundFont bank '%s' is not a supported format", path->u.string.ptr);
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
sprintf(error_buf, "SoundFont bank '%s' failed to load with error #%u", path->u.string.ptr, error_code);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (gain->type != json_none) {
|
||||
double gain_value = 0.0;
|
||||
if (gain->type == json_integer) {
|
||||
gain_value = (double)gain->u.integer;
|
||||
}
|
||||
else if (gain->type == json_double) {
|
||||
gain_value = gain->u.dbl;
|
||||
}
|
||||
gain_value = pow(10.0, gain_value / 20.0);
|
||||
BASS_MIDI_FontSetVolume(hfont, gain_value);
|
||||
}
|
||||
fontex.font = hfont;
|
||||
fontex.spreset = -1;
|
||||
fontex.sbank = -1;
|
||||
fontex.dpreset = -1;
|
||||
fontex.dbank = 0;
|
||||
fontex.dbanklsb = 0;
|
||||
/* Simplest case, whole bank loading */
|
||||
if (channels->type == json_none && patchMappings->type == json_none) {
|
||||
rval->presets[preset_number++] = fontex;
|
||||
}
|
||||
else if (patchMappings->type == json_none) {
|
||||
for (k = 0, l = channels->u.array.length; k < l; ++k) {
|
||||
fontex.dbanklsb = (int)channels->u.array.values[k]->u.integer;
|
||||
rval->presets[preset_number++] = fontex;
|
||||
}
|
||||
}
|
||||
else if (channels->type == json_none) {
|
||||
sflist_process_patchmappings(rval->presets + preset_number, &fontex, patchMappings, 0);
|
||||
preset_number += patchMappings->u.array.length;
|
||||
}
|
||||
else {
|
||||
for (k = 0, l = channels->u.array.length; k < l; ++k) {
|
||||
sflist_process_patchmappings(rval->presets + preset_number, &fontex, patchMappings, (int)channels->u.array.values[k]->u.integer);
|
||||
preset_number += patchMappings->u.array.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
||||
error:
|
||||
if (hfont) {
|
||||
BASS_MIDI_FontFree(hfont);
|
||||
}
|
||||
if (rval) {
|
||||
sflist_free(rval);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int strpbrkn_all(const char * str, size_t size, const char * chrs)
|
||||
{
|
||||
const char * end = str + size;
|
||||
|
||||
while (str < end && *chrs) {
|
||||
while (str < end && *str != *chrs) ++str;
|
||||
++str, ++chrs;
|
||||
}
|
||||
|
||||
return str < end;
|
||||
}
|
||||
|
||||
sflist_presets * sflist_load(const char * sflist, size_t size, const char * base_path, char * error)
|
||||
{
|
||||
sflist_presets * rval;
|
||||
|
||||
json_value * list = 0;
|
||||
|
||||
/* Handle Unicode byte order markers */
|
||||
if (size >= 2) {
|
||||
if ((sflist[0] == 0xFF && sflist[1] == 0xFE) ||
|
||||
(sflist[0] == 0xFE && sflist[1] == 0xFF)) {
|
||||
strcpy(error, "UTF-16 encoding is not supported at this time");
|
||||
return 0;
|
||||
}
|
||||
if (size >= 3 && sflist[0] == 0xEF &&
|
||||
sflist[1] == 0xBB && sflist[2] == 0xBF) {
|
||||
sflist += 3;
|
||||
size -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
list = sflist_load_v2(sflist, size, error);
|
||||
|
||||
if (!list) {
|
||||
if (!strpbrkn_all(sflist, size, "{[]}"))
|
||||
list = sflist_load_v1(sflist, size, error);
|
||||
}
|
||||
|
||||
if (!list) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rval = sflist_process(list, base_path, error);
|
||||
|
||||
json_builder_free(list);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
void sflist_free(sflist_presets *presetlist)
|
||||
{
|
||||
if (presetlist) {
|
||||
if (presetlist->presets) {
|
||||
unsigned int i, j;
|
||||
for (i = 0, j = presetlist->count; i < j; ++i) {
|
||||
HSOUNDFONT hfont = presetlist->presets[i].font;
|
||||
if (hfont) {
|
||||
BASS_MIDI_FontFree(hfont);
|
||||
}
|
||||
}
|
||||
free(presetlist->presets);
|
||||
}
|
||||
free(presetlist);
|
||||
}
|
||||
}
|
||||
|
||||
const char * sflist_upgrade(const char * sflist, size_t size, char * error_buf)
|
||||
{
|
||||
char * rval = 0;
|
||||
|
||||
json_value * list = 0;
|
||||
|
||||
size_t length = 0;
|
||||
|
||||
const json_serialize_opts opts =
|
||||
{
|
||||
json_serialize_mode_multiline,
|
||||
0,
|
||||
3 /* indent_size */
|
||||
};
|
||||
|
||||
list = sflist_load_v2(sflist, size, error_buf);
|
||||
|
||||
if (!list) {
|
||||
if (!strpbrkn_all(sflist, size, "{[]}"))
|
||||
list = sflist_load_v1(sflist, size, error_buf);
|
||||
}
|
||||
|
||||
if (!list) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
length = json_measure_ex( list, opts );
|
||||
|
||||
rval = (char *) malloc( length + 1 );
|
||||
|
||||
if (!rval) {
|
||||
strcpy(error_buf, "Out of memory");
|
||||
goto error;
|
||||
}
|
||||
|
||||
json_serialize_ex( rval, list, opts );
|
||||
|
||||
json_builder_free( list );
|
||||
|
||||
rval[ length ] = '\0';
|
||||
|
||||
return (const char *) rval;
|
||||
|
||||
error:
|
||||
if ( list ) {
|
||||
json_builder_free( list );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sflist_upgrade_free(const char *ptr)
|
||||
{
|
||||
free( (void *) ptr );
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/* vim: set et ts=3 sw=3 sts=3 ft=c:
|
||||
*
|
||||
* Copyright (C) 2021 Christopher Snowhill. All rights reserved.
|
||||
* https://github.com/kode54/sflist
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SFLIST_H
|
||||
#define _SFLIST_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <bassmidi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct sflist_presets
|
||||
{
|
||||
unsigned int count;
|
||||
BASS_MIDI_FONTEX * presets;
|
||||
} sflist_presets;
|
||||
|
||||
#define sflist_max_error 1024
|
||||
|
||||
sflist_presets * sflist_load(const char * sflist, size_t size, const char * base_path, char * error);
|
||||
void sflist_free(sflist_presets *);
|
||||
|
||||
const char * sflist_upgrade(const char * sflist, size_t size, char * error);
|
||||
void sflist_upgrade_free(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/* vim: set et ts=3 sw=3 sts=3 ft=c:
|
||||
*
|
||||
* Copyright (C) 2021 Christopher Snowhill. All rights reserved.
|
||||
* https://github.com/kode54/sflist
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "sflist.h"
|
||||
|
||||
int main(int argc, const char ** argv)
|
||||
{
|
||||
char error[sflist_max_error];
|
||||
char path_temp[32768];
|
||||
int i;
|
||||
FILE *f;
|
||||
size_t length;
|
||||
char * in;
|
||||
const char * out;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
const char * end = argv[i] + strlen(argv[i]);
|
||||
if (((end - argv[i]) >= 5) && !strcmp(&end[-5], ".json")) continue;
|
||||
strcpy(path_temp, argv[i]);
|
||||
strcat(path_temp, ".json");
|
||||
f = fopen(argv[i], "r");
|
||||
fseek(f, 0, SEEK_END);
|
||||
length = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
in = malloc(length + 1);
|
||||
if (!in) {
|
||||
fclose(f);
|
||||
fputs("Out of memory.\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
if (fread(in, length, 1, f) != 1) {
|
||||
free(in);
|
||||
fclose(f);
|
||||
fprintf(stderr, "Cannot read all of file '%s'.\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
fclose(f);
|
||||
in[length] = '\0';
|
||||
out = sflist_upgrade(in, length, error);
|
||||
free(in);
|
||||
if (!out) {
|
||||
fprintf(stderr, "Error processing '%s': %s\n", argv[i], error);
|
||||
return 1;
|
||||
}
|
||||
f = fopen(path_temp, "w");
|
||||
if (!f) {
|
||||
sflist_upgrade_free(out);
|
||||
fprintf(stderr, "Unable to open output file '%s'.\n", path_temp);
|
||||
return 1;
|
||||
}
|
||||
if (fwrite(out, strlen(out), 1, f) != 1) {
|
||||
fclose(f);
|
||||
sflist_upgrade_free(out);
|
||||
fprintf(stderr, "Unable to write to output file '%s'.\n", path_temp);
|
||||
return 1;
|
||||
}
|
||||
fclose(f);
|
||||
sflist_upgrade_free(out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
These binaries were carefully retrieved from Homebrew for both x86_64
|
||||
and arm64, their signatures were removed, then their id and import
|
||||
paths were patched using install_name_tool.
|
||||
|
||||
The following versions are included as of this commit:
|
||||
|
||||
flac: 1.3.3
|
||||
glib: 2.68.1
|
||||
libogg: 1.3.4
|
||||
libvorbis: 1.3.7
|
||||
opus: 1.3.1
|
||||
pcre: 8.44
|
||||
readline: 8.1
|
||||
libsndfile: 1.0.31
|
||||
portaudio: HEAD-aa05346
|
|
@ -0,0 +1,118 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_H
|
||||
#define _FLUIDSYNTH_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BUILD_SHARED_LIBS 1
|
||||
|
||||
#if (BUILD_SHARED_LIBS == 0)
|
||||
#define FLUIDSYNTH_API // building static lib? no visibility control then
|
||||
#elif defined(WIN32)
|
||||
#if defined(FLUIDSYNTH_NOT_A_DLL)
|
||||
#define FLUIDSYNTH_API
|
||||
#elif defined(FLUIDSYNTH_DLL_EXPORTS)
|
||||
#define FLUIDSYNTH_API __declspec(dllexport)
|
||||
#else
|
||||
#define FLUIDSYNTH_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#elif defined(MACOS9)
|
||||
#define FLUIDSYNTH_API __declspec(export)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define FLUIDSYNTH_API __attribute__ ((visibility ("default")))
|
||||
|
||||
#else
|
||||
#define FLUIDSYNTH_API
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define FLUID_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER) && _MSC_VER > 1200
|
||||
# define FLUID_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
# define FLUID_DEPRECATED
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file fluidsynth.h
|
||||
* @brief FluidSynth is a real-time synthesizer designed for SoundFont(R) files.
|
||||
*
|
||||
* This is the header of the fluidsynth library and contains the
|
||||
* synthesizer's public API.
|
||||
*
|
||||
* Depending on how you want to use or extend the synthesizer you
|
||||
* will need different API functions. You probably do not need all
|
||||
* of them. Here is what you might want to do:
|
||||
*
|
||||
* - Embedded synthesizer: create a new synthesizer and send MIDI
|
||||
* events to it. The sound goes directly to the audio output of
|
||||
* your system.
|
||||
*
|
||||
* - Plugin synthesizer: create a synthesizer and send MIDI events
|
||||
* but pull the audio back into your application.
|
||||
*
|
||||
* - SoundFont plugin: create a new type of "SoundFont" and allow
|
||||
* the synthesizer to load your type of SoundFonts.
|
||||
*
|
||||
* - MIDI input: Create a MIDI handler to read the MIDI input on your
|
||||
* machine and send the MIDI events directly to the synthesizer.
|
||||
*
|
||||
* - MIDI files: Open MIDI files and send the MIDI events to the
|
||||
* synthesizer.
|
||||
*
|
||||
* - Command lines: You can send textual commands to the synthesizer.
|
||||
*
|
||||
* SoundFont(R) is a registered trademark of E-mu Systems, Inc.
|
||||
*/
|
||||
|
||||
#include "fluidsynth/types.h"
|
||||
#include "fluidsynth/settings.h"
|
||||
#include "fluidsynth/synth.h"
|
||||
#include "fluidsynth/shell.h"
|
||||
#include "fluidsynth/sfont.h"
|
||||
#include "fluidsynth/audio.h"
|
||||
#include "fluidsynth/event.h"
|
||||
#include "fluidsynth/midi.h"
|
||||
#include "fluidsynth/seq.h"
|
||||
#include "fluidsynth/seqbind.h"
|
||||
#include "fluidsynth/log.h"
|
||||
#include "fluidsynth/misc.h"
|
||||
#include "fluidsynth/mod.h"
|
||||
#include "fluidsynth/gen.h"
|
||||
#include "fluidsynth/voice.h"
|
||||
#include "fluidsynth/version.h"
|
||||
#include "fluidsynth/ladspa.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_H */
|
|
@ -0,0 +1,84 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_AUDIO_H
|
||||
#define _FLUIDSYNTH_AUDIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file audio.h
|
||||
* @brief Functions for audio driver output.
|
||||
* @defgroup AudioFunctions Functions for audio output
|
||||
*
|
||||
* Defines functions for creating audio driver output. Use
|
||||
* new_fluid_audio_driver() to create a new audio driver for a given synth
|
||||
* and configuration settings. The function new_fluid_audio_driver2() can be
|
||||
* used if custom audio processing is desired before the audio is sent to the
|
||||
* audio driver (although it is not as efficient).
|
||||
*
|
||||
* @sa @ref CreatingAudioDriver
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback function type used with new_fluid_audio_driver2() to allow for
|
||||
* custom user audio processing before the audio is sent to the driver. This
|
||||
* function is responsible for rendering audio to the buffers.
|
||||
* The buffers passed to this function are allocated and owned by the respective
|
||||
* audio driver and are only valid during that specific call (do not cache them).
|
||||
* For further details please refer to fluid_synth_process().
|
||||
* @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarentee that @p out
|
||||
* and @p fx buffers provided by fluidsynth's audio drivers never alias. This prevents downstream
|
||||
* applications from e.g. applying a custom effect accidentially to the same buffer multiple times.
|
||||
* @param data The user data parameter as passed to new_fluid_audio_driver2().
|
||||
* @param len Count of audio frames to synthesize.
|
||||
* @param nfx Count of arrays in \c fx.
|
||||
* @param fx Array of buffers to store effects audio to. Buffers may alias with buffers of \c out.
|
||||
* @param nout Count of arrays in \c out.
|
||||
* @param out Array of buffers to store (dry) audio to. Buffers may alias with buffers of \c fx.
|
||||
* @return Should return #FLUID_OK on success, #FLUID_FAILED if an error occurred.
|
||||
*/
|
||||
typedef int (*fluid_audio_func_t)(void *data, int len,
|
||||
int nfx, float *fx[],
|
||||
int nout, float *out[]);
|
||||
|
||||
FLUIDSYNTH_API fluid_audio_driver_t *new_fluid_audio_driver(fluid_settings_t *settings,
|
||||
fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API fluid_audio_driver_t *new_fluid_audio_driver2(fluid_settings_t *settings,
|
||||
fluid_audio_func_t func,
|
||||
void *data);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_audio_driver(fluid_audio_driver_t *driver);
|
||||
|
||||
FLUIDSYNTH_API fluid_file_renderer_t *new_fluid_file_renderer(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_file_renderer_process_block(fluid_file_renderer_t *dev);
|
||||
FLUIDSYNTH_API void delete_fluid_file_renderer(fluid_file_renderer_t *dev);
|
||||
FLUIDSYNTH_API int fluid_file_set_encoding_quality(fluid_file_renderer_t *dev, double q);
|
||||
|
||||
FLUIDSYNTH_API int fluid_audio_driver_register(const char **adrivers);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_AUDIO_H */
|
|
@ -0,0 +1,138 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_EVENT_H
|
||||
#define _FLUIDSYNTH_EVENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file event.h
|
||||
* @brief Sequencer event functions and defines.
|
||||
*
|
||||
* Functions and constants for creating/processing sequencer events.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sequencer event type enumeration.
|
||||
*/
|
||||
enum fluid_seq_event_type
|
||||
{
|
||||
FLUID_SEQ_NOTE = 0, /**< Note event with duration */
|
||||
FLUID_SEQ_NOTEON, /**< Note on event */
|
||||
FLUID_SEQ_NOTEOFF, /**< Note off event */
|
||||
FLUID_SEQ_ALLSOUNDSOFF, /**< All sounds off event */
|
||||
FLUID_SEQ_ALLNOTESOFF, /**< All notes off event */
|
||||
FLUID_SEQ_BANKSELECT, /**< Bank select message */
|
||||
FLUID_SEQ_PROGRAMCHANGE, /**< Program change message */
|
||||
FLUID_SEQ_PROGRAMSELECT, /**< Program select message */
|
||||
FLUID_SEQ_PITCHBEND, /**< Pitch bend message */
|
||||
FLUID_SEQ_PITCHWHEELSENS, /**< Pitch wheel sensitivity set message @since 1.1.0 was misspelled previously */
|
||||
FLUID_SEQ_MODULATION, /**< Modulation controller event */
|
||||
FLUID_SEQ_SUSTAIN, /**< Sustain controller event */
|
||||
FLUID_SEQ_CONTROLCHANGE, /**< MIDI control change event */
|
||||
FLUID_SEQ_PAN, /**< Stereo pan set event */
|
||||
FLUID_SEQ_VOLUME, /**< Volume set event */
|
||||
FLUID_SEQ_REVERBSEND, /**< Reverb send set event */
|
||||
FLUID_SEQ_CHORUSSEND, /**< Chorus send set event */
|
||||
FLUID_SEQ_TIMER, /**< Timer event (useful for giving a callback at a certain time) */
|
||||
FLUID_SEQ_ANYCONTROLCHANGE, /**< Any control change message (only internally used for remove_events) */
|
||||
FLUID_SEQ_CHANNELPRESSURE, /**< Channel aftertouch event @since 1.1.0 */
|
||||
FLUID_SEQ_KEYPRESSURE, /**< Polyphonic aftertouch event @since 2.0.0 */
|
||||
FLUID_SEQ_SYSTEMRESET, /**< System reset event @since 1.1.0 */
|
||||
FLUID_SEQ_UNREGISTERING, /**< Called when a sequencer client is being unregistered. @since 1.1.0 */
|
||||
#ifndef __DOXYGEN__
|
||||
FLUID_SEQ_LASTEVENT /**< @internal Defines the count of events enums @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Event alloc/free */
|
||||
FLUIDSYNTH_API fluid_event_t *new_fluid_event(void);
|
||||
FLUIDSYNTH_API void delete_fluid_event(fluid_event_t *evt);
|
||||
|
||||
/* Initializing events */
|
||||
FLUIDSYNTH_API void fluid_event_set_source(fluid_event_t *evt, fluid_seq_id_t src);
|
||||
FLUIDSYNTH_API void fluid_event_set_dest(fluid_event_t *evt, fluid_seq_id_t dest);
|
||||
|
||||
/* Timer events */
|
||||
FLUIDSYNTH_API void fluid_event_timer(fluid_event_t *evt, void *data);
|
||||
|
||||
/* Note events */
|
||||
FLUIDSYNTH_API void fluid_event_note(fluid_event_t *evt, int channel,
|
||||
short key, short vel,
|
||||
unsigned int duration);
|
||||
|
||||
FLUIDSYNTH_API void fluid_event_noteon(fluid_event_t *evt, int channel, short key, short vel);
|
||||
FLUIDSYNTH_API void fluid_event_noteoff(fluid_event_t *evt, int channel, short key);
|
||||
FLUIDSYNTH_API void fluid_event_all_sounds_off(fluid_event_t *evt, int channel);
|
||||
FLUIDSYNTH_API void fluid_event_all_notes_off(fluid_event_t *evt, int channel);
|
||||
|
||||
/* Instrument selection */
|
||||
FLUIDSYNTH_API void fluid_event_bank_select(fluid_event_t *evt, int channel, short bank_num);
|
||||
FLUIDSYNTH_API void fluid_event_program_change(fluid_event_t *evt, int channel, short preset_num);
|
||||
FLUIDSYNTH_API void fluid_event_program_select(fluid_event_t *evt, int channel, unsigned int sfont_id, short bank_num, short preset_num);
|
||||
|
||||
/* Real-time generic instrument controllers */
|
||||
FLUIDSYNTH_API
|
||||
void fluid_event_control_change(fluid_event_t *evt, int channel, short control, short val);
|
||||
|
||||
/* Real-time instrument controllers shortcuts */
|
||||
FLUIDSYNTH_API void fluid_event_pitch_bend(fluid_event_t *evt, int channel, int val);
|
||||
FLUIDSYNTH_API void fluid_event_pitch_wheelsens(fluid_event_t *evt, int channel, short val);
|
||||
FLUIDSYNTH_API void fluid_event_modulation(fluid_event_t *evt, int channel, short val);
|
||||
FLUIDSYNTH_API void fluid_event_sustain(fluid_event_t *evt, int channel, short val);
|
||||
FLUIDSYNTH_API void fluid_event_pan(fluid_event_t *evt, int channel, short val);
|
||||
FLUIDSYNTH_API void fluid_event_volume(fluid_event_t *evt, int channel, short val);
|
||||
FLUIDSYNTH_API void fluid_event_reverb_send(fluid_event_t *evt, int channel, short val);
|
||||
FLUIDSYNTH_API void fluid_event_chorus_send(fluid_event_t *evt, int channel, short val);
|
||||
|
||||
FLUIDSYNTH_API void fluid_event_key_pressure(fluid_event_t *evt, int channel, short key, short val);
|
||||
FLUIDSYNTH_API void fluid_event_channel_pressure(fluid_event_t *evt, int channel, short val);
|
||||
FLUIDSYNTH_API void fluid_event_system_reset(fluid_event_t *evt);
|
||||
|
||||
|
||||
/* Only for removing events */
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API void fluid_event_any_control_change(fluid_event_t *evt, int channel);
|
||||
|
||||
/* Only when unregistering clients */
|
||||
FLUIDSYNTH_API void fluid_event_unregistering(fluid_event_t *evt);
|
||||
|
||||
/* Accessing event data */
|
||||
FLUIDSYNTH_API int fluid_event_get_type(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API fluid_seq_id_t fluid_event_get_source(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API fluid_seq_id_t fluid_event_get_dest(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_event_get_channel(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_key(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_velocity(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_control(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_value(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_program(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API void *fluid_event_get_data(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API unsigned int fluid_event_get_duration(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API short fluid_event_get_bank(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_event_get_pitch(fluid_event_t *evt);
|
||||
FLUIDSYNTH_API unsigned int fluid_event_get_sfont_id(fluid_event_t *evt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_EVENT_H */
|
|
@ -0,0 +1,130 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_GEN_H
|
||||
#define _FLUIDSYNTH_GEN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file gen.h
|
||||
* @brief Functions and defines for SoundFont generator effects.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generator (effect) numbers (Soundfont 2.01 specifications section 8.1.3)
|
||||
*/
|
||||
enum fluid_gen_type
|
||||
{
|
||||
GEN_STARTADDROFS, /**< Sample start address offset (0-32767) */
|
||||
GEN_ENDADDROFS, /**< Sample end address offset (-32767-0) */
|
||||
GEN_STARTLOOPADDROFS, /**< Sample loop start address offset (-32767-32767) */
|
||||
GEN_ENDLOOPADDROFS, /**< Sample loop end address offset (-32767-32767) */
|
||||
GEN_STARTADDRCOARSEOFS, /**< Sample start address coarse offset (X 32768) */
|
||||
GEN_MODLFOTOPITCH, /**< Modulation LFO to pitch */
|
||||
GEN_VIBLFOTOPITCH, /**< Vibrato LFO to pitch */
|
||||
GEN_MODENVTOPITCH, /**< Modulation envelope to pitch */
|
||||
GEN_FILTERFC, /**< Filter cutoff */
|
||||
GEN_FILTERQ, /**< Filter Q */
|
||||
GEN_MODLFOTOFILTERFC, /**< Modulation LFO to filter cutoff */
|
||||
GEN_MODENVTOFILTERFC, /**< Modulation envelope to filter cutoff */
|
||||
GEN_ENDADDRCOARSEOFS, /**< Sample end address coarse offset (X 32768) */
|
||||
GEN_MODLFOTOVOL, /**< Modulation LFO to volume */
|
||||
GEN_UNUSED1, /**< Unused */
|
||||
GEN_CHORUSSEND, /**< Chorus send amount */
|
||||
GEN_REVERBSEND, /**< Reverb send amount */
|
||||
GEN_PAN, /**< Stereo panning */
|
||||
GEN_UNUSED2, /**< Unused */
|
||||
GEN_UNUSED3, /**< Unused */
|
||||
GEN_UNUSED4, /**< Unused */
|
||||
GEN_MODLFODELAY, /**< Modulation LFO delay */
|
||||
GEN_MODLFOFREQ, /**< Modulation LFO frequency */
|
||||
GEN_VIBLFODELAY, /**< Vibrato LFO delay */
|
||||
GEN_VIBLFOFREQ, /**< Vibrato LFO frequency */
|
||||
GEN_MODENVDELAY, /**< Modulation envelope delay */
|
||||
GEN_MODENVATTACK, /**< Modulation envelope attack */
|
||||
GEN_MODENVHOLD, /**< Modulation envelope hold */
|
||||
GEN_MODENVDECAY, /**< Modulation envelope decay */
|
||||
GEN_MODENVSUSTAIN, /**< Modulation envelope sustain */
|
||||
GEN_MODENVRELEASE, /**< Modulation envelope release */
|
||||
GEN_KEYTOMODENVHOLD, /**< Key to modulation envelope hold */
|
||||
GEN_KEYTOMODENVDECAY, /**< Key to modulation envelope decay */
|
||||
GEN_VOLENVDELAY, /**< Volume envelope delay */
|
||||
GEN_VOLENVATTACK, /**< Volume envelope attack */
|
||||
GEN_VOLENVHOLD, /**< Volume envelope hold */
|
||||
GEN_VOLENVDECAY, /**< Volume envelope decay */
|
||||
GEN_VOLENVSUSTAIN, /**< Volume envelope sustain */
|
||||
GEN_VOLENVRELEASE, /**< Volume envelope release */
|
||||
GEN_KEYTOVOLENVHOLD, /**< Key to volume envelope hold */
|
||||
GEN_KEYTOVOLENVDECAY, /**< Key to volume envelope decay */
|
||||
GEN_INSTRUMENT, /**< Instrument ID (shouldn't be set by user) */
|
||||
GEN_RESERVED1, /**< Reserved */
|
||||
GEN_KEYRANGE, /**< MIDI note range */
|
||||
GEN_VELRANGE, /**< MIDI velocity range */
|
||||
GEN_STARTLOOPADDRCOARSEOFS, /**< Sample start loop address coarse offset (X 32768) */
|
||||
GEN_KEYNUM, /**< Fixed MIDI note number */
|
||||
GEN_VELOCITY, /**< Fixed MIDI velocity value */
|
||||
GEN_ATTENUATION, /**< Initial volume attenuation */
|
||||
GEN_RESERVED2, /**< Reserved */
|
||||
GEN_ENDLOOPADDRCOARSEOFS, /**< Sample end loop address coarse offset (X 32768) */
|
||||
GEN_COARSETUNE, /**< Coarse tuning */
|
||||
GEN_FINETUNE, /**< Fine tuning */
|
||||
GEN_SAMPLEID, /**< Sample ID (shouldn't be set by user) */
|
||||
GEN_SAMPLEMODE, /**< Sample mode flags */
|
||||
GEN_RESERVED3, /**< Reserved */
|
||||
GEN_SCALETUNE, /**< Scale tuning */
|
||||
GEN_EXCLUSIVECLASS, /**< Exclusive class number */
|
||||
GEN_OVERRIDEROOTKEY, /**< Sample root note override */
|
||||
|
||||
/**
|
||||
* @brief Initial Pitch
|
||||
*
|
||||
* @note This is not "standard" SoundFont generator, because it is not
|
||||
* mentioned in the list of generators in the SF2 specifications.
|
||||
* It is used by FluidSynth internally to compute the nominal pitch of
|
||||
* a note on note-on event. By nature it shouldn't be allowed to be modulated,
|
||||
* however the specification defines a default modulator having "Initial Pitch"
|
||||
* as destination (cf. SF2.01 page 57 section 8.4.10 MIDI Pitch Wheel to Initial Pitch).
|
||||
* Thus it is impossible to cancel this default modulator, which would be required
|
||||
* to let the MIDI Pitch Wheel controller modulate a different generator.
|
||||
* In order to provide this flexibility, FluidSynth >= 2.1.0 uses a default modulator
|
||||
* "Pitch Wheel to Fine Tune", rather than Initial Pitch. The same "compromise" can
|
||||
* be found on the Audigy 2 ZS for instance.
|
||||
*/
|
||||
GEN_PITCH,
|
||||
|
||||
GEN_CUSTOM_BALANCE, /**< Balance @note Not a real SoundFont generator */
|
||||
/* non-standard generator for an additional custom high- or low-pass filter */
|
||||
GEN_CUSTOM_FILTERFC, /**< Custom filter cutoff frequency */
|
||||
GEN_CUSTOM_FILTERQ, /**< Custom filter Q */
|
||||
|
||||
#ifndef __DOXYGEN__
|
||||
GEN_LAST /**< @internal Value defines the count of generators (#fluid_gen_type) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_GEN_H */
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_LADSPA_H
|
||||
#define _FLUIDSYNTH_LADSPA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file ladspa.h
|
||||
* @brief Functions for manipulating the ladspa effects unit
|
||||
*
|
||||
* This header defines useful functions for programmatically manipulating the ladspa
|
||||
* effects unit of the synth that can be retrieved via fluid_synth_get_ladspa_fx().
|
||||
*
|
||||
* Using any of those functions requires fluidsynth to be compiled with ladspa support.
|
||||
* Else all of those functions are useless dummies.
|
||||
*/
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_is_active(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_activate(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_deactivate(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_reset(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_check(fluid_ladspa_fx_t *fx, char *err, int err_size);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_host_port_exists(fluid_ladspa_fx_t *fx, const char *name);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_add_buffer(fluid_ladspa_fx_t *fx, const char *name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_buffer_exists(fluid_ladspa_fx_t *fx, const char *name);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_add_effect(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *lib_name, const char *plugin_name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_can_mix(fluid_ladspa_fx_t *fx, const char *name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_set_mix(fluid_ladspa_fx_t *fx, const char *name, int mix, float gain);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_port_exists(fluid_ladspa_fx_t *fx, const char *effect_name, const char *port_name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_set_control(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *port_name, float val);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_link(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *port_name, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_LADSPA_H */
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_LOG_H
|
||||
#define _FLUIDSYNTH_LOG_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file log.h
|
||||
* @brief Logging interface
|
||||
*
|
||||
* The default logging function of the fluidsynth prints its messages
|
||||
* to the stderr. The synthesizer uses five level of messages: #FLUID_PANIC,
|
||||
* #FLUID_ERR, #FLUID_WARN, #FLUID_INFO, and #FLUID_DBG.
|
||||
*
|
||||
* A client application can install a new log function to handle the
|
||||
* messages differently. In the following example, the application
|
||||
* sets a callback function to display #FLUID_PANIC messages in a dialog,
|
||||
* and ignores all other messages by setting the log function to
|
||||
* NULL:
|
||||
*
|
||||
* @code
|
||||
* fluid_set_log_function(FLUID_PANIC, show_dialog, (void*) root_window);
|
||||
* fluid_set_log_function(FLUID_ERR, NULL, NULL);
|
||||
* fluid_set_log_function(FLUID_WARN, NULL, NULL);
|
||||
* fluid_set_log_function(FLUID_DBG, NULL, NULL);
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
/**
|
||||
* FluidSynth log levels.
|
||||
*/
|
||||
enum fluid_log_level
|
||||
{
|
||||
FLUID_PANIC, /**< The synth can't function correctly any more */
|
||||
FLUID_ERR, /**< Serious error occurred */
|
||||
FLUID_WARN, /**< Warning */
|
||||
FLUID_INFO, /**< Verbose informational messages */
|
||||
FLUID_DBG, /**< Debugging messages */
|
||||
#ifndef __DOXYGEN__
|
||||
LAST_LOG_LEVEL /**< @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Log function handler callback type used by fluid_set_log_function().
|
||||
* @param level Log level (#fluid_log_level)
|
||||
* @param message Log message text
|
||||
* @param data User data pointer supplied to fluid_set_log_function().
|
||||
*/
|
||||
typedef void (*fluid_log_function_t)(int level, const char *message, void *data);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_log_function_t fluid_set_log_function(int level, fluid_log_function_t fun, void *data);
|
||||
|
||||
FLUIDSYNTH_API void fluid_default_log_function(int level, const char *message, void *data);
|
||||
|
||||
FLUIDSYNTH_API int fluid_log(int level, const char *fmt, ...)
|
||||
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_LOG_H */
|
|
@ -0,0 +1,159 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_MIDI_H
|
||||
#define _FLUIDSYNTH_MIDI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file midi.h
|
||||
* @brief Functions for MIDI events, drivers and MIDI file playback.
|
||||
*/
|
||||
|
||||
FLUIDSYNTH_API fluid_midi_event_t *new_fluid_midi_event(void);
|
||||
FLUIDSYNTH_API void delete_fluid_midi_event(fluid_midi_event_t *event);
|
||||
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_type(fluid_midi_event_t *evt, int type);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_type(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_channel(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_key(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_key(fluid_midi_event_t *evt, int key);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_velocity(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int vel);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_control(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_control(fluid_midi_event_t *evt, int ctrl);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_value(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_value(fluid_midi_event_t *evt, int val);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_program(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_program(fluid_midi_event_t *evt, int val);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_pitch(fluid_midi_event_t *evt);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_pitch(fluid_midi_event_t *evt, int val);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_sysex(fluid_midi_event_t *evt, void *data,
|
||||
int size, int dynamic);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_text(fluid_midi_event_t *evt,
|
||||
void *data, int size, int dynamic);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_text(fluid_midi_event_t *evt,
|
||||
void **data, int *size);
|
||||
FLUIDSYNTH_API int fluid_midi_event_set_lyrics(fluid_midi_event_t *evt,
|
||||
void *data, int size, int dynamic);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_lyrics(fluid_midi_event_t *evt,
|
||||
void **data, int *size);
|
||||
|
||||
/**
|
||||
* MIDI router rule type.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FLUID_MIDI_ROUTER_RULE_NOTE, /**< MIDI note rule */
|
||||
FLUID_MIDI_ROUTER_RULE_CC, /**< MIDI controller rule */
|
||||
FLUID_MIDI_ROUTER_RULE_PROG_CHANGE, /**< MIDI program change rule */
|
||||
FLUID_MIDI_ROUTER_RULE_PITCH_BEND, /**< MIDI pitch bend rule */
|
||||
FLUID_MIDI_ROUTER_RULE_CHANNEL_PRESSURE, /**< MIDI channel pressure rule */
|
||||
FLUID_MIDI_ROUTER_RULE_KEY_PRESSURE, /**< MIDI key pressure rule */
|
||||
#ifndef __DOXYGEN__
|
||||
FLUID_MIDI_ROUTER_RULE_COUNT /**< @internal Total count of rule types @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time!*/
|
||||
#endif
|
||||
} fluid_midi_router_rule_type;
|
||||
|
||||
/**
|
||||
* Generic callback function for MIDI events.
|
||||
* @param data User defined data pointer
|
||||
* @param event The MIDI event
|
||||
* @return Should return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*
|
||||
* Will be used between
|
||||
* - MIDI driver and MIDI router
|
||||
* - MIDI router and synth
|
||||
* to communicate events.
|
||||
* In the not-so-far future...
|
||||
*/
|
||||
typedef int (*handle_midi_event_func_t)(void *data, fluid_midi_event_t *event);
|
||||
|
||||
FLUIDSYNTH_API fluid_midi_router_t *new_fluid_midi_router(fluid_settings_t *settings,
|
||||
handle_midi_event_func_t handler,
|
||||
void *event_handler_data);
|
||||
FLUIDSYNTH_API void delete_fluid_midi_router(fluid_midi_router_t *handler);
|
||||
FLUIDSYNTH_API int fluid_midi_router_set_default_rules(fluid_midi_router_t *router);
|
||||
FLUIDSYNTH_API int fluid_midi_router_clear_rules(fluid_midi_router_t *router);
|
||||
FLUIDSYNTH_API int fluid_midi_router_add_rule(fluid_midi_router_t *router,
|
||||
fluid_midi_router_rule_t *rule, int type);
|
||||
FLUIDSYNTH_API fluid_midi_router_rule_t *new_fluid_midi_router_rule(void);
|
||||
FLUIDSYNTH_API void delete_fluid_midi_router_rule(fluid_midi_router_rule_t *rule);
|
||||
FLUIDSYNTH_API void fluid_midi_router_rule_set_chan(fluid_midi_router_rule_t *rule,
|
||||
int min, int max, float mul, int add);
|
||||
FLUIDSYNTH_API void fluid_midi_router_rule_set_param1(fluid_midi_router_rule_t *rule,
|
||||
int min, int max, float mul, int add);
|
||||
FLUIDSYNTH_API void fluid_midi_router_rule_set_param2(fluid_midi_router_rule_t *rule,
|
||||
int min, int max, float mul, int add);
|
||||
FLUIDSYNTH_API int fluid_midi_router_handle_midi_event(void *data, fluid_midi_event_t *event);
|
||||
FLUIDSYNTH_API int fluid_midi_dump_prerouter(void *data, fluid_midi_event_t *event);
|
||||
FLUIDSYNTH_API int fluid_midi_dump_postrouter(void *data, fluid_midi_event_t *event);
|
||||
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_midi_driver_t *new_fluid_midi_driver(fluid_settings_t *settings,
|
||||
handle_midi_event_func_t handler,
|
||||
void *event_handler_data);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_midi_driver(fluid_midi_driver_t *driver);
|
||||
|
||||
|
||||
/**
|
||||
* MIDI player status enum.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
enum fluid_player_status
|
||||
{
|
||||
FLUID_PLAYER_READY, /**< Player is ready */
|
||||
FLUID_PLAYER_PLAYING, /**< Player is currently playing */
|
||||
FLUID_PLAYER_DONE /**< Player is finished playing */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API fluid_player_t *new_fluid_player(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API void delete_fluid_player(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_add(fluid_player_t *player, const char *midifile);
|
||||
FLUIDSYNTH_API int fluid_player_add_mem(fluid_player_t *player, const void *buffer, size_t len);
|
||||
FLUIDSYNTH_API int fluid_player_play(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_stop(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_join(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_set_loop(fluid_player_t *player, int loop);
|
||||
FLUIDSYNTH_API int fluid_player_set_midi_tempo(fluid_player_t *player, int tempo);
|
||||
FLUIDSYNTH_API int fluid_player_set_bpm(fluid_player_t *player, int bpm);
|
||||
FLUIDSYNTH_API int fluid_player_set_playback_callback(fluid_player_t *player, handle_midi_event_func_t handler, void *handler_data);
|
||||
|
||||
FLUIDSYNTH_API int fluid_player_get_status(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_current_tick(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_total_ticks(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_bpm(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_midi_tempo(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_seek(fluid_player_t *player, int ticks);
|
||||
|
||||
///
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_MIDI_H */
|
|
@ -0,0 +1,72 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_MISC_H
|
||||
#define _FLUIDSYNTH_MISC_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file misc.h
|
||||
* @brief Miscellaneous utility functions and defines
|
||||
*/
|
||||
|
||||
/**
|
||||
* Value that indicates success, used by most libfluidsynth functions.
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @note This was not publicly defined prior to libfluidsynth 1.1.0. When
|
||||
* writing code which should also be compatible with older versions, something
|
||||
* like the following can be used:
|
||||
*
|
||||
* @code
|
||||
* #include <fluidsynth.h>
|
||||
*
|
||||
* #ifndef FLUID_OK
|
||||
* #define FLUID_OK (0)
|
||||
* #define FLUID_FAILED (-1)
|
||||
* #endif
|
||||
* @endcode
|
||||
*/
|
||||
#define FLUID_OK (0)
|
||||
|
||||
/**
|
||||
* Value that indicates failure, used by most libfluidsynth functions.
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @note See #FLUID_OK for more details.
|
||||
*/
|
||||
#define FLUID_FAILED (-1)
|
||||
|
||||
|
||||
FLUIDSYNTH_API int fluid_is_soundfont(const char *filename);
|
||||
FLUIDSYNTH_API int fluid_is_midifile(const char *filename);
|
||||
FLUIDSYNTH_API void fluid_free(void* ptr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_MISC_H */
|
|
@ -0,0 +1,98 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_MOD_H
|
||||
#define _FLUIDSYNTH_MOD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file mod.h
|
||||
* @brief SoundFont modulator functions and constants.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Flags defining the polarity, mapping function and type of a modulator source.
|
||||
* Compare with SoundFont 2.04 PDF section 8.2.
|
||||
*
|
||||
* Note: Bit values do not correspond to the SoundFont spec! Also note that
|
||||
* #FLUID_MOD_GC and #FLUID_MOD_CC are in the flags field instead of the source field.
|
||||
*/
|
||||
enum fluid_mod_flags
|
||||
{
|
||||
FLUID_MOD_POSITIVE = 0, /**< Mapping function is positive */
|
||||
FLUID_MOD_NEGATIVE = 1, /**< Mapping function is negative */
|
||||
FLUID_MOD_UNIPOLAR = 0, /**< Mapping function is unipolar */
|
||||
FLUID_MOD_BIPOLAR = 2, /**< Mapping function is bipolar */
|
||||
FLUID_MOD_LINEAR = 0, /**< Linear mapping function */
|
||||
FLUID_MOD_CONCAVE = 4, /**< Concave mapping function */
|
||||
FLUID_MOD_CONVEX = 8, /**< Convex mapping function */
|
||||
FLUID_MOD_SWITCH = 12, /**< Switch (on/off) mapping function */
|
||||
FLUID_MOD_GC = 0, /**< General controller source type (#fluid_mod_src) */
|
||||
FLUID_MOD_CC = 16, /**< MIDI CC controller (source will be a MIDI CC number) */
|
||||
|
||||
FLUID_MOD_SIN = 0x80, /**< Custom non-standard sinus mapping function */
|
||||
};
|
||||
|
||||
/**
|
||||
* General controller (if #FLUID_MOD_GC in flags). This
|
||||
* corresponds to SoundFont 2.04 PDF section 8.2.1
|
||||
*/
|
||||
enum fluid_mod_src
|
||||
{
|
||||
FLUID_MOD_NONE = 0, /**< No source controller */
|
||||
FLUID_MOD_VELOCITY = 2, /**< MIDI note-on velocity */
|
||||
FLUID_MOD_KEY = 3, /**< MIDI note-on note number */
|
||||
FLUID_MOD_KEYPRESSURE = 10, /**< MIDI key pressure */
|
||||
FLUID_MOD_CHANNELPRESSURE = 13, /**< MIDI channel pressure */
|
||||
FLUID_MOD_PITCHWHEEL = 14, /**< Pitch wheel */
|
||||
FLUID_MOD_PITCHWHEELSENS = 16 /**< Pitch wheel sensitivity */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API fluid_mod_t *new_fluid_mod(void);
|
||||
FLUIDSYNTH_API void delete_fluid_mod(fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API size_t fluid_mod_sizeof(void);
|
||||
|
||||
FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t *mod, int src, int flags);
|
||||
FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t *mod, int src, int flags);
|
||||
FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t *mod, int dst);
|
||||
FLUIDSYNTH_API void fluid_mod_set_amount(fluid_mod_t *mod, double amount);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_get_source1(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_flags1(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_source2(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_flags2(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API int fluid_mod_get_dest(const fluid_mod_t *mod);
|
||||
FLUIDSYNTH_API double fluid_mod_get_amount(const fluid_mod_t *mod);
|
||||
|
||||
FLUIDSYNTH_API int fluid_mod_test_identity(const fluid_mod_t *mod1, const fluid_mod_t *mod2);
|
||||
FLUIDSYNTH_API int fluid_mod_has_source(const fluid_mod_t *mod, int cc, int ctrl);
|
||||
FLUIDSYNTH_API int fluid_mod_has_dest(const fluid_mod_t *mod, int gen);
|
||||
|
||||
FLUIDSYNTH_API void fluid_mod_clone(fluid_mod_t *mod, const fluid_mod_t *src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_MOD_H */
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_SEQ_H
|
||||
#define _FLUIDSYNTH_SEQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file seq.h
|
||||
* @brief MIDI event sequencer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Event callback prototype for destination clients.
|
||||
* @param time Current sequencer tick value (see fluid_sequencer_get_tick()).
|
||||
* @param event The event being received
|
||||
* @param seq The sequencer instance
|
||||
* @param data User defined data registered with the client
|
||||
*/
|
||||
typedef void (*fluid_event_callback_t)(unsigned int time, fluid_event_t *event,
|
||||
fluid_sequencer_t *seq, void *data);
|
||||
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API fluid_sequencer_t *new_fluid_sequencer(void);
|
||||
FLUIDSYNTH_API fluid_sequencer_t *new_fluid_sequencer2(int use_system_timer);
|
||||
FLUIDSYNTH_API void delete_fluid_sequencer(fluid_sequencer_t *seq);
|
||||
FLUIDSYNTH_API int fluid_sequencer_get_use_system_timer(fluid_sequencer_t *seq);
|
||||
FLUIDSYNTH_API
|
||||
fluid_seq_id_t fluid_sequencer_register_client(fluid_sequencer_t *seq, const char *name,
|
||||
fluid_event_callback_t callback, void *data);
|
||||
FLUIDSYNTH_API void fluid_sequencer_unregister_client(fluid_sequencer_t *seq, fluid_seq_id_t id);
|
||||
FLUIDSYNTH_API int fluid_sequencer_count_clients(fluid_sequencer_t *seq);
|
||||
FLUIDSYNTH_API fluid_seq_id_t fluid_sequencer_get_client_id(fluid_sequencer_t *seq, int index);
|
||||
FLUIDSYNTH_API char *fluid_sequencer_get_client_name(fluid_sequencer_t *seq, fluid_seq_id_t id);
|
||||
FLUIDSYNTH_API int fluid_sequencer_client_is_dest(fluid_sequencer_t *seq, fluid_seq_id_t id);
|
||||
FLUIDSYNTH_API void fluid_sequencer_process(fluid_sequencer_t *seq, unsigned int msec);
|
||||
FLUIDSYNTH_API void fluid_sequencer_send_now(fluid_sequencer_t *seq, fluid_event_t *evt);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_sequencer_send_at(fluid_sequencer_t *seq, fluid_event_t *evt,
|
||||
unsigned int time, int absolute);
|
||||
FLUIDSYNTH_API
|
||||
void fluid_sequencer_remove_events(fluid_sequencer_t *seq, fluid_seq_id_t source, fluid_seq_id_t dest, int type);
|
||||
FLUIDSYNTH_API unsigned int fluid_sequencer_get_tick(fluid_sequencer_t *seq);
|
||||
FLUIDSYNTH_API void fluid_sequencer_set_time_scale(fluid_sequencer_t *seq, double scale);
|
||||
FLUIDSYNTH_API double fluid_sequencer_get_time_scale(fluid_sequencer_t *seq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SEQ_H */
|
|
@ -0,0 +1,45 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_SEQBIND_H
|
||||
#define _FLUIDSYNTH_SEQBIND_H
|
||||
|
||||
#include "seq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file seqbind.h
|
||||
* @brief Functions for binding sequencer objects to other subsystems.
|
||||
*/
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_seq_id_t fluid_sequencer_register_fluidsynth(fluid_sequencer_t *seq, fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int
|
||||
fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_SEQBIND_H */
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_SETTINGS_H
|
||||
#define _FLUIDSYNTH_SETTINGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file settings.h
|
||||
* @brief Synthesizer settings
|
||||
* @defgroup SettingsFunctions Functions for settings management
|
||||
*
|
||||
* To create a synthesizer object you will have to specify its
|
||||
* settings. These settings are stored in a fluid_settings_t object.
|
||||
* @code
|
||||
* void
|
||||
* my_synthesizer ()
|
||||
* {
|
||||
* fluid_settings_t *settings;
|
||||
* fluid_synth_t *synth;
|
||||
* fluid_audio_driver_t *adriver;
|
||||
*
|
||||
* settings = new_fluid_settings ();
|
||||
* fluid_settings_setstr(settings, "audio.driver", "alsa");
|
||||
* // ... change settings ...
|
||||
* synth = new_fluid_synth (settings);
|
||||
* adriver = new_fluid_audio_driver (settings, synth);
|
||||
* // ...
|
||||
* }
|
||||
* @endcode
|
||||
* @sa @ref CreatingSettings
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hint FLUID_HINT_BOUNDED_BELOW indicates that the LowerBound field
|
||||
* of the FLUID_PortRangeHint should be considered meaningful. The
|
||||
* value in this field should be considered the (inclusive) lower
|
||||
* bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
|
||||
* specified then the value of LowerBound should be multiplied by the
|
||||
* sample rate.
|
||||
*/
|
||||
#define FLUID_HINT_BOUNDED_BELOW 0x1
|
||||
|
||||
/** Hint FLUID_HINT_BOUNDED_ABOVE indicates that the UpperBound field
|
||||
of the FLUID_PortRangeHint should be considered meaningful. The
|
||||
value in this field should be considered the (inclusive) upper
|
||||
bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
|
||||
specified then the value of UpperBound should be multiplied by the
|
||||
sample rate. */
|
||||
#define FLUID_HINT_BOUNDED_ABOVE 0x2
|
||||
|
||||
/**
|
||||
* Hint FLUID_HINT_TOGGLED indicates that the data item should be
|
||||
* considered a Boolean toggle. Data less than or equal to zero should
|
||||
* be considered `off' or `false,' and data above zero should be
|
||||
* considered `on' or `true.' FLUID_HINT_TOGGLED may not be used in
|
||||
* conjunction with any other hint.
|
||||
*/
|
||||
#define FLUID_HINT_TOGGLED 0x4
|
||||
|
||||
#define FLUID_HINT_OPTIONLIST 0x02 /**< Setting is a list of string options */
|
||||
|
||||
|
||||
/**
|
||||
* Settings type
|
||||
*
|
||||
* Each setting has a defined type: numeric (double), integer, string or a
|
||||
* set of values. The type of each setting can be retrieved using the
|
||||
* function fluid_settings_get_type()
|
||||
*/
|
||||
enum fluid_types_enum
|
||||
{
|
||||
FLUID_NO_TYPE = -1, /**< Undefined type */
|
||||
FLUID_NUM_TYPE, /**< Numeric (double) */
|
||||
FLUID_INT_TYPE, /**< Integer */
|
||||
FLUID_STR_TYPE, /**< String */
|
||||
FLUID_SET_TYPE /**< Set of values */
|
||||
};
|
||||
|
||||
|
||||
FLUIDSYNTH_API fluid_settings_t *new_fluid_settings(void);
|
||||
FLUIDSYNTH_API void delete_fluid_settings(fluid_settings_t *settings);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_get_type(fluid_settings_t *settings, const char *name);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_get_hints(fluid_settings_t *settings, const char *name, int *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_is_realtime(fluid_settings_t *settings, const char *name);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_setstr(fluid_settings_t *settings, const char *name, const char *str);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_copystr(fluid_settings_t *settings, const char *name, char *str, int len);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_dupstr(fluid_settings_t *settings, const char *name, char **str);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getstr_default(fluid_settings_t *settings, const char *name, char **def);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_str_equal(fluid_settings_t *settings, const char *name, const char *value);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_setnum(fluid_settings_t *settings, const char *name, double val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getnum(fluid_settings_t *settings, const char *name, double *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getnum_default(fluid_settings_t *settings, const char *name, double *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getnum_range(fluid_settings_t *settings, const char *name,
|
||||
double *min, double *max);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_setint(fluid_settings_t *settings, const char *name, int val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getint(fluid_settings_t *settings, const char *name, int *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getint_default(fluid_settings_t *settings, const char *name, int *val);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_getint_range(fluid_settings_t *settings, const char *name,
|
||||
int *min, int *max);
|
||||
|
||||
/**
|
||||
* Callback function type used with fluid_settings_foreach_option()
|
||||
* @param data User defined data pointer
|
||||
* @param name Setting name
|
||||
* @param option A string option for this setting (iterates through the list)
|
||||
*/
|
||||
typedef void (*fluid_settings_foreach_option_t)(void *data, const char *name, const char *option);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_settings_foreach_option(fluid_settings_t *settings,
|
||||
const char *name, void *data,
|
||||
fluid_settings_foreach_option_t func);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_settings_option_count(fluid_settings_t *settings, const char *name);
|
||||
FLUIDSYNTH_API char *fluid_settings_option_concat(fluid_settings_t *settings,
|
||||
const char *name,
|
||||
const char *separator);
|
||||
|
||||
/**
|
||||
* Callback function type used with fluid_settings_foreach()
|
||||
* @param data User defined data pointer
|
||||
* @param name Setting name
|
||||
* @param type Setting type (#fluid_types_enum)
|
||||
*/
|
||||
typedef void (*fluid_settings_foreach_t)(void *data, const char *name, int type);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_settings_foreach(fluid_settings_t *settings, void *data,
|
||||
fluid_settings_foreach_t func);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SETTINGS_H */
|
|
@ -0,0 +1,316 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_SFONT_H
|
||||
#define _FLUIDSYNTH_SFONT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file sfont.h
|
||||
* @brief SoundFont plugins
|
||||
*
|
||||
* It is possible to add new SoundFont loaders to the
|
||||
* synthesizer. This API allows for virtual SoundFont files to be loaded
|
||||
* and synthesized, which may not actually be SoundFont files, as long as they
|
||||
* can be represented by the SoundFont synthesis model.
|
||||
*
|
||||
* To add a new SoundFont loader to the synthesizer, call
|
||||
* fluid_synth_add_sfloader() and pass a pointer to an
|
||||
* #fluid_sfloader_t instance created by new_fluid_sfloader().
|
||||
* On creation, you must specify a callback function \p load
|
||||
* that will be called for every file attempting to load it and
|
||||
* if successful returns a #fluid_sfont_t instance, or NULL if it fails.
|
||||
*
|
||||
* The #fluid_sfont_t structure contains a callback to obtain the
|
||||
* name of the SoundFont. It contains two functions to iterate
|
||||
* though the contained presets, and one function to obtain a
|
||||
* preset corresponding to a bank and preset number. This
|
||||
* function should return a #fluid_preset_t instance.
|
||||
*
|
||||
* The #fluid_preset_t instance contains some functions to obtain
|
||||
* information from the preset (name, bank, number). The most
|
||||
* important callback is the noteon function. The noteon function
|
||||
* is called by fluidsynth internally and
|
||||
* should call fluid_synth_alloc_voice() for every sample that has
|
||||
* to be played. fluid_synth_alloc_voice() expects a pointer to a
|
||||
* #fluid_sample_t instance and returns a pointer to the opaque
|
||||
* #fluid_voice_t structure. To set or increment the values of a
|
||||
* generator, use fluid_voice_gen_set() or fluid_voice_gen_incr(). When you are
|
||||
* finished initializing the voice call fluid_voice_start() to
|
||||
* start playing the synthesis voice.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Some notification enums for presets and samples.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
FLUID_PRESET_SELECTED, /**< Preset selected notify */
|
||||
FLUID_PRESET_UNSELECTED, /**< Preset unselected notify */
|
||||
FLUID_SAMPLE_DONE /**< Sample no longer needed notify */
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates the type of a sample used by the _fluid_sample_t::sampletype field.
|
||||
* This enum corresponds to the \c SFSampleLink enum in the SoundFont spec.
|
||||
* One \c flag may be bit-wise OR-ed with one \c value.
|
||||
*/
|
||||
enum fluid_sample_type
|
||||
{
|
||||
FLUID_SAMPLETYPE_MONO = 0x1, /**< Value used for mono samples */
|
||||
FLUID_SAMPLETYPE_RIGHT = 0x2, /**< Value used for right samples of a stereo pair */
|
||||
FLUID_SAMPLETYPE_LEFT = 0x4, /**< Value used for left samples of a stereo pair */
|
||||
FLUID_SAMPLETYPE_LINKED = 0x8, /**< Value used for linked sample, which is currently not supported */
|
||||
FLUID_SAMPLETYPE_OGG_VORBIS = 0x10, /**< Flag used for Ogg Vorbis compressed samples (non-standard compliant extension) as found in the program "sftools" developed by Werner Schweer from MuseScore @since 1.1.7 */
|
||||
FLUID_SAMPLETYPE_ROM = 0x8000 /**< Flag that indicates ROM samples, causing the sample to be ignored */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Method to load an instrument file (does not actually need to be a real file name,
|
||||
* could be another type of string identifier that the \a loader understands).
|
||||
* @param loader SoundFont loader
|
||||
* @param filename File name or other string identifier
|
||||
* @return The loaded instrument file (SoundFont) or NULL if an error occurred.
|
||||
*/
|
||||
typedef fluid_sfont_t *(*fluid_sfloader_load_t)(fluid_sfloader_t *loader, const char *filename);
|
||||
|
||||
/**
|
||||
* The free method should free the memory allocated for a fluid_sfloader_t instance in
|
||||
* addition to any private data. Any custom user provided cleanup function must ultimately call
|
||||
* delete_fluid_sfloader() to ensure proper cleanup of the #fluid_sfloader_t struct. If no private data
|
||||
* needs to be freed, setting this to delete_fluid_sfloader() is sufficient.
|
||||
* @param loader SoundFont loader
|
||||
*/
|
||||
typedef void (*fluid_sfloader_free_t)(fluid_sfloader_t *loader);
|
||||
|
||||
|
||||
FLUIDSYNTH_API fluid_sfloader_t *new_fluid_sfloader(fluid_sfloader_load_t load, fluid_sfloader_free_t free);
|
||||
FLUIDSYNTH_API void delete_fluid_sfloader(fluid_sfloader_t *loader);
|
||||
|
||||
FLUIDSYNTH_API fluid_sfloader_t *new_fluid_defsfloader(fluid_settings_t *settings);
|
||||
|
||||
/**
|
||||
* Opens the file or memory indicated by \c filename in binary read mode.
|
||||
* \c filename matches the string provided during the fluid_synth_sfload() call.
|
||||
*
|
||||
* @return returns a file handle on success, NULL otherwise
|
||||
*/
|
||||
typedef void *(* fluid_sfloader_callback_open_t)(const char *filename);
|
||||
|
||||
/**
|
||||
* Reads \c count bytes to the specified buffer \c buf.
|
||||
*
|
||||
* @return returns #FLUID_OK if exactly \c count bytes were successfully read, else returns #FLUID_FAILED and leaves \a buf unmodified.
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_read_t)(void *buf, int count, void *handle);
|
||||
|
||||
/**
|
||||
* Same purpose and behaviour as fseek.
|
||||
*
|
||||
* @param origin either \c SEEK_SET, \c SEEK_CUR or \c SEEK_END
|
||||
*
|
||||
* @return returns #FLUID_OK if the seek was successfully performed while not seeking beyond a buffer or file, #FLUID_FAILED otherwise
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_seek_t)(void *handle, long offset, int origin);
|
||||
|
||||
/**
|
||||
* Closes the handle returned by #fluid_sfloader_callback_open_t and frees used resources.
|
||||
*
|
||||
* @return returns #FLUID_OK on success, #FLUID_FAILED on error
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_close_t)(void *handle);
|
||||
|
||||
/** @return returns current file offset or #FLUID_FAILED on error */
|
||||
typedef long (* fluid_sfloader_callback_tell_t)(void *handle);
|
||||
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfloader_set_callbacks(fluid_sfloader_t *loader,
|
||||
fluid_sfloader_callback_open_t open,
|
||||
fluid_sfloader_callback_read_t read,
|
||||
fluid_sfloader_callback_seek_t seek,
|
||||
fluid_sfloader_callback_tell_t tell,
|
||||
fluid_sfloader_callback_close_t close);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfloader_set_data(fluid_sfloader_t *loader, void *data);
|
||||
FLUIDSYNTH_API void *fluid_sfloader_get_data(fluid_sfloader_t *loader);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Method to return the name of a virtual SoundFont.
|
||||
* @param sfont Virtual SoundFont
|
||||
* @return The name of the virtual SoundFont.
|
||||
*/
|
||||
typedef const char *(*fluid_sfont_get_name_t)(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Get a virtual SoundFont preset by bank and program numbers.
|
||||
* @param sfont Virtual SoundFont
|
||||
* @param bank MIDI bank number (0-16383)
|
||||
* @param prenum MIDI preset number (0-127)
|
||||
* @return Should return an allocated virtual preset or NULL if it could not
|
||||
* be found.
|
||||
*/
|
||||
typedef fluid_preset_t *(*fluid_sfont_get_preset_t)(fluid_sfont_t *sfont, int bank, int prenum);
|
||||
|
||||
/**
|
||||
* Start virtual SoundFont preset iteration method.
|
||||
* @param sfont Virtual SoundFont
|
||||
*
|
||||
* Starts/re-starts virtual preset iteration in a SoundFont.
|
||||
*/
|
||||
typedef void (*fluid_sfont_iteration_start_t)(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Virtual SoundFont preset iteration function.
|
||||
* @param sfont Virtual SoundFont
|
||||
* @return NULL when no more presets are available, otherwise the a pointer to the current preset
|
||||
*
|
||||
* Returns preset information to the caller. The returned buffer is only valid until a subsequent
|
||||
* call to this function.
|
||||
*/
|
||||
typedef fluid_preset_t *(*fluid_sfont_iteration_next_t)(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Method to free a virtual SoundFont bank. Any custom user provided cleanup function must ultimately call
|
||||
* delete_fluid_sfont() to ensure proper cleanup of the #fluid_sfont_t struct. If no private data
|
||||
* needs to be freed, setting this to delete_fluid_sfont() is sufficient.
|
||||
* @param sfont Virtual SoundFont to free.
|
||||
* @return Should return 0 when it was able to free all resources or non-zero
|
||||
* if some of the samples could not be freed because they are still in use,
|
||||
* in which case the free will be tried again later, until success.
|
||||
*/
|
||||
typedef int (*fluid_sfont_free_t)(fluid_sfont_t *sfont);
|
||||
|
||||
|
||||
FLUIDSYNTH_API fluid_sfont_t *new_fluid_sfont(fluid_sfont_get_name_t get_name,
|
||||
fluid_sfont_get_preset_t get_preset,
|
||||
fluid_sfont_iteration_start_t iter_start,
|
||||
fluid_sfont_iteration_next_t iter_next,
|
||||
fluid_sfont_free_t free);
|
||||
|
||||
FLUIDSYNTH_API int delete_fluid_sfont(fluid_sfont_t *sfont);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfont_set_data(fluid_sfont_t *sfont, void *data);
|
||||
FLUIDSYNTH_API void *fluid_sfont_get_data(fluid_sfont_t *sfont);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfont_get_id(fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API const char *fluid_sfont_get_name(fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API fluid_preset_t *fluid_sfont_get_preset(fluid_sfont_t *sfont, int bank, int prenum);
|
||||
FLUIDSYNTH_API void fluid_sfont_iteration_start(fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API fluid_preset_t *fluid_sfont_iteration_next(fluid_sfont_t *sfont);
|
||||
|
||||
/**
|
||||
* Method to get a virtual SoundFont preset name.
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @return Should return the name of the preset. The returned string must be
|
||||
* valid for the duration of the virtual preset (or the duration of the
|
||||
* SoundFont, in the case of preset iteration).
|
||||
*/
|
||||
typedef const char *(*fluid_preset_get_name_t)(fluid_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Method to get a virtual SoundFont preset MIDI bank number.
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @param return The bank number of the preset
|
||||
*/
|
||||
typedef int (*fluid_preset_get_banknum_t)(fluid_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Method to get a virtual SoundFont preset MIDI program number.
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @param return The program number of the preset
|
||||
*/
|
||||
typedef int (*fluid_preset_get_num_t)(fluid_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Method to handle a noteon event (synthesize the instrument).
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @param synth Synthesizer instance
|
||||
* @param chan MIDI channel number of the note on event
|
||||
* @param key MIDI note number (0-127)
|
||||
* @param vel MIDI velocity (0-127)
|
||||
* @return #FLUID_OK on success (0) or #FLUID_FAILED (-1) otherwise
|
||||
*
|
||||
* This method may be called from within synthesis context and therefore
|
||||
* should be as efficient as possible and not perform any operations considered
|
||||
* bad for realtime audio output (memory allocations and other OS calls).
|
||||
*
|
||||
* Call fluid_synth_alloc_voice() for every sample that has
|
||||
* to be played. fluid_synth_alloc_voice() expects a pointer to a
|
||||
* #fluid_sample_t structure and returns a pointer to the opaque
|
||||
* #fluid_voice_t structure. To set or increment the values of a
|
||||
* generator, use fluid_voice_gen_set() or fluid_voice_gen_incr(). When you are
|
||||
* finished initializing the voice call fluid_voice_start() to
|
||||
* start playing the synthesis voice. Starting with FluidSynth 1.1.0 all voices
|
||||
* created will be started at the same time.
|
||||
*/
|
||||
typedef int (*fluid_preset_noteon_t)(fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel);
|
||||
|
||||
/**
|
||||
* Method to free a virtual SoundFont preset. Any custom user provided cleanup function must ultimately call
|
||||
* delete_fluid_preset() to ensure proper cleanup of the #fluid_preset_t struct. If no private data
|
||||
* needs to be freed, setting this to delete_fluid_preset() is sufficient.
|
||||
* @param preset Virtual SoundFont preset
|
||||
* @return Should return 0
|
||||
*/
|
||||
typedef void (*fluid_preset_free_t)(fluid_preset_t *preset);
|
||||
|
||||
FLUIDSYNTH_API fluid_preset_t *new_fluid_preset(fluid_sfont_t *parent_sfont,
|
||||
fluid_preset_get_name_t get_name,
|
||||
fluid_preset_get_banknum_t get_bank,
|
||||
fluid_preset_get_num_t get_num,
|
||||
fluid_preset_noteon_t noteon,
|
||||
fluid_preset_free_t free);
|
||||
FLUIDSYNTH_API void delete_fluid_preset(fluid_preset_t *preset);
|
||||
|
||||
FLUIDSYNTH_API int fluid_preset_set_data(fluid_preset_t *preset, void *data);
|
||||
FLUIDSYNTH_API void *fluid_preset_get_data(fluid_preset_t *preset);
|
||||
|
||||
FLUIDSYNTH_API const char *fluid_preset_get_name(fluid_preset_t *preset);
|
||||
FLUIDSYNTH_API int fluid_preset_get_banknum(fluid_preset_t *preset);
|
||||
FLUIDSYNTH_API int fluid_preset_get_num(fluid_preset_t *preset);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_preset_get_sfont(fluid_preset_t *preset);
|
||||
|
||||
FLUIDSYNTH_API fluid_sample_t *new_fluid_sample(void);
|
||||
FLUIDSYNTH_API void delete_fluid_sample(fluid_sample_t *sample);
|
||||
FLUIDSYNTH_API size_t fluid_sample_sizeof(void);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sample_set_name(fluid_sample_t *sample, const char *name);
|
||||
FLUIDSYNTH_API int fluid_sample_set_sound_data(fluid_sample_t *sample,
|
||||
short *data,
|
||||
char *data24,
|
||||
unsigned int nbframes,
|
||||
unsigned int sample_rate,
|
||||
short copy_data);
|
||||
|
||||
FLUIDSYNTH_API int fluid_sample_set_loop(fluid_sample_t *sample, unsigned int loop_start, unsigned int loop_end);
|
||||
FLUIDSYNTH_API int fluid_sample_set_pitch(fluid_sample_t *sample, int root_key, int fine_tune);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SFONT_H */
|
|
@ -0,0 +1,97 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_SHELL_H
|
||||
#define _FLUIDSYNTH_SHELL_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file shell.h
|
||||
* @brief Command shell interface
|
||||
*
|
||||
* The shell interface allows you to send simple textual commands to
|
||||
* the synthesizer, to parse a command file, or to read commands
|
||||
* from the stdin or other input streams.
|
||||
*/
|
||||
|
||||
FLUIDSYNTH_API fluid_istream_t fluid_get_stdin(void);
|
||||
FLUIDSYNTH_API fluid_ostream_t fluid_get_stdout(void);
|
||||
|
||||
FLUIDSYNTH_API char *fluid_get_userconf(char *buf, int len);
|
||||
FLUIDSYNTH_API char *fluid_get_sysconf(char *buf, int len);
|
||||
|
||||
|
||||
/* The command handler */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_router_t *router);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void delete_fluid_cmd_handler(fluid_cmd_handler_t *handler);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_cmd_handler_set_synth(fluid_cmd_handler_t *handler, fluid_synth_t *synth);
|
||||
|
||||
|
||||
|
||||
/* Command function */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_command(fluid_cmd_handler_t *handler, const char *cmd, fluid_ostream_t out);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_source(fluid_cmd_handler_t *handler, const char *filename);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
void fluid_usershell(fluid_settings_t *settings, fluid_cmd_handler_t *handler);
|
||||
|
||||
|
||||
/* Shell */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_shell_t *new_fluid_shell(fluid_settings_t *settings, fluid_cmd_handler_t *handler,
|
||||
fluid_istream_t in, fluid_ostream_t out, int thread);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_shell(fluid_shell_t *shell);
|
||||
|
||||
|
||||
|
||||
/* TCP/IP server */
|
||||
|
||||
|
||||
FLUIDSYNTH_API
|
||||
fluid_server_t *new_fluid_server(fluid_settings_t *settings,
|
||||
fluid_synth_t *synth, fluid_midi_router_t *router);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_server(fluid_server_t *server);
|
||||
|
||||
FLUIDSYNTH_API int fluid_server_join(fluid_server_t *server);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SHELL_H */
|
|
@ -0,0 +1,397 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_SYNTH_H
|
||||
#define _FLUIDSYNTH_SYNTH_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file synth.h
|
||||
* @brief Embeddable SoundFont synthesizer
|
||||
*
|
||||
* You create a new synthesizer with new_fluid_synth() and you destroy
|
||||
* it with delete_fluid_synth(). Use the fluid_settings_t structure to specify
|
||||
* the synthesizer characteristics.
|
||||
*
|
||||
* You have to load a SoundFont in order to hear any sound. For that
|
||||
* you use the fluid_synth_sfload() function.
|
||||
*
|
||||
* You can use the audio driver functions to open
|
||||
* the audio device and create a background audio thread.
|
||||
*
|
||||
* The API for sending MIDI events is probably what you expect:
|
||||
* fluid_synth_noteon(), fluid_synth_noteoff(), ...
|
||||
*/
|
||||
|
||||
|
||||
FLUIDSYNTH_API fluid_synth_t *new_fluid_synth(fluid_settings_t *settings);
|
||||
FLUIDSYNTH_API void delete_fluid_synth(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API fluid_settings_t *fluid_synth_get_settings(fluid_synth_t *synth);
|
||||
|
||||
/* MIDI channel messages */
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_noteon(fluid_synth_t *synth, int chan, int key, int vel);
|
||||
FLUIDSYNTH_API int fluid_synth_noteoff(fluid_synth_t *synth, int chan, int key);
|
||||
FLUIDSYNTH_API int fluid_synth_cc(fluid_synth_t *synth, int chan, int ctrl, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_get_cc(fluid_synth_t *synth, int chan, int ctrl, int *pval);
|
||||
FLUIDSYNTH_API int fluid_synth_sysex(fluid_synth_t *synth, const char *data, int len,
|
||||
char *response, int *response_len, int *handled, int dryrun);
|
||||
FLUIDSYNTH_API int fluid_synth_pitch_bend(fluid_synth_t *synth, int chan, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_get_pitch_bend(fluid_synth_t *synth, int chan, int *ppitch_bend);
|
||||
FLUIDSYNTH_API int fluid_synth_pitch_wheel_sens(fluid_synth_t *synth, int chan, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_get_pitch_wheel_sens(fluid_synth_t *synth, int chan, int *pval);
|
||||
FLUIDSYNTH_API int fluid_synth_program_change(fluid_synth_t *synth, int chan, int program);
|
||||
FLUIDSYNTH_API int fluid_synth_channel_pressure(fluid_synth_t *synth, int chan, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_key_pressure(fluid_synth_t *synth, int chan, int key, int val);
|
||||
FLUIDSYNTH_API int fluid_synth_bank_select(fluid_synth_t *synth, int chan, int bank);
|
||||
FLUIDSYNTH_API int fluid_synth_sfont_select(fluid_synth_t *synth, int chan, int sfont_id);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_program_select(fluid_synth_t *synth, int chan, int sfont_id,
|
||||
int bank_num, int preset_num);
|
||||
FLUIDSYNTH_API int
|
||||
fluid_synth_program_select_by_sfont_name(fluid_synth_t *synth, int chan,
|
||||
const char *sfont_name, int bank_num,
|
||||
int preset_num);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_get_program(fluid_synth_t *synth, int chan, int *sfont_id,
|
||||
int *bank_num, int *preset_num);
|
||||
FLUIDSYNTH_API int fluid_synth_unset_program(fluid_synth_t *synth, int chan);
|
||||
FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_all_notes_off(fluid_synth_t *synth, int chan);
|
||||
FLUIDSYNTH_API int fluid_synth_all_sounds_off(fluid_synth_t *synth, int chan);
|
||||
|
||||
/**
|
||||
* The midi channel type used by fluid_synth_set_channel_type()
|
||||
*/
|
||||
enum fluid_midi_channel_type
|
||||
{
|
||||
CHANNEL_TYPE_MELODIC = 0, /**< Melodic midi channel */
|
||||
CHANNEL_TYPE_DRUM = 1 /**< Drum midi channel */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_channel_type(fluid_synth_t *synth, int chan, int type);
|
||||
|
||||
|
||||
/* Low level access */
|
||||
FLUIDSYNTH_API fluid_preset_t *fluid_synth_get_channel_preset(fluid_synth_t *synth, int chan);
|
||||
FLUIDSYNTH_API int fluid_synth_start(fluid_synth_t *synth, unsigned int id,
|
||||
fluid_preset_t *preset, int audio_chan,
|
||||
int midi_chan, int key, int vel);
|
||||
FLUIDSYNTH_API int fluid_synth_stop(fluid_synth_t *synth, unsigned int id);
|
||||
|
||||
|
||||
/* SoundFont management */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_sfload(fluid_synth_t *synth, const char *filename, int reset_presets);
|
||||
FLUIDSYNTH_API int fluid_synth_sfreload(fluid_synth_t *synth, int id);
|
||||
FLUIDSYNTH_API int fluid_synth_sfunload(fluid_synth_t *synth, int id, int reset_presets);
|
||||
FLUIDSYNTH_API int fluid_synth_add_sfont(fluid_synth_t *synth, fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API int fluid_synth_remove_sfont(fluid_synth_t *synth, fluid_sfont_t *sfont);
|
||||
FLUIDSYNTH_API int fluid_synth_sfcount(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_synth_get_sfont(fluid_synth_t *synth, unsigned int num);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_synth_get_sfont_by_id(fluid_synth_t *synth, int id);
|
||||
FLUIDSYNTH_API fluid_sfont_t *fluid_synth_get_sfont_by_name(fluid_synth_t *synth,
|
||||
const char *name);
|
||||
FLUIDSYNTH_API int fluid_synth_set_bank_offset(fluid_synth_t *synth, int sfont_id, int offset);
|
||||
FLUIDSYNTH_API int fluid_synth_get_bank_offset(fluid_synth_t *synth, int sfont_id);
|
||||
|
||||
|
||||
/* Reverb */
|
||||
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb(fluid_synth_t *synth, double roomsize,
|
||||
double damping, double width, double level);
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_roomsize(fluid_synth_t *synth, double roomsize);
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_damp(fluid_synth_t *synth, double damping);
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_width(fluid_synth_t *synth, double width);
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb_level(fluid_synth_t *synth, double level);
|
||||
|
||||
FLUIDSYNTH_API void fluid_synth_set_reverb_on(fluid_synth_t *synth, int on);
|
||||
FLUIDSYNTH_API double fluid_synth_get_reverb_roomsize(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API double fluid_synth_get_reverb_damp(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API double fluid_synth_get_reverb_level(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API double fluid_synth_get_reverb_width(fluid_synth_t *synth);
|
||||
|
||||
|
||||
/* Chorus */
|
||||
|
||||
/**
|
||||
* Chorus modulation waveform type.
|
||||
*/
|
||||
enum fluid_chorus_mod
|
||||
{
|
||||
FLUID_CHORUS_MOD_SINE = 0, /**< Sine wave chorus modulation */
|
||||
FLUID_CHORUS_MOD_TRIANGLE = 1 /**< Triangle wave chorus modulation */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus(fluid_synth_t *synth, int nr, double level,
|
||||
double speed, double depth_ms, int type);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_nr(fluid_synth_t *synth, int nr);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_level(fluid_synth_t *synth, double level);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_speed(fluid_synth_t *synth, double speed);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_depth(fluid_synth_t *synth, double depth_ms);
|
||||
FLUIDSYNTH_API int fluid_synth_set_chorus_type(fluid_synth_t *synth, int type);
|
||||
|
||||
FLUIDSYNTH_API void fluid_synth_set_chorus_on(fluid_synth_t *synth, int on);
|
||||
FLUIDSYNTH_API int fluid_synth_get_chorus_nr(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API double fluid_synth_get_chorus_level(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API double fluid_synth_get_chorus_speed(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API double fluid_synth_get_chorus_depth(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_get_chorus_type(fluid_synth_t *synth); /* see fluid_chorus_mod */
|
||||
|
||||
|
||||
/* Audio and MIDI channels */
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_count_midi_channels(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_audio_channels(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_audio_groups(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_effects_channels(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_count_effects_groups(fluid_synth_t *synth);
|
||||
|
||||
|
||||
/* Synthesis parameters */
|
||||
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API void fluid_synth_set_sample_rate(fluid_synth_t *synth, float sample_rate);
|
||||
FLUIDSYNTH_API void fluid_synth_set_gain(fluid_synth_t *synth, float gain);
|
||||
FLUIDSYNTH_API float fluid_synth_get_gain(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_set_polyphony(fluid_synth_t *synth, int polyphony);
|
||||
FLUIDSYNTH_API int fluid_synth_get_polyphony(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_get_active_voice_count(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API int fluid_synth_get_internal_bufsize(fluid_synth_t *synth);
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_set_interp_method(fluid_synth_t *synth, int chan, int interp_method);
|
||||
|
||||
/**
|
||||
* Synthesis interpolation method.
|
||||
*/
|
||||
enum fluid_interp
|
||||
{
|
||||
FLUID_INTERP_NONE = 0, /**< No interpolation: Fastest, but questionable audio quality */
|
||||
FLUID_INTERP_LINEAR = 1, /**< Straight-line interpolation: A bit slower, reasonable audio quality */
|
||||
FLUID_INTERP_4THORDER = 4, /**< Fourth-order interpolation, good quality, the default */
|
||||
FLUID_INTERP_7THORDER = 7, /**< Seventh-order interpolation */
|
||||
|
||||
FLUID_INTERP_DEFAULT = FLUID_INTERP_4THORDER, /**< Default interpolation method */
|
||||
FLUID_INTERP_HIGHEST = FLUID_INTERP_7THORDER, /**< Highest interpolation method */
|
||||
};
|
||||
|
||||
/* Generator interface */
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_gen(fluid_synth_t *synth, int chan,
|
||||
int param, float value);
|
||||
FLUIDSYNTH_API float fluid_synth_get_gen(fluid_synth_t *synth, int chan, int param);
|
||||
|
||||
|
||||
/* Tuning */
|
||||
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_key_tuning(fluid_synth_t *synth, int bank, int prog,
|
||||
const char *name, const double *pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_octave_tuning(fluid_synth_t *synth, int bank, int prog,
|
||||
const char *name, const double *pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_tune_notes(fluid_synth_t *synth, int bank, int prog,
|
||||
int len, const int *keys, const double *pitch, int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_activate_tuning(fluid_synth_t *synth, int chan, int bank, int prog,
|
||||
int apply);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_deactivate_tuning(fluid_synth_t *synth, int chan, int apply);
|
||||
FLUIDSYNTH_API void fluid_synth_tuning_iteration_start(fluid_synth_t *synth);
|
||||
FLUIDSYNTH_API
|
||||
int fluid_synth_tuning_iteration_next(fluid_synth_t *synth, int *bank, int *prog);
|
||||
FLUIDSYNTH_API int fluid_synth_tuning_dump(fluid_synth_t *synth, int bank, int prog,
|
||||
char *name, int len, double *pitch);
|
||||
|
||||
/* Misc */
|
||||
|
||||
FLUIDSYNTH_API double fluid_synth_get_cpu_load(fluid_synth_t *synth);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API const char *fluid_synth_error(fluid_synth_t *synth);
|
||||
|
||||
|
||||
/* Default modulators */
|
||||
|
||||
/**
|
||||
* Enum used with fluid_synth_add_default_mod() to specify how to handle duplicate modulators.
|
||||
*/
|
||||
enum fluid_synth_add_mod
|
||||
{
|
||||
FLUID_SYNTH_OVERWRITE, /**< Overwrite any existing matching modulator */
|
||||
FLUID_SYNTH_ADD, /**< Sum up modulator amounts */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_add_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod, int mode);
|
||||
FLUIDSYNTH_API int fluid_synth_remove_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod);
|
||||
|
||||
|
||||
/*
|
||||
* Synthesizer plugin
|
||||
*
|
||||
* To create a synthesizer plugin, create the synthesizer as
|
||||
* explained above. Once the synthesizer is created you can call
|
||||
* any of the functions below to get the audio.
|
||||
*/
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_write_s16(fluid_synth_t *synth, int len,
|
||||
void *lout, int loff, int lincr,
|
||||
void *rout, int roff, int rincr);
|
||||
FLUIDSYNTH_API int fluid_synth_write_float(fluid_synth_t *synth, int len,
|
||||
void *lout, int loff, int lincr,
|
||||
void *rout, int roff, int rincr);
|
||||
FLUID_DEPRECATED FLUIDSYNTH_API int fluid_synth_nwrite_float(fluid_synth_t *synth, int len,
|
||||
float **left, float **right,
|
||||
float **fx_left, float **fx_right);
|
||||
FLUIDSYNTH_API int fluid_synth_process(fluid_synth_t *synth, int len,
|
||||
int nfx, float *fx[],
|
||||
int nout, float *out[]);
|
||||
|
||||
|
||||
/* Synthesizer's interface to handle SoundFont loaders */
|
||||
|
||||
FLUIDSYNTH_API void fluid_synth_add_sfloader(fluid_synth_t *synth, fluid_sfloader_t *loader);
|
||||
FLUIDSYNTH_API fluid_voice_t *fluid_synth_alloc_voice(fluid_synth_t *synth,
|
||||
fluid_sample_t *sample,
|
||||
int channum, int key, int vel);
|
||||
FLUIDSYNTH_API void fluid_synth_start_voice(fluid_synth_t *synth, fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API void fluid_synth_get_voicelist(fluid_synth_t *synth,
|
||||
fluid_voice_t *buf[], int bufsize, int ID);
|
||||
FLUIDSYNTH_API int fluid_synth_handle_midi_event(void *data, fluid_midi_event_t *event);
|
||||
|
||||
/**
|
||||
* Specifies the type of filter to use for the custom IIR filter
|
||||
*/
|
||||
enum fluid_iir_filter_type
|
||||
{
|
||||
FLUID_IIR_DISABLED = 0, /**< Custom IIR filter is not operating */
|
||||
FLUID_IIR_LOWPASS, /**< Custom IIR filter is operating as low-pass filter */
|
||||
FLUID_IIR_HIGHPASS, /**< Custom IIR filter is operating as high-pass filter */
|
||||
FLUID_IIR_LAST /**< @internal Value defines the count of filter types (#fluid_iir_filter_type) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies optional settings to use for the custom IIR filter. Can be bitwise ORed.
|
||||
*/
|
||||
enum fluid_iir_filter_flags
|
||||
{
|
||||
FLUID_IIR_Q_LINEAR = 1 << 0, /**< The Soundfont spec requires the filter Q to be interpreted in dB. If this flag is set the filter Q is instead assumed to be in a linear range */
|
||||
FLUID_IIR_Q_ZERO_OFF = 1 << 1, /**< If this flag the filter is switched off if Q == 0 (prior to any transformation) */
|
||||
FLUID_IIR_NO_GAIN_AMP = 1 << 2 /**< The Soundfont spec requires to correct the gain of the filter depending on the filter's Q. If this flag is set the filter gain will not be corrected. */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_custom_filter(fluid_synth_t *, int type, int flags);
|
||||
|
||||
|
||||
/* LADSPA */
|
||||
|
||||
FLUIDSYNTH_API fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth);
|
||||
|
||||
|
||||
/* API: Poly mono mode */
|
||||
|
||||
/** Interface to poly/mono mode variables
|
||||
*
|
||||
* Channel mode bits OR-ed together so that it matches with the midi spec: poly omnion (0), mono omnion (1), poly omnioff (2), mono omnioff (3)
|
||||
*/
|
||||
enum fluid_channel_mode_flags
|
||||
{
|
||||
FLUID_CHANNEL_POLY_OFF = 0x01, /**< if flag is set, the basic channel is in mono on state, if not set poly is on */
|
||||
FLUID_CHANNEL_OMNI_OFF = 0x02, /**< if flag is set, the basic channel is in omni off state, if not set omni is on */
|
||||
};
|
||||
|
||||
/** Indicates the breath mode a channel is set to */
|
||||
enum fluid_channel_breath_flags
|
||||
{
|
||||
FLUID_CHANNEL_BREATH_POLY = 0x10, /**< when channel is poly, this flag indicates that the default velocity to initial attenuation modulator is replaced by a breath to initial attenuation modulator */
|
||||
FLUID_CHANNEL_BREATH_MONO = 0x20, /**< when channel is mono, this flag indicates that the default velocity to initial attenuation modulator is replaced by a breath modulator */
|
||||
FLUID_CHANNEL_BREATH_SYNC = 0x40, /**< when channel is mono, this flag indicates that the breath controller(MSB)triggers noteon/noteoff on the running note */
|
||||
};
|
||||
|
||||
/** Indicates the mode a basic channel is set to */
|
||||
enum fluid_basic_channel_modes
|
||||
{
|
||||
FLUID_CHANNEL_MODE_MASK = (FLUID_CHANNEL_OMNI_OFF | FLUID_CHANNEL_POLY_OFF), /**< Mask Poly and Omni bits of #fluid_channel_mode_flags, usually only used internally */
|
||||
FLUID_CHANNEL_MODE_OMNION_POLY = FLUID_CHANNEL_MODE_MASK & (~FLUID_CHANNEL_OMNI_OFF & ~FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 0 */
|
||||
FLUID_CHANNEL_MODE_OMNION_MONO = FLUID_CHANNEL_MODE_MASK & (~FLUID_CHANNEL_OMNI_OFF & FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 1 */
|
||||
FLUID_CHANNEL_MODE_OMNIOFF_POLY = FLUID_CHANNEL_MODE_MASK & (FLUID_CHANNEL_OMNI_OFF & ~FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 2 */
|
||||
FLUID_CHANNEL_MODE_OMNIOFF_MONO = FLUID_CHANNEL_MODE_MASK & (FLUID_CHANNEL_OMNI_OFF | FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 3 */
|
||||
FLUID_CHANNEL_MODE_LAST /**< @internal Value defines the count of basic channel modes (#fluid_basic_channel_modes) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_reset_basic_channel(fluid_synth_t *synth, int chan);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_get_basic_channel(fluid_synth_t *synth, int chan,
|
||||
int *basic_chan_out,
|
||||
int *mode_chan_out,
|
||||
int *basic_val_out);
|
||||
FLUIDSYNTH_API int fluid_synth_set_basic_channel(fluid_synth_t *synth, int chan, int mode, int val);
|
||||
|
||||
/** Interface to mono legato mode
|
||||
*
|
||||
* Indicates the legato mode a channel is set to
|
||||
* n1,n2,n3,.. is a legato passage. n1 is the first note, and n2,n3,n4 are played legato with previous note. */
|
||||
enum fluid_channel_legato_mode
|
||||
{
|
||||
FLUID_CHANNEL_LEGATO_MODE_RETRIGGER, /**< Mode 0 - Release previous note, start a new note */
|
||||
FLUID_CHANNEL_LEGATO_MODE_MULTI_RETRIGGER, /**< Mode 1 - On contiguous notes retrigger in attack section using current value, shape attack using current dynamic and make use of previous voices if any */
|
||||
FLUID_CHANNEL_LEGATO_MODE_LAST /**< @internal Value defines the count of legato modes (#fluid_channel_legato_mode) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_legato_mode(fluid_synth_t *synth, int chan, int legatomode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_legato_mode(fluid_synth_t *synth, int chan, int *legatomode);
|
||||
|
||||
/** Interface to portamento mode
|
||||
*
|
||||
* Indicates the portamento mode a channel is set to
|
||||
*/
|
||||
enum fluid_channel_portamento_mode
|
||||
{
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_EACH_NOTE, /**< Mode 0 - Portamento on each note (staccato or legato) */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_LEGATO_ONLY, /**< Mode 1 - Portamento only on legato note */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_STACCATO_ONLY, /**< Mode 2 - Portamento only on staccato note */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_LAST /**< @internal Value defines the count of portamento modes (#fluid_channel_portamento_mode) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_portamento_mode(fluid_synth_t *synth,
|
||||
int chan, int portamentomode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_portamento_mode(fluid_synth_t *synth,
|
||||
int chan, int *portamentomode);
|
||||
|
||||
/* Interface to breath mode */
|
||||
FLUIDSYNTH_API int fluid_synth_set_breath_mode(fluid_synth_t *synth,
|
||||
int chan, int breathmode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_breath_mode(fluid_synth_t *synth,
|
||||
int chan, int *breathmode);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_SYNTH_H */
|
|
@ -0,0 +1,71 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_TYPES_H
|
||||
#define _FLUIDSYNTH_TYPES_H
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file types.h
|
||||
* @brief Type declarations
|
||||
*/
|
||||
|
||||
typedef struct _fluid_hashtable_t fluid_settings_t; /**< Configuration settings instance */
|
||||
typedef struct _fluid_synth_t fluid_synth_t; /**< Synthesizer instance */
|
||||
typedef struct _fluid_voice_t fluid_voice_t; /**< Synthesis voice instance */
|
||||
typedef struct _fluid_sfloader_t fluid_sfloader_t; /**< SoundFont loader plugin */
|
||||
typedef struct _fluid_sfont_t fluid_sfont_t; /**< SoundFont */
|
||||
typedef struct _fluid_preset_t fluid_preset_t; /**< SoundFont preset */
|
||||
typedef struct _fluid_sample_t fluid_sample_t; /**< SoundFont sample */
|
||||
typedef struct _fluid_mod_t fluid_mod_t; /**< SoundFont modulator */
|
||||
typedef struct _fluid_audio_driver_t fluid_audio_driver_t; /**< Audio driver instance */
|
||||
typedef struct _fluid_file_renderer_t fluid_file_renderer_t; /**< Audio file renderer instance */
|
||||
typedef struct _fluid_player_t fluid_player_t; /**< MIDI player instance */
|
||||
typedef struct _fluid_midi_event_t fluid_midi_event_t; /**< MIDI event */
|
||||
typedef struct _fluid_midi_driver_t fluid_midi_driver_t; /**< MIDI driver instance */
|
||||
typedef struct _fluid_midi_router_t fluid_midi_router_t; /**< MIDI router instance */
|
||||
typedef struct _fluid_midi_router_rule_t fluid_midi_router_rule_t; /**< MIDI router rule */
|
||||
typedef struct _fluid_hashtable_t fluid_cmd_hash_t; /**< Command handler hash table */
|
||||
typedef struct _fluid_shell_t fluid_shell_t; /**< Command shell */
|
||||
typedef struct _fluid_server_t fluid_server_t; /**< TCP/IP shell server instance */
|
||||
typedef struct _fluid_event_t fluid_event_t; /**< Sequencer event */
|
||||
typedef struct _fluid_sequencer_t fluid_sequencer_t; /**< Sequencer instance */
|
||||
typedef struct _fluid_ramsfont_t fluid_ramsfont_t; /**< RAM SoundFont */
|
||||
typedef struct _fluid_rampreset_t fluid_rampreset_t; /**< RAM SoundFont preset */
|
||||
typedef struct _fluid_cmd_handler_t fluid_cmd_handler_t; /**< Shell Command Handler */
|
||||
typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t; /**< LADSPA effects instance */
|
||||
typedef struct _fluid_file_callbacks_t fluid_file_callbacks_t; /**< Callback struct to perform custom file loading of soundfonts */
|
||||
|
||||
typedef int fluid_istream_t; /**< Input stream descriptor */
|
||||
typedef int fluid_ostream_t; /**< Output stream descriptor */
|
||||
|
||||
typedef short fluid_seq_id_t; /**< Unique client IDs used by the sequencer and #fluid_event_t, obtained by fluid_sequencer_register_client() and fluid_sequencer_register_fluidsynth() */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_TYPES_H */
|
|
@ -0,0 +1,47 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_VERSION_H
|
||||
#define _FLUIDSYNTH_VERSION_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file version.h
|
||||
* @brief Library version functions and defines
|
||||
*/
|
||||
|
||||
#define FLUIDSYNTH_VERSION "2.1.8" /**< String constant of libfluidsynth version. */
|
||||
#define FLUIDSYNTH_VERSION_MAJOR 2 /**< libfluidsynth major version integer constant. */
|
||||
#define FLUIDSYNTH_VERSION_MINOR 1 /**< libfluidsynth minor version integer constant. */
|
||||
#define FLUIDSYNTH_VERSION_MICRO 8 /**< libfluidsynth micro version integer constant. */
|
||||
|
||||
FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro);
|
||||
FLUIDSYNTH_API char* fluid_version_str(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_VERSION_H */
|
|
@ -0,0 +1,72 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_VOICE_H
|
||||
#define _FLUIDSYNTH_VOICE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file voice.h
|
||||
* @brief Synthesis voice manipulation functions.
|
||||
*
|
||||
* The interface to the synthesizer's voices.
|
||||
* Examples on using them can be found in fluid_defsfont.c.
|
||||
* Most of these functions should only be called from within synthesis context,
|
||||
* such as the SoundFont loader's noteon method.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Enum used with fluid_voice_add_mod() to specify how to handle duplicate modulators.
|
||||
*/
|
||||
enum fluid_voice_add_mod
|
||||
{
|
||||
FLUID_VOICE_OVERWRITE, /**< Overwrite any existing matching modulator */
|
||||
FLUID_VOICE_ADD, /**< Add (sum) modulator amounts */
|
||||
FLUID_VOICE_DEFAULT /**< For default modulators only, no need to check for duplicates */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API void fluid_voice_add_mod(fluid_voice_t *voice, fluid_mod_t *mod, int mode);
|
||||
FLUIDSYNTH_API float fluid_voice_gen_get(fluid_voice_t *voice, int gen);
|
||||
FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t *voice, int gen, float val);
|
||||
FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t *voice, int gen, float val);
|
||||
|
||||
FLUIDSYNTH_API unsigned int fluid_voice_get_id(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_channel(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_key(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_key(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_velocity(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_get_actual_velocity(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_playing(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_on(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_sustained(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_is_sostenuto(const fluid_voice_t *voice);
|
||||
FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t *s);
|
||||
FLUIDSYNTH_API void fluid_voice_update_param(fluid_voice_t *voice, int gen);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FLUIDSYNTH_VOICE_H */
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue