作为一名潜在的程序员和电吉他爱好者,我无法远离开发音乐软件。 曾经尝试使用某种吉他处理器将电吉他连接到Windows计算机的每个人都知道,通常出于这些目的需要ASIO接口(也可以使用ASIO接口,但ASIO最受欢迎)。 这是由于以下事实:花费大量时间来处理音频输入和输出,结果,演奏乐器时听到了不愉快的延迟,这使游戏非常困难。 ASIO允许您在输出声音时跳过混音阶段,因此可以大大减少延迟。
在此处了解更多信息。
有什么问题
我决定使用ASIO,因为该驱动程序非常流行且方便使用,但是在这里我遇到了一个问题:关于该技术的开发主题的文章很少。 实际上,我从一开始就可以指导所有工作-SDK的
官方文档和一些英语论坛。 我希望如果您有类似的问题,那么本文对您至少是有用的。
低音库
来自
Stainberg官方网站的使用该SDK的代码仅播放20秒钟的静默时间,需要500行。 但是,这里有一个很棒的
低音库。 从事声音工作的爱好者知道如何使用它来创建声音流和声道,如何应用FX效果,进行混音……我真的希望如此。 Bass有一个Bassasio附加组件,实际上,它使您可以用几行代码来配置ASIO驱动程序,并执行与上述示例相同的任务。
安装和配置库
- 下载Bass库及其附加的Bassasio 。 这是官方网站
- 我们将.lib文件转储到单独的文件夹中。 在这种情况下,我将bass.lib和bassasio.lib文件放入Libs文件夹中
- .dll文件被传输到Release和Debug文件夹。 (bass.dll和bassasio.dll)如果没有完成,那么当您运行应用程序的代码时,程序将引发如下错误:

- 接下来,在项目设置中,我们将链接器的路径分配给.link文件,将.lib文件分配给链接器 。 对于c / c ++,我们也是如此。


