Linux:录制/播放声音期间的计时
我有一个更普遍的问题,关于标准 Linux 操作系统中处理播放声音和通过串行端口接收数据的时序。
目前,我正在读取通过 USB 转串口桥 (pl2303) 到达的 PCM 信号,该信号是从 FPGA 记录、编码和发送的。
现在,我需要在录制的声音流中的已知位置创建“峰值”,并计划从在已知时刻录制的同一台机器播放声音文件。峰值必须在最大 50 毫秒的窗口内开始和停止,其长度可能约为 200 毫秒...
现在,我的问题是:我期望的计时有多精确?我知道,有几个组件会增加“未知的滞后”、抖动:
- USB 转串行桥在将它们发送到 USB 端之前从串行端收集约 20 个字节(在 230400 波特率下,这会导致约 1 毫秒)
- 如果我调用“`睡眠 123 $MP3FILE` &"就在我的录音软件之前,Linux内核将以不同的方式安排它们(也许这会导致几个10毫秒,具体取决于系统负载?)
- 声卡/驱动程序可能会增加一些未知的延迟......
- 会像“nice”或“ sched_setscheduler”在我的情况下增加价值?
- 我可以在录音软件中构建一个额外的线程来播放声音。这样做,时间可能会更精确,但我还有很多工作要做......
非常感谢。
无论如何我都会尝试一下,但我正在寻找一些背景知识来更好地理解和解决我即将遇到的问题。
I have a more general question, regarding timing in a standard Linux-OS dealing with playing sound and receiving data over a serial port.
In the moment, I'm reading a PCM-Signal arriving over a USB-to-Serial Bridge (pl2303) which is recorded, encoded and sent from a FPGA.
Now, I need to create "peaks" at a known position in the recorded soundstream, and plan to play a soundfile from the same machine which is recording at a known moment. The peak has to begin and stop inside windows of maximal 50ms, it's length could be ~200ms...
Now, my question is: How precise can I expect the timing to be? I know, that several components add "unkown lag", jitter:
- USB-to-Serial Bridge collects ~20 bytes from the serial side before sending them to the USB-side (at 230400Baud this results in ~1ms)
- If I call "`sleep 1; mpg123 $MP3FILE` &" directly before my recording software, the Linux-Kernel will schedule them differenty (maybe this causes a few 10ms, depending on system load?)
- The soundcard/driver will maybe add some more unkown lag...
- Will tricks like "nice" or "sched_setscheduler" add value in my case?
- I could build an additional thread inside my recording sofware, which plays the sound. Doing this, the timing may be more precise, but I have a lot more work to do ...
Thanks a lot.
I will try it anyway, but I'm looking for some background toughts to understand and solve my upcoming problems better.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不是 100% 确定,但我想你的内核需要重建,以允许调度程序减少切换任务的延迟时间,就像多任务处理一样,在内核 2.6.x 系列中,有一个选项可以使内核更平滑通过使其可先发制人。
这应该会简化时序并使声音因抖动较少而显得更加平滑。
尝试一下并再次重新编译内核。当然,有大量的内核补丁可以减少每个任务切换的时间片,使其更加平滑,您的里程可能会有所不同,具体取决于:
这三个因素结合起来就越愉快,将对调度程序和多任务处理功能产生影响。延迟越低,粒度越细。
顺便说一句,有一个专门用于实时捕捉声音的linux发行版,我不记得它的名字了,该发行版中的内核经过大量修补,使声音捕捉非常流畅。
I am not 100% sure, but I would imagine that your kernel would need to be rebuilt to allow the scheduler to reduce latency time in switching tasks a la multitasking, in kernels 2.6.x series, there's an option to make the kernel more smoother by making it pre-emptible.
This should streamline the timing and make the sounds appear smoother as a result of less jitters.
Try that and recompile the kernel again. There are of course, plenty of kernel patches that would reduce the timeslice for each task-switch to make it even more smoother, your mileage may vary depending on:
using those three factors combined, will have an influence on the scheduler and the multi-tasking features. The lower the latency, the more fine-grained it is.
Incidentally, there is a specialized linux distribution that is catered for capturing sound in real-time, I cannot remember the name of it, the kernel in that distribution was heavily patched to make sound capture very smooth.
又是我...经过一个不安的夜晚,我解决了我奇怪的计时问题...我的第一次编辑并不完全正确,因为我发布的内容不是 100% 可复制的。运行更多测试后,我可以得出以下图,显示计时准确性:
分析结果http://mega2000.de/~mzenzes/pics4web/2010-05-28_13-37-08_timingexperiment.png
我尝试了两种不同的ubuntu 内核:
2.6.32-21-generic
和2.6.32-10-rt
我尝试实现 RT 调度:
sudo chrt --fifo 99 ./experimenter.sh
我尝试更改省电选项:
echo {performance,conservative} | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
这导致了 8 个不同的测试,每个测试运行 50 次。以下是数字:
it's me again... After one restless night, I solved my strange timing-problems... My first edit is not completely correct, since what I posted was not 100% reproducible. After running some more tests, I can come up with the following Plot, showing timing accuracy:
Results from analysis http://mega2000.de/~mzenzes/pics4web/2010-05-28_13-37-08_timingexperiment.png
I tried two different ubuntu-kernels:
2.6.32-21-generic
and2.6.32-10-rt
I tried to achieve RT-scheduling:
sudo chrt --fifo 99 ./experimenter.sh
And I tried to change powersaving-options:
echo {performance,conservative} | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
This resulted in 8 different tests, with 50 runs each. Here are the numbers: