流体合成  1.1.11
FluidSynth 1.1开发人员文档
作者
彼得·汉纳佩
康拉德·贝赫斯特(ConradBerhörster)
安托万·施密特(Antoine Schmitt)
佩德罗·洛佩斯(PedroLópez-Cabanillas)
乔希·格林(Josh Green)
戴维·亨宁森
汤姆·莫伯特
版权©2003-2018年Peter Hanappe,ConradBerhörster,Antoine Schmitt,PedroLópez-Cabanillas,Josh Green,David Henningsson,Tom Moebert
修订1.1.11
日期
2018-05-04

本文档中的所有源代码示例均位于公共领域;您可以随意使用它们。本文档根据知识共享署名-相同方式共享3.0未移植许可证获得许可。要查看此许可证的副本,请访问 http://creativecommons.org/licenses/by-sa/3.0/ 。 FluidSynth库是根据GNU较小通用公共许可证发行的。 FluidSynth软件包中包含GNU较小通用公共许可证的副本。如果没有,请访问 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt 或写信给美国自由软件基金会有限公司(Free Software Foundation,Inc.),地址为:51 Franklin Street,Fifth Floor,Boston,MA 02110-1301 USA。

抽象

FluidSynth 是基于以下内容的软件合成器: SoundFont 2 规格。合成器可以作为共享对象使用,可以在任何要使用波表合成的应用程序中轻松重用。本文档介绍了FluidSynth的基本用法。一些更高级的功能尚未讨论,但将在以后的版本中添加。

目录

免责声明

当前版本的文档不完整。与往常一样,源代码是最终参考。

SoundFont(R)是E-mu Systems,Inc.的注册商标。

介绍

什么是FluidSynth?

1.1.10有什么新功能?

针对开发人员的FluidSynth 1.1.10中的更改:

1.1.9中有什么新功能?

FluidSynth 1.1.9中与开发人员有关的更改:

1.1.8中有什么新功能?

FluidSynth 1.1.8中与开发人员有关的更改:

1.1.7中有什么新功能?

FluidSynth 1.1.7中与开发人员有关的更改:

1.1.6中有什么新功能?

FluidSynth 1.1.6中与开发人员有关的更改:

1.1.5中有什么新功能?

针对开发人员的FluidSynth 1.1.5的更改:

1.1.4中有什么新功能?

FluidSynth 1.1.4中与开发人员有关的更改:

1.1.3有什么新功能?

FluidSynth 1.1.3中与开发人员有关的更改:

1.1.2有什么新功能?

FluidSynth 1.1.2中与开发人员有关的更改:

1.1.1中有什么新功能?

FluidSynth 1.1.1中与开发人员有关的更改:

1.1.0中有什么新功能?

FluidSynth 1.1.0中与开发人员有关的更改概述:

API新增功能:

创建和更改设置

必须先创建一个设置对象,然后才能使用合成器。设置对象被FluidSynth库的许多组件使用。它提供了一个统一的API,用于设置音频驱动程序,MIDI驱动程序,合成器等的参数。当前的实现定义了许多默认设置。

所有设置的名称都遵循“点名”符号。例如,“ 合成复音”是指合成器预先分配的声音(复音)的数量。设置也有一个类型。当前有三种类型:字符串,数字(双浮点数)和整数。您可以使用来更改设置的值 fluid_settings_setstr(), fluid_settings_setnum()fluid_settings_setint() 职能。例如:

#包括<fluidsynth.h>
整型 主要(整型 argc, 烧焦** argv)
{
fluid_settings_t*设置= new_fluid_settings();
fluid_settings_setint(设置, "synth.polyphony",128);
/ * ... * /
delete_fluid_settings(设置);
返回 0;
}

API包含用于查询类型,当前值,默认值,范围和设置的“提示”的函数。范围是设置的最小值和最大值。这些提示提供了有关设置的其他信息。例如,字符串是否代表文件名。或者数字是否应该以对数尺度进行解释。检查 settings.h 有关所有功能的描述的API文档。

创建合成器

要创建合成器,请向其传递设置对象,如以下示例所示:

#包括<fluidsynth.h>
整型 主要(整型 argc, 烧焦** argv)
{
fluid_settings_t*设置;
fluid_synth_t*合成器;
设置= new_fluid_settings();
合成= new_fluid_synth(设置);
/ *在这里做有用的事情* /
delete_fluid_synth(合成);
delete_fluid_settings(设置);
返回 0;
}

下表提供了合成器使用的所有设置的详细信息。

表1.合成器设置
合成音频通道 类型 整数
默认 1
最小-最大 1-128
描述

默认情况下,合成器输出单个立体声信号。使用此选项,合成器可以输出多声道音频。设置立体声通道对的数量。所以1实际上是2个声道(立体声对)。