- 我们将.h文件拖放到项目文件夹中,并将它们包括在项目中,即bass.h和bassasio.h文件 。
#include "bass.h" #include "bassasio.h"
使用范例
例如,创建一个小型控制台应用程序,该应用程序将播放吉他的声音,即 程序会将流从音频输入重定向到音频输出。 该应用程序代码在
github上可用,
这似乎很简单。 它看起来应该像吉他组合(粘住并弹奏!),但是到目前为止声音仍然清晰(没有效果)。
我们在上一段中连接了库,现在我们需要初始化声音输入和输出设备。 让我们开始吧!
BASS_Init()初始化声音输出设备,并采用以下参数作为输入:
参量int device-输出设备的标识符。 如果您将参数设置为-1,则将使用标准输出设备;如果为0,则声音将完全不播放,即 不会提供给任何输出设备。
DWORD频率 -采样频率(Hz)
DWORD标志 -标志...有很多,您可以在官方文档
www.un4seen.com/doc/#bass/BASS_Init.html中阅读更多内容。 简而言之,借助标志,您可以选择声音编码的深度,单声道或立体声,两个以上扬声器的声音再现等。
HWND win-安装主应用程序窗口。 对于控制台应用程序,设置为0。
GUID * clsid-用于初始化将用于初始化DirectSound的对象的类。 在其他情况下,设置为Null。
初始化ASIO驱动程序要简单一些。
我们仅将2个参数传递给
BASSASIO_Init函数:
参量int设备 -“设备”的标识符...库将使用的技术。 问题是,如果您已经安装了诸如吉他架之类的软件,或者您的声卡带有自己的ASIO驱动程序,您将在可用“设备”列表中看到多个项目。 可以通过为每个标识符调用BASS_ASIO_GetDeviceInfo()函数(通过它们进行排序)来获取列表。 通常,ASIO4ALL驱动程序为0,我们将在以后使用它。 值-1将默认设置设备,如文档中所述。
std::cout << "ASIO Devices info:" << std::endl; a = 0; count = 0; BASS_ASIO_DEVICEINFO asio_info; for (a = 0; BASS_ASIO_GetDeviceInfo(a, &asio_info); a++) std::cout << "Device " << a << ") " << asio_info.name << std::endl; std::cout << " ________ " << std::endl;
驱动程式清单DWORD标志 -标志。 它们只有2个:BASS_ASIO_THREAD-在单独的线程中运行驱动程序,而BASS_ASIO_JOINORDER-负责通道通道的操作。
代码,声音输出设备和ASIO驱动程序的初始化:
try { if ( ! BASS_Init(0, 44100, 0, 0, NULL) ) throw BASS_ErrorGetCode(); if ( ! BASS_ASIO_Init( 0, NULL ) ) throw BASS_ASIO_ErrorGetCode(); } catch ( int err ) { std::cout << "Err no - " << err << std::endl; system("pause"); return; }
可能会出现问题:为什么
BASS_Init (0)中未使用
输出设备。 事实是,音频输出将使用BASSASIO插件通过ASIO进行。 我们不需要使用BASS库来实现手头任务的标准声音输出-因此为0。但是,有两点值得注意:
- 您可以在一台设备上使用ASIO驱动程序,并在另一台设备上使用标准方式输出声音(例如...将播放音乐)。 为此,只需在初始化BASS并设置ASIO驱动程序时选择其他设备(在操作过程中,通知区域中将显示其图标)。
- 有关可用设备的列表,请使用BASS_GetDeviceInfo。
setlocale(LC_ALL, "Rus"); std::cout << "Devices info:" << std::endl; int a, count = 0; BASS_DEVICEINFO info; for (a = 1; BASS_GetDeviceInfo(a, &info); a++) { if (info.flags&BASS_DEVICE_ENABLED)

BASS仅适用于当前处于活动状态的设备。 断开连接的设备将根本不可见。

有源声音输出设备
无论是否通过操作系统断开设备的连接,BASSASIO都是绝对相同的。 在驱动程序设置中,选择所需的声音输入和输出设备。
- 尝试同时使用BASS和BASSASIO将声音同时输出到一个设备中是没有意义的-ASIO技术是专门为以下事实而设计的,即该声音不会被操作系统混合,而是直接进入声卡以进行后续输出。 即 您只会听到使用ASIO的应用发出的声音。
接下来,我们需要将声音从麦克风引导到声音输出设备。 有几种方法可以做到这一点。 最简单的方法是“镜像”通道。
我们有3个频道:麦克风,左耳机和右耳机。 要将信号从麦克风传输到输出通道,我们使用
BOOL BASS_ASIO_ChannelEnableMirror( DWORD channel - BOOL input2 - ? (0 1) DWORD channel2 – ( ) );
这里的一切都很简单。 我们需要将信号从输入通道0传输到输出通道0和1:
BASS_ASIO_ChannelEnableMirror( 0, 1, 0 ); BASS_ASIO_ChannelEnableMirror( 1, 1, 0 );
然后出现了问题:我如何找出将信号传输到哪些通道。 答案-有关频道的信息可以使用
BASS_ASIO_ ChannelGetInfo函数找到。
a = 0; BASS_ASIO_CHANNELINFO channel_info; std::cout << "inputs: " << std::endl; for (a = 0; BASS_ASIO_ChannelGetInfo(0, a, &channel_info ); a++ ) std::cout << a << ") " << channel_info.name << " format: " << channel_info.format << std::endl; std::cout << "Outputs: " << std::endl; for (a = 0; BASS_ASIO_ChannelGetInfo(1, a, &channel_info); a++) std::cout << a << ") " << channel_info.name << " format: " << channel_info.format << std::endl; std::cout << "__________" << std::endl;

所有设置均已准备就绪。 开始
-BASS_ASIO_Start 。 您可以为最大样本长度和输入的流数指定参数,但是对于我们的任务,我们可以默认保留这些参数(用零填充)。
BASS_ASIO_Start( 0, 0 );
实际上,仅此而已。 但是,这是一个控制台应用程序,请不要忘记
系统(“暂停”) ,这样它就不会在启动后立即关闭,并且在此之后立即释放内存并停止使用设备和驱动程序。
BASS_ASIO_Stop(); BASS_ASIO_Free(); BASS_Stop(); BASS_Free(); return;
总结
我将源代码保留在
github上 。
因此,我们得到了一个使用ASIO技术的简单控制台应用程序。 将乐器连接到声卡时,我们不会听到使用标准Windows工具进行标准连接时可能发生的延迟。 当然,BASS库和BASSASIO附加组件的可能性都比上面介绍的要广泛,但是,本文的格式和我的知识都不足以陈述所有内容。
如果这个主题至少对您来说很有趣,我很乐意尝试。 反过来,我会花一点时间来编写续集,在续集中,我们可以使用DX8的标准FX效果,获得类似于简单吉他处理器的外观。
感谢您的关注!