为什么这个 C++ ALSA(Linux 音频)程序有延迟?
Why is there latency in this C++ ALSA (Linux audio) program?
我正在 Ubuntu Linux 探索使用 C++ 生成声音。这是我的代码:
#include <iostream>
#include <cmath>
#include <stdint.h>
#include <ncurses.h>
//to compile: make [file_name] && ./[file_name]|aplay
int main()
{
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
timeout(0);
for ( int t=0;; t++ )
{
int ch = getch();
if (ch == 'q')
{
break;
}
uint8_t temp = t;
std::cout<<temp;
}
}
当此代码为 运行 时,我希望它发出声音,直到我在键盘上按下“q”,之后我希望程序退出。这很好用;但是,在按下键盘和程序退出之间存在明显的延迟。这不是由于 ncurses 的延迟,因为当我 运行 没有 std::cout<<temp;
的程序(即没有声音生成)时,没有延迟
有办法修改吗?如果没有,实时响应的音频程序是怎么写的?
欢迎对问题进行编辑和建议。我是 ALSA 的新手,所以我不确定是否需要任何其他详细信息来复制该错误。
上述循环中的延迟很可能是由于 ncurses getch 函数引入的延迟。
通常对于实时音频,您需要一个实时音频线程 运行 和一个非实时用户控制线程 运行。用户控制线程可以改变实时音频线程的内存space,强制实时音频循环根据需要调整合成。
在这个 gtkIOStream 示例中,full duplex audio class is created. The process method in the class 可以编译您的合成计算。这将使用 ALSA 处理您的声音播放。
要获取用户输入,一种可能是通过继承 FullDuplexTest class 向 class 添加线程方法,如下所示:
class UIALSA : public FullDuplexTest, public ThreadedMethod {
void *threadMain(void){
while (1){
// use getchar here to block and wait for user input
// change the memory in FullDuplexTest to indicate a change in variables
}
return NULL;
}
public:
UIALSA(const char*devName, int latency) : FullDuplexTest(devName, latency), ThreadedMethod() {};
};
然后在 original test file 中将对 FullDuplexTest 的所有引用更改为 UIALSA(您可能必须修复一些编译时错误):
UIALSA fullDuplex(deviceName, latency);
您还需要调用 UIALSA::run() 以确保 UI 线程处于 运行 并侦听用户输入。您可以添加调用 before you call "go" :
fullDuplex.run(); // start the UI thread
res=fullDuplex.go(); // start the full duplex read/write/process going.
我正在 Ubuntu Linux 探索使用 C++ 生成声音。这是我的代码:
#include <iostream>
#include <cmath>
#include <stdint.h>
#include <ncurses.h>
//to compile: make [file_name] && ./[file_name]|aplay
int main()
{
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
scrollok(stdscr, TRUE);
timeout(0);
for ( int t=0;; t++ )
{
int ch = getch();
if (ch == 'q')
{
break;
}
uint8_t temp = t;
std::cout<<temp;
}
}
当此代码为 运行 时,我希望它发出声音,直到我在键盘上按下“q”,之后我希望程序退出。这很好用;但是,在按下键盘和程序退出之间存在明显的延迟。这不是由于 ncurses 的延迟,因为当我 运行 没有 std::cout<<temp;
的程序(即没有声音生成)时,没有延迟
有办法修改吗?如果没有,实时响应的音频程序是怎么写的?
欢迎对问题进行编辑和建议。我是 ALSA 的新手,所以我不确定是否需要任何其他详细信息来复制该错误。
上述循环中的延迟很可能是由于 ncurses getch 函数引入的延迟。
通常对于实时音频,您需要一个实时音频线程 运行 和一个非实时用户控制线程 运行。用户控制线程可以改变实时音频线程的内存space,强制实时音频循环根据需要调整合成。
在这个 gtkIOStream 示例中,full duplex audio class is created. The process method in the class 可以编译您的合成计算。这将使用 ALSA 处理您的声音播放。
要获取用户输入,一种可能是通过继承 FullDuplexTest class 向 class 添加线程方法,如下所示:
class UIALSA : public FullDuplexTest, public ThreadedMethod {
void *threadMain(void){
while (1){
// use getchar here to block and wait for user input
// change the memory in FullDuplexTest to indicate a change in variables
}
return NULL;
}
public:
UIALSA(const char*devName, int latency) : FullDuplexTest(devName, latency), ThreadedMethod() {};
};
然后在 original test file 中将对 FullDuplexTest 的所有引用更改为 UIALSA(您可能必须修复一些编译时错误):
UIALSA fullDuplex(deviceName, latency);
您还需要调用 UIALSA::run() 以确保 UI 线程处于 运行 并侦听用户输入。您可以添加调用 before you call "go" :
fullDuplex.run(); // start the UI thread
res=fullDuplex.go(); // start the full duplex read/write/process going.