1 Star 0 Fork 13

lvyh / lark-release

forked from 王揆 / lark-release 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Unlicense

lark

English | 简体中文

lark是一个免费、轻量、功能强大的软件音频DSP。它提供了一种灵活可扩展的方法来设计效能高、空间占用小、延时低的音频路由,让您可以像搭积木一样构建音频系统。 主要特性(至v0.10版本):

  • 支持实时操作音频路由
    • 实时加载/卸载块
    • 实时改变路径
    • 实时调节块参数
  • 支持预编译的输入/输出块
    • 文件读取(file-reader), 文件写入(file-writer), 流输入(stream-in), 流输出(stream-out), alsa录音, alsa播放, tinyalsa录音, tinyalsa播放, portaudio录音, portaudio播放
  • 支持预编译的算法块
    • 增益(gain), 混音器(mixer), 复制器(duplicator), 多路复用器(multiplexer), 声道交织器(interleave), 声道分离器(de-interleave), 格式适配器(format-adapter), 延时器(delay), 对齐(align), 缓存(buffer)
    • speexdsp算法: 重采样(speex-resampler), 前处理(speex-preprocessor)
    • soundtouch算法: 音调调节器(pitch), 节拍调节器(tempo), 速度调节器(rate)
    • sox效果器: 音量(vol), 镶边(flanger), 颤音(tremolo), 回音(echos), 合唱(chorus), 卡拉OK(oops), 均衡器(equalizer), 高通(highpass), 低通(lowpass), 等等
  • 支持无限客制化块
  • 支持每块最多32个输入端点,32个输出端点
  • 支持基于帧的时间戳和基于采样点的时间戳
  • 支持实时调试工具
    • 打印状态
    • 打印路由快照到文件
    • 实时设定日志等级
    • 转储日志到文件
    • 转储各个块的音频数据到文件
  • 跨平台
    • Linux (x86_64), MacOS (x86_64), Android (aarch64)

开始

lark是由一个基础的动态库liblark.so,各种可选的块(动态加载库)例如libblkmixer.so,和一个可选的可执行调试工具lkdb组成。基于 lark,您可以很容易地创建您想实现的既可以简单又可以复杂的音频路由,实时启动/停止任意一个路由,或者实时设定/获取任意块的参数。

第1步

由于 lark 依赖于klogging库,您首先需要安装klogging。访问 https://gitee.com/wksuper/klogging 以安装之。另一种方式是,此仓库已经包含了预编译好的libklogging.so,它会随着lark的安装而一起安装。

第2步

安装 lark 到您的Linux机器。

$ cd lark-release
$ sudo ./install.sh
$ sudo ldconfig

当您不需要 lark 时,您可以使用sudo ./uninstall.sh来移除它。

第3步

运行音频路由。

例1:运行一个单路由,做立体声音乐文件播放

RouteA

  libblkfilereader.so     libblkalsaplayback.so
  *******************      ******************
  *                 *      *                *
  *  filereader_0   *0--->0* alsaplayback_0 *
  *                 *      *                *
  *******************      ******************
$ x86_64-linux-gnu/bin/larkexample1

如果没错误的话,音乐文件应该开始播放了。

这个例子的源代码在此:larkexample1.cpp

例2:运行一个单路由,把两个音乐文件输入做带各自增益的混合播放

RouteA

 libblkfilereader.so   libblkdeinterleave.so   libblkgain.so           libblkmixer.so       libblkinterleave.so     libblkalsaplayback.so

  *****************     ******************     *************           **************       *******************      ******************
  *               *     *                *0-->0*           *0-------->0*            *0---->0*                 *      *                *
  * filereader_0  *0-->0* deinterleave_0 *1-->1*   gain_0  *1---+      *   mixer_0  *       *   interleave_0  *0--->0* alsaplayback_0 *
  *               *     *                *     *           *    | +-->1*            *   +->1*                 *      *                *
  *****************     ******************     *************    | |    **************   |   *******************      ******************
                                                                | |                     |
  *****************     ******************     *************    | |    **************   |
  *               *     *                *     *           *    +-|-->0*            *0--+
  * filereader_1  *0-->0* deinterleave_0 *0-->0*   gain_1  *0-----+    *   mixer_1  *
  *               *     *                *1-->1*           *1-------->1*            *
  *****************     ******************     *************           **************
