Merge branch 'master' into sm24

This commit is contained in:
derselbst 2017-10-28 16:23:24 +02:00
commit 0ac6209356
67 changed files with 4346 additions and 3495 deletions

53
.clang-tidy Normal file
View file

@ -0,0 +1,53 @@
---
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,cert-*,clang-analyzer-*,performance-*,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-delete-null-pointer,readability-implicit-bool-conversion,readability-inconsistent-declaration-parameter-name,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-simplify-boolean-expr'
WarningsAsErrors: ''
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
User: tom
CheckOptions:
- key: cert-dcl59-cpp.HeaderFileExtensions
value: h,hh,hpp,hxx
- key: cert-err09-cpp.CheckThrowTemporaries
value: '1'
- key: cert-err61-cpp.CheckThrowTemporaries
value: '1'
- key: cert-oop11-cpp.IncludeStyle
value: llvm
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
- key: modernize-loop-convert.MaxCopySize
value: '16'
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: 'NULL'
- key: performance-faster-string-find.StringLikeClasses
value: 'std::basic_string'
- key: performance-for-range-copy.WarnOnAllAutoCopies
value: '0'
- key: performance-inefficient-string-concatenation.StrictMode
value: '0'
- key: performance-type-promotion-in-math-fn.IncludeStyle
value: llvm
- key: performance-unnecessary-value-param.IncludeStyle
value: llvm
- key: readability-braces-around-statements.ShortStatementLines
value: '0'
- key: readability-simplify-boolean-expr.ChainedConditionalAssignment
value: '0'
- key: readability-simplify-boolean-expr.ChainedConditionalReturn
value: '0'
...

39
.github/issue_template.md vendored Normal file
View file

