在C中有一个全双工ALSA连接的例子吗?我已经读过它支持了,但是我看到的所有介绍性示例都记录或播放了一个声音样本,但我希望有一个处理程序可以同时为我的VoIP应用程序执行.
非常感谢你的帮助,Jens
我想用Python录制USB麦克风的短音频片段.我已经尝试了pyaudio,它似乎无法与ALSA通信,而alsaaudio,其代码示例产生了一个不可读的文件.
所以我的问题是:在Python中用USB麦克风录制剪辑的最简单方法是什么?
我正在尝试从麦克风录制数据,然后通过扬声器实时播放,并有一些延迟,但我遇到了一些问题.我选择使用python和alsaaudio,我可以在这里找到我遇到问题的当前脚本 .这适用于我迄今为止所拥有的(不是延迟部分),但会产生一些点击.alsaaudio docs有这样的说法:
播放PCM音频问题的最常见原因是对PCM设备的写入必须与设备的数据速率完全匹配.
如果向设备写入的数据太少,则会发生欠载,并且会发出丑陋的咔嗒声.相反,如果将太多数据写入器件,写入功能将阻塞(PCM_NORMAL模式)或返回零(PCM_NONBLOCK模式).
我似乎误解了文档,它说的是关于write():
PCM.write(数据)
在数据中写入(播放)声音.数据长度必须是帧大小的倍数,并且应该与周期的大小完全相同
我脚本中的一段时间是160.
它说关于read():
在PCM_NORMAL模式下,此功能将阻塞直到整个周期可用,然后返回一个元组(长度,数据),其中length是捕获数据的帧数,而数据是捕获的声音帧作为字符串.返回数据的长度为periodicize*framesize字节.
在我的脚本中,period_size*frame_size也应该等于160,但是当我打印长度(元组read()的一部分返回)我得到940.显然我似乎没有传递适量的数据.写(),但我不知道该去哪里.我把这些代码放在一起,主要是通过我发现的例子,我刚开始使用alsaaudio/sound,尝试组合一些有趣的项目,所以我还不知道很多.
我还想从麦克风录制直播,然后以100ms的延迟播放,因此注释了time.sleep().如果我取消注释它,长度似乎反复从940到-32,最终导致out.write()抛出异常(数据不够).
有人能告诉我如何(或我的剧本有什么问题)我会实时录制和播放声音数据,并延迟100毫秒?
我正在使用ALSA API snd_pcm_drop()来清除缓冲区.但是当我稍后继续播放音频时snd_pcm_prepare(),我可以听到之前应该被清除的部分音频.当我的价值很高时会发生这种情况snd_pcm_sw_params_set_stop_threshold().如果我使用较低的值,则不会播放来自先前音频会话的部分音频.
这里发生了什么?如何完全清除缓冲区?
(我是ALSA的新手)
谢谢
我想要实现的总结:
我正在做一些关于Discord机器人的工作.我正在尝试加入语音通道,这是一个简单的部分,然后使用该语音通道中扬声器的组合音频作为Web浏览器中网页的输入.只要它可以通过Selenium控制,它对哪个浏览器来说并不重要.
到目前为止,我的机器人使用discord.py API包装器在Python中编写.不幸的是,听取而不是放入音频并没有完全实现 - 更不用说记录 - 与discord.py.这让我决定切换到node.js(即discord.js)以获取我的机器人的语音通道内容.
切换到discord.js之后,很容易确定谁在说话并为该用户创建音频流(PCM流).对于下一部分,我只是将音频流传输到虚拟麦克风并选择它作为浏览器上的音频输入.您甚至可以在node.js 1中使用FFMPEG ,以获得如下所示的内容:
const Discord = require("discord.js");
const client = new Discord.Client();
client.on('ready', () => {
voiceChannel = client.channels.get('SOME_CHANNEL_ID');
voiceChannel.join()
.then(conn => {
console.log('Connected')
const receiver = conn.createReceiver();
conn.on('speaking', (user, speaking) => {
if (speaking) {
const audioStream = receiver.createPCMStream(user);
ffmpeg(stream)
.inputFormat('s32le')
.audioFrequency(16000)
.audioChannels(1)
.audioCodec('pcm_s16le')
.format('s16le')
.pipe(someVirtualMic);
}
});
})
.catch(console.log);
});
client.login('SOME_TOKEN');
Run Code Online (Sandbox Code Playgroud)
最后一部分,创建和流式传输到虚拟麦克风,已被证明是相当复杂的.我已经阅读了关于高级Linux声音架构(ALSA)和JACK音频连接套件的大量SO帖子和文档,但我根本无法弄清楚如何设置将显示为麦克风的虚拟麦克风我的浏览器,或如何管道音频到它.
任何帮助或指向解决方案的指针将不胜感激!
在过去的几天里,我一直在研究这个问题.我现在已经了解了ALSA环回设备,并认为解决方案必须存在.
我已经差不多跟着后谈到有关环回设备,旨在实现以下目标:
简单地假设您在同一设备的一个OUT和一个IN之间有物理链接. …
使用Ubuntu 10.04 64位进行Android开发,一切顺利,除了声音.
我使用-audio选项和-audio-out使用alsa作为后端参数,但没有运气.
任何的想法?
我有一个c ++对象接受声音请求并使用ALSA播放它们.有线程处理声音请求.一些声音是周期性的,并在将wav文件内容写入ALSA库后重新安排.有没有办法在发布所有数据时发现?函数snd_pcm_writei是一个阻塞写入函数,但它并不一定意味着该文件已被播放.
我正在考虑的一个选项是在播放每个声音文件后调用snd_pcm_drain,然后在播放下一个文件时调用snd_pcm_prepare.这会是一个很好的解决方案吗?或者效率低下?
更新: "排水解决方案"似乎有效,但效率不高.这些调用需要一段时间才能返回(可能会清理一些资源)并增加程序的延迟.当我连续播放许多小文件时,延迟最佳.每个文件之间可以听到几秒钟的沉默; 这是snd_pcm_drain正在执行.
我想使用ALSA将一些音频数据回放到PCM设备.作为示例,我已下载此示例示例并在我的PC中运行它.当没有其他进程正在使用声卡时,它工作正常.但是当其他一些进程使用音频设备(即播放歌曲的媒体播放器)并显示以下错误时,它不播放任何内容 -
Playback open error: Device or resource busy
Run Code Online (Sandbox Code Playgroud)
看一下这个例子的源代码,我可以说第882行的snd_pcm_open函数抛出了这个错误.它找到设备忙,因为另一个进程当前正在使用它.
我也尝试了相反的方式 - 首先开始这个例子然后尝试开始一首歌.在这种情况下,媒体播放器保持空闲状态,在进度条旁边显示"空闲"(我正在使用Banshee).我假设snd_pcm_open获得了设备资源的专有权,因此没有其他进程可以使用它.
但我不希望这样.我想在不需要任何专有权的情况下向音频设备播放声音,以便PC中的其他进程可以共享同一设备以输出音频数据.
我怎样才能做到这一点?如何打开PCM设备以便其他进程也可以共享同一设备?
我需要使用嵌入式Linux系统将音频从收音机发送到辅助系统.
辅助系统需要建立一个需要几秒钟的通信信道.
因此,如果我不想丢失音频的开头,我需要一种方法来录制声音并以自定义延迟播放(最多几秒钟).
应该可以开始arecord将音频记录在tmpfs文件系统中的文件中,并且当进入通信时,启动aplay.但在这种情况下,开始仍然失败,因为要记录的信号来得太晚了.
Linux上是否有一个程序可以在RAM中的环形缓冲区中连续录制声音,并且能够根据需要自定义延迟播放?
如果没有,在嵌入式系统上编写这样一个程序的最佳库是什么?alsa还是其他什么?
我打算用Python实现一个"类DSP"信号处理器.它应该通过ALSA捕获音频的小片段,处理它们,然后通过ALSA播放它们.
为了开始,我编写了以下(非常简单的)代码.
import alsaaudio
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL)
inp.setchannels(1)
inp.setrate(96000)
inp.setformat(alsaaudio.PCM_FORMAT_U32_LE)
inp.setperiodsize(1920)
outp = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, alsaaudio.PCM_NORMAL)
outp.setchannels(1)
outp.setrate(96000)
outp.setformat(alsaaudio.PCM_FORMAT_U32_LE)
outp.setperiodsize(1920)
while True:
l, data = inp.read()
# TODO: Perform some processing.
outp.write(data)
Run Code Online (Sandbox Code Playgroud)
问题是,音频"口吃"并且不是无间隙的.我尝试使用PCM模式,将其设置为PCM_ASYNC或PCM_NONBLOCK,但问题仍然存在.我认为问题是两个后续调用"inp.read()"之间的样本"丢失".
有没有办法在Python中"连续"捕获音频(最好不需要太"特定"/"非标准"的库)?我希望信号总是"在后台"被捕获到一些缓冲区中,我可以从中读取一些"瞬间状态",同时即使在我执行读取操作的时间内,音频也会被捕获到缓冲区中.我怎样才能做到这一点?
即使我使用专用的进程/线程来捕获音频,这个进程/线程总是至少必须(1)从源读取音频,(2)然后将其放入某个缓冲区(从中"信号处理")进程/线程然后读取).因此,这两个操作仍将按时间顺序进行,因此样本将丢失.我该如何避免这种情况?
非常感谢您的建议!
编辑2:现在我开始运行了.
import alsaaudio
from multiprocessing import Process, Queue
import numpy as np
import struct
"""
A class implementing buffered audio I/O.
"""
class Audio:
"""
Initialize the audio buffer.
"""
def __init__(self):
#self.__rate = 96000
self.__rate = 8000
self.__stride = 4
self.__pre_post = …Run Code Online (Sandbox Code Playgroud)