$ x86_64-linux-gnu/bin/larkexample2

如果没错误的话,两个音乐文件应该开始混合播放输出了。

这个例子的源代码在此:larkexample2.cpp

例3:运行双路由,一个做音乐播放,一个采集麦克风以做关键词侦测

                                                                                                     ****************      ******************      ***************
                                                                                        RouteA       *              *      *                *      *             *
                                                                                                     * filereader_0 *0--->0* alsaplayback_0 *0--->0* streamout_0 *
                                                                                                     *              *      *                *      *             *
                                                                                                     ****************      ******************      ********|******
                                                                                                                                                           v
========================================================================================================================================================[FIFO]=====
                                                                                                                                                         |
  **************     **************     *************     ***********************     ******************     ***********     *****************      *****v********
  *            *     *            *     *           *     *                     *     *                *     *         *     *               *      *            *
  * dummykwd_0 *0<--0*            *     *           *     *                     *0<--0* deinterleave_0 *0<--0*         *0<--0* alsacapture_0 *      * streamin_0 *
  *            *     *            *     *           *     *                     *1<--1*                *     *         *     *               *      *            *
  **************     *            *     *           *     *                     *     ******************     *         *     *****************      ******0*******
                     *            *     *           *     *                     *                            *         *                                  v
                     *  mixer_1   *0<--0* dummybf_0 *0<--0* speexpreprocessor_0 *                            * align_0 *                        **********0*******
                     *(duplicator)*     *           *1<--1* (aec, denoise, ...) *                            *         *          RouteB        * deinterleave_1 *
                     *            *     *           *     *                     *                            *         *                        ********0**1******
                     *            *     *           *     *                     *                            *         *                                v  v
****************     *            *     *           *     *                     *                            *         *     ***********      **********0**1******
*              *     *            *     *           *     *                     *16<------------------------1*         *     *         *0<---0*                  *
* filewriter_0 *0<--1*            *     *           *     *                     *                            *         *1<--0* mixer_0 *1<---1* speexresampler_0 *
*              *     *            *     *           *     *                     *                            *         *     *         *      *                  *
****************     **************     *************     ***********************                            ***********     ***********      ********************

运行例3之前,需要先安装speex库。

$ sudo apt install libspeexdsp-dev

运行例3:

# 两个参数指的是alsa playback pcm name和capture pcm name。
# 它们随着机器的不同而不同。
$ x86_64-linux-gnu/bin/larkexample3 plughw:0,0 plughw:0,0

如果没错误的话,播放和录音应该同时开始了。 录到的声音文件存放在./cap-16000_16_1.pcm

这个例子的源代码在此:larkexample3.cpp

例5:运行一个单播放路由,嵌入了SoundTouch以做音调、节拍、播放速率的调节

RouteA

 libblkfilereader.so   libblkformatdapter.so    libblksoundtouch.so   libblkpaplayback.so
  ****************      *******************      ****************      ****************
  *              *      *                 *      *              *      *              *
  * filereader_0 *0--->0* formatadapter_0 *0--->0* soundtouch_0 *0--->0* paplayback_0 *
  *              *      *                 *      *              *      *              *
  ****************      *******************      ****************      ****************

运行例5之前需要先安装 SoundTouch 库和 PortAudio 库。

$ sudo apt install libsoundtouch-dev
$ sudo apt install libportaudio2

运行例5:

$ x86_64-linux-gnu/bin/larkexample5

如果没错误的话,播放应该开始了。

在另一个shell里,

$ lkdb status                                   # 显示lark状态

$ lkdb setparam RouteA blksoundtouch_0 1 0.6    # 音调变低
$ lkdb setparam RouteA blksoundtouch_0 1 1.8    # 音调变高
$ lkdb setparam RouteA blksoundtouch_0 1 1.0    # 音调变正常
$ lkdb setparam RouteA blksoundtouch_0 2 0.5    # 节拍变慢
$ lkdb setparam RouteA blksoundtouch_0 2 2.0    # 节拍变块
$ lkdb setparam RouteA blksoundtouch_0 2 1.0    # 节拍变正常
$ lkdb setparam RouteA blksoundtouch_0 3 2.2    # 播放速率变快
$ lkdb setparam RouteA blksoundtouch_0 3 0.4    # 播放速率变慢
$ lkdb setparam RouteA blksoundtouch_0 3 1.0    # 播放速率变正常