合成音频组 类型 整数
默认 1
最小-最大 1-128
描述

通常与synth.audio-channels的值相同。 LADSPA效果子系统可以使用此值,在这种情况下,它可能会有所不同。

合成合唱 类型 布尔值
默认 1(真)
描述

设置为1(TRUE)时,合唱效果模块被激活。否则,不会将合唱添加到输出信号。请注意,发送到合唱模块的信号量取决于SoundFont中定义的“合唱发送”发生器。

synth.cpu核心 类型 整数
默认 1
最小-最大 1-256
描述

(实验性)设置综合CPU内核的数量。如果设置为大于1的值,则将创建其他综合线程以利用多CPU或CPU核心系统。在将音频合成到文件中时,这会产生以下影响:占用更多的CPU资源进行语音处理或减少渲染时间。

synth.device-id 类型 整数
默认 0
最小-最大 0-126
描述

用于SYSEX命令(例如MIDI Tuning Standard命令)的设备标识符。仅作用于此ID或所有设备的SYSEX命令。

合成转储 类型 布尔值
默认 0(假)
描述

目前不执行任何操作。

合成效应通道 类型 整数
默认 2
最小-最大 2-2
描述

合成增益 类型
默认 0.2
最小-最大 0.0-10.0
描述

增益被应用于合成器的最终或主输出。默认情况下,它设置为较低的值,以避免在演奏许多音符时输出饱和。

synlad.ladspa.active 类型 布尔值
默认 0(假)
描述

设置为“是”时,将启用LADSPA子系统。该子系统允许加载和互连LADSPA插件。 LADSPA子系统处理合成器的输出。请注意,合成器必须在LADSPA支持下进行编译。稍后有关LADSPA子系统的更多信息。

合成中音通道 类型 整数
默认 16
最小-最大 16-256
描述

此设置定义合成器的MIDI通道数。 MIDI标准定义了16个通道,因此MIDI硬件仅限于此数目。在内部,FluidSynth可以使用更多通道,这些通道可以映射到不同的MIDI源。

synth.midi-bank-select 类型
默认 s
选件 gm,gs,xg,mma
描述

此设置定义合成器如何解释Bank Select消息。

  • gm:忽略CC0和CC32消息。
  • s :(默认)CC0成为存储区号,CC32被忽略。
  • xg:CC32成为存储区号,CC0被忽略。
  • mma:存储区计算为CC0 * 128 + CC32。

合成器最小音符长度 类型 整数
默认 10
最小-最大 0-65535
描述

设置最小音符持续时间(以毫秒为单位)。这样可以确保真正持续时间较短的音符事件(例如打击乐音符)有更好的发声预期。设置为0以禁用此功能。

合成并行渲染 类型 布尔值
默认 1(真)
描述

合成并行渲染是低延迟设置。如果启用,则允许您与其余的调用并行地调用fluid_synth_write_s16,fluid_synth_write_float,fluid_synth_nwrite_float或fluid_synth_process,并且不会因对合成器的时间密集的调用而阻塞它。如果吞吐量比延迟更重要,请关闭此功能,例如在渲染不足的情况下渲染到文件的情况下。

不推荐使用:
从1.1.7版本开始,此选项已被弃用。此选项可增强rvoice_mixer的线程安全性,这会导致rvoice_events在内部排队。当前的实现依赖于以下事实:此选项设置为TRUE,以正确呈现任意数量的请求音频。同样,并行调用fluid_synth_write_ *也不视为用例。这将导致未定义的音频输出,因为对于用户而言,rvoice_events具体将被分派到哪个fluid_synth_write_ *调用是不可预测的。

合成复音 类型 整数
默认 256
最小-最大 1-65535
描述

复音定义了可以并行播放多少个声音。笔记事件会产生一个或多个声音。最好将其设置为系统可以处理的值,从而限制FluidSynth的CPU使用率。当FluidSynth的声音用尽时,它将开始为新的音符事件终止优先级较低的声音。

synth.reverb.active 类型 布尔值
默认 1(真)
描述

设置为1(TRUE)时,混响效果模块被激活。否则,不会将混响添加到输出信号。请注意,发送到混响模块的信号量取决于SoundFont中定义的“混响发送”生成器。

合成采样率 类型
默认 44100
最小-最大 22050-96000
描述

合成器生成的音频的采样率。

synth.threadsafe-api 类型 布尔值
默认 1(真)
描述

synth.threadsafe-api控制合成器的公共API是否受互斥锁保护。默认是打开的,如果您只知道仅从一个线程访问合成器,则将其关闭以获得更好的性能,例如,在许多嵌入式用例中可能就是这种情况。请注意,libfluidsynth本身可以使用多个线程(shell是一个,midi驱动程序是一个,midi player是一个,等等),因此通常应将其保留。另请参见合成并行渲染。

