设想:
操作系统: Raspberry Buster
- 我有一个音频链如下USB 音频输入->arecord->命名管道->forked-daapd。在目前的配置中,一个记录和 分叉的 daapd均按标准设置系统服务。
- 目标是将音频从转盘发送到网络音频端点 (Sonos)。
- 管道的 arecord 部分非常简单”arecord -Dplughw:1,0 -t wav -f cd /srv/music/phono-source”
- 如果我使用 mkfifo 创建命名管道(“phono-source”),然后启动一个记录和分叉DAAP服务,一切似乎都按预期进行。
- 如果我让配置运行但“空闲”,即转盘未使用,那么假设有效地生成静音/噪音,在稍后的某个时刻,原始命名管道对象将重命名为“phono-source-01”和一个新的常规(不是管道)文件“phono-source-02”被创建。 arecord 现在正在将数据写入新文件,该文件的大小以预期的速度增长。
- 这让我困惑了一段时间,直到我意识到音频输出已经达到了 wav 文件的最大大小。让事情运行一段时间,当 phono-source-02 达到 2147483692 字节时,输出恢复到新的常规文件 phono-source-03,这得到了一定程度的确认。
- 我隐约意识到 wav 文件有 2Gig 限制,但我假设这是一个物理文件限制,而且由于我在这种情况下写入管道,因此它不适用 - 显然不适用。这里的强力方法是在转盘上播放每张专辑后终止 arecord 服务并在新专辑开始时启动它。
关于避免此问题的策略有什么建议吗,或者通过对管道做一些不同的事情,或者使用像 sox 这样的替代音频采集器?
有什么想法吗?
答案1
如果你查看源代码aplay.c/arecord.c,您会看到一个表格,格式如下
static const struct fmt_capture {
void (*start) (int fd, size_t count);
void (*end) (int fd);
char *what;
long long max_filesize;
} fmt_rec_table[] = {
{ NULL, NULL, N_("raw data"), LLONG_MAX },
{ begin_voc, end_voc, N_("VOC"), 16000000LL },
/* FIXME: can WAV handle exactly 2GB or less than it? */
{ begin_wave, end_wave, N_("WAVE"), 2147483648LL },
{ begin_au, end_au, N_("Sparc Audio"), LLONG_MAX }
};
所以你可以看到WAV文件的大小是受到设计限制的。
您可能会更幸运-t raw
(可能需要采样率等附加参数)或-t au
(Sun Sparc Audio 文件格式),假设forked-daapd
可以处理这些(我从未使用过forked-daapd
)。在 64 位系统上,LLONG_MAX 为 9223372036854775807,在文件达到该大小之前,您的文件系统可能会发出抱怨。
如果您确实需要 WAV 文件,请记住,这种格式的文件头大小不能大于 2 GB,因此大多数实现可能都会有某种限制。最大文件大小。
我不知道具有“流模式”的录音机的任何特定实现(据我所知,这实际上会违反 WAV 规范)并且故意忽略这一点。这并不意味着它不存在。