这个例子的源代码在此:larkexample5.cpp

例7:运行一个带SoX效果器的单播放路由

RouteA

 libblkfilereader.so  libblkformatdapter.so   libblkdeinterleave.so  libblkmixer.so  libblksoxeffect.so  libblkinterleave.so  libblkpaplayback.so

  ****************     *******************     ******************     ***********     ***************     ****************     ****************
  *              *     *                 *     *                *     *         *     * soxeffect_0 *     *              *     *              *
  *              *     *                 *     *                *0-->0*         *0-->0* (highpass)  *0-->0*              *     *              *
  *              *     *                 *     *                *     *         *     ***************     *              *     *              *
  * filereader_0 *0-->0* formatadapter_0 *0-->0* deinterleave_0 *     * mixer_0 *                         * interleave_0 *0-->0* paplayback_0 *
  *              *     *                 *     *                *     *         *     ***************     *              *     *              *
  *              *     *                 *     *                *1-->1*         *0-->0* soxeffect_1 *0-->1*              *     *              *
  *              *     *                 *     *                *     *         *     *  (lowpass)  *     *              *     *              *
  ****************     *******************     ******************     ***********     ***************     ****************     ****************

运行例7之前需要先安装 SoX 库和 PortAudio 库。

$ sudo apt install libsox-dev
$ sudo apt install libportaudio2

运行例7:

$ x86_64-linux-gnu/bin/larkexample7

如果没错误的话,播放应该开始了。

在另一个shell里,

$ lkdb status                                  # 显示lark状态
$ lkdb setparam RouteA blksoxeffect_0 0 400    # 只有高于400Hz的音乐信号输出到左喇叭
$ lkdb setparam RouteA blksoxeffect_1 0 400    # 只有低于400Hz的音乐信号输出到右喇叭

这个例子的源代码在此:larkexample7.cpp

更多的例子

作者的博客文章:<我的工程师爸爸-音频应用DIY系列>通过一系列小故事展示了利用lark来编程解决生活中遇到的音频问题。

lkdb实时调试

lark 在一个进程里运行时,调试工具lkdb可以跟它通信,从 lark 获取信息,向 lark 发送命令。

Usage:
  lkdb status [--dot]
    - Print the lark running status
    - Print dot code if enabled '--dot' option
  lkdb newroute ROUTENAME
    - Create a named route
  lkdb newblock ROUTENAME SOLIB ISFIRST ISLAST [ARGS]
    - Create a block on the route from the dynamic load library
  lkdb newlink ROUTENAME RATE FORMAT CHNUM FRAMESIZEINSAMPLES SRCBLKNAME SRCBLKOUTEPIDX SINKBLKNAME SINKBLKINEPIDX
    - Create a link to link the source block and sink block on the route
  lkdb start ROUTENAME
    - Start the route
  lkdb stop ROUTENAME
    - Stop the route
  lkdb setparam ROUTENAME BLOCKNAME PARAMID [PARAMS]
    - Set parameter to the block in the route
  lkdb getparam ROUTENAME BLOCKNAME PARAMID
    - Get parameter from the block in the route
  lkdb delete ROUTENAME LINKNAME
    - Delete the link from the route
  lkdb delete ROUTENAME BLOCKNAME
    - Delete the block and associated link(s) from the route
  lkdb delete ROUTENAME !
    - Delete the entire route
  lkdb loglevel LEVEL
    - Set the logging LEVEL: 0=off 1=fatal 2=error 3=warning 4=info(default) 5=debug 6=verbose
  lkdb setdump DIRECTORY
    - Enable dumping log & data when DIRECTORY is a valid path
    - Disable dumping log & data when DIRECTORY is --

举个例子,当例2运行时,在另外一个shell里,您可以通过lkdb调节例2的音量。

