Linux如何在RAM缓冲区中录制声音,并自定义延迟播放audio【JAVA教程】

!
也想出现在这里? 联系我们
信息

Linux如何在RAM缓冲区中录制声音,并自定义延迟播放audio,第1张

概述Linux如何在RAM缓冲区中录制声音,并自定义延迟播放audio

我需要使用embedded式linux系统将audio从收音机发送到辅助系统。

辅助系统需要build立一个需要几秒钟的通信通道。

所以,如果我不想失去audio的开始,我需要一种方法来logging声音,并以自定义延迟(最多几秒)播放。

应该可以启动arecord将audiologging到tmpfs文件系统中的文件中,并且当通信传入时,启动aplay 。 但在这种情况下,由于要logging的信号来得太迟,所以开始还是丢失了。

在C + Ubuntu(GNU / linux)中JACK录制/播放编程

如何在Raspbian下实时优先设置jackd和guitarix?

在windows和linux之间运行Jack

JACK mIDi事件在64位机器上丢失

如何启动与新贵实时优先(杰克)的过程?

在linux上有没有一个程序可以在RAM的环形缓冲区中连续录制声音,并能够根据需要自定义延迟播放?

如果没有,在embedded式系统上编写这样一个程序的最好的库是什么? alsa还是别的什么?

SuperCollIDer没有插孔服务器

JACKaudio连接套件jackd守护程序无法在RaspBerryPi上启动

这是一个简单的C程序,它将在管道进出之间保持一个循环缓冲区。 使用像in | buffer_program | out in | buffer_program | out in | buffer_program | out 。 错误检查省略。 鲁棒性不能保证。 给出一般的想法。

测试脚本(但是实际上,因为它的循环缓冲区中的管道数据需要保持一致,只需要在流中包含任何块,或者只是使缓冲区大于数据):

cat some.wav | ./circular_buffer 100000 | (sleep 1 && aplay)

circular_buffer.c:

/** * This program simply maintains a circular buffer of a given size indefinitely. */ #include <stdio.h> #include <stddef.h> #include <unistd.h> #include <stdlib.h> #include <stdbool.h> /* C99 only */ #include <sys/select.h> #include <errno.h> #include <fcntl.h> int c_read(int fd,char * buf,unsigned int size,unsigned int * head_in,unsigned int * tail_in); int c_write(int fd,unsigned int * tail_in); bool empty_buf(unsigned int head,unsigned int tail); bool setblock(int fd,bool block); #define FD_SET_SET(set,fd,max) FD_SET(fd,&set); max = ((fd > max) ? fd : max); #define FD_SET_UNSET(set,max) FD_CLR(fd,&set); max = ((fd == max) ? max – 1 : max); //not IDeal. do while ISFDSET… int main(int argc,char **argv) { char * buf; unsigned int buf_size = 0; unsigned int buf_head = 0; unsigned int buf_tail = 0; // Check args. if(argc != 2) { fprintf(stderr,\”Usage: %s <buffer size in bytes>n\”,__file__); exit(EXIT_FAILURE); } sscanf(argv[1],\”%d\”,&buf_size); buf_size = ( buf_size < 2 ) ? 2 : buf_size; // Note the usable buffer space is buf_size-1. fprintf(stderr,\”Allocating %dn\”,buf_size); buf = (char*)malloc(buf_size); bool done_reading = false; int maxfd = 0; fd_set r_set,w_set,r_tempset,w_tempset; setblock(STDIN_fileNO,false); setblock(STDOUT_fileNO,false); FD_ZERO(&r_set); FD_ZERO(&w_set); FD_ZERO(&r_tempset); FD_ZERO(&w_tempset); FD_SET_SET(r_tempset,STDIN_fileNO,maxfd); FD_SET_SET(w_tempset,STDOUT_fileNO,maxfd); r_set = r_tempset; while(true) { select((maxfd + 1),&r_set,&w_set,NulL,NulL); if(FD_ISSET(STDIN_fileNO,&r_set)) { int c = c_read(STDIN_fileNO,buf,buf_size,&buf_head,&buf_tail); if(c == -1) { // EOF,disable select on the input. fprintf(stderr,\”No more bytes to readn\”); done_reading = true; FD_ZERO(&r_set); } } if(!done_reading) { r_set = r_tempset; } if(FD_ISSET(STDOUT_fileNO,&w_set)) { c_write(STDOUT_fileNO,&buf_tail); } if(!empty_buf(buf_head,buf_tail)) { // Enable select on write whenever there is bytes. w_set = w_tempset; } else { FD_ZERO(&w_set); if(done_reading) { // Finish. fprintf(stderr,\”No more bytes to writen\”); break; } } } fflush(stderr); return 0; } bool empty_buf(unsigned int head,unsigned int tail) { return head == tail; } /** * Keep reading until we can read no more. Keep on pushing the tail forward as we overflow. * Expects fd to be non blocking. * @returns number of byte read,0 on non stopPing error,or -1 on error or EOF. */ int c_read(int fd,unsigned int * tail_in) { fprintf(stderr,\”In c_read()n\”); unsigned int head = *head_in; unsigned int tail = *tail_in; bool more_bytes = true; int n = 0; int c = 0; while(more_bytes) { bool in_front = tail > head; fprintf(stderr,\”Read %d %d %dn\”,size,head,tail); n = read(fd,buf+head,size – head); if(n == -1) { more_bytes = false; if(errno == EAGAIN || errno == EWOulDBLOCK || errno == EINTR) { // Not EOF but the read would block. c = 0; } else { c = -1; } } else if(n == 0) { // EOF. No more bytes possible. more_bytes = false; c = -1; } else if(n != (size – head)) { // if not full read adjust pointers and break. more_bytes = false; c += n; head = (head+n)%size; if(in_front && (head >= tail || head == 0)) { tail = (head+1)%size; } } else { c = 0; head = 0; tail = (tail == 0) ? 1 : tail; } } *head_in = head; *tail_in = tail; return c; } /** * Try flush the buffer to fd. fd should be non blocking. */ int c_write(int fd,\”In c_write()n\”); unsigned int head = *head_in; unsigned int tail = *tail_in; int n = 0; fprintf(stderr,\”Write %d %d %dn\”,tail); if(tail < head) { n = write(fd,buf+tail,head-tail); tail += n; } else if(head < tail) { n = write(fd,size-tail); if(n == size-tail) { n = write(fd,head); tail = n; } } *head_in = head; *tail_in = tail; return n; } bool setblock(int fd,bool block) { int flags; flags = fcntl(fd,F_GETFL); if (block) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; fcntl(fd,F_SETFL,flags); return true; }

如果你所需要的只是有一个缓冲区来保持声音输出,直到准备好被使用,这个变体应该可以工作:

开始录制:

mkfifo /tmp/f stdbuf -o256M arecord -i | cat > /tmp/f

开始播放,当你的输出设备准备就绪时:

aplay /tmp/f

调整输出缓冲区大小以适应您的需求。

编辑(鉴于玩可以随时开始):

如果您需要连续录制并随时开始播放,则可以使用split命令将输出分割为较小的文件,并在辅助进程中删除旧文件。

就像是:

# Garbage collector ( while sleep 1 ; do rm $(ls *.blb 2>/dev/null | sort | head -n-3 ) > /dev/null 2>&1 ; done ) & # Actual recording arecord -i | split -a 10 -u -b 24576 –additional-suffix \’.blb\’

并玩:

{ while true ; do for f in $(find . -name \’*.blb\’ -size 24576c | sort) ; do cat $f ; rm $f ; done ; done } | aplay

这个解决方案很脏,但可能会工作(最好在tmpfs,因为你已经提到)…

总结

以上是内存溢出为你收集整理的Linux如何在RAM缓冲区中录制声音,并自定义延迟播放audio全部内容,希望文章能够帮你解决Linux如何在RAM缓冲区中录制声音,并自定义延迟播放audio所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

© 版权声明
THE END
喜欢就支持一下吧
点赞152 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容