@ -0,0 +1,39 @@
<!--
Before submitting an issue, consider looking into our
wiki ( https://github.com/FluidSynth/fluidsynth/wiki ) or the
developer resources ( http://www.fluidsynth.org/api/ )
Please do not submit support requests or "How to" questions here. Instead, please use FluidSynth's
mailing list: https://lists.nongnu.org/mailman/listinfo/fluid-dev
Below is a form that shall help getting relevant information for bugs and feature requests together.
Feel free to use it, modify it or remove inapplicable/unneeded parts.
-->
### FluidSynth version <!-- enter FluidSynths version you're using -->
1.1.x
### Current behavior
<!-- Describe the current situation, e.g. how the bug manifests. -->
### Expected behavior
<!-- Describe what the behavior would be without the bug or how the
feature request would make your life easier. -->
### Steps to reproduce
<!-- Please explain the steps required to duplicate the issue,
esp. if you are able to provide a sample application. -->
### Other information
<!-- If you are able to illustrate the bug or feature request with an example, please provide simple
source code below or as attatched file. List any other information that is relevant to your issue:
Stack traces,
related issues,
build logs,
suggestions on how to fix,
links to related discussions at fluid-dev
etc.
-->
```
insert code snippets or anything relevant here, or attach it as extra file(s) if it's too much
```

View file

@ -6,7 +6,6 @@ env:
- CMAKE_FLAGS="-Denable-floats=1 -Denable-profiling=1"
- CMAKE_FLAGS="-Denable-trap-on-fpe=1"
- CMAKE_FLAGS="-Denable-fpe-check=1"
- CMAKE_FLAGS="-Denable-debug=1"
matrix:
include:
- os: linux
@ -25,6 +24,7 @@ matrix:
- portaudio19-dev
- libpulse-dev
- libdbus-glib-1-dev
- ladspa-sdk
env:
- MATRIX_EVAL="CC=gcc-4.8 && CXX=g++-4.8"
- CMAKE_FLAGS="-Denable-floats=1"
@ -45,6 +45,7 @@ matrix:
- portaudio19-dev
- libpulse-dev
- libdbus-glib-1-dev
- ladspa-sdk
env:
- MATRIX_EVAL="CC=gcc-4.8 && CXX=g++-4.8"
- CMAKE_FLAGS="-Denable-floats=0"
@ -59,6 +60,7 @@ matrix:
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
@ -73,8 +75,10 @@ matrix:
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
- CMAKE_FLAGS="-Denable-debug=1"
# works on Precise and Trusty
- os: linux
@ -87,6 +91,7 @@ matrix:
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
@ -101,6 +106,7 @@ matrix:
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
@ -111,12 +117,12 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- george-edison55-precise-backports
packages:
- clang-3.8
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=clang-3.8 && CXX=clang++-3.8"
@ -126,12 +132,12 @@ matrix:
apt:
sources:
- llvm-toolchain-trusty-3.9
- george-edison55-precise-backports
packages:
- clang-3.9
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9"
@ -141,12 +147,12 @@ matrix:
apt:
sources:
- llvm-toolchain-trusty-4.0
- george-edison55-precise-backports
packages:
- clang-4.0
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
@ -156,12 +162,12 @@ matrix:
apt:
sources:
- llvm-toolchain-trusty-5.0
- george-edison55-precise-backports
packages:
- clang-5.0
- cmake-data
- cmake
- libglib2.0-0
- ladspa-sdk
env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0"
@ -181,11 +187,12 @@ matrix:
- MATRIX_EVAL="brew install gcc glib libsndfile jack dbus-glib pulseaudio portaudio && CC=gcc-7 && CXX=g++-7"
before_install:
- if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get update; else brew update; fi
- eval "${MATRIX_EVAL}"
before_script:
- mkdir build && cd build
script:
- cmake ${CMAKE_FLAGS} "-DCMAKE_BUILD_TYPE=RelWithDebInfo" ..
- cmake ${CMAKE_FLAGS} "-Denable-portaudio=1" "-Denable-ladspa=1" "-DCMAKE_BUILD_TYPE=RelWithDebInfo" ..
- make -j4

View file

@ -22,6 +22,7 @@
cmake_minimum_required ( VERSION 3.0.2 )
project ( FluidSynth C )
set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_admin )
set ( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# FluidSynth package name
set ( PACKAGE "fluidsynth" )
@ -29,7 +30,7 @@ set ( PACKAGE "fluidsynth" )
# FluidSynth package version
set ( FLUIDSYNTH_VERSION_MAJOR 1 )
set ( FLUIDSYNTH_VERSION_MINOR 1 )
set ( FLUIDSYNTH_VERSION_MICRO 7 )
set ( FLUIDSYNTH_VERSION_MICRO 8 )
set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" )
set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
@ -44,7 +45,7 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
# This is not exactly the same algorithm as the libtool one, but the results are the same.
set ( LIB_VERSION_CURRENT 1 )
set ( LIB_VERSION_AGE 6 )
set ( LIB_VERSION_REVISION 0 )
set ( LIB_VERSION_REVISION 1 )
set ( LIB_VERSION_INFO
"${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
@ -152,7 +153,7 @@ if ( CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" )
endif ( OS2 )
set ( GNUCC_WARNING_FLAGS "-Wall -W -Wpointer-arith -Wbad-function-cast -Wno-cast-qual -Wcast-align -Wstrict-prototypes -Wno-unused-parameter -Wdeclaration-after-statement" )
set ( CMAKE_C_FLAGS_DEBUG "-std=gnu89 -g ${GNUCC_VISIBILITY_FLAG} -DDEBUG ${GNUCC_WARNING_FLAGS}" )
set ( CMAKE_C_FLAGS_DEBUG "-std=gnu89 -g ${GNUCC_VISIBILITY_FLAG} -DDEBUG ${GNUCC_WARNING_FLAGS} -fsanitize=undefined" )
set ( CMAKE_C_FLAGS_RELEASE "-std=gnu89 -O2 -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS}" )
set ( CMAKE_C_FLAGS_RELWITHDEBINFO "-std=gnu89 -O2 -g -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS}" )
endif ( CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" )

View file

@ -1,7 +1,6 @@
[![Build Status](https://travis-ci.org/FluidSynth/fluidsynth.svg?branch=master)](https://travis-ci.org/FluidSynth/fluidsynth)
Introduction
============
# Introduction
FluidSynth is a software real-time synthesizer based on the
Soundfont 2 specifications.
@ -11,15 +10,13 @@ device. It is the software analogue of a MIDI synthesizer. FluidSynth
can also play midifiles using a Soundfont.
Information on the web
======================
# Information on the web
The place to look if you are looking for the latest information on
FluidSynth is the web site at http://www.fluidsynth.org/.
Why did we do it
================
# Why did we do it
The synthesizer grew out of a project, started by Samuel Bianchini and
Peter Hanappe, and later joined by Johnathan Lee, that aimed at
@ -53,8 +50,7 @@ synthesizer. That is why we developed FluidSynth.
Design decisions
================
# Design decisions
The synthesizer was designed to be as self-contained as possible for
several reasons:
@ -74,14 +70,13 @@ several reasons:
on external code.
Links
=====
# Links
Home Page
### Home Page
- http://www.fluidsynth.org
Documentation
### Documentation
- Introduction to SoundFonts, by Josh Green,
http://smurf.sourceforge.net/sfont_intro.php
@ -96,7 +91,7 @@ Documentation
http://www.midi.org/about-midi/dls/abtdls.htm
Software SoundFont Synthesizers:
### Software SoundFont Synthesizers:
- LiveSynth Pro DXi and Crescendo from LiveUpdate (Win),
http://www.livesynth.com/lspro.html
@ -108,7 +103,7 @@ http://www.livesynth.com/lspro.html
- Logic from eMagic, http://www.emagic.de
Soundfont Editors
### Soundfont Editors
- Project SWAMI by Josh Green (Linux), http://www.swamiproject.org/
@ -120,7 +115,7 @@ Soundfont Editors
**Note:** We cannot recommend using Audio Compositor for creating or editing Soundfonts, as it generates files that violate the Soundfont2 spec (specifically the order of generators as defined in section 8.1.2) and are therefore unusable with fluidsynth!
Conversion Tools
### Conversion Tools
- CDxtract from CDxtract (Win), http://www.cdxtract.com
@ -131,7 +126,7 @@ http://www.propellerheads.se/products/recycle/
http://www.chickensys.com/translator
Soundfont Databases
### Soundfont Databases
- HammerSound, http://www.hammersound.net

View file

@ -1065,7 +1065,7 @@ fluidmax_version(t_object *o)
post(" Max/MSP integration by Norbert Schnell IMTR IRCAM - Centre Pompidou");
}
extern fluid_gen_info_t fluid_gen_info[];
extern const fluid_gen_info_t fluid_gen_info[];
static void
fluidmax_print(t_object *o, Symbol *s, short ac, Atom *at)

View file

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libfluidsynth
PROJECT_NUMBER = 1.1.7
PROJECT_NUMBER = 1.1.8
OUTPUT_DIRECTORY = api
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
@ -124,6 +124,7 @@ HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
HTML_EXTRA_FILES = ../doc/fluidsettings.xml ../doc/fluidsettings.xsl
GENERATE_HTMLHELP = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"

View file

@ -124,6 +124,7 @@ HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
HTML_EXTRA_FILES = @CMAKE_SOURCE_DIR@/doc/fluidsettings.xml @CMAKE_SOURCE_DIR@/doc/fluidsettings.xsl
GENERATE_HTMLHELP = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"

522
doc/fluidsettings.xml Normal file
View file

@ -0,0 +1,522 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
NOTE: You're not expected to look at this raw XML file. Please open it in a webbrowser, favourably firefox,
and it should display a nice HTML page. Make sure the fluidsettings.xsl stylesheet is provided in the
same directory as the fluidsettings.xml
Some browsers may not allow local XML files to be rendered and display blank page instead. Please
consult the web on how to make your browser display XSLT content. For instance if you're using Chrome
and open the file locally you'll need to start Chrome with the "allow-file-access-from-files" flag.
https://stackoverflow.com/a/3839054
https://stackoverflow.com/a/6251757
-->
<?xml-stylesheet type="text/xsl" href="fluidsettings.xsl"?>
<fluidsettings>
<synth>
<setting>
<isFirst>Synthesizer settings</isFirst>
<name>audio-channels</name>
<type>int</type>
<def>1</def>
<min>1</min>
<max>128</max>
<desc>
By default, the synthesizer outputs a single stereo signal. Using this option, the synthesizer can output multichannel audio. Sets the number of stereo channel pairs. So 1 is actually 2 channels (a stereo pair).</desc>
</setting>
<setting>
<name>audio-groups</name>
<type>int</type>
<def>1</def>
<min>1</min>
<max>128</max>
<desc>
Normally the same value as synth.audio-channels. LADSPA effects subsystem can use this value though, in which case it may differ.</desc>
</setting>
<setting>
<name>chorus.active</name>
<type>bool</type>
<def>1 (TRUE)</def>
<desc>
When set to 1 (TRUE) the chorus effects module is activated. Otherwise, no chorus will be added to the output signal. Note that the amount of signal sent to the chorus module depends on the "chorus send" generator defined in the SoundFont.</desc>
</setting>
<setting>
<name>cpu-cores</name>
<type>int</type>
<def>1</def>
<min>1</min>
<max>256</max>
<desc>
(Experimental) Sets the number of synthesis CPU cores. If set to a value greater than 1, then additional synthesis threads will be created to take advantage of a multi CPU or CPU core system. This has the affect of utilizing more of the total CPU for voices or decreasing render times when synthesizing audio to a file.</desc>
</setting>
<setting>
<name>device-id</name>
<type>int</type>
<def>0</def>
<min>0</min>
<max>126</max>
<desc>
Device identifier used for SYSEX commands, such as MIDI Tuning Standard commands. Only those SYSEX commands destined for this ID or to all devices will be acted upon.</desc>
</setting>
<setting>
<name>effects-channels</name>
<type>int</type>
<def>2</def>
<min>2</min>
<max>2</max>
<desc>Currently unused.</desc>
</setting>
<setting>
<name>gain</name>
<type>num</type>
<def>0.2</def>
<min>0.0</min>
<max>10.0</max>
<desc>The gain is applied to the final or master output of the synthesizer. It is set to a low value by default to avoid the saturation of the output when many notes are played.</desc>
</setting>
<setting>
<name>ladspa.active</name>
<type>bool</type>
<def>0 (FALSE)</def>
<desc>
When set to "yes" the LADSPA subsystem will be enabled. This subsystem allows to load and interconnect LADSPA plug-ins. The output of the synthesizer is processed by the LADSPA subsystem. Note that the synthesizer has to be compiled with LADSPA support. More information about the LADSPA subsystem later.</desc>
</setting>
<setting>
<name>midi-channels</name>
<type>int</type>
<def>16</def>
<min>16</min>
<max>256</max>
<desc>
This setting defines the number of MIDI channels of the synthesizer. The MIDI standard defines 16 channels, so MIDI hardware is limited to this number. Internally FluidSynth can use more channels which can be mapped to different MIDI sources.</desc>
</setting>
<setting>
<name>midi-bank-select</name>
<type>str</type>
<def>gs</def>
<vals>gm, gs, xg, mma</vals>
<desc>
This setting defines how the synthesizer interprets Bank Select messages.
<ul>
<li>gm: ignores CC0 and CC32 messages.</li>
<li>gs: (default) CC0 becomes the bank number, CC32 is ignored.</li>
<li>xg: CC32 becomes the bank number, CC0 toggles between melodic or drum channel.</li>
<li>mma: bank is calculated as CC0*128+CC32.</li>
</ul>
</desc>
</setting>
<setting>
<name>min-note-length</name>
<type>int</type>
<def>10</def>
<min>0</min>
<max>65535</max>
<desc>
Sets the minimum note duration in milliseconds. This ensures that really short duration note events, such as percussion notes, have a better chance of sounding as intended. Set to 0 to disable this feature.</desc>
</setting>
<setting>
<name>parallel-render</name>
<type>bool</type>
<def>1 (TRUE)</def>
<desc>
This is the low-latency setting. If on, you're allowed to call fluid_synth_write_s16, fluid_synth_write_float, fluid_synth_nwrite_float or fluid_synth_process in parallel with the rest of the calls, and it won't be blocked by time intensive calls to the synth. Turn it off if throughput is more important than latency, e g in rendering-to-file scenarios where underruns is not an issue.
</desc>
<deprecated>
As of 1.1.7 this option is deprecated. This option enforces thread safety for rvoice_mixer, which causes rvoice_events to be queued internally. The current implementation relies on the fact that this option is set to TRUE to correctly render any amount of requested audio. Also calling fluid_synth_write_* in parallel is not considered to be a use-case. It would cause undefined audio output, as it would be unpredictable for the user which rvoice_events specifically would be dispatched to which fluid_synth_write_* call.
</deprecated>
</setting>
<setting>
<name>polyphony</name>
<type>int</type>
<def>256</def>
<min>1</min>
<max>65535</max>
<desc>
The polyphony defines how many voices can be played in parallel. A note event produces one or more voices. Its good to set this to a value which the system can handle and will thus limit FluidSynth's CPU usage. When FluidSynth runs out of voices it will begin terminating lower priority voices for new note events.</desc>
</setting>
<setting>
<name>reverb.active</name>
<type>bool</type>
<def>1 (TRUE)</def>
<desc>
When set to 1 (TRUE) the reverb effects module is activated. Otherwise, no reverb will be added to the output signal. Note that the amount of signal sent to the reverb module depends on the "reverb send" generator defined in the SoundFont.
</desc>
</setting>
<setting>
<name>sample-rate</name>
<type>num</type>
<def>44100.0</def>
<min>22050.0</min>
<max>96000.0</max>
<desc>
The sample rate of the audio generated by the synthesizer.
</desc>
</setting>
<setting>
<name>threadsafe-api</name>
<type>bool</type>
<def>1 (TRUE)</def>
<desc>
Controls whether the synth's public API is protected by a mutex or not. Default is on, turn it off for slightly better performance if you know you're only accessing the synth from one thread only, this could be the case in many embedded use cases for example. Note that libfluidsynth can use many threads by itself (shell is one, midi driver is one, midi player is one etc) so you should usually leave it on. Also see synth.parallel-render.
</desc>
</setting>
<setting>
<name>verbose</name>
<type>bool</type>
<def>0 (FALSE)</def>
<desc>
When set to 1 (TRUE) the synthesizer will print out information about the received MIDI events to the stdout. This can be helpful for debugging. This setting cannot be changed after the synthesizer has started.
</desc>
</setting>
<setting>
<name>volenv</name>
<type>str</type>
<def>emu</def>
<vals>compliant, emu</vals>
<desc>
Specifies the kind of volume envelope processing. This esp. influences the way fluidsynth responses to noteon velocity. The default setting 'emu' causes the envelope to be highly dynamic (i.e. compatible with the EMU10K1). Alternatively this may be set to 'compliant' for a less dynamic envelope, as it was done before fluidsynth 1.0.9. Note that this setting can only be changed until the first synth has been created. Changing it afterwards will have no effect for the rest of fluidsynths lifetime.
</desc>
</setting>
</synth>
<audio>
<setting>
<isFirst>Audio driver settings</isFirst>
<name>driver</name>
<type>str</type>
<def>jack (Linux),<br />
dsound (Windows),<br />
sndman (MacOS9),<br />
coreaudio (Mac OS X),<br />
dart (OS/2)
</def>
<vals>jack, alsa, oss, pulseaudio, coreaudio, dsound, portaudio, sndman, dart, file</vals>
<desc>
The audio system to be used.
</desc>
</setting>
<setting>
<name>periods</name>
<type>int</type>
<def>16 (Linux, Mac OS X),<br />
8 (Windows)
</def>
<min>2</min>
<max>64</max>
<desc>
The number of the audio buffers used by the driver. This number of buffers, multiplied by the buffer size (see setting audio.period-size), determines the maximum latency of the audio driver.
</desc>
</setting>
<setting>
<name>period-size</name>
<type>int</type>
<def>64 (Linux, Mac OS X),<br />
512 (Windows)
</def>
<min>64</min>
<max>8192</max>
<desc>
The size of the audio buffers (in frames).
</desc>
</setting>
<setting>
<name>realtime-prio</name>
<type>int</type>
<def>60</def>
<min>0</min>
<max>99</max>
<desc>
Sets the realtime scheduling priority of the audio synthesis thread (0 disables high priority scheduling). Linux is the only platform which currently makes use of different priority levels. Drivers which use this option: alsa, oss and pulseaudio
</desc>
</setting>
<setting>
<name>sample-format</name>
<type>str</type>
<def>16bits</def>
<vals>16bits, float</vals>
<desc>
The format of the audio samples. This is currently only an indication; the audio driver may ignore this setting if it can't handle the specified format.
</desc>
</setting>
<setting>
<name>alsa.device</name>
<type>str</type>
<def>default</def>
<vals>ALSA device string, such as: "hw:0", "plughw:1", etc.</vals>
<desc>
Selects the ALSA audio device to use.
</desc>
</setting>
<setting>
<name>coreaudio.device</name>
<type>str</type>
<def>default</def>
<desc>
Selects the CoreAudio device to use.
</desc>
</setting>
<setting>
<name>dart.device</name>
<type>str</type>
<def>default</def>
<desc>
Selects the Dart (OS/2 driver) device to use.
</desc>
</setting>
<setting>
<name>dsound.device</name>
<type>str</type>
<def>default</def>
<desc>
Selects the DirectSound (Windows) device to use.
</desc>
</setting>
<setting>
<name>file.endian</name>
<type>str</type>
<def>'auto' if libsndfile support is built in,<br />
'cpu' otherwise.</def>
<vals>auto, big, cpu, little ('cpu' is all that is supported if libsndfile support is not built in)</vals>
<desc>
Defines the byte order when using the 'file' driver or file renderer to store audio to a file. 'auto' uses the default for the given file type, 'cpu' uses the CPU byte order, 'big' uses big endian byte order and 'little' uses little endian byte order.
</desc>
</setting>
<setting>
<name>file.format</name>
<type>str</type>
<def>s16</def>
<vals>double, float, s16, s24, s32, s8, u8</vals>
<desc>
Defines the audio format when rendering audio to a file. Limited to 's16' if no libsndfile support.
<ul>
<li>'double' is 64 bit floating point,</li>
<li>'float' is 32 bit floating point,</li>
<li>'s16' is 16 bit signed PCM,</li>
<li>'s24' is 24 bit signed PCM,</li>
<li>'s32' is 32 bit signed PCM,</li>
<li>'s8' is 8 bit signed PCM and</li>
<li>'u8' is 8 bit unsigned PCM.</li>
</ul>
</desc>
</setting>
<setting>
<name>file.name</name>
<type>str</type>
<def>'fluidsynth.wav' if libsndfile support is built in,<br />
'fluidsynth.raw' otherwise.</def>
<desc>
Specifies the file name to store the audio to, when rendering audio to a file.
</desc>
</setting>
<setting>
<name>file.type</name>
<type>str</type>
<def>'auto' if libsndfile support is built in,<br />
'raw' otherwise.</def>
<vals>aiff, au, auto, avr, caf, flac, htk, iff, mat, oga, paf, pvf, raw, sd2, sds, sf, voc, w64, wav, xi</vals>
<desc>
Sets the file type of the file which the audio will be stored to. 'auto' attempts to determine the file type from the audio.file.name file extension and falls back to 'wav' if the extension doesn't match any types. Limited to 'raw' if compiled without libsndfile support. Actual options will vary depending on libsndfile library.
</desc>
</setting>
<setting>
<name>jack.autoconnect</name>
<type>bool</type>
<def>0 (FALSE)</def>
<desc>
If 1 (TRUE), then FluidSynth output is automatically connected to jack system audio output.
</desc>
</setting>
<setting>
<name>jack.id</name>
<type>str</type>
<def>fluidsynth</def>
<desc>
ID used when creating Jack client connection.
</desc>
</setting>
<setting>
<name>jack.multi</name>
<type>bool</type>
<def>0 (FALSE)</def>
<desc>
If 1 (TRUE), then multi-channel Jack output will be enabled if synth.audio-channels is greater than 1.
</desc>
</setting>
<setting>
<name>jack.server</name>
<type>str</type>
<def></def>
<desc>
Jack server to connect to. Defaults to an empty string, which uses default Jack server.
</desc>
</setting>
<setting>
<name>oss.device</name>
<type>str</type>
<def>/dev/dsp</def>
<desc>
Device to use for OSS audio output.
</desc>
</setting>
<setting>
<name>portaudio.device</name>
<type>str</type>
<def>PortAudio Default</def>
<desc>
Device to use for PortAudio driver output. Note that 'PortAudio Default' is a special value which outputs to the default PortAudio device.
</desc>
</setting>
<setting>
<name>pulseaudio.adjust-latency</name>
<type>bool</type>
<def>1 (TRUE)</def>
<desc>
If TRUE increases the latency dynamically if PulseAudio suggests so. Else uses a buffer with length of "audio.period-size".
</desc>
</setting>
<setting>
<name>pulseaudio.device</name>
<type>str</type>
<def>default</def>
<desc>
Device to use for PulseAudio driver output.
</desc>
</setting>
<setting>
<name>pulseaudio.media-role</name>
<type>str</type>
<def>music</def>
<desc>
PulseAudio media role information.
</desc>
</setting>
<setting>
<name>pulseaudio.server</name>
<type>str</type>
<def>default</def>
<desc>
Server to use for PulseAudio driver output.
</desc>
</setting>
</audio>
<midi>
<setting>
<isFirst>MIDI driver settings</isFirst>
<name>autoconnect</name>
<type>bool</type>
<def>0 (FALSE)</def>
<desc>
If 1 (TRUE), automatically connects FluidSynth to available MIDI input ports. alsa_seq is currently the only driver making use of this.
</desc>
</setting>
<setting>
<name>driver</name>
<type>str</type>
<def>alsa_seq (Linux),<br />
winmidi (Windows),<br />
jack (Mac OS X)</def>
<vals>alsa_raw, alsa_seq, coremidi, jack, midishare, oss, winmidi</vals>
<desc>The MIDI system to be used.</desc>
</setting>
<setting>
<name>realtime-prio</name>
<type>int</type>
<def>50</def>
<min>0</min>
<max>99</max>
<desc>Sets the realtime scheduling priority of the MIDI thread (0 disables high priority scheduling). Linux is the only platform which currently makes use of different priority levels. Drivers which use this option: alsa_raw, alsa_seq, oss</desc>
</setting>
<setting>
<name>portname</name>
<type>str</type>
<def></def>
<desc>Used by coremidi and alsa_seq drivers for the portnames registered with the MIDI subsystem.</desc>
</setting>
<setting>
<name>alsa.device</name>
<type>str</type>
<def>default</def>
<desc>ALSA MIDI device to use for RAW ALSA MIDI driver.</desc>
</setting>
<setting>
<name>alsa_seq.device</name>
<type>str</type>
<def>default</def>
<desc>ALSA sequencer device to use for ALSA sequencer driver.</desc>
</setting>
<setting>
<name>alsa_seq.id</name>
<type>str</type>
<def>pid</def>
<desc>ID to use when registering ports with the ALSA sequencer driver. If set to "pid" then the ID will be "FLUID Synth (PID)", where PID is the FluidSynth process ID of the audio thread otherwise the provided string will be used in place of PID.</desc>
</setting>
<setting>
<name>coremidi.id</name>
<type>str</type>
<def>pid</def>
<desc>Client ID to use for CoreMIDI driver. 'pid' will use process ID as port of the client name.</desc>
</setting>
<setting>
<name>jack.server</name>
<type>str</type>
<def></def>
<desc>Jack server to connect to for Jack MIDI driver. If an empty string then the default server will be used.</desc>
</setting>
<setting>
<name>jack.id</name>
<type>str</type>
<def>fluidsynth-midi</def>
<desc>Client ID to use with the Jack MIDI driver. If jack is also used as audio driver and "midi.jack.server" and "audio.jack.server" are equal, this setting will be overridden by "audio.jack.id", because a client cannot have multiple names.</desc>
</setting>
<setting>
<name>oss.device</name>
<type>str</type>
<def>/dev/midi</def>
<desc>Device to use for OSS MIDI driver.</desc>
</setting>
<setting>
<name>winmidi.device</name>
<type>str</type>
<def>default</def>
<desc>Device for Windows MIDI driver.</desc>
</setting>
</midi>
<player>
<setting>
<isFirst>MIDI player settings</isFirst>
<name>reset-synth</name>
<type>bool</type>
<def>1 (TRUE)</def>
<desc>If true, reset the synth before starting a new MIDI song, so the state of a previous song can't affect the new song. Turn it off for seamless looping of a song.</desc>
</setting>
<setting>
<name>timing-source</name>
<type>str</type>
<def>sample</def>
<vals>sample, system</vals>
<desc>Determines the timing source of the player sequencer. 'sample' uses the sample clock (how much audio has been output) to sequence events, in which case audio is synchronized with MIDI events. 'system' uses the system clock, audio and MIDI are not synchronized exactly.</desc>
</setting>
</player>
<shell>
<setting>
<isFirst>Shell (command line) settings</isFirst>
<name>prompt</name>
<type>str</type>
<def>""</def>
<desc>In dump mode we set the prompt to "". The ui cannot easily handle lines, which don't end with cr. Changing the prompt cannot be done through a command, because the current shell does not handle empty arguments.</desc>
</setting>
<setting>
<name>port</name>
<type>num</type>
<def>9800</def>
<min>1</min>
<max>65535</max>
<desc>The shell can be used in a client/server mode. This setting controls what TCP/IP port the server uses.</desc>
</setting>
</shell>
</fluidsettings>

209
doc/fluidsettings.xsl Normal file
View file

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-system="about:legacy-compat"/>
<xsl:template match="/">
<html>
<head>
<style>
table
{
border: 3px solid black;
}
.first-row
{
border-top: 3px solid black;
}
th
{
font-weight: normal;
white-space: nowrap;
padding: 15px 5px 15px 5px;
border-top: 1px solid black;
border-left: 1px solid black;
border-right: 1px solid black;
}
td
{
padding: 15px 5px 15px 5px;
}
.cell-def
{
white-space: nowrap;
border-top: 1px solid black;
}
.cell-vals
{
border-top: 1px solid black;
}
.cell-desc
{
border-top: 1px solid black;
}
.audio {background-color: hsl(170, 100%, 90%);}
.midi {background-color: hsl(125, 100%, 90%);}
.player {background-color: hsl(85, 100%, 85%);}
.shell {background-color: hsl(60, 100%, 90%);}
.synth {background-color: hsl(35, 100%, 90%);}
.deprecated {background-color: hsl(0, 0%, 93%);}
</style>
<title>FluidSettings</title>
</head>
<body>
<h1>FluidSettings</h1>
<ul>
<!-- Select the first setting of each group and use it for building up a TOC -->
<xsl:for-each select="fluidsettings/*/*[isFirst]">
<xsl:sort select="name(..)" />
<li style="margin-bottom: 15px">
<xsl:attribute name="class">
<xsl:value-of select="name(..)" />
</xsl:attribute>
<a>
<xsl:attribute name="href"><![CDATA[#]]><xsl:value-of select="name(..)" /><![CDATA[.]]><xsl:value-of select="name" /></xsl:attribute>
<xsl:value-of select="isFirst" />
</a>
</li>
</xsl:for-each>
</ul>
<table>
<!--print each and every setting row by row in the table-->
<xsl:for-each select="fluidsettings/*/*">
<xsl:sort select="name(..)" />
<!-- <xsl:sort select="name" /> -->
<tr>
<!-- the class attribute of tr shall be the name of the settings group of the current setting, unless the setting is marked deprecated -->
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="deprecated">
deprecated
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(..)" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td class="cell-name first-row">
<xsl:attribute name="id"><xsl:value-of select="name(..)" /><![CDATA[.]]><xsl:value-of select="name" /></xsl:attribute>
<a>
<xsl:attribute name="href"><![CDATA[#]]><xsl:value-of select="name(..)" /><![CDATA[.]]><xsl:value-of select="name" /></xsl:attribute>
<xsl:value-of select="name(..)" />.<xsl:value-of select="name" />
</a>
</td>
<th class="first-row">Type</th>
<td class="cell-type first-row">
<xsl:value-of select="type" />
</td>
</tr>
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="deprecated">
deprecated
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(..)" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td></td>
<th>Default</th>
<td class="cell-def">
<xsl:copy-of select="def" />
</td>
</tr>
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="deprecated">
deprecated
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(..)" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td></td>
<th>
<xsl:choose>
<xsl:when test="type = 'str'">
Values
</xsl:when>
<xsl:when test="type = 'bool'">
Values
</xsl:when>
<xsl:otherwise>
Min
-
Max
</xsl:otherwise>
</xsl:choose>
</th>
<td class="cell-vals">
<xsl:choose>
<xsl:when test="type = 'str'">
<xsl:value-of select="vals" />
</xsl:when>
<xsl:when test="type = 'bool'">
1, "yes", 0, "no"
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="min" />
-
<xsl:value-of select="max" />
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="deprecated">
deprecated
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(..)" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td></td>
<th>Description</th>
<td class="cell-desc">
<xsl:copy-of select="desc" />
<xsl:choose>
<xsl:when test="deprecated">
<br /><br />
<strong style="color:red">DEPRECATED</strong><br /><br />
<xsl:copy-of select="deprecated" />
</xsl:when>
</xsl:choose>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

File diff suppressed because it is too large Load diff

View file

@ -10,10 +10,10 @@
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public License
.\" along with this program; see the file COPYING. If not, write to
.\" along with this program; see the file LICENSE. If not, write to
.\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
.\"
.TH FluidSynth 1 "Aug 26, 2010"
.TH FluidSynth 1 "Oct 14, 2017"
.\" Please update the above date whenever this man page is modified.
.\"
.\" Some roff macros, for reference:
@ -141,232 +141,7 @@ Show version of program
Size of each audio buffer
.SH SETTINGS
All settings are non-realtime (have no effect if set after startup), except for those
indicated as realtime.
.TP
.B SYNTHESIZER
.TP
.B synth.audio\-channels INT [min=1, max=128, def=1]
Number of audio channels (DOCME!).
.TP
.B synth.audio\-groups INT [min=1, max=128, def=1]
Number of audio groups (DOCME!).
.TP
.B synth.chorus.active BOOL [def=True]
Chorus effect enable toggle.
.TP
.B synth.cpu\-cores INT [min=1, max=256, def=1]
Number of CPU cores to use for multi-core support.
.TP
.B synth.device\-id INT [min=0, max=126, def=0] REALTIME
Device ID to use for accepting incoming SYSEX messages.
.TP
.B synth.effects\-channels INT [min=2, max=2, def=2]
No effect currently.
.TP
.B synth.gain FLOAT [min=0.000, max=10.000, def=0.200] REALTIME
Master synthesizer gain.
.TP
.B synth.ladspa.active BOOL [def=False]
LADSPA subsystem enable toggle.
.TP
.B synth.midi\-channels INT [min=16, max=256, def=16]
Total MIDI channel count (must be multiple of 16).
.TP
.B synth.midi\-bank\-select STR [def='gs' vals:'gm', 'gs', 'xg', 'mma']
MIDI Bank Select message style.
.TP
.B synth.min\-note\-length INT [min=0, max=65535, def=10]
Minimum duration for note events (work around for very short percussion notes).
.TP
.B synth.overflow.age FLOAT [min=\-10000, max=10000, def=1000]
Weigthing (on overflow) for a voice's duration.
.TP
.B synth.overflow.percussion FLOAT [min=\-10000, max=10000, def=4000]
Weighting (on overflow) for a voice being on the drum channel.
.TP
.B synth.overflow.released FLOAT [min=\-10000, max=10000, def=\-2000]
Weighting (on overflow) for a voice that has been released,
i e note off and no sustain pedal.
.TP
.B synth.overflow.sustained FLOAT [min=\-10000, max=10000, def=\-1000]
Weighting (on overflow) for a voice that has been sustained,
i e note off, but sustain pedal held down.
.TP
.B synth.overflow.volume FLOAT [min=\-10000, max=10000, def=500]
Weighting (on overflow) for a voice's volume.
.TP
.B synth.parallel-render BOOL [def=True]
Enables low-latency audio rendering response, even if synth is otherwise busy.
Should always to be true for usage by fluidsynth executable.
.TP
.B synth.polyphony INT [min=1, max=65535, def=256] REALTIME
Voice polyphony count (number of simultaneous voices allowed).
.TP
.B synth.reverb.active BOOL [def=True]
Reverb effect enable toggle.
.TP
.B synth.sample\-rate FLOAT [min=22050.000, max=96000.000, def=44100.000]
Synthesizer sample rate.
.TP
.B synth.threadsafe-api BOOL [def=True]
Serializes access to the synth API.
Must always to be true for usage by fluidsynth executable.
.TP
.B synth.verbose BOOL [def=False]
Print received MIDI events to stdout.
.TP
.B synth.volenv STR [def='emu' vals:'compliant', 'emu']
Specifies the kind of volume envelope processing. This esp. influences the way fluidsynth responses to noteon velocity. The default setting 'emu' causes the envelope to be highly dynamic (i.e. compatible with the EMU10K1). Alternatively this may be set to 'compliant' for a less dynamic envelope, as it was done before fluidsynth 1.0.9.
.TP
.B GENERAL AUDIO
.TP
.B audio.driver STR
Audio driver to use. Default and valid options depend on available drivers.
.TP
.B audio.input\-channels INT [min=0, max=2, def=0]
Not used currently? (DOCME).
.TP
.B audio.output\-channels INT [min=2, max=32, def=2]
DOCME
.TP
.B audio.period\-size INT [min=64, max=8192, def=64]
Period size for audio buffers. Used by many audio drivers.
.TP
.B audio.periods INT [min=2, max=64, def=16]
Count of audio buffers. Used by many audio drivers.
.TP
.B audio.realtime\-prio INT [min=0, max=99, def=60]
Realtime priority to assign to audio thread or 0 to disable high priority scheduling.
Only used by some audio drivers (currently 'alsa' and 'oss').
.TP
.B audio.sample\-format STR [def='16bits' vals:'16bits','float']
Audio output format, to select format for those drivers which support 16 bit or floating point.
.TP
.B AUDIO DRIVER SPECIFIC
.TP
.B audio.alsa.device STR [def='default']
ALSA audio driver output device.
.TP
.B audio.coreaudio.device STR [def='default']
CoreAudio driver output device. Valid options depend on system.
.TP
.B audio.dart.device STR [def='default']
OS/2 Dart audio driver device.
.TP
.B audio.dsound.device STR [def='default']
Device to use for DirectSound driver. Valid options depend on system.
.TP
.B audio.file.endian STR [def='auto' vals:'auto','big','cpu','little']
File renderer or file driver byte order selection. 'auto' selects the default for the selected
file type. 'cpu' uses the CPU byte order. Limited to 'cpu' if no libsndfile support.
.TP
.B audio.file.format STR [def='s16' vals:'double','float','s16','s24','s32','s8','u8']
File renderer or file driver audio format. Limited to 's16' if no libsndfile support.
.TP
.B audio.file.name STR [def='fluidsynth.wav']
Output file name for file renderer or file driver.
.TP
.B audio.file.type STR [def='auto' vals:'aiff','au','auto','flac','oga','raw','wav']
Output file type for file renderer or file driver. 'auto' attempts to determine type from file
extension in audio.file.name. Limited to 'raw' if no libsndfile support. Actual options will vary
depending on libsndfile library.
.TP
.B audio.jack.autoconnect BOOL [def=False]
If enabled, then FluidSynth is automatically connected to Jack system audio output ports.
.TP
.B audio.jack.id STR [def='fluidsynth']
Client ID to use when connecting to Jack.
.TP
.B audio.jack.multi BOOL [def=False]
TRUE to enable multi-channel output.
.TP
.B audio.jack.server STR [def='']
Jack server name. Blank for default.
.TP
.B audio.oss.device STR [def='/dev/dsp']
OSS driver output device.
.TP
.B audio.portaudio.device STR [def='PortAudio Default']
PortAudio driver output device. Available options depends on system.
.TP
.B audio.pulseaudio.adjust-latency BOOL [def=True]
Increases the latency dynamically if PulseAudio suggests so.
.TP
.B audio.pulseaudio.device STR [def='default']
PulseAudio driver output device.
.TP
.B audio.pulseaudio.media-role STR [def='music']
PulseAudio media role information.
.TP
.B audio.pulseaudio.server STR [def='default']
PulseAudio driver server.
.TP
.B GENERAL MIDI
.TP
.B midi.driver STR
MIDI driver to use. Default and valid options depend on available drivers.
.TP
.B midi.realtime\-prio INT [min=0, max=99, def=50]
Realtime priority to assign to MIDI thread or 0 to disable high priority scheduling.
Only used by some MIDI drivers (currently 'alsa_seq', 'alsa_raw' and 'oss').
.TP
.B MIDI DRIVER SPECIFIC
.TP
.B midi.alsa.device STR [def='default']
ALSA raw MIDI driver device.
.TP
.B midi.alsa_seq.device STR [def='default']
ALSA sequencer MIDI driver device.
.TP
.B midi.alsa_seq.id STR [def='pid']
ALSA sequencer client ID. 'pid' will use process ID as part of the client name.
.TP
.B midi.coremidi.id STR [def='pid']
Client ID to use for CoreMIDI driver. 'pid' will use process ID as port of the client name.
.TP
.B midi.jack.id STR [def='fluidsynth-midi']
Jack MIDI driver client ID.
.TP
.B midi.jack.server STR [def='']
Jack MIDI driver server. Blank to use default.
.TP
.B midi.oss.device STR [def='/dev/midi']
OSS MIDI driver device.
.TP
.B midi.portname STR [def='']
Port name used for CoreAudio and ALSA sequencer drivers.
.TP
.B midi.winmidi.device STR [def='default']
Device for Windows MIDI driver.
.TP
.B MISCELLANEOUS
.TP
.B player.reset\-synth BOOL [def=True]
TRUE to reset synthesizer MIDI state between MIDI songs.
.TP
.B player.timing\-source STR [def='sample' vals:'sample','system']
Selects timing source for MIDI sequencer. 'system' uses the system timer. 'sample'
uses the sample clock (amount of audio output, events synchronized with audio).
.TP
.B shell.port INT [min=1, max=65535, def=9800]
Shell command server TCP/IP port number to use.
.TP
.B shell.prompt STR [def='']
Shell prompt string.
The settings to be specified with \-o are documented in the fluidsettings.xml hopefully shipped with this distribution or online at http://www.fluidsynth.org/api/fluidsettings.xml . We recommend viewing this file in a webbrowser, favourably Firefox.
.SH SHELL COMMANDS
.TP

64
doc/ladspa.md Normal file
View file

@ -0,0 +1,64 @@
# FluidSynth LADSPA Interface
The [LADSPA](http://ladspa.org/) (Linux Audio Developer's Simple Plugin API)
binding can be used to route the FluidSynth audio output through any number
of LADSPA plugins. As the name implies, it is only available on Linux.
## Configuration
To configure and compile FluidSynth with LADSPA support, make sure you have
the LADSPA SDK (basically the ladspa.h header file) installed. Then enable
LADSPA when calling cmake:
cmake -Denable-ladspa=1 <path-to-source>
You should see `LADSPA support: yes` in the cmake output.
To enable the LADSPA engine, use the `synth.ladspa.active` setting when
starting FluidSynth:
fluidsynth -o synth.ladspa.active=1 ...
# Signal Flow
The LADSPA effects unit runs immediately after the internal reverb and chorus
effects have been processed. When no plugins have been configured, the
effects unit is dormant and uses no additional system resources.
When at least one plugin is configured and the engine is activated, the
rendered audio is passed into the LADSPA effects unit, each plugin is
run in the order that they were created and the resulting audio is
passed back into FluidSynth (and from there to the sound card or other
output).
# Loading and Connecting Plugins
Currently the only way to configure the effects unit is via the FluidSynth
shell or via a config file.
## Example Setups
All examples assume that your `LADSPA_PATH` environment variable points
to the directory containing the plugin libraries (e.g. /usr/lib/ladspa).
### Single Plugin
The following loads the delay.so plugin library from the LADSPA SDK and
instantiates the `delay_5s` plugin from that library. It connects the
main left channel output from FluidSynth with the plugin input, the
main left channel input to FluidSynth with the plugin output. It also
sets the two control ports of the plugin to example values and starts
the engine.
ladspa_plugin delay.so delay_5s
ladspa_port Input < in1_L
ladspa_port Output > out1_L
ladspa_port Delay = 1.0
ladspa_port Dry/Wet = 0.5
ladspa_start
The audible effect should be an untouched right channel and a slightly
lower volume on the left with a delay effect of 1 second on top.

View file

@ -46,6 +46,15 @@ extern "C" {
#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.

View file

@ -95,18 +95,22 @@ FLUIDSYNTH_API
int fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id,
unsigned int* bank_num, unsigned int* preset_num);
FLUIDSYNTH_API int fluid_synth_unset_program (fluid_synth_t *synth, int chan);
FLUIDSYNTH_API int fluid_synth_get_channel_info (fluid_synth_t *synth, int chan,
fluid_synth_channel_info_t *info);
FLUIDSYNTH_API
FLUID_DEPRECATED
int fluid_synth_get_channel_info (fluid_synth_t *synth, int chan, fluid_synth_channel_info_t *info);
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,
CHANNEL_TYPE_DRUM = 1
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);
@ -241,12 +245,14 @@ FLUIDSYNTH_API float fluid_synth_get_gen(fluid_synth_t* synth, int chan, int par
/* Tuning */
FLUIDSYNTH_API
FLUID_DEPRECATED
int fluid_synth_create_key_tuning(fluid_synth_t* synth, int bank, int prog,
const char* name, const double* pitch);
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
FLUID_DEPRECATED
int fluid_synth_create_octave_tuning(fluid_synth_t* synth, int bank, int prog,
const char* name, const double* pitch);
FLUIDSYNTH_API
@ -256,11 +262,14 @@ 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
FLUID_DEPRECATED
int fluid_synth_select_tuning(fluid_synth_t* synth, int chan, int bank, int prog);
FLUIDSYNTH_API
int fluid_synth_activate_tuning(fluid_synth_t* synth, int chan, int bank, int prog,
int apply);
FLUIDSYNTH_API int fluid_synth_reset_tuning(fluid_synth_t* synth, int chan);
FLUIDSYNTH_API
FLUID_DEPRECATED
int fluid_synth_reset_tuning(fluid_synth_t* synth, int chan);
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);
@ -275,6 +284,19 @@ FLUIDSYNTH_API double fluid_synth_get_cpu_load(fluid_synth_t* synth);
FLUIDSYNTH_API 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, /**< Add (sum) modulator amounts */
};
FLUIDSYNTH_API int fluid_synth_add_default_mod(fluid_synth_t* synth, fluid_mod_t* mod, int mode);
/*
* Synthesizer plugin
*
@ -320,8 +342,9 @@ FLUIDSYNTH_API void fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t*
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);
FLUIDSYNTH_API void fluid_synth_set_midi_router(fluid_synth_t* synth,
fluid_midi_router_t* router);
FLUIDSYNTH_API
FLUID_DEPRECATED
void fluid_synth_set_midi_router(fluid_synth_t* synth, fluid_midi_router_t* router);
#ifdef __cplusplus
}

289
run-clang-tidy.py Normal file
View file

@ -0,0 +1,289 @@
#!/usr/bin/env python
#
#===- run-clang-tidy.py - Parallel clang-tidy runner ---------*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
# FIXME: Integrate with clang-tidy-diff.py
"""
Parallel clang-tidy runner
==========================
Runs clang-tidy over all files in a compilation database. Requires clang-tidy
and clang-apply-replacements in $PATH.
Example invocations.
- Run clang-tidy on all files in the current working directory with a default
set of checks and show warnings in the cpp files and all project headers.
run-clang-tidy.py $PWD
- Fix all header guards.
run-clang-tidy.py -fix -checks=-*,llvm-header-guard
- Fix all header guards included from clang-tidy and header guards
for clang-tidy headers.
run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \
-header-filter=extra/clang-tidy
Compilation database setup:
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
"""
from __future__ import print_function
import argparse
import glob
import json
import multiprocessing
import os
import re
import shutil
import subprocess
import sys
import tempfile
import threading
import traceback
import yaml
is_py2 = sys.version[0] == '2'
if is_py2:
import Queue as queue
else:
import queue as queue
def find_compilation_database(path):
"""Adjusts the directory until a compilation database is found."""
result = './'
while not os.path.isfile(os.path.join(result, path)):
if os.path.realpath(result) == '/':
print('Error: could not find compilation database.')
sys.exit(1)
result += '../'
return os.path.realpath(result)
def get_tidy_invocation(f, clang_tidy_binary, checks, tmpdir, build_path,
header_filter, extra_arg, extra_arg_before, quiet):
"""Gets a command line for clang-tidy."""
start = [clang_tidy_binary]
if header_filter is not None:
start.append('-header-filter=' + header_filter)
else:
# Show warnings in all in-project headers by default.
start.append('-header-filter=^' + build_path + '/.*')
if checks:
start.append('-checks=' + checks)
if tmpdir is not None:
start.append('-export-fixes')
# Get a temporary file. We immediately close the handle so clang-tidy can
# overwrite it.
(handle, name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir)
os.close(handle)
start.append(name)
for arg in extra_arg:
start.append('-extra-arg=%s' % arg)
for arg in extra_arg_before:
start.append('-extra-arg-before=%s' % arg)
start.append('-p=' + build_path)
if quiet:
start.append('-quiet')
start.append(f)
return start
def merge_replacement_files(tmpdir, mergefile):
"""Merge all replacement files in a directory into a single file"""
# The fixes suggested by clang-tidy >= 4.0.0 are given under
# the top level key 'Diagnostics' in the output yaml files
mergekey="Diagnostics"
merged=[]
for replacefile in glob.iglob(os.path.join(tmpdir, '*.yaml')):
content = yaml.safe_load(open(replacefile, 'r'))
if not content:
continue # Skip empty files.
merged.extend(content.get(mergekey, []))
if merged:
# MainSourceFile: The key is required by the definition inside
# include/clang/Tooling/ReplacementsYaml.h, but the value
# is actually never used inside clang-apply-replacements,
# so we set it to '' here.
output = { 'MainSourceFile': '', mergekey: merged }
with open(mergefile, 'w') as out:
yaml.safe_dump(output, out)
else:
# Empty the file:
open(mergefile, 'w').close()
def check_clang_apply_replacements_binary(args):
"""Checks if invoking supplied clang-apply-replacements binary works."""
try:
subprocess.check_call([args.clang_apply_replacements_binary, '--version'])
except:
print('Unable to run clang-apply-replacements. Is clang-apply-replacements '
'binary correctly specified?', file=sys.stderr)
traceback.print_exc()
sys.exit(1)
def apply_fixes(args, tmpdir):
"""Calls clang-apply-fixes on a given directory."""
invocation = [args.clang_apply_replacements_binary]
if args.format:
invocation.append('-format')
if args.style:
invocation.append('-style=' + args.style)
invocation.append(tmpdir)
subprocess.call(invocation)
def run_tidy(args, tmpdir, build_path, queue):
"""Takes filenames out of queue and runs clang-tidy on them."""
while True:
name = queue.get()
invocation = get_tidy_invocation(name, args.clang_tidy_binary, args.checks,
tmpdir, build_path, args.header_filter,
args.extra_arg, args.extra_arg_before,
args.quiet)
sys.stdout.write(' '.join(invocation) + '\n')
subprocess.call(invocation)
queue.task_done()
def main():
parser = argparse.ArgumentParser(description='Runs clang-tidy over all files '
'in a compilation database. Requires '
'clang-tidy and clang-apply-replacements in '
'$PATH.')
parser.add_argument('-clang-tidy-binary', metavar='PATH',
default='clang-tidy',
help='path to clang-tidy binary')
parser.add_argument('-clang-apply-replacements-binary', metavar='PATH',
default='clang-apply-replacements',
help='path to clang-apply-replacements binary')
parser.add_argument('-checks', default=None,
help='checks filter, when not specified, use clang-tidy '
'default')
parser.add_argument('-header-filter', default=None,
help='regular expression matching the names of the '
'headers to output diagnostics from. Diagnostics from '
'the main file of each translation unit are always '
'displayed.')
parser.add_argument('-export-fixes', metavar='filename', dest='export_fixes',
help='Create a yaml file to store suggested fixes in, '
'which can be applied with clang-apply-replacements.')
parser.add_argument('-j', type=int, default=0,
help='number of tidy instances to be run in parallel.')
parser.add_argument('files', nargs='*', default=['.*'],
help='files to be processed (regex on path)')
parser.add_argument('-fix', action='store_true', help='apply fix-its')
parser.add_argument('-format', action='store_true', help='Reformat code '
'after applying fixes')
parser.add_argument('-style', default='file', help='The style of reformat '
'code after applying fixes')
parser.add_argument('-p', dest='build_path',
help='Path used to read a compile command database.')
parser.add_argument('-extra-arg', dest='extra_arg',
action='append', default=[],
help='Additional argument to append to the compiler '
'command line.')
parser.add_argument('-extra-arg-before', dest='extra_arg_before',
action='append', default=[],
help='Additional argument to prepend to the compiler '
'command line.')
parser.add_argument('-quiet', action='store_true',
help='Run clang-tidy in quiet mode')
args = parser.parse_args()
db_path = 'compile_commands.json'
if args.build_path is not None:
build_path = args.build_path
else:
# Find our database
build_path = find_compilation_database(db_path)
try:
invocation = [args.clang_tidy_binary, '-list-checks']
invocation.append('-p=' + build_path)
if args.checks:
invocation.append('-checks=' + args.checks)
invocation.append('-')
print(subprocess.check_output(invocation))
except:
print("Unable to run clang-tidy.", file=sys.stderr)
sys.exit(1)
# Load the database and extract all files.
database = json.load(open(os.path.join(build_path, db_path)))
files = [entry['file'] for entry in database]
max_task = args.j
if max_task == 0:
max_task = multiprocessing.cpu_count()
tmpdir = None
if args.fix or args.export_fixes:
check_clang_apply_replacements_binary(args)
tmpdir = tempfile.mkdtemp()
# Build up a big regexy filter from all command line arguments.
file_name_re = re.compile('|'.join(args.files))
try:
# Spin up a bunch of tidy-launching threads.
task_queue = queue.Queue(max_task)
for _ in range(max_task):
t = threading.Thread(target=run_tidy,
args=(args, tmpdir, build_path, task_queue))
t.daemon = True
t.start()
# Fill the queue with files.
for name in files:
if file_name_re.search(name):
task_queue.put(name)
# Wait for all threads to be done.
task_queue.join()
except KeyboardInterrupt:
# This is a sad hack. Unfortunately subprocess goes
# bonkers with ctrl-c and we start forking merrily.
print('\nCtrl-C detected, goodbye.')
if tmpdir:
shutil.rmtree(tmpdir)
os.kill(0, 9)
return_code = 0
if args.export_fixes:
print('Writing fixes to ' + args.export_fixes + ' ...')
try:
merge_replacement_files(tmpdir, args.export_fixes)
except:
print('Error exporting fixes.\n', file=sys.stderr)
traceback.print_exc()
return_code=1
if args.fix:
print('Applying fixes ...')
try:
apply_fixes(args, tmpdir)
except:
print('Error applying fixes.\n', file=sys.stderr)
traceback.print_exc()
return_code=1
if tmpdir:
shutil.rmtree(tmpdir)
sys.exit(return_code)
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load diff

View file

@ -33,64 +33,74 @@ int fluid_is_empty(char* a);
char* fluid_expand_path(char* path, char* new_path, int len);
/** the handlers for the command lines */
int fluid_handle_help(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_quit(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_noteon(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_noteoff(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_pitch_bend(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_pitch_bend_range(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_cc(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_prog(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_select(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_inst(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_channels(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_load(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_unload(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reload(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_fonts(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_mstat(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbpreset(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetroomsize(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetdamp(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetwidth(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetlevel(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorusnr(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_choruslevel(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorusspeed(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorusdepth(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorus(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverb(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_gain(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_interp(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_interpc(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_tuning(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_tune(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_settuning(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_resettuning(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_tunings(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_dumptuning(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reset(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_source(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_echo(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_help(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_quit(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_noteon(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_noteoff(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_pitch_bend(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_pitch_bend_range(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_cc(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_prog(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_select(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_inst(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_channels(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_load(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_unload(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reload(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_fonts(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbpreset(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetroomsize(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetdamp(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetwidth(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverbsetlevel(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorusnr(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_choruslevel(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorusspeed(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorusdepth(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_chorus(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reverb(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_gain(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_interp(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_interpc(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_tuning(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_tune(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_settuning(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_resettuning(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_tunings(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_dumptuning(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_reset(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_source(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_echo(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_set(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_get(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_info(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_settings(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_set(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_get(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_info(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_settings(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_clear(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_default(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_begin(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_end(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_chan(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_par1(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_par2(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_clear(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_default(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_begin(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_end(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_chan(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_par1(void* data, int ac, char** av, fluid_ostream_t out);
int fluid_handle_router_par2(void* data, int ac, char** av, fluid_ostream_t out);
#ifdef LADSPA
int fluid_handle_ladspa_plugin(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_port(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_node(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_control(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_control_defaults(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_check(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_start(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_stop(void* data, int ac, char **av, fluid_ostream_t out);
int fluid_handle_ladspa_reset(void* data, int ac, char **av, fluid_ostream_t out);
#endif
fluid_cmd_t* fluid_cmd_copy(fluid_cmd_t* cmd);
void delete_fluid_cmd(fluid_cmd_t* cmd);
int fluid_cmd_handler_handle(fluid_cmd_handler_t* handler,
int fluid_cmd_handler_handle(void* data,
int ac, char** av,
fluid_ostream_t out);
@ -102,7 +112,6 @@ void fluid_server_add_client(fluid_server_t* server, fluid_client_t* client);
fluid_client_t* new_fluid_client(fluid_server_t* server,
fluid_settings_t* settings,
fluid_cmd_handler_t* handler,
fluid_socket_t sock);
void delete_fluid_client(fluid_client_t* client);

View file

@ -54,21 +54,20 @@ struct _fluid_file_renderer_t {
/* File audio format names.
* !! Keep in sync with format_ids[] */
const char *format_names[] = {
static const char * const format_names[] = {
"s8",
"s16",
"s24",
"s32",
"u8",
"float",
"double",
NULL /* Terminator */
"double"
};
/* File audio format IDs.
* !! Keep in sync with format_names[] */
const int format_ids[] = {
static const int format_ids[] = {
SF_FORMAT_PCM_S8,
SF_FORMAT_PCM_16,
SF_FORMAT_PCM_24,
@ -80,17 +79,16 @@ const int format_ids[] = {
/* File endian byte order names.
* !! Keep in sync with endian_ids[] */
const char *endian_names[] = {
static const char * const endian_names[] = {
"auto",
"little",
"big",
"cpu",
NULL
"cpu"
};
/* File endian byte order ids.
* !! Keep in sync with endian_names[] */
const int endian_ids[] = {
static const int endian_ids[] = {
SF_ENDIAN_FILE,
SF_ENDIAN_LITTLE,
SF_ENDIAN_BIG,
@ -107,21 +105,18 @@ static int fluid_file_renderer_find_valid_format (SF_INFO *info);
/* File type names. */
const char *type_names[] = {
"raw",
NULL /* Terminator */
static const char * const type_names[] = {
"raw"
};
/* File audio format names. */
const char *format_names[] = {
"s16",
NULL /* Terminator */
static const char * const format_names[] = {
"s16"
};
/* File endian byte order names. */
const char *endian_names[] = {
"cpu",
NULL
static const char * const endian_names[] = {
"cpu"
};
#endif
@ -134,7 +129,7 @@ fluid_file_renderer_settings (fluid_settings_t* settings)
SF_FORMAT_INFO finfo, cmpinfo;
int major_count;
int i, i2;
const char **np;
unsigned int n;
fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.wav",
FLUID_HINT_FILENAME, NULL, NULL);
@ -165,11 +160,11 @@ fluid_file_renderer_settings (fluid_settings_t* settings)
fluid_settings_add_option (settings, "audio.file.type", finfo.extension);
}
for (np = format_names; *np; np++)
fluid_settings_add_option (settings, "audio.file.format", *np);
for (n = 0; n < FLUID_N_ELEMENTS(format_names); n++)
fluid_settings_add_option (settings, "audio.file.format", format_names[n]);
for (np = endian_names; *np; np++)
fluid_settings_add_option (settings, "audio.file.endian", *np);
for (n = 0; n < FLUID_N_ELEMENTS(endian_names); n++)
fluid_settings_add_option (settings, "audio.file.endian", endian_names[n]);
#else
@ -317,7 +312,7 @@ int
fluid_file_set_encoding_quality(fluid_file_renderer_t* r, double q)
{
#if LIBSNDFILE_SUPPORT
if (sf_command (r->sndfile, SFC_SET_VBR_ENCODING_QUALITY, &q, sizeof (double)) == 0)
if (sf_command (r->sndfile, SFC_SET_VBR_ENCODING_QUALITY, &q, sizeof (double)) == SF_TRUE)
return FLUID_OK;
else
#endif
@ -417,7 +412,7 @@ fluid_file_renderer_parse_options (char *filetype, char *format, char *endian,
{
int type = -1; /* -1 indicates "auto" type */
char *s;
int i;
unsigned int i;
/* If "auto" type, then use extension to search for a match */
if (!filetype || FLUID_STRCMP (filetype, "auto") == 0)
@ -443,11 +438,11 @@ fluid_file_renderer_parse_options (char *filetype, char *format, char *endian,
/* Look for subtype */
if (format)
{
for (i = 0; format_names[i]; i++)
for (i = 0; i < FLUID_N_ELEMENTS(format_names); i++)
if (FLUID_STRCMP (format, format_names[i]) == 0)
break;
if (!format_names[i])
if (i >= FLUID_N_ELEMENTS(format_names))
{
FLUID_LOG (FLUID_ERR, "Invalid or unsupported file audio format '%s'", format);
return FALSE;
@ -466,11 +461,11 @@ fluid_file_renderer_parse_options (char *filetype, char *format, char *endian,
/* Look for endian */
if (endian)
{
for (i = 0; endian_names[i]; i++)
for (i = 0; i < FLUID_N_ELEMENTS(endian_names); i++)
if (FLUID_STRCMP (endian, endian_names[i]) == 0)
break;
if (!endian_names[i])
if (i >= FLUID_N_ELEMENTS(endian_names))
{
FLUID_LOG (FLUID_ERR, "Invalid or unsupported endian byte order '%s'", endian);
return FALSE;

File diff suppressed because it is too large Load diff

View file

@ -21,220 +21,48 @@
/* Author: Markus Nentwig, nentwig@users.sourceforge.net
*/
#ifndef _FLUID_LADSPA_H
#define _FLUID_LADSPA_H
/***************************************************************
*
* INCLUDES
*/
#include "fluid_sys.h"
#include "fluidsynth_priv.h"
#ifdef LADSPA
#include "fluid_list.h"
#include <pthread.h>
#include <ladspa.h>
/***************************************************************
*
* DEFINES
*/
typedef enum _fluid_ladspa_dir_t {
FLUID_LADSPA_INPUT,
FLUID_LADSPA_OUTPUT,
FLUID_LADSPA_FIXED
/* How many different plugin libraries may be used at the same time? */
#define FLUID_LADSPA_MaxLibs 100
/* How many plugin instances may be used at the same time? */
#define FLUID_LADSPA_MaxPlugins 100
/* How many nodes are allowed? */
#define FLUID_LADSPA_MaxNodes 100
/* How many tokens are allowed in one command line? (for example 152 => max. 50 port plugin allowed) */
#define FLUID_LADSPA_MaxTokens 152
/* What is the maximum path length? */
#define FLUID_LADSPA_MaxPathLength 512
/***************************************************************
*
* ENUM
*/
} fluid_ladspa_dir_t;
typedef enum {
fluid_LADSPA_NoMatch,
fluid_LADSPA_PartialMatch,
fluid_LADSPA_FullMatch
} fluid_LADSPA_Stringmatch_t;
/* Bypass state of the Fx unit */
typedef enum {
fluid_LADSPA_Active,
fluid_LADSPA_Bypassed,
fluid_LADSPA_BypassRequest
} fluid_LADSPA_BypassState;
typedef enum {
fluid_LADSPA_node_is_source=1,
fluid_LADSPA_node_is_sink=2,
fluid_LADSPA_node_is_audio=4,
fluid_LADSPA_node_is_control=8,
fluid_LADSPA_node_is_dummy=16,
fluid_LADSPA_node_is_user_ctrl=32
} fluid_LADSPA_nodeflags;
/* fluid_LADSPA_Node_t
* An internal node of the Fx unit.
* A 'node' is the 'glue' that connects several LADSPA plugins.
* Basically it's a real-valued variable (control node) or a real-valued buffer (audio node).
*/
typedef struct {
LADSPA_Data * buf; /*Either the buffer (Audio node) or a single control value (Control node)*/
char * Name; /* Unique identifier*/
int InCount; /* How many sources feed into this node? (0 or 1) */
int OutCount; /* How many other elements take data out of this node? */
int flags;
} fluid_LADSPA_Node_t;
/*
* fluid_LADSPA_Fx_t
* Fx unit using LADSPA.
* This includes a number of LADSPA plugins, their libraries, nodes etc.
* The Fx unit connects its input to Fluidsynth and its output to the soundcard.
*/
typedef struct {
/* LADSPA-plugins are in shared libraries (for example aw.so).
* Pointers to them are stored here. A library is uniquely identified through
* its filename (full path).*/
fluid_synth_t* synth;
int NumberLibs;
void * ppvPluginLibs[FLUID_LADSPA_MaxLibs];
char * ppvPluginLibNames[FLUID_LADSPA_MaxLibs];
/*List of plugins (descriptor and instance)
* A LADSPA plugin descriptor points to the code, which is executed, when a plugin is run.
* The plugin instance is given as a parameter, when calling.
*/
int NumberPlugins;
const LADSPA_Descriptor * PluginDescriptorTable[FLUID_LADSPA_MaxPlugins];
LADSPA_Handle * PluginInstanceTable[FLUID_LADSPA_MaxPlugins];
/* List of nodes */
int NumberNodes;
fluid_LADSPA_Node_t * Nodelist[FLUID_LADSPA_MaxNodes];
/* List of Command lines
* During the setup phase, each ladspa_add command creates one command sequence. For example:
* ./aw.so alienwah_stereo Input <- Master_L_Synth Output -> Master_R_Synth Parameter <- $42.0
* Those lists are stored in LADSPA_Command_Sequence.
* One command line results in one plugin => size MaxPlugins.
*/
int NumberCommands;
char ** LADSPA_Command_Sequence[FLUID_LADSPA_MaxPlugins];
/* User control nodes
* A user control node is declared at any time before the ladspa_start command.
* It acts as a constant node, but it has a name and can be changed with the ladspa_nodeset command. */
int NumberUserControlNodes;
char * UserControlNodeNames[FLUID_LADSPA_MaxNodes];
fluid_real_t UserControlNodeValues[FLUID_LADSPA_MaxNodes];
/* Bypass switch
* If set, the LADSPA Fx unit does not touch the signal.*/
fluid_LADSPA_BypassState Bypass;
/* Communication between the 'command line' process and the synthesis process.
* A possible conflict situation arises, when fluid_clear is called, and starts to destroy
* the plugins. But the synthesis thread still processes plugins at the same time. The consequences are ugly.
* Therefore ladspa_clear waits for acknowledgement from the synthesis thread, that the Fx unit is bypassed.
* 'cond' is used for the communication, the mutex is required for changing the condition.
*/
pthread_cond_t cond;
pthread_mutex_t mutex;
} fluid_LADSPA_FxUnit_t;
/*
* misc
*/
/* Purpose:
* Creates a new Fx unit in bypass mode with default settings.
* It is ready for further calls (add, clear, start).
*/
fluid_LADSPA_FxUnit_t* new_fluid_LADSPA_FxUnit(fluid_synth_t* synth);
/* Purpose:
* Applies the master gain (from command line option --gain or gain command).
* Processes one block of sound data (generated from the synthesizer) through
* the LADSPA Fx unit.
* Acknowledges a bypass request.
*/
void fluid_LADSPA_run(fluid_LADSPA_FxUnit_t* Fx_unit, fluid_real_t* left_buf[], fluid_real_t* right_buf[], fluid_real_t* fx_left_buf[], fluid_real_t* fx_right_buf[]);
/* Purpose:
* Returns the node belonging to Name or NULL, if not found
*/
fluid_LADSPA_Node_t* fluid_LADSPA_RetrieveNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name);
/* Purpose:
* Creates a new node with the given characteristics.
*/
fluid_LADSPA_Node_t* fluid_LADSPA_CreateNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name, int flags);
/* Purpose:
* - Resets LADSPA Fx unit to bypass.
* - Removes all plugins from the reverb unit.
* - Releases all libraries.
* Note: It would be more efficient to keep the libraries. But then the user would have to restart fluidsynth each time
* a plugin is recompiled.
*/
void fluid_LADSPA_clear(fluid_LADSPA_FxUnit_t* FxUnit);
/* Purpose:
* Frees all memory and shuts down the Fx block.
* The synthesis thread must be stopped, when calling.
*/
void fluid_LADSPA_shutdown(fluid_LADSPA_FxUnit_t* FxUnit);
typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t;
fluid_ladspa_fx_t *new_fluid_ladspa_fx(fluid_real_t sample_rate, int audio_groups, int effects_channels, int audio_channels, int buffer_size);
void delete_fluid_ladspa_fx(fluid_ladspa_fx_t *fx);
int fluid_ladspa_set_sample_rate(fluid_ladspa_fx_t *fx, fluid_real_t sample_rate);
/*
* fluid_handle_LADSPA_XXX
* Those functions are called from fluid_cmd, when a command is entered on the command line.
*/
int fluid_ladspa_is_active(fluid_ladspa_fx_t *fx);
int fluid_ladspa_activate(fluid_ladspa_fx_t *fx);
int fluid_ladspa_deactivate(fluid_ladspa_fx_t *fx);
int fluid_ladspa_reset(fluid_ladspa_fx_t *fx);
/* Purpose:
* - Resets LADSPA Fx unit to bypass.
* - Removes all plugins from the reverb unit.
* - Releases all libraries.
* Note: It would be more efficient to keep the libraries. But then the user would have to restart fluidsynth each time
* a plugin is recompiled.
*/
int fluid_LADSPA_handle_clear(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out);
void fluid_ladspa_run(fluid_ladspa_fx_t *fx, fluid_real_t *left_buf[], fluid_real_t *right_buf[],
fluid_real_t *fx_left_buf[], fluid_real_t *fx_right_buf[], int block_count, int block_size);
/* Purpose:
* Loads the plugins added with 'ladspa_add' and then start the Fx unit.
* Internal processes:
* - load the LADSPA plugin libraries
* - instantiate the plugins
* - connect the plugins
* - set the bypass switch to 'not bypassed'
*/
int fluid_LADSPA_handle_start(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out);
int fluid_ladspa_add_plugin(fluid_ladspa_fx_t *fx, const char *lib_name, const char *plugin_name);
int fluid_ladspa_port_exists(fluid_ladspa_fx_t *fx, int plugin_id, const char *name);
/* Purpose:
* Adds one plugin into the list of the LADSPA Fx unit.
* This is only allowed, while the Fx block is in 'bypass' state (after clear).
*/
int fluid_LADSPA_handle_add(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out);
int fluid_ladspa_add_audio_node(fluid_ladspa_fx_t *fx, const char *name);
int fluid_ladspa_add_control_node(fluid_ladspa_fx_t *fx, const char *name, fluid_real_t val);
int fluid_ladspa_set_control_node(fluid_ladspa_fx_t *fx, const char *name, fluid_real_t val);
int fluid_ladspa_node_exists(fluid_ladspa_fx_t *fx, const char *name);
/* Purpose:
* Declares a user control node and a value; for further processing in ladspa_start.
*/
int fluid_LADSPA_handle_declnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out);
/* Purpose:
* Assigns a value to the a user control node
*/
int fluid_LADSPA_handle_setnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out);
int fluid_ladspa_connect(fluid_ladspa_fx_t *fx, int plugin_id, fluid_ladspa_dir_t dir,
const char *port_name, const char *node_name);
int fluid_ladspa_check(fluid_ladspa_fx_t *fx, char *err, int err_size);
int fluid_ladspa_control_defaults(fluid_ladspa_fx_t *fx);
#endif /* LADSPA */
#endif /* _FLUID_LADSPA_H */
#endif /* _FLUID_LADSPA_H */

View file

@ -5,15 +5,6 @@
#define DSOUND_SUPPORT 1
#define WINMIDI_SUPPORT 1
#if _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define strcasecmp _stricmp
#if _MSC_VER < 1500
#define vsnprintf _vsnprintf
#endif
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2

View file

@ -27,7 +27,7 @@
typedef struct _fluid_audriver_definition_t
{
char* name;
const char* name;
fluid_audio_driver_t* (*new)(fluid_settings_t* settings, fluid_synth_t* synth);
fluid_audio_driver_t* (*new2)(fluid_settings_t* settings,
fluid_audio_func_t func,
@ -119,7 +119,7 @@ int delete_fluid_file_audio_driver(fluid_audio_driver_t* p);
#endif
/* Available audio drivers, listed in order of preference */
fluid_audriver_definition_t fluid_audio_drivers[] = {
static const fluid_audriver_definition_t fluid_audio_drivers[] = {
#if JACK_SUPPORT
{ "jack",
new_fluid_jack_audio_driver,
@ -190,7 +190,6 @@ fluid_audriver_definition_t fluid_audio_drivers[] = {
delete_fluid_file_audio_driver,
NULL },
#endif
{ NULL, NULL, NULL, NULL, NULL }
};
@ -198,7 +197,7 @@ fluid_audriver_definition_t fluid_audio_drivers[] = {
void fluid_audio_driver_settings(fluid_settings_t* settings)
{
int i;
unsigned int i;
fluid_settings_register_str(settings, "audio.sample-format", "16bits", 0, NULL, NULL);
fluid_settings_add_option(settings, "audio.sample-format", "16bits");
@ -275,7 +274,7 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
fluid_settings_add_option(settings, "audio.driver", "file");
#endif
for (i = 0; fluid_audio_drivers[i].name != NULL; i++) {
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers); i++) {
if (fluid_audio_drivers[i].settings != NULL) {
fluid_audio_drivers[i].settings(settings);
}
@ -295,12 +294,12 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
fluid_audio_driver_t*
new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
{
int i;
unsigned int i;
fluid_audio_driver_t* driver = NULL;
char* name;
char *allnames;
for (i = 0; fluid_audio_drivers[i].name != NULL; i++) {
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers); i++) {
if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name)) {
FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name);
driver = (*fluid_audio_drivers[i].new)(settings, synth);
@ -337,11 +336,11 @@ new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
fluid_audio_driver_t*
new_fluid_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data)
{
int i;
unsigned int i;
fluid_audio_driver_t* driver = NULL;
char* name;
for (i = 0; fluid_audio_drivers[i].name != NULL; i++) {
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers); i++) {
if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name) &&
(fluid_audio_drivers[i].new2 != NULL)) {
FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name);
@ -369,9 +368,9 @@ new_fluid_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, voi
void
delete_fluid_audio_driver(fluid_audio_driver_t* driver)
{
int i;
unsigned int i;
for (i = 0; fluid_audio_drivers[i].name != NULL; i++) {
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers); i++) {
if (fluid_audio_drivers[i].name == driver->name) {
fluid_audio_drivers[i].free(driver);
return;

View file

@ -21,7 +21,7 @@
#ifndef _FLUID_AUDRIVER_H
#define _FLUID_AUDRIVER_H
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
void fluid_audio_driver_settings(fluid_settings_t* settings);
@ -32,7 +32,7 @@ void fluid_audio_driver_settings(fluid_settings_t* settings);
struct _fluid_audio_driver_t
{
char* name;
const char* name;
};

View file

@ -72,8 +72,8 @@ fluid_audio_driver_t* new_fluid_alsa_audio_driver2(fluid_settings_t* settings,
int delete_fluid_alsa_audio_driver(fluid_audio_driver_t* p);
void fluid_alsa_audio_driver_settings(fluid_settings_t* settings);
static void fluid_alsa_audio_run_float(void* d);
static void fluid_alsa_audio_run_s16(void* d);
static fluid_thread_return_t fluid_alsa_audio_run_float(void* d);
static fluid_thread_return_t fluid_alsa_audio_run_s16(void* d);
struct fluid_alsa_formats_t {
@ -107,7 +107,7 @@ typedef struct {
struct pollfd *pfd;
int npfd;
fluid_thread_t *thread;
gint should_quit;
fluid_atomic_int_t should_quit;
unsigned char buffer[BUFFER_LENGTH];
fluid_midi_parser_t* parser;
} fluid_alsa_rawmidi_driver_t;
@ -118,7 +118,7 @@ fluid_midi_driver_t* new_fluid_alsa_rawmidi_driver(fluid_settings_t* settings,
void* event_handler_data);
int delete_fluid_alsa_rawmidi_driver(fluid_midi_driver_t* p);
static void fluid_alsa_midi_run(void* d);
static fluid_thread_return_t fluid_alsa_midi_run(void* d);
/*
@ -131,7 +131,7 @@ typedef struct {
struct pollfd *pfd;
int npfd;
fluid_thread_t *thread;
gint should_quit;
fluid_atomic_int_t should_quit;
int port_count;
} fluid_alsa_seq_driver_t;
@ -139,7 +139,7 @@ fluid_midi_driver_t* new_fluid_alsa_seq_driver(fluid_settings_t* settings,
handle_midi_event_func_t handler,
void* data);
int delete_fluid_alsa_seq_driver(fluid_midi_driver_t* p);
static void fluid_alsa_seq_run(void* d);
static fluid_thread_return_t fluid_alsa_seq_run(void* d);
/**************************************************************
*
@ -243,7 +243,7 @@ new_fluid_alsa_audio_driver2(fluid_settings_t* settings,
if (tmp != sample_rate) {
/* There's currently no way to change the sampling rate of the
synthesizer after it's been created. */
FLUID_LOG(FLUID_WARN, "Requested sample rate of %d, got %d instead, "
FLUID_LOG(FLUID_WARN, "Requested sample rate of %u, got %u instead, "
"synthesizer likely out of tune!", (unsigned int) sample_rate, tmp);
}
@ -377,7 +377,7 @@ static int fluid_alsa_handle_write_error (snd_pcm_t *pcm, int errval)
return FLUID_OK;
}
static void fluid_alsa_audio_run_float (void *d)
static fluid_thread_return_t fluid_alsa_audio_run_float (void *d)
{
fluid_alsa_audio_driver_t* dev = (fluid_alsa_audio_driver_t*) d;
fluid_synth_t *synth = (fluid_synth_t *)(dev->data);
@ -450,9 +450,11 @@ static void fluid_alsa_audio_run_float (void *d)
FLUID_FREE(left);
FLUID_FREE(right);
return FLUID_THREAD_RETURN_VALUE;
}
static void fluid_alsa_audio_run_s16 (void *d)
static fluid_thread_return_t fluid_alsa_audio_run_s16 (void *d)
{
fluid_alsa_audio_driver_t* dev = (fluid_alsa_audio_driver_t*) d;
float* left;
@ -535,6 +537,8 @@ static void fluid_alsa_audio_run_s16 (void *d)
FLUID_FREE(left);
FLUID_FREE(right);
FLUID_FREE(buf);
return FLUID_THREAD_RETURN_VALUE;
}
@ -623,7 +627,7 @@ new_fluid_alsa_rawmidi_driver(fluid_settings_t* settings,
}
FLUID_FREE(pfd);
g_atomic_int_set(&dev->should_quit, 0);
fluid_atomic_int_set(&dev->should_quit, 0);
/* create the MIDI thread */
dev->thread = new_fluid_thread ("alsa-midi-raw", fluid_alsa_midi_run, dev, realtime_prio, FALSE);
@ -656,7 +660,7 @@ delete_fluid_alsa_rawmidi_driver(fluid_midi_driver_t* p)
}
/* cancel the thread and wait for it before cleaning up */
g_atomic_int_set(&dev->should_quit, 1);
fluid_atomic_int_set(&dev->should_quit, 1);
if (dev->thread)
fluid_thread_join (dev->thread);
@ -674,7 +678,7 @@ delete_fluid_alsa_rawmidi_driver(fluid_midi_driver_t* p)
/*
* fluid_alsa_midi_run
*/
void
fluid_thread_return_t
fluid_alsa_midi_run(void* d)
{
fluid_midi_event_t* evt;
@ -682,7 +686,7 @@ fluid_alsa_midi_run(void* d)
int n, i;
/* go into a loop until someone tells us to stop */
while (!g_atomic_int_get(&dev->should_quit)) {
while (!fluid_atomic_int_get(&dev->should_quit)) {
/* is there something to read? */
n = poll(dev->pfd, dev->npfd, 100); /* use a 100 milliseconds timeout */
@ -694,7 +698,7 @@ fluid_alsa_midi_run(void* d)
n = snd_rawmidi_read(dev->rawmidi_in, dev->buffer, BUFFER_LENGTH);
if ((n < 0) && (n != -EAGAIN)) {
FLUID_LOG(FLUID_ERR, "Failed to read the midi input");
g_atomic_int_set(&dev->should_quit, 1);
fluid_atomic_int_set(&dev->should_quit, 1);
}
/* let the parser convert the data into events */
@ -706,6 +710,8 @@ fluid_alsa_midi_run(void* d)
}
}
}
return FLUID_THREAD_RETURN_VALUE;
}
/**************************************************************
@ -726,12 +732,12 @@ static char* fluid_alsa_seq_full_id(char* id, char* buf, int len)
{
if (id != NULL) {
if (FLUID_STRCMP(id, "pid") == 0) {
snprintf(buf, len, "FLUID Synth (%d)", getpid());
FLUID_SNPRINTF (buf, len, "FLUID Synth (%d)", getpid());
} else {
snprintf(buf, len, "FLUID Synth (%s)", id);
FLUID_SNPRINTF (buf, len, "FLUID Synth (%s)", id);
}
} else {
snprintf(buf, len, "FLUID Synth");
FLUID_SNPRINTF (buf, len, "FLUID Synth");
}
return buf;
@ -741,16 +747,60 @@ static char* fluid_alsa_seq_full_name(char* id, int port, char* buf, int len)
{
if (id != NULL) {
if (FLUID_STRCMP(id, "pid") == 0) {
snprintf(buf, len, "Synth input port (%d:%d)", getpid(), port);
FLUID_SNPRINTF (buf, len, "Synth input port (%d:%d)", getpid(), port);
} else {
snprintf(buf, len, "Synth input port (%s:%d)", id, port);
FLUID_SNPRINTF (buf, len, "Synth input port (%s:%d)", id, port);
}
} else {
snprintf(buf, len, "Synth input port");
FLUID_SNPRINTF (buf, len, "Synth input port");
}
return buf;
}
// Connect available ALSA MIDI inputs to port_info
static void fluid_alsa_seq_autoconnect(fluid_alsa_seq_driver_t* dev, const snd_seq_port_info_t *port_info)
{
snd_seq_t *seq = dev->seq_handle;
snd_seq_port_subscribe_t *subs;
snd_seq_client_info_t *cinfo;
snd_seq_port_info_t *pinfo;
snd_seq_port_subscribe_alloca(&subs);
snd_seq_client_info_alloca(&cinfo);
snd_seq_port_info_alloca(&pinfo);
snd_seq_client_info_set_client(cinfo, -1);
while (snd_seq_query_next_client(seq, cinfo) >= 0) {
const snd_seq_addr_t *dest = snd_seq_port_info_get_addr(port_info);
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
snd_seq_port_info_set_port(pinfo, -1);
while (snd_seq_query_next_port(seq, pinfo) >= 0) {
const unsigned int needed_type = SND_SEQ_PORT_TYPE_MIDI_GENERIC;
const unsigned int needed_cap = SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ;
const snd_seq_addr_t *sender = snd_seq_port_info_get_addr(pinfo);
const char *pname = snd_seq_port_info_get_name(pinfo);
if ((snd_seq_port_info_get_type(pinfo) & needed_type) != needed_type)
continue;
if ((snd_seq_port_info_get_capability(pinfo) & needed_cap) != needed_cap)
continue;
snd_seq_port_subscribe_set_sender(subs, sender);
snd_seq_port_subscribe_set_dest(subs, dest);
if (snd_seq_get_port_subscription(seq, subs) == 0) {
FLUID_LOG(FLUID_WARN, "Connection %s is already subscribed\n", pname);
continue;
}
if (snd_seq_subscribe_port(seq, subs) < 0) {
FLUID_LOG(FLUID_ERR, "Connection of %s failed (%s)\n", pname, snd_strerror(errno));
continue;
}
FLUID_LOG(FLUID_INFO, "Connection of %s succeeded\n", pname);
}
}
}
/*
* new_fluid_alsa_seq_driver
@ -760,6 +810,7 @@ new_fluid_alsa_seq_driver(fluid_settings_t* settings,
handle_midi_event_func_t handler, void* data)
{
int i, err;
int autoconn_inputs = 0;
fluid_alsa_seq_driver_t* dev;
int realtime_prio = 0;
int count;
@ -889,6 +940,10 @@ new_fluid_alsa_seq_driver(fluid_settings_t* settings,
}
}
fluid_settings_getint(settings, "midi.autoconnect", &autoconn_inputs);
if (autoconn_inputs)
fluid_alsa_seq_autoconnect(dev, port_info);
/* tell the lash server our client id */
#ifdef LASH_ENABLED
{
@ -899,7 +954,7 @@ new_fluid_alsa_seq_driver(fluid_settings_t* settings,
}
#endif /* LASH_ENABLED */
g_atomic_int_set(&dev->should_quit, 0);
fluid_atomic_int_set(&dev->should_quit, 0);
/* create the MIDI thread */
dev->thread = new_fluid_thread ("alsa-midi-seq", fluid_alsa_seq_run, dev, realtime_prio, FALSE);
@ -935,7 +990,7 @@ delete_fluid_alsa_seq_driver(fluid_midi_driver_t* p)
}
/* cancel the thread and wait for it before cleaning up */
g_atomic_int_set(&dev->should_quit, 1);
fluid_atomic_int_set(&dev->should_quit, 1);
if (dev->thread)
fluid_thread_join (dev->thread);
@ -953,7 +1008,7 @@ delete_fluid_alsa_seq_driver(fluid_midi_driver_t* p)
/*
* fluid_alsa_seq_run
*/
void
fluid_thread_return_t
fluid_alsa_seq_run(void* d)
{
int n, ev;
@ -962,7 +1017,7 @@ fluid_alsa_seq_run(void* d)
fluid_alsa_seq_driver_t* dev = (fluid_alsa_seq_driver_t*) d;
/* go into a loop until someone tells us to stop */
while (!g_atomic_int_get(&dev->should_quit)) {
while (!fluid_atomic_int_get(&dev->should_quit)) {
/* is there something to read? */
n = poll(dev->pfd, dev->npfd, 100); /* use a 100 milliseconds timeout */
@ -982,7 +1037,7 @@ fluid_alsa_seq_run(void* d)
if (ev != -EPERM && ev != -ENOSPC)
{
FLUID_LOG(FLUID_ERR, "Error while reading ALSA sequencer (code=%d)", ev);
g_atomic_int_set(&dev->should_quit, 1);
fluid_atomic_int_set(&dev->should_quit, 1);
}
break;
}
@ -1046,6 +1101,8 @@ fluid_alsa_seq_run(void* d)
while (ev > 0);
} /* if poll() > 0 */
} /* while (!dev->should_quit) */
return FLUID_THREAD_RETURN_VALUE;
}
#endif /* #if ALSA_SUPPORT */

View file

@ -221,7 +221,7 @@ new_fluid_core_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func
size = sizeof (name);
pa.mSelector = kAudioDevicePropertyDeviceName;
if (OK (AudioObjectGetPropertyData (devs[i], &pa, 0, 0, &size, name))) {
if (get_num_outputs (devs[i]) > 0 && strcasecmp(devname, name) == 0) {
if (get_num_outputs (devs[i]) > 0 && FLUID_STRCASECMP(devname, name) == 0) {
AudioDeviceID selectedID = devs[i];
status = AudioUnitSetProperty (dev->outputUnit,
kAudioOutputUnitProperty_CurrentDevice,

View file

@ -112,9 +112,9 @@ new_fluid_coremidi_driver(fluid_settings_t* settings, handle_midi_event_func_t h
memset (clientid, 0, sizeof(clientid));
if (id != NULL) {
if (FLUID_STRCMP (id, "pid") == 0) {
snprintf (clientid, sizeof(clientid), " (%d)", getpid());
FLUID_SNPRINTF (clientid, sizeof(clientid), " (%d)", getpid());
} else {
snprintf (clientid, sizeof(clientid), " (%s)", id);
FLUID_SNPRINTF (clientid, sizeof(clientid), " (%s)", id);
}
FLUID_FREE (id); /* -- free id string */
}

View file

@ -76,7 +76,7 @@ fluid_dsound_enum_callback2(LPGUID guid, LPCTSTR description, LPCTSTR module, LP
{
fluid_dsound_devsel_t* devsel = (fluid_dsound_devsel_t*) context;
FLUID_LOG(FLUID_DBG, "Testing audio device: %s", description);
if (strcasecmp(devsel->devname, description) == 0) {
if (FLUID_STRCASECMP(devsel->devname, description) == 0) {
devsel->devGUID = FLUID_NEW(GUID);
if(devsel->devGUID) {
memcpy(devsel->devGUID, guid, sizeof(GUID));

View file

@ -128,16 +128,19 @@ new_fluid_jack_client (fluid_settings_t *settings, int isaudio, void *driver)
char* client_name;
char name[64];
fluid_settings_dupstr (settings, isaudio ? "audio.jack.server" /* ++ alloc server name */
: "midi.jack.server", &server);
if (fluid_settings_dupstr (settings, isaudio ? "audio.jack.server" /* ++ alloc server name */
: "midi.jack.server", &server) != FLUID_OK)
{
return NULL;
}
fluid_mutex_lock (last_client_mutex); /* ++ lock last_client */
/* If the last client uses the same server and is not the same type (audio or MIDI),
* then re-use the client. */
if (last_client && ((!last_client->server && !server)
|| FLUID_STRCMP (last_client->server, server) == 0)
&& ((!isaudio && !last_client->midi_driver) || (isaudio && !last_client->audio_driver)))
if (last_client &&
(last_client->server != NULL && server != NULL && FLUID_STRCMP (last_client->server, server) == 0) &&
((!isaudio && last_client->midi_driver != NULL) || (isaudio && last_client->audio_driver != NULL)))
{
client_ref = last_client;
last_client = NULL; /* No more pairing for this client */
@ -171,7 +174,7 @@ new_fluid_jack_client (fluid_settings_t *settings, int isaudio, void *driver)
: "midi.jack.id", &client_name);
if (client_name != NULL && client_name[0] != 0)
snprintf(name, 64, "%s", client_name);
FLUID_SNPRINTF (name, 64, "%s", client_name);
else strcpy (name, "fluidsynth");
name[63] = '\0';

View file

@ -86,7 +86,7 @@ void fluid_coremidi_driver_settings(fluid_settings_t* settings);
* fluid_mdriver_definition
*/
struct fluid_mdriver_definition_t {
char* name;
const char* name;
fluid_midi_driver_t* (*new)(fluid_settings_t* settings,
handle_midi_event_func_t event_handler,
void* event_handler_data);
@ -95,7 +95,7 @@ struct fluid_mdriver_definition_t {
};
struct fluid_mdriver_definition_t fluid_midi_drivers[] = {
static const struct fluid_mdriver_definition_t fluid_midi_drivers[] = {
#if JACK_SUPPORT
{ "jack",
new_fluid_jack_midi_driver,
@ -136,15 +136,16 @@ struct fluid_mdriver_definition_t fluid_midi_drivers[] = {
delete_fluid_coremidi_driver,
fluid_coremidi_driver_settings },
#endif
{ NULL, NULL, NULL, NULL }
};
void fluid_midi_driver_settings(fluid_settings_t* settings)
{
int i;
unsigned int i;
fluid_settings_register_int (settings, "midi.autoconnect", 0, 0, 1, FLUID_HINT_TOGGLED, NULL, NULL);
fluid_settings_register_int (settings, "midi.realtime-prio",
FLUID_DEFAULT_MIDI_RT_PRIO, 0, 99, 0, NULL, NULL);
@ -186,7 +187,7 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
fluid_settings_add_option(settings, "midi.driver", "coremidi");
#endif
for (i = 0; fluid_midi_drivers[i].name != NULL; i++) {
for (i = 0; i < FLUID_N_ELEMENTS(fluid_midi_drivers); i++) {
if (fluid_midi_drivers[i].settings != NULL) {
fluid_midi_drivers[i].settings(settings);
}
@ -205,9 +206,9 @@ fluid_midi_driver_t* new_fluid_midi_driver(fluid_settings_t* settings, handle_mi
{
fluid_midi_driver_t* driver = NULL;
char *allnames;
int i;
unsigned int i;
for (i = 0; fluid_midi_drivers[i].name != NULL; i++) {
for (i = 0; i < FLUID_N_ELEMENTS(fluid_midi_drivers); i++) {
if (fluid_settings_str_equal(settings, "midi.driver", fluid_midi_drivers[i].name)) {
FLUID_LOG(FLUID_DBG, "Using '%s' midi driver", fluid_midi_drivers[i].name);
driver = fluid_midi_drivers[i].new(settings, handler, event_handler_data);
@ -232,9 +233,9 @@ fluid_midi_driver_t* new_fluid_midi_driver(fluid_settings_t* settings, handle_mi
*/
void delete_fluid_midi_driver(fluid_midi_driver_t* driver)
{
int i;
unsigned int i;
for (i = 0; fluid_midi_drivers[i].name != NULL; i++) {
for (i = 0; i < FLUID_N_ELEMENTS(fluid_midi_drivers); i++) {
if (fluid_midi_drivers[i].name == driver->name) {
fluid_midi_drivers[i].free(driver);
return;

View file

@ -21,7 +21,7 @@
#ifndef _FLUID_MDRIVER_H
#define _FLUID_MDRIVER_H
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
void fluid_midi_driver_settings(fluid_settings_t* settings);
@ -32,7 +32,7 @@ void fluid_midi_driver_settings(fluid_settings_t* settings);
struct _fluid_midi_driver_t
{
char* name;
const char* name;
handle_midi_event_func_t handler;
void* data;
};

View file

@ -77,8 +77,8 @@ int delete_fluid_oss_audio_driver(fluid_audio_driver_t* p);
/* local utilities */
static int fluid_oss_set_queue_size(fluid_oss_audio_driver_t* dev, int ss, int ch, int qs, int bs);
static void fluid_oss_audio_run(void* d);
static void fluid_oss_audio_run2(void* d);
static fluid_thread_return_t fluid_oss_audio_run(void* d);
static fluid_thread_return_t fluid_oss_audio_run2(void* d);
typedef struct {
@ -95,7 +95,7 @@ new_fluid_oss_midi_driver(fluid_settings_t* settings,
handle_midi_event_func_t handler, void* data);
int delete_fluid_oss_midi_driver(fluid_midi_driver_t* p);
int fluid_oss_midi_driver_status(fluid_midi_driver_t* p);
static void fluid_oss_midi_run(void* d);
static fluid_thread_return_t fluid_oss_midi_run(void* d);
void
@ -441,7 +441,7 @@ fluid_oss_set_queue_size(fluid_oss_audio_driver_t* dev, int ss, int ch, int qs,
/*
* fluid_oss_audio_run
*/
void
fluid_thread_return_t
fluid_oss_audio_run(void* d)
{
fluid_oss_audio_driver_t* dev = (fluid_oss_audio_driver_t*) d;
@ -463,13 +463,15 @@ fluid_oss_audio_run(void* d)
}
FLUID_LOG(FLUID_DBG, "Audio thread finished");
return FLUID_THREAD_RETURN_VALUE;
}
/*
* fluid_oss_audio_run
*/
void
fluid_thread_return_t
fluid_oss_audio_run2(void* d)
{
fluid_oss_audio_driver_t* dev = (fluid_oss_audio_driver_t*) d;
@ -498,6 +500,8 @@ fluid_oss_audio_run2(void* d)
}
FLUID_LOG(FLUID_DBG, "Audio thread finished");
return FLUID_THREAD_RETURN_VALUE;
}
@ -621,7 +625,7 @@ delete_fluid_oss_midi_driver(fluid_midi_driver_t* p)
/*
* fluid_oss_midi_run
*/
void
fluid_thread_return_t
fluid_oss_midi_run(void* d)
{
fluid_oss_midi_driver_t* dev = (fluid_oss_midi_driver_t*) d;
@ -668,6 +672,8 @@ fluid_oss_midi_run(void* d)
}
}
}
return FLUID_THREAD_RETURN_VALUE;
}
int

View file

@ -37,9 +37,6 @@
#if PORTAUDIO_SUPPORT
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <portaudio.h>

View file

@ -55,8 +55,8 @@ fluid_audio_driver_t* new_fluid_pulse_audio_driver2(fluid_settings_t* settings,
fluid_audio_func_t func, void* data);
int delete_fluid_pulse_audio_driver(fluid_audio_driver_t* p);
void fluid_pulse_audio_driver_settings(fluid_settings_t* settings);
static void fluid_pulse_audio_run(void* d);
static void fluid_pulse_audio_run2(void* d);
static fluid_thread_return_t fluid_pulse_audio_run(void* d);
static fluid_thread_return_t fluid_pulse_audio_run2(void* d);
void fluid_pulse_audio_driver_settings(fluid_settings_t* settings)
@ -196,7 +196,7 @@ int delete_fluid_pulse_audio_driver(fluid_audio_driver_t* p)
}
/* Thread without audio callback, more efficient */
static void
static fluid_thread_return_t
fluid_pulse_audio_run(void* d)
{
fluid_pulse_audio_driver_t* dev = (fluid_pulse_audio_driver_t*) d;
@ -212,7 +212,7 @@ fluid_pulse_audio_run(void* d)
if (buf == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory.");
return;
return FLUID_THREAD_RETURN_VALUE;
}
while (dev->cont)
@ -228,9 +228,11 @@ fluid_pulse_audio_run(void* d)
} /* while (dev->cont) */
FLUID_FREE(buf);
return FLUID_THREAD_RETURN_VALUE;
}
static void
static fluid_thread_return_t
fluid_pulse_audio_run2(void* d)
{
fluid_pulse_audio_driver_t* dev = (fluid_pulse_audio_driver_t*) d;
@ -250,8 +252,11 @@ fluid_pulse_audio_run2(void* d)
if (left == NULL || right == NULL || buf == NULL)
{
FLUID_FREE(left);
FLUID_FREE(right);
FLUID_FREE(buf);
FLUID_LOG(FLUID_ERR, "Out of memory.");
return;
return FLUID_THREAD_RETURN_VALUE;
}
handle[0] = left;
@ -279,4 +284,6 @@ fluid_pulse_audio_run2(void* d)
FLUID_FREE(left);
FLUID_FREE(right);
FLUID_FREE(buf);
return FLUID_THREAD_RETURN_VALUE;
}

View file

@ -44,7 +44,7 @@
typedef struct {
fluid_midi_driver_t driver;
HMIDIIN hmidiin;
int closing; /* Set to TRUE when closing driver, to prevent endless SYSEX lockup loop */
fluid_atomic_int_t closing; /* Set to TRUE when closing driver, to prevent endless SYSEX lockup loop */
fluid_thread_t *sysExAddThread; /* Thread for SYSEX re-add thread */
fluid_cond_mutex_t *mutex; /* Lock for condition */
@ -54,7 +54,7 @@ typedef struct {
MIDIHDR sysExHdrs[MIDI_SYSEX_BUF_COUNT];
/* TRUE for each MIDIHDR buffer which should be re-added to MIDI device */
int sysExHdrAdd[MIDI_SYSEX_BUF_COUNT];
fluid_atomic_int_t sysExHdrAdd[MIDI_SYSEX_BUF_COUNT];
/* Sysex data buffer */
unsigned char sysExBuf[MIDI_SYSEX_BUF_COUNT * MIDI_SYSEX_MAX_SIZE];
@ -76,7 +76,7 @@ int delete_fluid_winmidi_driver(fluid_midi_driver_t* p);
void CALLBACK fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
DWORD_PTR msg, DWORD_PTR extra);
static void fluid_winmidi_add_sysex_thread (void *data);
static fluid_thread_return_t fluid_winmidi_add_sysex_thread (void *data);
static char* fluid_winmidi_input_error(int no);
int fluid_winmidi_driver_status(fluid_midi_driver_t* p);
@ -129,7 +129,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
dev->hmidiin = NULL;
dev->driver.handler = handler;
dev->driver.data = data;
dev->closing = FALSE;
fluid_atomic_int_set (&dev->closing, FALSE);
/* get the device name. if none is specified, use the default device. */
if(fluid_settings_dupstr(settings, "midi.winmidi.device", &devname) != FLUID_OK || !devname) {
@ -150,12 +150,12 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
}
/* find the device */
if (strcasecmp("default", devname) != 0) {
if (FLUID_STRCASECMP("default", devname) != 0) {
for (i = 0; i < num; i++) {
res = midiInGetDevCaps(i, &in_caps, sizeof(MIDIINCAPS));
if (res == MMSYSERR_NOERROR) {
FLUID_LOG(FLUID_DBG, "Testing midi device: %s\n", in_caps.szPname);
if (strcasecmp(devname, in_caps.szPname) == 0) {
if (FLUID_STRCASECMP(devname, in_caps.szPname) == 0) {
FLUID_LOG(FLUID_DBG, "Selected midi device number: %d\n", i);
midi_num = i;
break;
@ -181,7 +181,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
/* Prepare and add SYSEX buffers */
for (i = 0; i < MIDI_SYSEX_BUF_COUNT; i++)
{
dev->sysExHdrAdd[i] = FALSE;
fluid_atomic_int_set (&dev->sysExHdrAdd[i], FALSE);
hdr = &dev->sysExHdrs[i];
hdr->lpData = &dev->sysExBuf[i * MIDI_SYSEX_MAX_SIZE];
@ -305,7 +305,7 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
break;
case MIM_LONGDATA: /* SYSEX data */
if (dev->closing) break; /* Prevent MIM_LONGDATA endless loop, don't re-add buffer if closing */
if (fluid_atomic_int_get (&dev->closing)) break; /* Prevent MIM_LONGDATA endless loop, don't re-add buffer if closing */
pMidiHdr = (LPMIDIHDR)dwParam1;
data = (unsigned char *)(pMidiHdr->lpData);
@ -339,7 +339,7 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
}
/* Thread for re-adding SYSEX buffers */
static void
static fluid_thread_return_t
fluid_winmidi_add_sysex_thread (void *data)
{
fluid_winmidi_driver_t *dev = data;
@ -360,6 +360,8 @@ fluid_winmidi_add_sysex_thread (void *data)
}
}
}
return FLUID_THREAD_RETURN_VALUE;
}
int

View file

@ -34,6 +34,7 @@
#if defined(HAVE_GETOPT_H)
#include <getopt.h>
#define GETOPT_SUPPORT 1
#endif
#include "fluidsynth.h"
@ -58,15 +59,6 @@ void print_welcome(void);
fluid_cmd_handler_t* cmd_handler = NULL;
int option_help = 0; /* set to 1 if "-o help" is specified */
/*
* support for the getopt function
*/
#if defined(HAVE_GETOPT_H)
#define GETOPT_SUPPORT 1
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#endif
/* Process a command line option -o setting=value, for example: -o synth.polyhony=16 */
void process_o_cmd_line_option(fluid_settings_t* settings, char* optarg)

View file

@ -42,8 +42,8 @@
/* Private data for SEQUENCER */
struct _fluid_sequencer_t {
unsigned int startMs;
gint currentMs;
gboolean useSystemTimer;
fluid_atomic_int_t currentMs;
int useSystemTimer;
double scale; // ticks per second
fluid_list_t* clients;
short clientsID;
@ -121,7 +121,7 @@ new_fluid_sequencer2 (int use_system_timer)
FLUID_MEMSET(seq, 0, sizeof(fluid_sequencer_t));
seq->scale = 1000; // default value
seq->useSystemTimer = use_system_timer ? TRUE : FALSE;
seq->useSystemTimer = use_system_timer ? 1 : 0;
seq->startMs = seq->useSystemTimer ? fluid_curtime() : 0;
seq->clients = NULL;
seq->clientsID = 0;
@ -196,7 +196,7 @@ delete_fluid_sequencer (fluid_sequencer_t* seq)
int
fluid_sequencer_get_use_system_timer (fluid_sequencer_t* seq)
{
return seq->useSystemTimer ? 1 : 0;
return seq->useSystemTimer;
}
@ -211,7 +211,7 @@ fluid_seq_dotrace(fluid_sequencer_t* seq, char *fmt, ...)
if (remain <= 0) return;
va_start (args, fmt);
len = vsnprintf(seq->traceptr, remain, fmt, args);
len = FLUID_VSNPRINTF (seq->traceptr, remain, fmt, args);
va_end (args);
if (len > 0) {
@ -500,7 +500,7 @@ fluid_sequencer_remove_events (fluid_sequencer_t* seq, short source,
unsigned int
fluid_sequencer_get_tick (fluid_sequencer_t* seq)
{
unsigned int absMs = seq->useSystemTimer ? (int) fluid_curtime() : g_atomic_int_get(&seq->currentMs);
unsigned int absMs = seq->useSystemTimer ? (int) fluid_curtime() : fluid_atomic_int_get(&seq->currentMs);
double nowFloat;
unsigned int now;
nowFloat = ((double)(absMs - seq->startMs))*seq->scale/1000.0f;
@ -846,7 +846,7 @@ fluid_sequencer_process(fluid_sequencer_t* seq, unsigned int msec)
}
/* send queued events */
g_atomic_int_set(&seq->currentMs, msec);
fluid_atomic_int_set(&seq->currentMs, msec);
_fluid_seq_queue_send_queued_events(seq);
}

View file

@ -111,7 +111,7 @@ fluid_adsr_env_set_data(fluid_adsr_env_t* env,
fluid_real_t min,
fluid_real_t max);
static inline void
static FLUID_INLINE void
fluid_adsr_env_reset(fluid_adsr_env_t* env)
{
env->count = 0;
@ -119,25 +119,25 @@ fluid_adsr_env_reset(fluid_adsr_env_t* env)
env->val = 0.0f;
}
static inline fluid_real_t
static FLUID_INLINE fluid_real_t
fluid_adsr_env_get_val(fluid_adsr_env_t* env)
{
return env->val;
}
static inline void
static FLUID_INLINE void
fluid_adsr_env_set_val(fluid_adsr_env_t* env, fluid_real_t val)
{
env->val = val;
}
static inline fluid_adsr_env_section_t
static FLUID_INLINE fluid_adsr_env_section_t
fluid_adsr_env_get_section(fluid_adsr_env_t* env)
{
return env->section;
}
static inline void
static FLUID_INLINE void
fluid_adsr_env_set_section(fluid_adsr_env_t* env,
fluid_adsr_env_section_t section)
{
@ -148,7 +148,7 @@ fluid_adsr_env_set_section(fluid_adsr_env_t* env,
/* Used for determining which voice to kill.
Returns max amplitude from now, and forward in time.
*/
static inline fluid_real_t
static FLUID_INLINE fluid_real_t
fluid_adsr_env_get_max_val(fluid_adsr_env_t* env)
{
if (env->section > FLUID_VOICE_ENVATTACK){

View file

@ -174,7 +174,7 @@ fluid_iir_filter_set_q_dB(fluid_iir_filter_t* iir_filter,
}
static inline void
static FLUID_INLINE void
fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t* iir_filter,
int transition_samples,
fluid_real_t output_rate)

View file

@ -21,7 +21,7 @@
#ifndef _FLUID_LFO_H
#define _FLUID_LFO_H
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
typedef struct _fluid_lfo_t fluid_lfo_t;
@ -31,7 +31,7 @@ struct _fluid_lfo_t {
fluid_real_t increment; /* the lfo frequency is converted to a per-buffer increment */
};
static inline void
static FLUID_INLINE void
fluid_lfo_reset(fluid_lfo_t* lfo)
{
lfo->val = 0.0f;
@ -41,13 +41,13 @@ fluid_lfo_reset(fluid_lfo_t* lfo)
void fluid_lfo_set_incr(fluid_lfo_t* lfo, fluid_real_t increment);
void fluid_lfo_set_delay(fluid_lfo_t* lfo, unsigned int delay);
static inline fluid_real_t
static FLUID_INLINE fluid_real_t
fluid_lfo_get_val(fluid_lfo_t* lfo)
{
return lfo->val;
}
static inline void
static FLUID_INLINE void
fluid_lfo_calc(fluid_lfo_t* lfo, unsigned int cur_delay)
{
if (cur_delay < lfo->delay)

View file

@ -46,7 +46,7 @@ typedef enum
* reverb preset
*/
typedef struct _fluid_revmodel_presets_t {
char* name;
const char* name;
fluid_real_t roomsize;
fluid_real_t damp;
fluid_real_t width;

View file

@ -25,7 +25,7 @@
/**
* @return -1 if voice has finished, 0 if it's currently quiet, 1 otherwise
*/
static inline int
static FLUID_INLINE int
fluid_rvoice_calc_amp(fluid_rvoice_t* voice)
{
fluid_real_t target_amp; /* target amplitude */
@ -371,7 +371,7 @@ fluid_rvoice_write (fluid_rvoice_t* voice, fluid_real_t *dsp_buf)
}
static inline fluid_real_t*
static FLUID_INLINE fluid_real_t*
get_dest_buf(fluid_rvoice_buffers_t* buffers, int index,
fluid_real_t** dest_bufs, int dest_bufcount)
{
@ -514,7 +514,7 @@ fluid_rvoice_noteoff(fluid_rvoice_t* voice, unsigned int min_ticks)
*/
if (fluid_adsr_env_get_val(&voice->envlfo.volenv) > 0){
fluid_real_t lfo = fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol;
fluid_real_t amp = fluid_adsr_env_get_val(&voice->envlfo.volenv) * pow (10.0, lfo / -200);
fluid_real_t amp = fluid_adsr_env_get_val(&voice->envlfo.volenv) * fluid_cb2amp(lfo);
fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1);
fluid_clip (env_value, 0.0, 1.0);
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);

View file

@ -229,7 +229,7 @@ new_fluid_rvoice_eventhandler(int is_threadsafe, int queuesize,
* that too many events are dispatched too early, causing incorrectly timed audio
*/
eventhandler->is_threadsafe = TRUE;
eventhandler->queue_stored = 0;
fluid_atomic_int_set(&eventhandler->queue_stored, 0);
eventhandler->finished_voices = new_fluid_ringbuffer(finished_voices_size,
sizeof(fluid_rvoice_t*));

View file

@ -50,7 +50,7 @@ void fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event);
struct _fluid_rvoice_eventhandler_t {
int is_threadsafe; /* False for optimal performance, true for atomic operations */
fluid_ringbuffer_t* queue; /**< List of fluid_rvoice_event_t */
int queue_stored; /**< Extras pushed but not flushed */
fluid_atomic_int_t queue_stored; /**< Extras pushed but not flushed */
fluid_ringbuffer_t* finished_voices; /**< return queue from handler, list of fluid_rvoice_t* */
fluid_rvoice_mixer_t* mixer;
};

View file

@ -45,7 +45,7 @@ struct _fluid_mixer_buffers_t {
fluid_rvoice_t** finished_voices; /* List of voices who have finished */
int finished_voice_count;
int ready; /**< Atomic: buffers are ready for mixing */
fluid_atomic_int_t ready; /**< Atomic: buffers are ready for mixing */
int buf_blocks; /**< Number of blocks allocated in the buffers */
@ -81,14 +81,14 @@ struct _fluid_rvoice_mixer_t {
int current_blockcount; /**< Read-only: how many blocks to process this time */
#ifdef LADSPA
fluid_LADSPA_FxUnit_t* LADSPA_FxUnit; /**< Used by mixer only: Effects unit for LADSPA support. Never created or freed */
fluid_ladspa_fx_t* ladspa_fx; /**< Used by mixer only: Effects unit for LADSPA support. Never created or freed */
#endif
#ifdef ENABLE_MIXER_THREADS
// int sleeping_threads; /**< Atomic: number of threads currently asleep */
// int active_threads; /**< Atomic: number of threads in the thread loop */
int threads_should_terminate; /**< Atomic: Set to TRUE when threads should terminate */
int current_rvoice; /**< Atomic: for the threads to know next voice to */
fluid_atomic_int_t threads_should_terminate; /**< Atomic: Set to TRUE when threads should terminate */
fluid_atomic_int_t current_rvoice; /**< Atomic: for the threads to know next voice to */
fluid_cond_t* wakeup_threads; /**< Signalled when the threads should wake up */
fluid_cond_mutex_t* wakeup_threads_m; /**< wakeup_threads mutex companion */
fluid_cond_t* thread_ready; /**< Signalled from thread, when the thread has a buffer ready for mixing */
@ -142,33 +142,12 @@ fluid_rvoice_mixer_process_fx(fluid_rvoice_mixer_t* mixer)
#ifdef LADSPA
/* Run the signal through the LADSPA Fx unit */
if (mixer->LADSPA_FxUnit) {
int j;
FLUID_DECLARE_VLA(fluid_real_t*, left_buf, mixer->buffers.buf_count);
FLUID_DECLARE_VLA(fluid_real_t*, right_buf, mixer->buffers.buf_count);
FLUID_DECLARE_VLA(fluid_real_t*, fx_left_buf, mixer->buffers.fx_buf_count);
FLUID_DECLARE_VLA(fluid_real_t*, fx_right_buf, mixer->buffers.fx_buf_count);
for (j=0; j < mixer->buffers.buf_count; j++) {
left_buf[j] = mixer->buffers.left_buf[j];
right_buf[j] = mixer->buffers.right_buf[j];
}
for (j=0; j < mixer->buffers.fx_buf_count; j++) {
fx_left_buf[j] = mixer->buffers.fx_left_buf[j];
fx_right_buf[j] = mixer->buffers.fx_right_buf[j];
}
for (i=0; i < mixer->current_blockcount * FLUID_BUFSIZE; i += FLUID_BUFSIZE) {
fluid_LADSPA_run(mixer->LADSPA_FxUnit, left_buf, right_buf, fx_left_buf,
fx_right_buf);
for (j=0; j < mixer->buffers.buf_count; j++) {
left_buf[j] += FLUID_BUFSIZE;
right_buf[j] += FLUID_BUFSIZE;
}
for (j=0; j < mixer->buffers.fx_buf_count; j++) {
fx_left_buf[j] += FLUID_BUFSIZE;
fx_right_buf[j] += FLUID_BUFSIZE;
}
}
fluid_check_fpe("LADSPA");
if (mixer->ladspa_fx) {
fluid_ladspa_run(mixer->ladspa_fx,
mixer->buffers.left_buf, mixer->buffers.right_buf,
mixer->buffers.fx_left_buf, mixer->buffers.fx_right_buf,
mixer->current_blockcount, FLUID_BUFSIZE);
fluid_check_fpe("LADSPA");
}
#endif
}
@ -522,6 +501,12 @@ fluid_rvoice_mixer_set_samplerate(fluid_rvoice_mixer_t* mixer, fluid_real_t samp
fluid_revmodel_samplerate_change(mixer->fx.reverb, samplerate);
for (i=0; i < mixer->active_voices; i++)
fluid_rvoice_set_output_rate(mixer->rvoices[i], samplerate);
#if LADSPA
if (mixer->ladspa_fx != NULL)
{
fluid_ladspa_set_sample_rate(mixer->ladspa_fx, samplerate);
}
#endif
}
@ -642,10 +627,9 @@ void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t* mixer)
#ifdef LADSPA
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer,
fluid_LADSPA_FxUnit_t* ladspa)
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer, fluid_ladspa_fx_t *ladspa_fx)
{
mixer->LADSPA_FxUnit = ladspa;
mixer->ladspa_fx = ladspa_fx;
}
#endif
@ -731,7 +715,7 @@ fluid_mixer_get_mt_rvoice(fluid_rvoice_mixer_t* mixer)
#define THREAD_BUF_TERMINATE 3
/* Core thread function (processes voices in parallel to primary synthesis thread) */
static void
static fluid_thread_return_t
fluid_mixer_thread_func (void* data)
{
fluid_mixer_buffers_t* buffers = data;
@ -772,6 +756,7 @@ fluid_mixer_thread_func (void* data)
}
}
return FLUID_THREAD_RETURN_VALUE;
}
static void
@ -940,7 +925,7 @@ fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_count,
if (!fluid_mixer_buffers_init(b, mixer))
return;
fluid_atomic_int_set(&b->ready, THREAD_BUF_NODATA);
g_snprintf (name, sizeof (name), "mixer%d", i);
FLUID_SNPRINTF (name, sizeof (name), "mixer%d", i);
b->thread = new_fluid_thread(name, fluid_mixer_thread_func, b, prio_level, 0);
if (!b->thread)
return;

View file

@ -69,8 +69,7 @@ void fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_coun
int prio_level);
#ifdef LADSPA
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer,
fluid_LADSPA_FxUnit_t* ladspa);
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer, fluid_ladspa_fx_t* ladspa_fx);
#endif
#endif

View file

@ -2040,86 +2040,59 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs
equivalent to the matching ID list in memory regardless of LE/BE machine
*/
#if FLUID_IS_BIG_ENDIAN
#define READCHUNK(var,fd) G_STMT_START { \
#define READCHUNK(var,fd) do { \
if (!safe_fread(var, 8, fd)) \
return(FAIL); \
((SFChunk *)(var))->size = GUINT32_FROM_LE(((SFChunk *)(var))->size); \
} G_STMT_END
((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \
} while(0)
#define READD(var,fd) G_STMT_START { \
unsigned int _temp; \
#define READD(var,fd) do { \
uint32 _temp; \
if (!safe_fread(&_temp, 4, fd)) \
return(FAIL); \
var = GINT32_FROM_LE(_temp); \
} G_STMT_END
var = FLUID_LE32TOH(_temp); \
} while(0)
#define READW(var,fd) G_STMT_START { \
unsigned short _temp; \
#define READW(var,fd) do { \
uint16 _temp; \
if (!safe_fread(&_temp, 2, fd)) \
return(FAIL); \
var = GINT16_FROM_LE(_temp); \
} G_STMT_END
var = FLUID_LE16TOH(_temp); \
} while(0)
#else
#define READCHUNK(var,fd) G_STMT_START { \
if (!safe_fread(var, 8, fd)) \
return(FAIL); \
((SFChunk *)(var))->size = GUINT32_FROM_LE(((SFChunk *)(var))->size); \
} G_STMT_END
#define READD(var,fd) G_STMT_START { \
unsigned int _temp; \
if (!safe_fread(&_temp, 4, fd)) \
return(FAIL); \
var = GINT32_FROM_LE(_temp); \
} G_STMT_END
#define READW(var,fd) G_STMT_START { \
unsigned short _temp; \
if (!safe_fread(&_temp, 2, fd)) \
return(FAIL); \
var = GINT16_FROM_LE(_temp); \
} G_STMT_END
#endif
#define READID(var,fd) G_STMT_START { \
#define READID(var,fd) do { \
if (!safe_fread(var, 4, fd)) \
return(FAIL); \
} G_STMT_END
} while(0)
#define READSTR(var,fd) G_STMT_START { \
#define READSTR(var,fd) do { \
if (!safe_fread(var, 20, fd)) \
return(FAIL); \
(*var)[20] = '\0'; \
} G_STMT_END
} while(0)
#define READB(var,fd) G_STMT_START { \
#define READB(var,fd) do { \
if (!safe_fread(&var, 1, fd)) \
return(FAIL); \
} G_STMT_END
} while(0)
#define FSKIP(size,fd) G_STMT_START { \
#define FSKIP(size,fd) do { \
if (!safe_fseek(fd, size, SEEK_CUR)) \
return(FAIL); \
} G_STMT_END
} while(0)
#define FSKIPW(fd) G_STMT_START { \
#define FSKIPW(fd) do { \
if (!safe_fseek(fd, 2, SEEK_CUR)) \
return(FAIL); \
} G_STMT_END
} while(0)
/* removes and advances a fluid_list_t pointer */
#define SLADVREM(list, item) G_STMT_START { \
#define SLADVREM(list, item) do { \
fluid_list_t *_temp = item; \
item = fluid_list_next(item); \
list = fluid_list_remove_link(list, _temp); \
delete1_fluid_list(_temp); \
} G_STMT_END
} while(0)
static int chunkid (unsigned int id);
static int load_body (unsigned int size, SFData * sf, FILE * fd);
@ -2142,7 +2115,7 @@ static int fixup_pgen (SFData * sf);
static int fixup_igen (SFData * sf);
static int fixup_sample (SFData * sf);
char idlist[] = {
static const char idlist[] = {
"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD"
"ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24"
};
@ -2471,7 +2444,7 @@ pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
int * size, FILE * fd)
{
unsigned int id;
char *expstr;
const char *expstr;
expstr = CHNKIDSTR (expid); /* in case we need it */
@ -2810,7 +2783,7 @@ load_pgen (int size, SFData * sf, FILE * fd)
{ /* inst is last gen */
level = 3;
READW (genval.uword, fd);
((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1);
((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1);
break; /* break out of generator loop */
}
else
@ -3160,7 +3133,7 @@ load_igen (int size, SFData * sf, FILE * fd)
{ /* sample is last gen */
level = 3;
READW (genval.uword, fd);
((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1);
((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1);
break; /* break out of generator loop */
}
else
@ -3320,7 +3293,7 @@ fixup_pgen (SFData * sf)
while (p2)
{ /* traverse this preset's zones */
z = (SFZone *) (p2->data);
if ((i = GPOINTER_TO_INT (z->instsamp)))
if ((i = FLUID_POINTER_TO_INT (z->instsamp)))
{ /* load instrument # */
p3 = fluid_list_nth (sf->inst, i - 1);
if (!p3)
@ -3355,7 +3328,7 @@ fixup_igen (SFData * sf)
while (p2)
{ /* traverse instrument's zones */
z = (SFZone *) (p2->data);
if ((i = GPOINTER_TO_INT (z->instsamp)))
if ((i = FLUID_POINTER_TO_INT (z->instsamp)))
{ /* load sample # */
p3 = fluid_list_nth (sf->sample, i - 1);
if (!p3)
@ -3480,11 +3453,13 @@ fixup_sample (SFData * sf)
#define MOD_CHUNK_OPTIMUM_AREA 256
#define GEN_CHUNK_OPTIMUM_AREA 256
unsigned short badgen[] = { Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4,
static const unsigned short badgen[] = {
Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4,
Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0
};
unsigned short badpgen[] = { Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs,
static const unsigned short badpgen[] = {
Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs,
Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs,
Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity,
Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass,

View file

@ -219,11 +219,6 @@ typedef enum
}
Gen_Unit;
/* global data */
extern unsigned short badgen[]; /* list of bad generators */
extern unsigned short badpgen[]; /* list of bad preset generators */
/* functions */
void sfont_init_chunks (void);
@ -302,9 +297,6 @@ typedef struct _SFShdr
}
SFShdr;
/* data */
extern char idlist[];
/* functions */
SFData *sfload_file (const char * fname);
@ -316,27 +308,6 @@ SFData *sfload_file (const char * fname);
/********************************************************************************/
/********************************************************************************/
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* 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 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., 59 Temple Place - Suite 330,
* Boston, MA 02110-1301, USA.
*/
#include <glib.h>
/*-----------------------------------util.h----------------------------*/
/*

View file

@ -24,7 +24,7 @@
/* See SFSpec21 $8.1.3 */
fluid_gen_info_t fluid_gen_info[] = {
static const fluid_gen_info_t fluid_gen_info[] = {
/* number/name init scale min max def */
{ GEN_STARTADDROFS, 1, 1, 0.0f, 1e10f, 0.0f },
{ GEN_ENDADDROFS, 1, 1, -1e10f, 0.0f, 0.0f },

View file

@ -80,7 +80,7 @@ static int fluid_synth_update_polyphony(fluid_synth_t* synth,
char* name, int value);
static int fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth, int new_polyphony);
static void init_dither(void);
static inline int roundi (float x);
static FLUID_INLINE int roundi (float x);
static int fluid_synth_render_blocks(fluid_synth_t* synth, int blockcount);
static fluid_voice_t* fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t* synth);
@ -116,7 +116,8 @@ static void fluid_synth_stop_LOCAL (fluid_synth_t *synth, unsigned int id);
*/
/* has the synth module been initialized? */
static int fluid_synth_initialized = 0;
/* fluid_atomic_int_t may be anything, so init with {0} to catch most cases */
static fluid_atomic_int_t fluid_synth_initialized = {0};
static void fluid_synth_init(void);
static void init_dither(void);
@ -139,14 +140,13 @@ fluid_mod_t default_chorus_mod; /* SF2.01 section 8.4.9 */
fluid_mod_t default_pitch_bend_mod; /* SF2.01 section 8.4.10 */
/* reverb presets */
static fluid_revmodel_presets_t revmodel_preset[] = {
static const fluid_revmodel_presets_t revmodel_preset[] = {
/* name */ /* roomsize */ /* damp */ /* width */ /* level */
{ "Test 1", 0.2f, 0.0f, 0.5f, 0.9f },
{ "Test 2", 0.4f, 0.2f, 0.5f, 0.8f },
{ "Test 3", 0.6f, 0.4f, 0.5f, 0.7f },
{ "Test 4", 0.8f, 0.7f, 0.5f, 0.6f },
{ "Test 5", 0.8f, 1.0f, 0.5f, 0.5f },
{ NULL, 0.0f, 0.0f, 0.0f, 0.0f }
};
@ -185,8 +185,10 @@ void fluid_synth_settings(fluid_settings_t* settings)
FLUID_HINT_TOGGLED, NULL, NULL);
fluid_settings_register_str(settings, "midi.portname", "", 0, NULL, NULL);
#ifdef DEFAULT_SOUNDFONT
fluid_settings_register_str(settings, "synth.default-soundfont",
DEFAULT_SOUNDFONT, 0, NULL, NULL);
DEFAULT_SOUNDFONT, 0, NULL, NULL);
#endif
fluid_settings_register_int(settings, "synth.polyphony",
256, 1, 65535, 0, NULL, NULL);
@ -273,8 +275,6 @@ fluid_version_str (void)
static void
fluid_synth_init(void)
{
fluid_synth_initialized++;
#ifdef TRAP_ON_FPE
/* Turn on floating point exception traps */
feenableexcept (FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
@ -440,18 +440,12 @@ fluid_synth_init(void)
static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t* synth)
{
if (synth->eventhandler->is_threadsafe)
return fluid_atomic_int_get(&synth->ticks_since_start);
else
return synth->ticks_since_start;
return fluid_atomic_int_get(&synth->ticks_since_start);
}
static FLUID_INLINE void fluid_synth_add_ticks(fluid_synth_t* synth, int val)
{
if (synth->eventhandler->is_threadsafe)
fluid_atomic_int_add((int*) &synth->ticks_since_start, val);
else
synth->ticks_since_start += val;
fluid_atomic_int_add(&synth->ticks_since_start, val);
}
@ -556,9 +550,11 @@ new_fluid_synth(fluid_settings_t *settings)
double gain;
int i, nbuf;
int with_ladspa = 0;
int with_reverb = 0;
int with_chorus = 0;
/* initialize all the conversion tables and other stuff */
if (fluid_synth_initialized == 0)
if (fluid_atomic_int_compare_and_exchange(&fluid_synth_initialized, 0, 1))
{
char buf[64];
if (fluid_settings_str_equal (settings, "synth.volenv", "compliant"))
@ -596,8 +592,10 @@ new_fluid_synth(fluid_settings_t *settings)
synth->settings = settings;
fluid_settings_getint(settings, "synth.reverb.active", &synth->with_reverb);
fluid_settings_getint(settings, "synth.chorus.active", &synth->with_chorus);
fluid_settings_getint(settings, "synth.reverb.active", &with_reverb);
fluid_atomic_int_set(&synth->with_reverb, with_reverb);
fluid_settings_getint(settings, "synth.chorus.active", &with_chorus);
fluid_atomic_int_set(&synth->with_chorus, with_chorus);
fluid_settings_getint(settings, "synth.verbose", &synth->verbose);
fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony);
@ -679,7 +677,7 @@ new_fluid_synth(fluid_settings_t *settings)
synth->sfont_info = NULL;
synth->sfont_hash = new_fluid_hashtable (NULL, NULL);
synth->noteid = 0;
synth->ticks_since_start = 0;
fluid_atomic_int_set(&synth->ticks_since_start, 0);
synth->tuning = NULL;
fluid_private_init(synth->tuning_iter);
@ -692,18 +690,37 @@ new_fluid_synth(fluid_settings_t *settings)
if (synth->eventhandler == NULL)
goto error_recovery;
#ifdef LADSPA
/* Setup the list of default modulators.
* Needs to happen after eventhandler has been set up, as fluid_synth_enter_api is called in the process */
synth->default_mod = NULL;
fluid_synth_add_default_mod(synth, &default_vel2att_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_vel2filter_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_at2viblfo_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_mod2viblfo_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_att_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_pan_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_expr_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_reverb_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_chorus_mod, FLUID_SYNTH_ADD);
fluid_synth_add_default_mod(synth, &default_pitch_bend_mod, FLUID_SYNTH_ADD);
/* Create and initialize the Fx unit.*/
fluid_settings_getint(settings, "synth.ladspa.active", &with_ladspa);
if (with_ladspa) {
synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth);
if(synth->LADSPA_FxUnit == NULL) {
#ifdef LADSPA
synth->ladspa_fx = new_fluid_ladspa_fx(synth->sample_rate, synth->audio_groups,
synth->effects_channels, synth->audio_channels,
FLUID_MIXER_MAX_BUFFERS_DEFAULT * FLUID_BUFSIZE);
if(synth->ladspa_fx == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
goto error_recovery;
}
fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->LADSPA_FxUnit);
fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->ladspa_fx);
#else /* LADSPA */
FLUID_LOG(FLUID_WARN, "FluidSynth has not been compiled with LADSPA support");
#endif /* LADSPA */
}
#endif
/* allocate and add the default sfont loader */
loader = new_fluid_defsfloader(settings);
@ -745,8 +762,8 @@ new_fluid_synth(fluid_settings_t *settings)
fluid_synth_update_overflow(synth, "", 0.0f);
fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_polyphony,
synth->polyphony, 0.0f);
fluid_synth_set_reverb_on(synth, synth->with_reverb);
fluid_synth_set_chorus_on(synth, synth->with_chorus);
fluid_synth_set_reverb_on(synth, fluid_atomic_int_get(&synth->with_reverb));
fluid_synth_set_chorus_on(synth, fluid_atomic_int_get(&synth->with_chorus));
synth->cur = FLUID_BUFSIZE;
synth->curmax = 0;
@ -811,6 +828,8 @@ delete_fluid_synth(fluid_synth_t* synth)
fluid_list_t *list;
fluid_sfont_info_t* sfont_info;
fluid_sfloader_t* loader;
fluid_mod_t* default_mod;
fluid_mod_t* mod;
if (synth == NULL) {
return FLUID_OK;
@ -911,13 +930,20 @@ delete_fluid_synth(fluid_synth_t* synth)
fluid_private_free (synth->tuning_iter);
#ifdef LADSPA
/* Release the LADSPA Fx unit */
if (synth->LADSPA_FxUnit) {
fluid_LADSPA_shutdown(synth->LADSPA_FxUnit);
FLUID_FREE(synth->LADSPA_FxUnit);
/* Release the LADSPA effects unit */
if (synth->ladspa_fx) {
delete_fluid_ladspa_fx(synth->ladspa_fx);
}
#endif
/* delete all default modulators */
default_mod = synth->default_mod;
while (default_mod != NULL) {
mod = default_mod;
default_mod = mod->next;
fluid_mod_delete(mod);
}
fluid_rec_mutex_destroy(synth->mutex);
FLUID_FREE(synth);
@ -1079,6 +1105,58 @@ fluid_synth_damp_voices_by_sostenuto_LOCAL(fluid_synth_t* synth, int chan)
return FLUID_OK;
}
/**
* Adds the specified modulator \c mod as default modulator to the synth. If \c mod is new it
* will be used by any subsequently created voice. If an amount of an existing modulator is
* changed by \c mod it will take effect for any subsequently created voice.
* @param synth FluidSynth instance
* @param mod Modulator info (values copied, passed in object can be freed again immediately)
* @param mode Determines how to handle an existing identical modulator (#fluid_synth_add_mod)
* @return FLUID_OK on success, FLUID_FAILED otherwise
*/
int
fluid_synth_add_default_mod(fluid_synth_t* synth, fluid_mod_t* mod, int mode)
{
fluid_mod_t* default_mod;
fluid_mod_t* last_mod = NULL;
fluid_mod_t* new_mod;
fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
fluid_return_val_if_fail (mod != NULL, FLUID_FAILED);
fluid_synth_api_enter(synth);
default_mod = synth->default_mod;
while (default_mod != NULL) {
if (fluid_mod_test_identity(default_mod, mod)) {
if (mode == FLUID_SYNTH_ADD)
default_mod->amount += mod->amount;
else if (mode == FLUID_SYNTH_OVERWRITE)
default_mod->amount = mod->amount;
else
FLUID_API_RETURN(FLUID_FAILED);
FLUID_API_RETURN(FLUID_OK);
}
last_mod = default_mod;
default_mod = default_mod->next;
}
/* Add a new modulator (no existing modulator to add / overwrite). */
new_mod = fluid_mod_new();
if (new_mod == NULL)
FLUID_API_RETURN(FLUID_FAILED);
fluid_mod_clone(new_mod, mod);
new_mod->next = NULL;
if (last_mod == NULL)
synth->default_mod = new_mod;
else
last_mod->next = new_mod;
FLUID_API_RETURN(FLUID_OK);
}
/**
* Send a MIDI controller event on a MIDI channel.
@ -1662,15 +1740,9 @@ fluid_synth_system_reset(fluid_synth_t* synth)
static int
fluid_synth_system_reset_LOCAL(fluid_synth_t* synth)
{
fluid_voice_t* voice;
int i;
for (i = 0; i < synth->polyphony; i++) {
voice = synth->voice[i];
if (fluid_voice_is_playing(voice))
fluid_voice_off(voice);
}
fluid_synth_all_sounds_off_LOCAL(synth, -1);
for (i = 0; i < synth->midi_channels; i++)
fluid_channel_reset(synth->channel[i]);
@ -2272,7 +2344,7 @@ fluid_synth_update_presets(fluid_synth_t* synth)
}
}
/* Handler for synth.gain setting. */
/* Handler for synth.sample-rate setting. */
static int
fluid_synth_update_sample_rate(fluid_synth_t* synth, char* name, double value)
{
@ -2676,7 +2748,7 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
synth->cur = num;
time = fluid_utime() - time;
cpu_load = 0.5 * (synth->cpu_load + time * synth->sample_rate / len / 10000.0);
cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
fluid_atomic_float_set (&synth->cpu_load, cpu_load);
if (!synth->eventhandler->is_threadsafe)
@ -2787,7 +2859,7 @@ fluid_synth_write_float(fluid_synth_t* synth, int len,
synth->cur = l;
time = fluid_utime() - time;
cpu_load = 0.5 * (synth->cpu_load + time * synth->sample_rate / len / 10000.0);
cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
fluid_atomic_float_set (&synth->cpu_load, cpu_load);
if (!synth->eventhandler->is_threadsafe)
@ -2821,7 +2893,7 @@ init_dither(void)
}
/* A portable replacement for roundf(), seems it may actually be faster too! */
static inline int
static FLUID_INLINE int
roundi (float x)
{
if (x >= 0.0f)
@ -2912,7 +2984,7 @@ fluid_synth_write_s16(fluid_synth_t* synth, int len,
fluid_profile(FLUID_PROF_WRITE, prof_ref);
time = fluid_utime() - time;
cpu_load = 0.5 * (synth->cpu_load + time * synth->sample_rate / len / 10000.0);
cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
fluid_atomic_float_set (&synth->cpu_load, cpu_load);
if (!synth->eventhandler->is_threadsafe)
@ -3142,6 +3214,7 @@ fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan,
int i, k;
fluid_voice_t* voice = NULL;
fluid_channel_t* channel = NULL;
fluid_mod_t* default_mod;
unsigned int ticks;
fluid_return_val_if_fail (sample != NULL, NULL);
@ -3194,16 +3267,11 @@ fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan,
}
/* add the default modulators to the synthesis process. */
fluid_voice_add_mod(voice, &default_vel2att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.1 */
fluid_voice_add_mod(voice, &default_vel2filter_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.2 */
fluid_voice_add_mod(voice, &default_at2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.3 */
fluid_voice_add_mod(voice, &default_mod2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.4 */
fluid_voice_add_mod(voice, &default_att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.5 */
fluid_voice_add_mod(voice, &default_pan_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.6 */
fluid_voice_add_mod(voice, &default_expr_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.7 */
fluid_voice_add_mod(voice, &default_reverb_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.8 */
fluid_voice_add_mod(voice, &default_chorus_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.9 */
fluid_voice_add_mod(voice, &default_pitch_bend_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.10 */
default_mod = synth->default_mod;
while (default_mod != NULL) {
fluid_voice_add_mod(voice, default_mod, FLUID_VOICE_DEFAULT);
default_mod = default_mod->next;
}
FLUID_API_RETURN(voice);
}
@ -3285,13 +3353,12 @@ fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice)
void
fluid_synth_add_sfloader(fluid_synth_t* synth, fluid_sfloader_t* loader)
{
gboolean sfont_already_loaded;
fluid_return_if_fail (synth != NULL);
fluid_return_if_fail (loader != NULL);
fluid_synth_api_enter(synth);
sfont_already_loaded = synth->sfont_info != NULL;
if (!sfont_already_loaded)
/* Test if sfont is already loaded */
if (synth->sfont_info == NULL)
synth->loaders = fluid_list_prepend(synth->loaders, loader);
fluid_synth_api_exit(synth);
}
@ -3731,7 +3798,7 @@ fluid_synth_get_channel_info (fluid_synth_t *synth, int chan,
{
fluid_channel_t *channel;
fluid_preset_t *preset;
char *name;
const char *name;
if (info)
{
@ -3829,19 +3896,17 @@ fluid_synth_set_reverb_on(fluid_synth_t* synth, int on)
* @note Currently private to libfluidsynth.
*/
int
fluid_synth_set_reverb_preset(fluid_synth_t* synth, int num)
fluid_synth_set_reverb_preset(fluid_synth_t* synth, unsigned int num)
{
int i = 0;
while (revmodel_preset[i].name != NULL) {
if (i == num) {
fluid_synth_set_reverb (synth, revmodel_preset[i].roomsize,
revmodel_preset[i].damp, revmodel_preset[i].width,
revmodel_preset[i].level);
return FLUID_OK;
}
i++;
}
return FLUID_FAILED;
fluid_return_val_if_fail (
num < FLUID_N_ELEMENTS(revmodel_preset),
FLUID_FAILED
);
fluid_synth_set_reverb (synth, revmodel_preset[num].roomsize,
revmodel_preset[num].damp, revmodel_preset[num].width,
revmodel_preset[num].level);
return FLUID_OK;
}
/**
@ -3927,16 +3992,16 @@ fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize,
fluid_synth_api_enter(synth);
if (set & FLUID_REVMODEL_SET_ROOMSIZE)
fluid_atomic_float_set (&synth->reverb_roomsize, roomsize);
synth->reverb_roomsize = roomsize;
if (set & FLUID_REVMODEL_SET_DAMPING)
fluid_atomic_float_set (&synth->reverb_damping, damping);
synth->reverb_damping = damping;
if (set & FLUID_REVMODEL_SET_WIDTH)
fluid_atomic_float_set (&synth->reverb_width, width);
synth->reverb_width = width;
if (set & FLUID_REVMODEL_SET_LEVEL)
fluid_atomic_float_set (&synth->reverb_level, level);
synth->reverb_level = level;
/* finally enqueue an rvoice event to the mixer to actual update reverb */
ret = fluid_rvoice_eventhandler_push5(synth->eventhandler,
@ -3958,7 +4023,7 @@ fluid_synth_get_reverb_roomsize(fluid_synth_t* synth)
double result;
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_roomsize);
result = synth->reverb_roomsize;
FLUID_API_RETURN(result);
}
@ -3974,7 +4039,7 @@ fluid_synth_get_reverb_damp(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_damping);
result = synth->reverb_damping;
FLUID_API_RETURN(result);
}
@ -3990,7 +4055,7 @@ fluid_synth_get_reverb_level(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_level);
result = synth->reverb_level;
FLUID_API_RETURN(result);
}
@ -4006,7 +4071,7 @@ fluid_synth_get_reverb_width(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_width);
result = synth->reverb_width;
FLUID_API_RETURN(result);
}
@ -4118,19 +4183,19 @@ fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double level,
fluid_synth_api_enter(synth);
if (set & FLUID_CHORUS_SET_NR)
fluid_atomic_int_set (&synth->chorus_nr, nr);
synth->chorus_nr = nr;
if (set & FLUID_CHORUS_SET_LEVEL)
fluid_atomic_float_set (&synth->chorus_level, level);
synth->chorus_level = level;
if (set & FLUID_CHORUS_SET_SPEED)
fluid_atomic_float_set (&synth->chorus_speed, speed);
synth->chorus_speed = speed;
if (set & FLUID_CHORUS_SET_DEPTH)
fluid_atomic_float_set (&synth->chorus_depth, depth_ms);
synth->chorus_depth = depth_ms;
if (set & FLUID_CHORUS_SET_TYPE)
fluid_atomic_int_set (&synth->chorus_type, type);
synth->chorus_type = type;
ret = fluid_rvoice_eventhandler_push5(synth->eventhandler,
fluid_rvoice_mixer_set_chorus_params,
@ -4152,7 +4217,7 @@ fluid_synth_get_chorus_nr(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_int_get (&synth->chorus_nr);
result = synth->chorus_nr;
FLUID_API_RETURN(result);
}
@ -4168,7 +4233,7 @@ fluid_synth_get_chorus_level(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->chorus_level);
result = synth->chorus_level;
FLUID_API_RETURN(result);
}
@ -4184,7 +4249,7 @@ fluid_synth_get_chorus_speed_Hz(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->chorus_speed);
result = synth->chorus_speed;
FLUID_API_RETURN(result);
}
@ -4200,7 +4265,7 @@ fluid_synth_get_chorus_depth_ms(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->chorus_depth);
result = synth->chorus_depth;
FLUID_API_RETURN(result);
}
@ -4216,7 +4281,7 @@ fluid_synth_get_chorus_type(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_int_get (&synth->chorus_type);
result = synth->chorus_type;
FLUID_API_RETURN(result);
}
@ -4472,12 +4537,14 @@ fluid_synth_update_voice_tuning_LOCAL (fluid_synth_t *synth, fluid_channel_t *ch
* @param name Label name for this tuning
* @param pitch Array of pitch values (length of 128, each value is number of
* cents, for example normally note 0 is 0.0, 1 is 100.0, 60 is 6000.0, etc).
* Pass NULL to create a well-tempered (normal) scale.
* Pass NULL to create a equal tempered (normal) scale.
* @return FLUID_OK on success, FLUID_FAILED otherwise
*
* @note Tuning is not applied in realtime to existing notes of the replaced
* tuning (if any), use fluid_synth_activate_key_tuning() instead to specify
* this behavior.
*
* @deprecated Use fluid_synth_activate_key_tuning(synth, bank, prog, name, pitch, FALSE) instead.
*/
int
fluid_synth_create_key_tuning(fluid_synth_t* synth, int bank, int prog,
@ -4494,7 +4561,7 @@ fluid_synth_create_key_tuning(fluid_synth_t* synth, int bank, int prog,
* @param name Label name for this tuning
* @param pitch Array of pitch values (length of 128, each value is number of
* cents, for example normally note 0 is 0.0, 1 is 100.0, 60 is 6000.0, etc).
* Pass NULL to create a well-tempered (normal) scale.
* Pass NULL to create a equal tempered (normal) scale.
* @param apply TRUE to apply new tuning in realtime to existing notes which
* are using the replaced tuning (if any), FALSE otherwise
* @return FLUID_OK on success, FLUID_FAILED otherwise
@ -4540,6 +4607,8 @@ fluid_synth_activate_key_tuning(fluid_synth_t* synth, int bank, int prog,
* @note Tuning is not applied in realtime to existing notes of the replaced
* tuning (if any), use fluid_synth_activate_octave_tuning() instead to specify
* this behavior.
*
* @deprecated Use fluid_synth_activate_octave_tuning(synth, bank, prog, name, pitch, FALSE) instead.
*/
int
fluid_synth_create_octave_tuning(fluid_synth_t* synth, int bank, int prog,
@ -4603,7 +4672,7 @@ fluid_synth_activate_octave_tuning(fluid_synth_t* synth, int bank, int prog,
* @return FLUID_OK on success, FLUID_FAILED otherwise
*
* @note Prior to version 1.1.0 it was an error to specify a tuning that didn't
* already exist. Starting with 1.1.0, the default equal tempered scale will be
* already exist. Starting with 1.1.0, the default equal tempered scale will be
* used as a basis, if no tuning exists for the given bank and prog.
*/
int
@ -4655,8 +4724,10 @@ fluid_synth_tune_notes(fluid_synth_t* synth, int bank, int prog,
* should cause existing notes to update.
*
* @note Prior to version 1.1.0 it was an error to select a tuning that didn't
* already exist. Starting with 1.1.0, a default equal tempered scale will be
* already exist. Starting with 1.1.0, a default equal tempered scale will be
* created, if no tuning exists for the given bank and prog.
*
* @deprecated Use fluid_synth_activate_tuning(synth, chan, bank, prog, FALSE) instead.
*/
int
fluid_synth_select_tuning(fluid_synth_t* synth, int chan, int bank, int prog)
@ -4740,7 +4811,7 @@ fluid_synth_set_tuning_LOCAL (fluid_synth_t *synth, int chan,
}
/**
* Clear tuning scale on a MIDI channel (set it to the default well-tempered scale).
* Clear tuning scale on a MIDI channel (set it to the default equal tempered scale).
* @param synth FluidSynth instance
* @param chan MIDI channel number (0 to MIDI channel count - 1)
* @return FLUID_OK on success, FLUID_FAILED otherwise
@ -4748,6 +4819,8 @@ fluid_synth_set_tuning_LOCAL (fluid_synth_t *synth, int chan,
* @note This function does NOT activate tuning change in realtime, use
* fluid_synth_deactivate_tuning() instead to specify whether tuning change
* should cause existing notes to update.
*
* @deprecated Use fluid_synth_deactivate_tuning(synth, chan, FALSE) instead.
*/
int
fluid_synth_reset_tuning(fluid_synth_t* synth, int chan)
@ -4865,7 +4938,7 @@ fluid_synth_tuning_dump(fluid_synth_t* synth, int bank, int prog,
{
if (name)
{
snprintf (name, len - 1, "%s", fluid_tuning_get_name (tuning));
FLUID_SNPRINTF (name, len - 1, "%s", fluid_tuning_get_name (tuning));
name[len - 1] = 0; /* make sure the string is null terminated */
}
@ -5174,7 +5247,7 @@ void fluid_synth_api_exit(fluid_synth_t* synth)
* Set midi channel type
* @param synth FluidSynth instance
* @param chan MIDI channel number (0 to MIDI channel count - 1)
* @param type CHANNEL_TYPE_MELODIC, or CHANNEL_TYPE_DRUM
* @param type MIDI channel type (#fluid_midi_channel_type)
* @return FLUID_OK on success, FLUID_FAILED otherwise
* @since 1.1.4
*/
@ -5187,4 +5260,3 @@ int fluid_synth_set_channel_type(fluid_synth_t* synth, int chan, int type)
FLUID_API_RETURN(FLUID_OK);
}

View file

@ -100,7 +100,7 @@ typedef struct _fluid_sfont_info_t {
* ticks_since_start - atomic, set by rendering thread only
* cpu_load - atomic, set by rendering thread only
* cur, curmax, dither_index - used by rendering thread only
* LADSPA_FxUnit - same instance copied in rendering thread. Synchronising handled internally (I think...?).
* ladspa_fx - same instance copied in rendering thread. Synchronising handled internally.
*
*/
@ -113,8 +113,8 @@ struct _fluid_synth_t
fluid_settings_t* settings; /**< the synthesizer settings */
int device_id; /**< Device ID used for SYSEX messages */
int polyphony; /**< Maximum polyphony */
int with_reverb; /**< Should the synth use the built-in reverb unit? */
int with_chorus; /**< Should the synth use the built-in chorus unit? */
fluid_atomic_int_t with_reverb; /**< Should the synth use the built-in reverb unit? */
fluid_atomic_int_t with_chorus; /**< Should the synth use the built-in chorus unit? */
int verbose; /**< Turn verbose mode on? */
double sample_rate; /**< The sample rate */
int midi_channels; /**< the number of MIDI channels (>= 16) */
@ -124,7 +124,7 @@ struct _fluid_synth_t
Typically equal to audio_channels. */
int effects_channels; /**< the number of effects channels (>= 2) */
int state; /**< the synthesizer state */
unsigned int ticks_since_start; /**< the number of audio samples since the start */
fluid_atomic_uint_t ticks_since_start; /**< the number of audio samples since the start */
unsigned int start; /**< the start in msec, as returned by system clock */
fluid_overflow_prio_t overflow; /**< parameters for overflow priority (aka voice-stealing) */
@ -142,22 +142,22 @@ struct _fluid_synth_t
unsigned int storeid;
fluid_rvoice_eventhandler_t* eventhandler;
float reverb_roomsize; /**< Shadow of reverb roomsize */
float reverb_damping; /**< Shadow of reverb damping */
float reverb_width; /**< Shadow of reverb width */
float reverb_level; /**< Shadow of reverb level */
double reverb_roomsize; /**< Shadow of reverb roomsize */
double reverb_damping; /**< Shadow of reverb damping */
double reverb_width; /**< Shadow of reverb width */
double reverb_level; /**< Shadow of reverb level */
int chorus_nr; /**< Shadow of chorus number */
float chorus_level; /**< Shadow of chorus level */
float chorus_speed; /**< Shadow of chorus speed */
float chorus_depth; /**< Shadow of chorus depth */
double chorus_level; /**< Shadow of chorus level */
double chorus_speed; /**< Shadow of chorus speed */
double chorus_depth; /**< Shadow of chorus depth */
int chorus_type; /**< Shadow of chorus type */
int cur; /**< the current sample in the audio buffers to be output */
int curmax; /**< current amount of samples present in the audio buffers */
int dither_index; /**< current index in random dither value buffer: fluid_synth_(write_s16|dither_s16) */
float cpu_load; /**< CPU load in percent (CPU time required / audio synthesized time * 100) */
fluid_atomic_float_t cpu_load; /**< CPU load in percent (CPU time required / audio synthesized time * 100) */
fluid_tuning_t*** tuning; /**< 128 banks of 128 programs for the tunings */
fluid_private_t tuning_iter; /**< Tuning iterators per each thread */
@ -167,8 +167,10 @@ struct _fluid_synth_t
int cores; /**< Number of CPU cores (1 by default) */
fluid_mod_t* default_mod; /**< the (dynamic) list of default modulators */
#ifdef LADSPA
fluid_LADSPA_FxUnit_t* LADSPA_FxUnit; /**< Effects unit for LADSPA support */
fluid_ladspa_fx_t* ladspa_fx; /**< Effects unit for LADSPA support */
#endif
};
@ -189,7 +191,7 @@ void fluid_synth_dither_s16(int *dither_index, int len, float* lin, float* rin,
void* rout, int roff, int rincr);
int fluid_synth_reset_reverb(fluid_synth_t* synth);
int fluid_synth_set_reverb_preset(fluid_synth_t* synth, int num);
int fluid_synth_set_reverb_preset(fluid_synth_t* synth, unsigned int num);
int fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize,
double damping, double width, double level);

View file

@ -48,7 +48,7 @@ fluid_tuning_t* new_fluid_tuning(const char* name, int bank, int prog)
tuning->pitch[i] = i * 100.0;
}
tuning->refcount = 1; /* Start with a refcount of 1 */
fluid_atomic_int_set(&tuning->refcount, 1); /* Start with a refcount of 1 */
return tuning;
}
@ -86,7 +86,7 @@ fluid_tuning_duplicate (fluid_tuning_t *tuning)
for (i = 0; i < 128; i++)
new_tuning->pitch[i] = tuning->pitch[i];
new_tuning->refcount = 1; /* Start with a refcount of 1 */
fluid_atomic_int_set(&new_tuning->refcount, 1); /* Start with a refcount of 1 */
return new_tuning;
}

View file

@ -39,7 +39,7 @@ struct _fluid_tuning_t {
int bank;
int prog;
double pitch[128]; /* the pitch of every key, in cents */
int refcount; /* Tuning reference count */
fluid_atomic_int_t refcount; /* Tuning reference count */
};
fluid_tuning_t* new_fluid_tuning(const char* name, int bank, int prog);

View file

@ -104,7 +104,7 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice);
#define UPDATE_RVOICE_ENVLFO_R1(proc, envp, rarg) UPDATE_RVOICE_GENERIC_R1(proc, &voice->rvoice->envlfo.envp, rarg)
#define UPDATE_RVOICE_ENVLFO_I1(proc, envp, iarg) UPDATE_RVOICE_GENERIC_I1(proc, &voice->rvoice->envlfo.envp, iarg)
static inline void
static FLUID_INLINE void
fluid_voice_update_volenv(fluid_voice_t* voice,
fluid_adsr_env_section_t section,
unsigned int count,
@ -120,7 +120,7 @@ fluid_voice_update_volenv(fluid_voice_t* voice,
coeff, increment, min, max);
}
static inline void
static FLUID_INLINE void
fluid_voice_update_modenv(fluid_voice_t* voice,
fluid_adsr_env_section_t section,
unsigned int count,
@ -134,7 +134,7 @@ fluid_voice_update_modenv(fluid_voice_t* voice,
coeff, increment, min, max);
}
static inline void fluid_sample_null_ptr(fluid_sample_t** sample)
static FLUID_INLINE void fluid_sample_null_ptr(fluid_sample_t** sample)
{
if (*sample != NULL) {
fluid_sample_decr_ref(*sample);
@ -268,7 +268,6 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
voice->channel = channel;
voice->mod_count = 0;
voice->start_time = start_time;
voice->debug = 0;
voice->has_noteoff = 0;
UPDATE_RVOICE0(fluid_rvoice_reset);
@ -503,8 +502,9 @@ static int
fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
{
int i;
unsigned int n;
int list_of_generators_to_initialize[35] = {
static int const list_of_generators_to_initialize[] = {
GEN_STARTADDROFS, /* SF2.01 page 48 #0 */
GEN_ENDADDROFS, /* #1 */
GEN_STARTLOOPADDROFS, /* #2 */
@ -554,8 +554,8 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
/* GEN_COARSETUNE [1] #51 */
/* GEN_FINETUNE [1] #52 */
GEN_OVERRIDEROOTKEY, /* #58 */
GEN_PITCH, /* --- */
-1}; /* end-of-list marker */
GEN_PITCH /* --- */
};
/* When the voice is made ready for the synthesis process, a lot of
* voice-internal parameters have to be calculated.
@ -599,8 +599,8 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
*/
/* Calculate the voice parameter(s) dependent on each generator. */
for (i = 0; list_of_generators_to_initialize[i] != -1; i++) {
fluid_voice_update_param(voice, list_of_generators_to_initialize[i]);
for (n = 0; n < FLUID_N_ELEMENTS(list_of_generators_to_initialize); n++) {
fluid_voice_update_param(voice, list_of_generators_to_initialize[n]);
}
/* Make an estimate on how loud this voice can get at any time (attenuation). */
@ -703,7 +703,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
fluid_real_t y;
unsigned int count, z;
// Alternate attenuation scale used by EMU10K1 cards when setting the attenuation at the preset or instrument level within the SoundFont bank.
static const float ALT_ATTENUATION_SCALE = 0.4;
static const float ALT_ATTENUATION_SCALE = 0.4f;
switch (gen) {
@ -1014,7 +1014,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
fluid_clip(x, -12000.0f, 8000.0f);
count = 1 + NUM_BUFFERS_ATTACK(x);
fluid_voice_update_volenv(voice, FLUID_VOICE_ENVATTACK,
count, 1.0f, count ? 1.0f / count : 0.0f, -1.0f, 1.0f);
count, 1.0f, 1.0f / count, -1.0f, 1.0f);
break;
case GEN_VOLENVHOLD: /* SF2.01 section 8.1.3 # 35 */
@ -1039,7 +1039,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
fluid_clip(x, FLUID_MIN_VOLENVRELEASE, 8000.0f);
count = 1 + NUM_BUFFERS_RELEASE(x);
fluid_voice_update_volenv(voice, FLUID_VOICE_ENVRELEASE,
count, 1.0f, count ? -1.0f / count : 0.0f, 0.0f, 1.0f);
count, 1.0f, -1.0f / count, 0.0f, 1.0f);
break;
/* Modulation envelope */
@ -1055,7 +1055,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
fluid_clip(x, -12000.0f, 8000.0f);
count = 1 + NUM_BUFFERS_ATTACK(x);
fluid_voice_update_modenv(voice, FLUID_VOICE_ENVATTACK,
count, 1.0f, count ? 1.0f / count : 0.0f, -1.0f, 1.0f);
count, 1.0f, 1.0f / count, -1.0f, 1.0f);
break;
case GEN_MODENVHOLD: /* SF2.01 section 8.1.3 # 27 */
@ -1080,7 +1080,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
fluid_clip(x, -12000.0f, 8000.0f);
count = 1 + NUM_BUFFERS_RELEASE(x);
fluid_voice_update_modenv(voice, FLUID_VOICE_ENVRELEASE,
count, 1.0f, count ? -1.0f / count : 0.0f, 0.0f, 2.0f);
count, 1.0f, -1.0f / count, 0.0f, 2.0f);
break;
@ -1445,7 +1445,7 @@ int fluid_voice_is_on(const fluid_voice_t* voice)
}
/**
* Check if a voice is sustained.
* Check if a voice keeps playing after it has received a noteoff due to being held by sustain.
* @param voice Voice instance
* @return TRUE if sustained, FALSE otherwise
* @since 1.1.7
@ -1456,7 +1456,7 @@ int fluid_voice_is_sustained(const fluid_voice_t* voice)
}
/**
* Check if a voice is held by sostenuto.
* Check if a voice keeps playing after it has received a noteoff due to being held by sostenuto.
* @param voice Voice instance
* @return TRUE if sostenuto, FALSE otherwise
* @since 1.1.7

View file

@ -71,8 +71,6 @@ struct _fluid_voice_t
int mod_count;
fluid_sample_t* sample; /* Pointer to sample (dupe in rvoice) */
int has_noteoff; /* Flag set when noteoff has been sent */
/* basic parameters */
fluid_real_t output_rate; /* the sample rate of the synthesizer (dupe in rvoice) */
@ -103,11 +101,11 @@ struct _fluid_voice_t
/* rvoice control */
fluid_rvoice_t* rvoice;
fluid_rvoice_t* overflow_rvoice; /* Used temporarily and only in overflow situations */
int can_access_rvoice; /* False if rvoice is being rendered in separate thread */
int can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */
char can_access_rvoice; /* False if rvoice is being rendered in separate thread */
char can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */
char has_noteoff; /* Flag set when noteoff has been sent */
/* for debugging */
int debug;
double ref;
};

View file

@ -123,7 +123,7 @@ void fluid_dsp_float_config (void)
}
static inline int
static FLUID_INLINE int
fluid_voice_is_looping(fluid_voice_t *voice)
{
return _SAMPLEMODE (voice) == FLUID_LOOP_DURING_RELEASE

View file

@ -112,7 +112,7 @@ fluid_rvoice_handler_remove_voice(fluid_rvoice_handler_t* handler, int index)
* @return Number of samples written
*/
#if 0
static inline int
static FLUID_INLINE int
fluid_rvoice_handler_write_one(fluid_rvoice_handler_t* handler, int index,
fluid_real_t* buf, int blockcount)
{
@ -137,7 +137,7 @@ fluid_rvoice_handler_write_one(fluid_rvoice_handler_t* handler, int index,
* voice has been finished, removed and possibly replaced with another voice.
* @return Number of samples written
*/
static inline int
static FLUID_INLINE int
fluid_rvoice_handler_mix_one(fluid_rvoice_handler_t* handler, int index,
fluid_real_t** bufs, unsigned int blockcount, unsigned int bufcount)
{
@ -166,7 +166,7 @@ fluid_rvoice_handler_mix_one(fluid_rvoice_handler_t* handler, int index,
return result;
}
static inline void
static FLUID_INLINE void
fluid_resetbufs(int blockcount, int bufcount, fluid_real_t** bufs)
{
int i;
@ -177,7 +177,7 @@ fluid_resetbufs(int blockcount, int bufcount, fluid_real_t** bufs)
/**
* Single-threaded scenario, no worker threads
*/
static inline void
static FLUID_INLINE void
fluid_rvoice_handler_render_loop_simple(fluid_rvoice_handler_t* handler,
int blockcount, int bufcount, fluid_real_t** bufs)
{

View file

@ -66,7 +66,7 @@ fluid_rvoice_handler_get_finished_voices(fluid_rvoice_handler_t* handler,
return handler->finished_voices;
}
static inline void
static FLUID_INLINE void
fluid_rvoice_handler_clear_finished_voices(fluid_rvoice_handler_t* handler)
{
handler->finished_voice_count = 0;

View file

@ -86,13 +86,13 @@ fluid_conversion_config(void)
implemented according to the pictures on SF2.01 page 73. */
for (i = 1; i < 127; i++) {
x = -20.0 / 96.0 * log((i * i) / (127.0 * 127.0)) / log(10.0);
x = -20.0 / 96.0 * log((i * i) / (127.0 * 127.0)) / M_LN10;
fluid_convex_tab[i] = (fluid_real_t) (1.0 - x);
fluid_concave_tab[127 - i] = (fluid_real_t) x;
}
/* initialize the pan conversion table */
x = PI / 2.0 / (FLUID_PAN_SIZE - 1.0);
x = M_PI / 2.0 / (FLUID_PAN_SIZE - 1.0);
for (i = 0; i < FLUID_PAN_SIZE; i++) {
fluid_pan_tab[i] = (fluid_real_t) sin(i * x);
}
@ -281,7 +281,7 @@ fluid_act2hz(fluid_real_t c)
fluid_real_t
fluid_hz2ct(fluid_real_t f)
{
return (fluid_real_t) (6900 + 1200 * log(f / 440.0) / log(2.0));
return (fluid_real_t) (6900 + 1200 * log(f / 440.0) / M_LN2);
}
/*

View file

@ -53,7 +53,7 @@ typedef struct
/* Excerpt from glib gprimes.c */
static const guint primes[] =
static const unsigned int primes[] =
{
11,
19,
@ -136,7 +136,7 @@ spaced_primes_closest (unsigned int num)
* save insertions from having to compute the hash record again for
* the new record.
*/
static inline fluid_hashnode_t **
static FLUID_INLINE fluid_hashnode_t **
fluid_hashtable_lookup_node (fluid_hashtable_t *hashtable, const void *key,
unsigned int *hash_return)
{
@ -316,7 +316,7 @@ fluid_hashtable_resize (fluid_hashtable_t *hashtable)
* Essentially, calls fluid_hashtable_resize() if the table has strayed
* too far from its ideal size for its number of nodes.
*/
static inline void
static FLUID_INLINE void
fluid_hashtable_maybe_resize (fluid_hashtable_t *hashtable)
{
int nnodes = hashtable->nnodes;
@ -389,7 +389,7 @@ new_fluid_hashtable_full (fluid_hash_func_t hash_func,
hashtable->nnodes = 0;
hashtable->hash_func = hash_func ? hash_func : fluid_direct_hash;
hashtable->key_equal_func = key_equal_func;
hashtable->ref_count = 1;
fluid_atomic_int_set(&hashtable->ref_count, 1);
hashtable->key_destroy_func = key_destroy_func;
hashtable->value_destroy_func = value_destroy_func;
hashtable->nodes = FLUID_ARRAY (fluid_hashnode_t*, hashtable->size);
@ -616,7 +616,7 @@ fluid_hashtable_t*
fluid_hashtable_ref (fluid_hashtable_t *hashtable)
{
fluid_return_val_if_fail (hashtable != NULL, NULL);
fluid_return_val_if_fail (hashtable->ref_count > 0, hashtable);
fluid_return_val_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0, hashtable);
fluid_atomic_int_add (&hashtable->ref_count, 1);
return hashtable;
@ -637,7 +637,7 @@ void
fluid_hashtable_unref (fluid_hashtable_t *hashtable)
{
fluid_return_if_fail (hashtable != NULL);
fluid_return_if_fail (hashtable->ref_count > 0);
fluid_return_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0);
if (fluid_atomic_int_exchange_and_add (&hashtable->ref_count, -1) - 1 == 0)
{
@ -662,7 +662,7 @@ void
delete_fluid_hashtable (fluid_hashtable_t *hashtable)
{
fluid_return_if_fail (hashtable != NULL);
fluid_return_if_fail (hashtable->ref_count > 0);
fluid_return_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0);
fluid_hashtable_remove_all (hashtable);
fluid_hashtable_unref (hashtable);
@ -753,7 +753,7 @@ fluid_hashtable_insert_internal (fluid_hashtable_t *hashtable, void *key,
unsigned int key_hash;
fluid_return_if_fail (hashtable != NULL);
fluid_return_if_fail (hashtable->ref_count > 0);
fluid_return_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0);
node_ptr = fluid_hashtable_lookup_node (hashtable, key, &key_hash);

View file

@ -65,7 +65,7 @@ struct _fluid_hashtable_t
fluid_hashnode_t **nodes;
fluid_hash_func_t hash_func;
fluid_equal_func_t key_equal_func;
volatile int ref_count;
fluid_atomic_int_t ref_count;
fluid_destroy_notify_t key_destroy_func;
fluid_destroy_notify_t value_destroy_func;
fluid_rec_mutex_t mutex; // Optionally used in other modules (fluid_settings.c for example)

View file

@ -67,7 +67,7 @@ new_fluid_ringbuffer (int count, int elementsize)
queue->totalcount = count;
queue->elementsize = elementsize;
queue->count = 0;
fluid_atomic_int_set(&queue->count, 0);
queue->in = 0;
queue->out = 0;

View file

@ -30,7 +30,7 @@ struct _fluid_ringbuffer_t
{
char *array; /**< Queue array of arbitrary size elements */
int totalcount; /**< Total count of elements in array */
int count; /**< Current count of elements */
fluid_atomic_int_t count; /**< Current count of elements */
int in; /**< Index in queue to store next pushed element */
int out; /**< Index in queue of next popped element */
int elementsize; /**< Size of each element */

View file

@ -410,9 +410,11 @@ fluid_settings_set(fluid_settings_t* settings, const char *name, fluid_setting_n
int n, num;
char *dupname;
num = fluid_settings_tokenize (name, buf, tokens) - 1;
num = fluid_settings_tokenize (name, buf, tokens);
if (num == 0)
return FLUID_FAILED;
num--;
for (n = 0; n < num; n++) {

View file

@ -74,7 +74,7 @@ static fluid_log_function_t fluid_log_function[LAST_LOG_LEVEL];
static void* fluid_log_user_data[LAST_LOG_LEVEL];
static int fluid_log_initialized = 0;
static char* fluid_libname = "fluidsynth";
static const char fluid_libname[] = "fluidsynth";
void fluid_sys_config()
@ -83,31 +83,6 @@ void fluid_sys_config()
}
unsigned int fluid_debug_flags = 0;
#if DEBUG
/*
* fluid_debug
*/
int fluid_debug(int level, char * fmt, ...)
{
if (fluid_debug_flags & level) {
fluid_log_function_t fun;
va_list args;
va_start (args, fmt);
vsnprintf(fluid_errbuf, sizeof (fluid_errbuf), fmt, args);
va_end (args);
fun = fluid_log_function[FLUID_DBG];
if (fun != NULL) {
(*fun)(level, fluid_errbuf, fluid_log_user_data[FLUID_DBG]);
}
}
return 0;
}
#endif
/**
* Installs a new log function for a specified log level.
* @param level Log level to install handler for.
@ -220,7 +195,7 @@ fluid_log(int level, const char* fmt, ...)
va_list args;
va_start (args, fmt);
vsnprintf(fluid_errbuf, sizeof (fluid_errbuf), fmt, args);
FLUID_VSNPRINTF (fluid_errbuf, sizeof (fluid_errbuf), fmt, args);
va_end (args);
if ((level >= 0) && (level < LAST_LOG_LEVEL)) {
@ -686,7 +661,7 @@ fluid_thread_join(fluid_thread_t* thread)
}
void
fluid_thread_return_t
fluid_timer_run (void *data)
{
fluid_timer_t *timer;
@ -719,7 +694,7 @@ fluid_timer_run (void *data)
if (timer->auto_destroy)
FLUID_FREE (timer);
return;
return FLUID_THREAD_RETURN_VALUE;
}
fluid_timer_t*
@ -753,7 +728,15 @@ new_fluid_timer (int msec, fluid_timer_callback_t callback, void* data,
return NULL;
}
}
else fluid_timer_run (timer); /* Run directly, instead of as a separate thread */
else
{
fluid_timer_run (timer); /* Run directly, instead of as a separate thread */
if(auto_destroy)
{
/* do NOT return freed memory */
return NULL;
}
}
return timer;
}
@ -834,7 +817,7 @@ fluid_istream_readline (fluid_istream_t in, fluid_ostream_t out, char* prompt,
if (line == NULL)
return -1;
snprintf(buf, len, "%s", line);
FLUID_SNPRINTF (buf, len, "%s", line);
buf[len - 1] = 0;
free(line);
@ -916,7 +899,7 @@ fluid_ostream_printf (fluid_ostream_t out, char* format, ...)
int len;
va_start (args, format);
len = vsnprintf (buf, 4095, format, args);
len = FLUID_VSNPRINTF (buf, 4095, format, args);
va_end (args);
if (len == 0)
@ -976,7 +959,7 @@ void fluid_socket_close(fluid_socket_t sock)
close (sock);
}
static void
static fluid_thread_return_t
fluid_server_socket_run (void *data)
{
fluid_server_socket_t *server_socket = (fluid_server_socket_t *)data;
@ -1006,7 +989,7 @@ fluid_server_socket_run (void *data)
FLUID_LOG(FLUID_ERR, "Failed to accept connection");
server_socket->cont = 0;
return;
return FLUID_THREAD_RETURN_VALUE;
} else {
#ifdef HAVE_INETNTOP
#ifdef IPV6_SUPPORT
@ -1029,6 +1012,8 @@ fluid_server_socket_run (void *data)
}
FLUID_LOG(FLUID_DBG, "Server closing");
return FLUID_THREAD_RETURN_VALUE;
}
fluid_server_socket_t*
@ -1139,7 +1124,7 @@ void fluid_socket_close (fluid_socket_t sock)
closesocket (sock);
}
static void fluid_server_socket_run (void *data)
static fluid_thread_return_t fluid_server_socket_run (void *data)
{
fluid_server_socket_t *server_socket = (fluid_server_socket_t *)data;
fluid_socket_t client_socket;
@ -1170,7 +1155,7 @@ static void fluid_server_socket_run (void *data)
FLUID_LOG (FLUID_ERR, "Failed to accept connection: %ld", WSAGetLastError ());
server_socket->cont = 0;
return;
return FLUID_THREAD_RETURN_VALUE;
}
else
{
@ -1194,6 +1179,8 @@ static void fluid_server_socket_run (void *data)
}
FLUID_LOG (FLUID_DBG, "Server closing");
return FLUID_THREAD_RETURN_VALUE;
}
fluid_server_socket_t*

View file

@ -67,33 +67,15 @@ void fluid_time_config(void);
#define FLUID_IS_BIG_ENDIAN (G_BYTE_ORDER == G_BIG_ENDIAN)
#define FLUID_LE32TOH(x) GINT32_FROM_LE(x)
#define FLUID_LE16TOH(x) GINT16_FROM_LE(x)
/*
* Utility functions
*/
char *fluid_strtok (char **str, char *delim);
/**
Additional debugging system, separate from the log system. This
allows to print selected debug messages of a specific subsystem.
*/
extern unsigned int fluid_debug_flags;
#if DEBUG
enum fluid_debug_level {
FLUID_DBG_DRIVER = 1
};
int fluid_debug(int level, char * fmt, ...);
#else
#define fluid_debug
#endif
#if defined(__OS2__)
#define INCL_DOS
#include <os2.h>
@ -211,10 +193,10 @@ typedef GStaticMutex fluid_mutex_t;
#define fluid_mutex_lock(_m) g_static_mutex_lock(&(_m))
#define fluid_mutex_unlock(_m) g_static_mutex_unlock(&(_m))
#define fluid_mutex_init(_m) G_STMT_START { \
#define fluid_mutex_init(_m) do { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_mutex_init (&(_m)); \
} G_STMT_END;
} while(0)
/* Recursive lock capable mutex */
typedef GStaticRecMutex fluid_rec_mutex_t;
@ -222,10 +204,10 @@ typedef GStaticRecMutex fluid_rec_mutex_t;
#define fluid_rec_mutex_lock(_m) g_static_rec_mutex_lock(&(_m))
#define fluid_rec_mutex_unlock(_m) g_static_rec_mutex_unlock(&(_m))
#define fluid_rec_mutex_init(_m) G_STMT_START { \
#define fluid_rec_mutex_init(_m) do { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_rec_mutex_init (&(_m)); \
} G_STMT_END;
} while(0)
/* Dynamically allocated mutex suitable for fluid_cond_t use */
typedef GMutex fluid_cond_mutex_t;
@ -254,10 +236,10 @@ typedef GStaticPrivate fluid_private_t;
#define fluid_private_set(_priv, _data) g_static_private_set(&(_priv), _data, NULL)
#define fluid_private_free(_priv) g_static_private_free(&(_priv))
#define fluid_private_init(_priv) G_STMT_START { \
#define fluid_private_init(_priv) do { \
if (!g_thread_supported ()) g_thread_init (NULL); \
g_static_private_init (&(_priv)); \
} G_STMT_END;
} while(0)
#endif
@ -309,8 +291,13 @@ fluid_atomic_float_get(volatile float *fptr)
/* Threads */
/* other thread implementations might change this for their needs */
typedef void* fluid_thread_return_t;
/* static return value for thread functions which requires a return value */
#define FLUID_THREAD_RETURN_VALUE (NULL)
typedef GThread fluid_thread_t;
typedef void (*fluid_thread_func_t)(void* data);
typedef fluid_thread_return_t (*fluid_thread_func_t)(void* data);
#define FLUID_THREAD_ID_NULL NULL /* A NULL "ID" value */
#define fluid_thread_id_t GThread * /* Data type for a thread ID */

View file

@ -122,8 +122,6 @@
#ifdef MINGW32
#include <stdint.h>
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define DSOUND_SUPPORT 1
#define WINMIDI_SUPPORT 1
@ -176,12 +174,17 @@ typedef int fluid_socket_t;
//typedef gint8 sint8;
typedef guint8 uint8;
//typedef gint16 sint16;
//typedef guint16 uint16;
typedef guint16 uint16;
typedef gint32 sint32;
typedef guint32 uint32;
//typedef gint64 sint64;
//typedef guint64 uint64;
/** Atomic types */
typedef int fluid_atomic_int_t;
typedef unsigned int fluid_atomic_uint_t;
typedef float fluid_atomic_float_t;
/***************************************************************
*
@ -208,10 +211,6 @@ typedef struct _fluid_sample_timer_t fluid_sample_timer_t;
#define FLUID_DEFAULT_AUDIO_RT_PRIO 60 /**< Default setting for audio.realtime-prio */
#define FLUID_DEFAULT_MIDI_RT_PRIO 50 /**< Default setting for midi.realtime-prio */
#ifndef PI
#define PI 3.141592654
#endif
/***************************************************************
*
* SYSTEM INTERFACE
@ -233,18 +232,49 @@ typedef FILE* fluid_file;
#define FLUID_STRCMP(_s,_t) strcmp(_s,_t)
#define FLUID_STRNCMP(_s,_t,_n) strncmp(_s,_t,_n)
#define FLUID_STRCPY(_dst,_src) strcpy(_dst,_src)
#define FLUID_STRNCPY(_dst,_src,_n) strncpy(_dst,_src,_n)
#define FLUID_STRNCPY(_dst,_src,_n) \
do { strncpy(_dst,_src,_n); \
(_dst)[(_n)-1]=0; \
}while(0)
#define FLUID_STRCHR(_s,_c) strchr(_s,_c)
#define FLUID_STRRCHR(_s,_c) strrchr(_s,_c)
#ifdef strdup
#define FLUID_STRDUP(s) strdup(s)
#define FLUID_STRDUP(s) strdup(s)
#else
#define FLUID_STRDUP(s) FLUID_STRCPY(FLUID_MALLOC(FLUID_STRLEN(s) + 1), s)
#define FLUID_STRDUP(s) FLUID_STRCPY(FLUID_MALLOC(FLUID_STRLEN(s) + 1), s)
#endif
#define FLUID_SPRINTF sprintf
#define FLUID_SNPRINTF snprintf
#define FLUID_FPRINTF fprintf
#if (defined(WIN32) && _MSC_VER < 1900) || defined(MINGW32)
#define FLUID_SNPRINTF _snprintf
#else
#define FLUID_SNPRINTF snprintf
#endif
#if (defined(WIN32) && _MSC_VER < 1500) || defined(MINGW32)
#define FLUID_VSNPRINTF _vsnprintf
#else
#define FLUID_VSNPRINTF vsnprintf
#endif
#if defined(WIN32) && !defined(MINGW32)
#define FLUID_STRCASECMP _stricmp
#else
#define FLUID_STRCASECMP strcasecmp
#endif
#if defined(WIN32) && !defined(MINGW32)
#define FLUID_STRNCASECMP _strincmp
#else
#define FLUID_STRNCASECMP strncasecmp
#endif
#define fluid_clip(_val, _min, _max) \
{ (_val) = ((_val) < (_min))? (_min) : (((_val) > (_max))? (_max) : (_val)); }
@ -262,6 +292,13 @@ typedef FILE* fluid_file;
#define M_PI 3.1415926535897932384626433832795
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530941723212145818
#endif
#ifndef M_LN10
#define M_LN10 2.3025850929940456840179914546844
#endif
#define FLUID_ASSERT(a,b)
#define FLUID_ASSERT_P(a,b)