$ lkdb status                               # 显示lark状态
RouteA is RUNNING, 625 frames processed OK, 0 error frame
	blkfilereader_0
		(O00) --> lnk_0    48000Hz   S16_LE  2ch    960samples/frame
	blkdeinterleave_0
		(I00) <-- lnk_0    48000Hz   S16_LE  2ch    960samples/frame
		(O00) --> lnk_1    48000Hz   S16_LE  1ch    960samples/frame
		(O01) --> lnk_2    48000Hz   S16_LE  1ch    960samples/frame
	blkfilereader_1
		(O00) --> lnk_3    48000Hz   S16_LE  2ch    960samples/frame
	blkdeinterleave_1
		(I01) <-- lnk_3    48000Hz   S16_LE  2ch    960samples/frame
		(O00) --> lnk_4    48000Hz   S16_LE  1ch    960samples/frame
		(O01) --> lnk_5    48000Hz   S16_LE  1ch    960samples/frame
	blkgain_0
		(I00) <-- lnk_1    48000Hz   S16_LE  1ch    960samples/frame
		(I01) <-- lnk_2    48000Hz   S16_LE  1ch    960samples/frame
		(O00) --> lnk_6    48000Hz   S16_LE  1ch    960samples/frame
		(O01) --> lnk_7    48000Hz   S16_LE  1ch    960samples/frame
	blkgain_1
		(I00) <-- lnk_4    48000Hz   S16_LE  1ch    960samples/frame
		(I01) <-- lnk_5    48000Hz   S16_LE  1ch    960samples/frame
		(O00) --> lnk_8    48000Hz   S16_LE  1ch    960samples/frame
		(O01) --> lnk_9    48000Hz   S16_LE  1ch    960samples/frame
	blkmixer_0
		(I00) <-- lnk_6    48000Hz   S16_LE  1ch    960samples/frame
		(I01) <-- lnk_8    48000Hz   S16_LE  1ch    960samples/frame
		(O00) --> lnk_10   48000Hz   S16_LE  1ch    960samples/frame
	blkmixer_1
		(I00) <-- lnk_7    48000Hz   S16_LE  1ch    960samples/frame
		(I01) <-- lnk_9    48000Hz   S16_LE  1ch    960samples/frame
		(O00) --> lnk_11   48000Hz   S16_LE  1ch    960samples/frame
	blkinterleave_0
		(I00) <-- lnk_10   48000Hz   S16_LE  1ch    960samples/frame
		(I01) <-- lnk_11   48000Hz   S16_LE  1ch    960samples/frame
		(O00) --> lnk_12   48000Hz   S16_LE  2ch    960samples/frame
	blkalsaplayback_0
		(I00) <-- lnk_12   48000Hz   S16_LE  2ch    960samples/frame
$ lkdb setparam RouteA blkgain_0 1 0 0.5    # kanr-48000_16_2.pcm左声道的输出音量变低
$ lkdb setparam RouteA blkgain_0 1 1 0.5    # kanr-48000_16_2.pcm右声道的输出音量变低
$ lkdb setparam RouteA blkgain_0 1 0 0.0    # kanr-48000_16_2.pcm左声道的输出静音
$ lkdb setparam RouteA blkgain_0 1 1 0.0    # kanr-48000_16_2.pcm右声道的输出静音

$ lkdb setparam RouteA blkgain_1 1 0 0.5    # pacificrim-48000_16_2.pcm左声道的输出音量变低
$ lkdb setparam RouteA blkgain_1 1 1 0.5    # pacificrim-48000_16_2.pcm右声道的输出音量变低
$ lkdb setparam RouteA blkgain_1 1 0 0.0    # pacificrim-48000_16_2.pcm左声道的输出静音
$ lkdb setparam RouteA blkgain_1 1 1 0.0    # pacificrim-48000_16_2.pcm右声道的输出静音

$ lkdb setparam RouteA blkgain_0 1 0 1.0    # kanr-48000_16_2.pcm左声道的输出音量恢复
$ lkdb setparam RouteA blkgain_0 1 1 1.0    # kanr-48000_16_2.pcm右声道的输出音量恢复

$ lkdb setparam RouteA blkgain_1 1 0 1.0    # pacificrim-48000_16_2.pcm左声道的输出音量恢复
$ lkdb setparam RouteA blkgain_1 1 1 1.0    # pacificrim-48000_16_2.pcm右声道的输出音量恢复

再举个例子,当例3运行时,在另外一个shell里,您可以通过lkdb抓取路由快照。