合成词 类型 布尔值
默认 0(假)
描述 设置为1(TRUE)时,合成器会将有关接收到的MIDI事件的信息打印到标准输出。这对于调试很有帮助。合成器启动后,无法更改此设置。

创建音频驱动程序

合成器本身不会将任何音频写入音频输出。这使应用程序开发人员可以根据需要自己管理音频输出。下一节将更详细地描述没有音频驱动器的合成器的使用。

创建音频驱动程序非常简单:设置适当的设置并创建驱动程序对象。因为FluidSynth支持多种音频系统,所以您可能需要更改要使用的音频系统。下面的列表显示了当前支持的音频系统。它显示了Fluidsynth库使用的名称和说明。

默认的音频驱动程序取决于使用FluidSynth进行编译的设置。您可以使用以下方法获取默认驱动程序 fluid_settings_getstr_default()。要获取可用驱动程序列表,请使用 fluid_settings_foreach_option() 功能。最后,您可以使用 fluid_settings_setstr()。在大多数情况下,默认驱动程序应开箱即用。

定义音频质量和延迟的其他选项是“ 音频样本格式 ”,“ 音频周期大小”和“ 音频周期”。详细内容将在后面说明。

您使用创建音频驱动程序 new_fluid_audio_driver() 功能。此函数将设置和合成器对象作为参数。例如:

虚空 在里面()
{
fluid_settings_t*设置;
fluid_synth_t*合成器;
fluid_audio_driver_t* 一个司机;
设置= new_fluid_settings();
/ *如果需要,设置合成器设置* /
合成= new_fluid_synth(设置);
fluid_settings_setstr(设置, "audio.driver", "jack");
驱动程序= new_fluid_audio_driver(设置,合成器);
}

音频驱动程序一经创建,便会开始播放。音频驱动程序创建一个单独的线程,该线程使用合成器对象生成音频。

有许多常规的音频驱动程序设置。 音频驱动程序设置定义将使用的音频子系统。 音频周期和audio.period-size设置定义了针对计划延迟的延迟和健壮性。另一个表中记录了所使用的音频子系统的其他设置。

表2.常规音频驱动程序设置
音频驱动程序 类型
默认 插孔(Linux),dsound(Windows),sndman(MacOS9),coreaudio(Mac OS X),dart(OS / 2)
选件 插孔,alsa,oss,pulseaudio,coreaudio,dsound,portaudio,sndman,dart,文件
描述

要使用的音频系统。

音频周期 类型 整型
默认 16(Linux,Mac OS X),8(Windows)
最小-最大 2-64
描述

驱动程序使用的音频缓冲区的数量。缓冲区的数量乘以缓冲区的大小(请参阅设置audio.period-size)可确定音频驱动程序的最大延迟。

音频周期大小 类型 整数
默认 64(Linux,Mac OS X),512(Windows)
最小-最大 64-8192
描述

音频缓冲区的大小(以帧为单位)。

音频实时优先 类型 整数
默认 60
最小-最大 0-99
描述

设置音频合成线程的实时调度优先级(0禁用高优先级调度)。 Linux是当前唯一使用不同优先级的平台。使用此选项的驱动程序:alsa,oss和pulseaudio

音频样本格式 类型
默认 “ 16位”
选件 “ 16bits”,“ float”
描述 音频样本的格式。目前这只是一个指示;如果音频驱动程序无法处理指定的格式,则它可能会忽略此设置。

下表描述了音频驱动程序特定的设置。

表3.音频驱动程序特定的设置
audio.alsa.device 类型
默认 “默认”
选件 ALSA设备字符串,例如:“ hw:0”,“ plughw:1”等。
描述

选择要使用的ALSA音频设备。

audio.coreaudio.device 类型
默认 “默认”
描述

选择要使用的CoreAudio设备。

audio.dart.device 类型
默认 “默认”
描述

选择要使用的Dart(OS / 2驱动程序)设备。

audio.dsound.device 类型
默认 “默认”
描述

选择要使用的DirectSound(Windows)设备。

audio.file.endian 类型
默认 如果内置了libsndfile支持,则为'auto',否则为'cpu'。
选件 auto,big,cpu,little(如果未内置libsndfile支持,则仅支持“ cpu”)
描述

使用“文件”驱动程序或文件渲染器将音频存储到文件时,定义字节顺序。 'auto'使用给定文件类型的默认值,'cpu'使用CPU字节顺序,'big'使用大字节序字节顺序,'little'使用小字节序字节顺序。