$ lkdb status --dot | dot -Tpng -o larkexample3.png

路由快照会被存成文件larkexample3.png

larkexample3.png

注意:这个功能需要graphviz(dot)先安装到您的机器。

$ sudo apt install graphviz

创建您自己的音频路由

第1步

在您的脑海中设计好路由。那些预编译好的块(像gain, mixer等)可以直接使用。如果您想要客制化的块,您可以自行编译动态库。 BlkPassthrough.cpp是一个块源码的例子。 参考MANUAL.md - 4 Build Your Own Block以获取更多信息。

第2步

如果只是尝试为目的,lkdb就可以做了。

例如,想要运行跟例1一样的路由,您也可以使用lkdb来创建路由,启动/停止路由,删除路由。

在一个shell里,

$ x86_64-linux-gnu/bin/larkexample0    # 运行lark

在另一个shell里,

$ lkdb newroute RouteA
Created RouteA
$ lkdb newblock RouteA libblkfilereader.so true false examples/kanr-48000_16_2.pcm
Created blkfilereader_0 from libblkfilereader.so on RouteA
$ lkdb newblock RouteA libblkalsaplayback.so false true
Created blkalsaplayback_0 from libblkalsaplayback.so on RouteA
$ lkdb newlink RouteA 48000 S16_LE 2 960 blkfilereader_0 0 blkalsaplayback_0 0
Created lnk_0 on RouteA
$ lkdb start RouteA      # 音乐播放应该开始了
Started RouteA
$ lkdb stop RouteA
Stopped RouteA
$ lkdb delete RouteA !
Deleted RouteA

这个例子的源代码在此:larkexample0.cpp

第3步

要应用在真实产品中,您需要在您的进程里调用 lark 的API来创建您自己的音频路由。样例已经列出。参考用户手册以获取更多信息。

常见问题与回答

Q1: “块”是什么?“端点”是什么?“链接”是什么?“路由”是什么?

A: 一个“块”就是一个软件DSP处理单元。它从一个动态加载库里被创建,并被 lark 路由所管理。它接受最多32路输入(即输入端点)数据,处理它们,把处理后的数据填入输出端点(最多32路输出)。 通常情况,一个端点代表一个声道音频,然而一个端点也可以运载多声道。例如“interleave”块的一个输出端点就可以运载多声道。 一个“链接”连接一个块的一个输出端点(作为源)至另一个块的一个输入端点(作为汇)。 一个“路由”是一个由多个块连接成的链条(或者图)。

Q2: 在一个机器上,我可以同时运行几个 lark 实例?在一个 lark 中,我可以创建几个路由?在一个路由中,我可以创建多少个块?多少个first块?多少个last块?

A: 在一个机器上,只有一个进程被容许创建一个 lark 实例。也就是说,一个机器运行一个 lark 实例。lkdb会跟这个唯一的 lark 实例通信。在一个 lark 中,最多可以创建26个路由,它们的名字需要被手动指定为"RouteA", "RouteB", ..., "RouteZ"。对于每个路由,名字是需要的,并且应该固定为"Route#"(大小写敏感),这里“#”代表[A-Z]。 在一个路由里,创建块没有数量限制。所有从一个路由里创建出来的块/链接都属于这个路由,也就是意味着它们的资源是被这个路由统一管理。 同样,创建first块和last块也没有数量限制。

Q3: 什么是“first块”?什么是“last块”?

A: 在一个路由里,至少需要创建一个“first块”和一个“last块”,这些块在创建的时候,都有“first”标志和“last”标志被各自指定。 这样的话,路由就可以知道从哪些块开始处理,到哪些块结束处理。从first块到last块之间,所有的块应该要被连接起来,不要有切断。只有所有连接都完整了,路由才可以启动。如果路由中间有切断,这是被容许的,但是路由就无法运行。如果您强制运行,路由将会进入BROKEN_RUNNING状态,直到切断被再接起来。

Q4: “多路由”跟“单路由多first块”有何不同?如果我有多路输入作为first块,我要如何在“多路由”和“单路由多first块”之间做选择?

A: 一个路由用一个线程处理数据。通常情况,“单路由多first块”可以工作地很好。在这种情况下,多输入以同样的步伐提供数据帧,并且它们不应该被相互阻塞。例如,一个输入是alsacapture,一个输入是filereader。 需要用到“多路由”的场景是,当多个输入放在一个路由里运行会有机会相互阻塞时,那么它们就应该被分离到多个路由。例如,一个输入alsacapture,一个输入是echo-reference。

版本历史

0.10

  • 增加了BlkDuplicator块,以复制任意声道(单声道或多声道)的端点。
  • 适配了klogging v1.1.3

0.9

  • 路由(Route): 支持了组操作,例如连续NewBlock()和NewLink()作为一组
  • 支持了aarch64-android

0.8

  • Sox效果器(BlkSoxEffect): 支持了交错声道
  • 路由(Route): 修复了当处于BROKEN_RUNNING时不能start的问题
  • 例4: 应用了sox oops效果器
  • 混音器(BlkMixer): 修复了浮点混合时溢出问题
  • 块(Block): 支持了子名字
  • 支持了多路复用器(BlkMultiplexer)

0.7.2

  • lkdb: 修复了lkdb status --dot当有多个路由时的画图问题
  • 支持了FIFO名字
  • lkdb: lkdb status --dot能够画出路由之间的FIFO连接
  • BlkDelay: 支持了默认的delay值设定

0.7.1

  • lkdb: 修复了lkdb status --dot输出的last block名字标签错误

0.7

  • lkdb: 增加了lkdb status --dot命令来输出dot代码,以把路由图形快照画出来。
  • 适配了klogging v1.1.2

0.6

  • 增加了BlkSoxEffect块:音量(vol),镶边(flanger),颤音(tremolo),回音(echos),合唱(chorus),均衡器(equalizer),高通(highpass),低通(lowpass),等等。
  • 增加了例7:一个简单的SoX高通滤波器和低通滤波器的应用
  • 适配了klogging v1.1

0.5

  • 修复了数据转储时无效的dumpFileName问题
  • 支持了日志转储
  • 支持了配置文件

0.4

  • lkdb: 参数更具可读性
  • BlkFileReader BlkFileWriter: 移除了创建时所需的参数
  • BlkAlsaPlayback BlkAlsaCapture: 支持创建时传递pcm name参数
  • 重命名块的一些函数名,以增加可读性
  • 适配了klogging v0.9

0.3

  • 支持了更多的块
    • BlkTinyAlsaPlayback BlkTinyAlsaCapture BlkFormatAdapter BlkPACapture
  • 增加了larkexample6
    • 该例子能够实时播放麦克风录音,同时调节音调。用了两个路由来实现:
    • RouteB(BlkPACapture->BlkMixer->BlkInterleave->BlkStreamOut)->FIFO->RouteA(BlkStreamIn->BlkDelay->BlkFormatAdapter->BlkSoundTouch->BlkPAPlayback)

0.2

  • 支持 MacOS (x86_64)
    • x86_64-apple-darwin/bin/larkexample4x86_64-apple-darwin/bin/larkexample5可以正常运行了
  • README.md拆分成了README.md(英语)和README-cn.md(简体中文)

0.1

  • 支持实时操作音频路由
    • 实时加载/卸载块
    • 实时改变路径
    • 实时调节块参数
    • 实时设定日志等级
    • 实时转储每个块的数据
  • 支持预编译的输入/输出块
    • file-reader, file-writer, stream-in, stream-out, alsa-capture, alsa-playback, portaudio-playback
  • 支持预编译的算法块
    • gain, mixer(duplicator), interleave, de-interleave, format-adapter, delay, align, buffer, speex-resampler, speex-preprocessor, soundtouch
  • 支持无限客制化块
  • 支持每块最多32个输入端点,32个输出端点
  • 支持基于帧的时间戳和基于采样点的时间戳
  • 支持实时调试工具
  • 支持多操作系统
    • 当前仅Linux (x86_64)
This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to <https://unlicense.org>

简介

一个免费、轻量、功能强大的软件音频DSP,让您像搭积木一样构建音频系统。 A free, lite and powerful software audio DSP that enables you to build your audio system like building blocks. 展开 收起
C++
Unlicense
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
C++
1
https://gitee.com/testos/lark-release.git
git@gitee.com:testos/lark-release.git
testos
lark-release
lark-release
master

搜索帮助