audio.file.format 类型
默认 s16
选件 double,float,s16,s24,s32,s8,u8(如果未内置libsndfile支持,则仅支持's16')
描述

在将音频渲染到文件时定义音频格式。 'double'是64位浮点,'float'是32位浮点,'s16'是16位带符号PCM,'s24'是24位带符号PCM,'s32'是32位带符号PCM,'s8'是8位有符号PCM,'u8'是8位无符号PCM。

audio.file.name 类型
默认 如果内置了libsndfile支持,则为'fluidsynth.wav',否则为'fluidsynth.raw'。
描述

指定在将音频渲染到文件时将音频存储到的文件名。

audio.file.type 类型
默认 如果内置了libsndfile支持,则为'auto',否则为'raw'。
选件 aiff,au,auto,avr,caf,flac,htk,iff,mat,oga,paf,pvf,raw,sd2,sds,sf,voc,w64,wav,xi(类型的实际列表可能有所不同,具体取决于使用libsndfile库,如果未内置libsndfile支持,则“ raw”是唯一可用的类型。
描述

设置音频将被存储到的文件的文件类型。 “自动”会尝试从audio.file.name文件扩展名确定文件类型,如果扩展名与任何类型都不匹配,则会回退到“ wav”。

audio.jack.autoconnect 类型 布尔值
默认 0(假)
描述

如果为1(TRUE),则FluidSynth输出将自动连接到插孔系统音频输出。

audio.jack.id 类型
默认 流体合成
描述

创建Jack客户端连接时使用的ID。

audio.jack.multi 类型 布尔值
默认 0(假)
描述

如果为1(TRUE),则当synth.audio-channels大于1时,将启用多声道Jack输出。

audio.jack.server 类型
默认
描述

要连接的杰克服务器。默认为空字符串,该字符串使用默认的Jack服务器。

audio.oss.device 类型
默认 / dev / dsp
描述

用于OSS音频输出的设备。

audio.portaudio.device 类型
默认 PortAudio默认
描述

用于PortAudio驱动程序输出的设备。请注意,“ PortAudio默认”是一个特殊值,可输出到默认PortAudio设备。

audio.pulseaudio.device 类型
默认 “默认”
描述

用于PulseAudio驱动程序输出的设备

audio.pulseaudio.server 类型
默认 “默认”
描述 服务器用于PulseAudio驱动程序输出

在没有音频驱动器的情况下使用合成器

可以在不创建音频驱动程序的情况下使用合成器对象。如果使用FluidSynth的应用程序自行管理音频输出,则这是理想的。合成器具有几个API函数,可用于获取音频输出:

fluid_synth_write_s16() 用编码为带符号的16位(字节序取决于机器)填充两个缓冲区(左右通道)。 fluid_synth_write_float() 用32位浮点样本填充左右音频缓冲区。对于多声道音频输出,该功能 fluid_synth_nwrite_float() 必须使用。

功能 fluid_synth_process() 仍处于试验阶段,因此不建议使用它,但它可能会在将来的版本中成为通用接口。

加载和管理SoundFonts

在产生任何声音之前,合成器需要一个SoundFont。

SoundFonts装有 fluid_synth_sfload() 功能。该函数获取SoundFont文件的路径和一个布尔值,以指示在加载SoundFont之后是否应更新MIDI通道的预设。当布尔值是TRUE时,将刷新所有MIDI通道库和程序号,这可能会导致从新加载的SoundFont中选择新乐器。

合成器可以加载任意数量的SoundFonts。加载的SoundFonts被视为堆栈,其中每个新加载的SoundFont都放置在堆栈的顶部。通过库号和程序号选择预设时,将从堆栈顶部开始搜索SoundFonts。如果不同SoundFonts中的预设具有相同的库和程序号,则使用最近加载的SoundFont中的预设。的 fluid_synth_program_select() 可以用于明确选择预设,也可以将库偏移应用到每个SoundFont fluid_synth_set_bank_offset(),以确保每个预设都有唯一的库号和程序号。

fluid_synth_sfload() 函数返回加载的SoundFont的唯一标识符,如果出现错误,则返回-1。此标识符用于后续管理功能: fluid_synth_sfunload() 删除SoundFont, fluid_synth_sfreload() 重新加载SoundFont。重新加载SoundFont时,它将保留其ID和在SoundFont堆栈上的位置。

提供了其他API函数来获取已加载的SoundFonts的数量并获取指向SoundFont的指针。

发送MIDI事件

一旦合成器启动并运行并且加载了SoundFont,大多数人就会想对它做一些有用的事情。例如发出声音。 MIDI信息可以使用 fluid_synth_noteon(), (), fluid_synth_cc(), fluid_synth_pitch_bend(), fluid_synth_pitch_wheel_sens()fluid_synth_program_change() 职能。为了方便起见,还有一个 fluid_synth_bank_select() 功能(库选择消息通常使用控制更改消息发送)。

下面的示例显示一个通用的图形按钮,单击该按钮便会发出注释:

声音按钮: 上市 SomeButton
{
上市:
SoundButton():SomeButton(){
如果 (!_synth){
initSynth();
}
}
静态的 虚空 initSynth(){
_settings = new_fluid_settings();
_synth = new_fluid_synth(_settings);
_adriver = new_fluid_audio_driver(_settings,_synth);
}
/ * ... * /
虚拟 整型 handleMouseDown(整型 X, 整型 y){
/ *在MIDI通道0上以速度100播放键60上的音符* /
fluid_synth_noteon(_synth,0,60,100);
}
虚拟 整型 handleMouseUp(整型 X, 整型 y){
/ *释放键60上的音符* /
fluid_synth_noteoff(_synth,0,60);
}
受保护的:
静态的 fluid_settings_t*设置;
静态的 fluid_synth_t* _synth;
静态的 fluid_audio_driver_t* _一个司机;
};

创建一个实时MIDI驱动程序

FluidSynth可以处理从硬件MIDI端口或其他应用程序接收到的实时MIDI事件。为此,客户端必须创建一个MIDI输入驱动程序。这与音频驱动程序的创建过程非常相似:您可以在设置实例中初始化一些属性,然后调用 new_fluid_midi_driver() 函数提供了一个回调函数,当接收到MIDI事件时将调用该函数。当前支持以下MIDI驱动程序:

#包括<fluidsynth.h>
整型 handle_midi_event(虚空*数据, fluid_midi_event_t*活动)
{
printf("event 类型: %d\n", fluid_midi_event_get_type(事件));
}
整型 主要(整型 argc, 烧焦** argv)
{
fluid_settings_t*设置;
fluid_midi_driver_t* mdriver;
设置= new_fluid_settings();
mdriver = new_fluid_midi_driver(设置,handle_midi_event,NULL);
/ * ... * /
delete_fluid_midi_driver(mdriver);
返回 0;
}

有许多常规的MIDI驱动程序设置。 midi.driver设置定义将使用的MIDI子系统。下表列出了所使用的MIDI子系统的其他设置。

表4.常规MIDI驱动程序设置
midi.driver 类型
默认 alsa_seq(Linux),winmidi(Windows),jack(Mac OS X)
选件 alsa_raw,alsa_seq,coremidi,jack,midishare,oss,winmidi
描述

所使用的MIDI系统。

实时实时 类型 整数
默认 50
最小-最大 0-99
描述 设置MIDI线程的实时调度优先级(0禁用高优先级调度)。 Linux是当前唯一使用不同优先级的平台。使用此选项的驱动程序:alsa_raw,alsa_seq,oss

下表定义了MIDI驱动程序特定的设置。

表5. MIDI驱动程序特定的设置
midi.alsa.device 类型
默认 “默认”
描述

用于RAW ALSA MIDI驱动程序的ALSA MIDI设备。

midi.alsa_seq.device 类型
默认 “默认”
描述

用于ALSA定序器驱动程序的ALSA定序器设备。

midi.alsa_seq.id 类型
默认 pid
描述

向ALSA音序器驱动程序注册端口时使用的ID。如果设置为“ pid”,则ID将为“ FLUID Synth(PID)”,其中PID是音频线程的FluidSynth进程ID,否则将使用提供的字符串代替PID。

midi.jack.id 类型
默认 液体合成中期
描述

与Jack MIDI驱动程序一起使用的客户端ID。

midi.jack.server 类型
默认
描述

用于Jack MIDI驱动程序连接的Jack服务器。如果为空字符串,则将使用默认服务器。

midi.oss.device 类型
默认 / dev / midi
描述

用于OSS MIDI驱动程序的设备。

midi.portname 类型
默认
描述 由coremidi和alsa_seq驱动程序用于在MIDI子系统中注册的端口名。

加载和播放MIDI文件

通过MIDI File Player界面,FluidSynth可用于播放MIDI文件。尽管目前尚不完整,但它遵循的是高级实现。初始化合成器后,创建将合成器实例传递到的播放器 new_fluid_player()。然后,您可以使用以下命令向播放器添加一些SMF文件名 fluid_player_add(),最后致电 fluid_player_play() 开始播放。您可以通过致电查看播放器是否完成播放 fluid_player_get_status(),或等待播放器终止使用 fluid_player_join().

#包括<fluidsynth.h>
整型 主要(整型 argc, 烧焦** argv)
{
整型 一世;
fluid_settings_t*设置;
fluid_synth_t*合成器;
fluid_player_t*玩家;
fluid_audio_driver_t* 一个司机;
设置= new_fluid_settings();
合成= new_fluid_synth(设置);
玩家= new_fluid_player(合成);
驱动程序= new_fluid_audio_driver(设置,合成器);
/ *处理命令行参数* /
对于 (i = 1;我< argc; i++) {
如果 (fluid_is_soundfont(argv [i])){
fluid_synth_sfload(合成,argv [1],1);
}
如果 (fluid_is_midifile(argv [i])){
fluid_player_add(玩家,argv [i]);
}
}
/ *播放midi文件(如果有)* /
fluid_player_play(玩家);
/ *等待播放终止* /
fluid_player_join(玩家);
/* 清理 */
delete_fluid_audio_driver(一个司机);
delete_fluid_player(玩家);
delete_fluid_synth(合成);
delete_fluid_settings(设置);
返回 0;
}

MIDI播放器使用的设置记录在下面。

表6.常规MIDI驱动程序设置
播放器重置合成器 类型 布尔值
默认 1(真)
描述

如果为true,则在开始新的MIDI歌曲之前重置合成器,因此上一首歌曲的状态不会影响新歌曲。请将其关闭以无缝播放歌曲。

玩家计时源 类型
默认 '样品'
选项 “样本”,“系统”
描述 确定播放器音序器的定时源。 “采样”使用采样时钟(已输出多少音频)来对事件进行排序,在这种情况下,音频与MIDI事件同步。 “系统”使用系统时钟,音频和MIDI不能完全同步。

快速文件渲染器,用于非实时MIDI文件渲染

而不是如本节所述创建音频驱动程序 加载和播放MIDI文件 人们可能会选择使用文件渲染器,这是合成MIDI文件的最快方法。

fluid_settings_t*设置;
fluid_synth_t*合成器;
fluid_player_t*玩家;
fluid_file_renderer_t*渲染器;
设置= new_fluid_settings();
//指定要将音频存储到的文件
//确保使用libsndfile编译了fluidsynth以获取真实的wave文件
//否则此文件将仅包含原始s16立体声PCM
fluid_settings_setstr(设置, "audio.file.name", "/path/to/output.wav");
//使用处理的样本数作为计时源,而不是系统计时器
fluid_settings_setstr(设置, "player.timing-source", "sample");
//由于这是非实时的szenario,因此无需固定示例数据
fluid_settings_setint(设置, "synth.lock-memory", 0);
合成= new_fluid_synth(设置);
// ***省略了声音字体的加载***
玩家= new_fluid_player(合成);
fluid_player_add(玩家, "/path/to/midifile.mid");
fluid_player_play(玩家);
渲染器= new_fluid_file_renderer (合成);
(fluid_player_get_status(玩家)== FLUID_PLAYER_PLAYING)
{
如果 (fluid_file_renderer_process_block(渲染器)!= FLUID_OK)
{
打破;
}
}
//只是要确定:明确停止播放并等待直到完成
fluid_player_stop(玩家);
fluid_player_join(玩家);
delete_fluid_file_renderer(渲染器);
delete_fluid_player(玩家);
delete_fluid_synth(合成);
delete_fluid_settings(设置);

Various output files 类型s are supported, 如果 compiled with libsndfile. Those can be specified via the settings object as well. Refer to the documentation of the audio.file.* 选项.

从内存播放MIDI文件

FluidSynth也可以直接从内存中的缓冲区播放MIDI文件。如果需要从流(例如stdin,网络或高级文件接口)中播放文件,则可以先将整个文件加载到缓冲区中,然后再使用此方法。使用与上述相同的技术,而不是调用 fluid_player_add(),将其加载到内存中并调用 fluid_player_add_mem() 代替。一旦您将缓冲区传递给 fluid_player_add_mem(),它已被复制,因此您可以再次使用它或立即释放它(如果分配了它,则有责任释放它)。

#包括<stdlib.h>
#包括<string.h>
#包括<fluidsynth.h>
/ *一个示例Midi文件* /
const 烧焦 MIDIFILE [] = {
0x4d,0x54、0x68、0x64、0x00、0x00、0x00、0x06,
0x00、0x01、0x00、0x01、0x01、0xe0、0x4d,0x54,
0x72、0x6b,0x00、0x00、0x00、0x20、0x00、0x90,
0x3c,0x64、0x87、0x40、0x80、0x3c,0x7f,0x00,
0x90、0x43、0x64、0x87、0x40、0x80、0x43、0x7f,
0x00、0x90、0x48、0x64、0x87、0x40、0x80、0x48,
0x7f,0x83、0x60、0xff,0x2f,0x00
};
整型 主要(整型 argc, 烧焦** argv)
{
整型 一世;
虚空* 缓冲;
size_t buffer_len;
fluid_settings_t*设置;
fluid_synth_t*合成器;
fluid_player_t*玩家;
fluid_audio_driver_t* 一个司机;
设置= new_fluid_settings();
合成= new_fluid_synth(设置);
玩家= new_fluid_player(合成);
驱动程序= new_fluid_audio_driver(设置,合成器);
/ *处理命令行参数* /
对于 (i = 1;我< argc; i++) {
如果 (fluid_is_soundfont(argv [i])){
fluid_synth_sfload(合成,argv [1],1);
}
}
/ *将内存中的Midi文件排队* /
fluid_player_add_mem(播放器,MIDIFILE, 大小(MIDIFILE));
/ *播放midi文件* /
fluid_player_play(玩家);
/ *等待播放终止* /
fluid_player_join(玩家);
/* 清理 */
delete_fluid_audio_driver(一个司机);
delete_fluid_player(玩家);
delete_fluid_synth(合成);
delete_fluid_settings(设置);
返回 0;
}

实时MIDI路由器

MIDI路由器是MIDI输入后面的另一个处理层。它处理传入的MIDI事件并为合成器生成控制事件。它可用于在将事件发送到合成器之前过滤或修改事件。创建后,MIDI路由器是透明的,仅传递所有MIDI事件。必须添加路由器“规则”以实际使用其功能。

MIDI路由器用法的一些示例:

MIDI驱动程序API在midi线程和合成器之间有清晰的分隔。这为添加Midi路由器模块打开了大门。

来自MIDI播放器的MIDI事件不会通过MIDI路由器。

#包括<fluidsynth.h>
整型 主要(整型 argc, 烧焦** argv)
{
fluid_settings_t*设置;
fluid_synth_t*合成器;
fluid_midi_router_t*路由器;
fluid_midi_router_rule_t* 规则;
设置= new_fluid_settings();
合成= new_fluid_synth(设置);
/ *创建MIDI路由器,并将事件传递到合成器* /
路由器= new_fluid_midi_router (设置, fluid_synth_handle_midi_event,synth);
/ *清除默认规则* /
fluid_midi_router_clear_rules (路由器);
/ *添加规则以映射所有注释<MIDI音符#60在通道4的任何通道上* /
规则= new_fluid_midi_router_rule ();
fluid_midi_router_rule_set_chan (规则0、15、0.0、4); / *将所有内容映射到通道4 * /
fluid_midi_router_rule_set_param1 (规则,0,59,1.0,0); / *比赛记录< 60 */
fluid_midi_router_add_rule (路由器,规则, FLUID_MIDI_ROUTER_RULE_NOTE);
/ *添加规则以映射所有注释>=通道5至通道5上的MIDI音符#60 * /
规则= new_fluid_midi_router_rule ();
fluid_midi_router_rule_set_chan (规则,0、15、0.0、5); / *全部映射到频道5 * /
fluid_midi_router_rule_set_param1 (第60、127、1.0、0条规则); / *比赛记录>= 60 */
fluid_midi_router_add_rule (路由器,规则, FLUID_MIDI_ROUTER_RULE_NOTE);
/ *将规则添加到通道7上的弯音器的反向* /
规则= new_fluid_midi_router_rule ();
fluid_midi_router_rule_set_chan (规则7、7、1.0、0); / *仅匹配频道7 * /
fluid_midi_router_rule_set_param1 (规则0、16383,-1.0、16383); / *反弯弯机* /
fluid_midi_router_add_rule (路由器,规则, FLUID_MIDI_ROUTER_RULE_PITCH_BEND);
/ * ...创建音频驱动程序,处理事件等... * /
/* 清理 */
delete_fluid_midi_router(路由器);
delete_fluid_synth(合成);
delete_fluid_settings(设置);
返回 0;
}

音序器

与使用MIDI文件播放器相比,FluidSynth的音序器可以更灵活地播放MIDI事件,而MIDI文件播放器希望将事件存储为标准MIDI文件。使用定序器,您可以逐一提供事件,并提供可选的时间戳以进行调度。

客户端程序应首先使用函数初始化音序器实例 new_fluid_sequencer2()。有一个补充功能 delete_fluid_sequencer() 删除它。创建音序器实例后,可以使用以下方式注册目标 fluid_sequencer_register_fluidsynth() 用于合成器目标,并且可以选择使用 fluid_sequencer_register_client() 为客户端目标提供合适的回调函数。可以使用取消注册 fluid_sequencer_unregister_client()。初始化后,可以通过以下方式发送事件 fluid_sequencer_send_now() 并计划与未来 fluid_sequencer_send_at()。注册函数返回标识符,可以使用以下命令将其用作事件的目的地 fluid_event_set_dest().

功能 fluid_sequencer_get_tick() 返回当前的播放位置。程序可以使用来选择以毫秒为单位的新时标 fluid_sequencer_set_time_scale().

下面的示例使用Fluidsynth音序器实现一种音乐盒。 FluidSynth内部时钟用于安排音符的重复序列。使用触发回调函数的计时器事件,可以在当前序列结束之前提前计划下一个序列。调度时间始终是绝对值,以避免滑移。

#包括"fluidsynth.h"
fluid_synth_t*合成器;
fluid_audio_driver_t* 一个司机;
fluid_sequencer_t*音序器;
synthSeqID,mySeqID;
未签名 整型 现在;
未签名 整型 顺序
//原型
虚空 seq_callback(未签名 整型 时间, fluid_event_t*事件, fluid_sequencer_t* seq, 虚空*数据);
虚空 createdynth()
{
fluid_settings_t*设置;
设置= new_fluid_settings();
fluid_settings_setstr(设置, "synth.reverb.active", "yes");
fluid_settings_setstr(设置, "synth.chorus.active", "no");
合成= new_fluid_synth(设置);
驱动程序= new_fluid_audio_driver(设置,合成器);
音序器= new_fluid_sequencer2(0);
//将合成器注册为第一个目的地
synthSeqID = fluid_sequencer_register_fluidsynth(音序器,合成器);
//将自己注册为第二个目的地
mySeqID = fluid_sequencer_register_client(音序器, "me",seq_callback,NULL);
//序列持续时间,以毫秒为单位
sequduration = 1000;
}
虚空 deletesynth()
{
delete_fluid_sequencer(音序器);
delete_fluid_audio_driver(一个司机);
delete_fluid_synth(合成);
}
虚空 loadsoundfont()
{
整型 fluid_res;
//在这里放置自己的路径
fluid_res = fluid_synth_sfload(合成器, "内部:VintageDreamsWaves-v2.sf2", 1);
}
虚空 sendnoteon(整型 键, 未签名 整型 日期)
{
整型 fluid_res;
fluid_event_t * evt = new_fluid_event();
fluid_event_set_source(evt,-1);
fluid_event_set_dest(evt,synthSeqID);
fluid_event_noteon(evt,chan,key,127);
fluid_res = fluid_sequencer_send_at(音序器,evt,日期,1);
delete_fluid_event(evt);
}
虚空 schedule_next_callback()
{
整型 fluid_res;
//我想在下一个序列结束之前回叫
未签名 整型 callbackdate =现在+ seqduration / 2;
fluid_event_t * evt = new_fluid_event();
fluid_event_set_source(evt,-1);
fluid_event_set_dest(evt,mySeqID);
fluid_event_timer(evt,NULL);
fluid_res = fluid_sequencer_send_at(sequencer,evt,callbackdate,1);
delete_fluid_event(evt);
}
虚空 schedule_next_sequence(){
//在每个序列开始之前或多或少调用
//下一个序列的开始日期
现在= now + sequduration;
//播放顺序
//节拍:每个序列2个节拍
sendnoteon(0,60,现在+ seqduration / 2);
sendnoteon(0,60,现在+序列);
//旋律
sendnoteon(1,45,现在+ seqduration / 10);
sendnoteon(1,50,现在+ 4 * seqduration / 10);
sendnoteon(1,55,现在+ 8 * seqduration / 10);
//这样我们就可以及早回呼以安排下一个序列
schedule_next_callback();
}
/ *定序器回调* /
虚空 seq_callback(未签名 整型 时间, fluid_event_t*事件, fluid_sequencer_t* seq, 虚空*数据){
schedule_next_sequence();
}
整型 主要(虚空){
createdynth();
loadsoundfont();
//初始化我们的绝对日期
现在= fluid_sequencer_get_tick(音序器);
schedule_next_sequence();
睡眠(100000);
deletesynth();
返回 0;
}

Shell界面

Shell界面允许您将简单的文本命令发送到合成器,解析命令文件或从stdin或其他输入流中读取命令。要查找当前支持的命令列表,请检查fluid_cmd.c文件或在fluidsynth命令行外壳中键入“ help”。

表7.常规MIDI驱动程序设置
shell提示 类型
默认
描述 在转储模式下,我们将提示设置为“”。 ui无法轻松处理以cr结尾的行。更改提示不能通过命令完成,因为当前的shell无法处理空参数。
shell.port 类型
默认 9800
最小-最大 1-65535
描述 该外壳程序可以在客户端/服务器模式下使用。此设置控制服务器使用哪个TCP / IP端口。

尚未记录的高级功能。 API参考可能包含更多信息。


产生者  氧 1.8.13