我不知道从哪里开始,我试图在linux上录制麦克风输入,是否可能,我的意思是我知道一切都是linux下的文件描述符,它会像用fopen / fread读取文件一样简单吗?还需要root吗?
感谢。
答案 0 :(得分:5)
这当然是可能的,但它并不像从文件中读取那么简单。最简单的方法是使用库,例如PortAudio。 PortAudio是跨平台的,使用起来相当简单。
PortAudio将允许您从麦克风录制,但它对文件格式一无所知。为此你需要另一个图书馆。我从未使用它,但the libsndfile library可能会做你需要的。
在任何情况下,您都必须从麦克风录制并将数据存储在缓冲区中,然后将该缓冲区写入文件(通过libsndfile或类似的东西)。
编辑:示例PortAudio的东西(未经测试,但你应该明白这一点。)
int main()
{
PaStream *stream;
/* allocate a buffer that can hold 30 seconds of audio at 44,100Hz */
int len = 44100*30;
float *buffer = malloc(len*sizeof(float));
Pa_Initialize();
/* open a default input (microphone) stream with a sampling rate of 44,100Hz */
Pa_OpenDefaultStream(&stream, 1, 0, paFloat32, 44100, paFramesPerBufferUnspecified, NULL, NULL);
Pa_StartStream(stream);
Pa_ReadStream(stream, buffer, len);
/* write buffer to a file here */
return 0;
}
答案 1 :(得分:2)
如果您安装了PulseAudio的Dev软件包(用于声音的多个发行版),这肯定是可行的,如果您将麦克风定义为PA接收器,您只需将数据从接收器传输到FIFO我就可以了没有很多经验,但维基应该帮助
http://pulseaudio.org/wiki/DeveloperDocumentation
编辑:来自文档的一些示例代码,看起来它完全符合您的要求使用FD等
> /*** This file is part of
> PulseAudio.
>
> PulseAudio is free software; you can
> redistribute it and/or modify it
> under the terms of the GNU Lesser
> General Public License as published
> by the Free Software Foundation;
> either version 2.1 of the License,
> or (at your option) any later version.
>
> PulseAudio is distributed in the
> hope that it will be useful, but
> WITHOUT ANY WARRANTY; without even the
> implied warranty of MERCHANTABILITY
> or FITNESS FOR A PARTICULAR PURPOSE.
> See the GNU General Public License
> for more details.
>
> You should have received a copy of
> the GNU Lesser General Public License
> along with PulseAudio; if not, write
> to the Free Software Foundation,
> Inc., 59 Temple Place, Suite 330,
> Boston, MA 02111-1307 USA.
> ***/
>
> #ifdef HAVE_CONFIG_H
> #include <config.h>
> #endif
>
> #include <stdio.h>
> #include <unistd.h>
> #include <string.h>
> #include <errno.h>
>
> #include <pulse/simple.h>
> #include <pulse/error.h>
> #include <pulse/gccmacro.h>
>
> #define BUFSIZE 1024
>
> /* A simple routine calling UNIX
> write() in a loop */ static ssize_t
> loop_write(int fd, const void*data,
> size_t size) {
> ssize_t ret = 0;
>
> while (size > 0) {
> ssize_t r;
>
> if ((r = write(fd, data, size)) < 0)
> return r;
>
> if (r == 0)
> break;
>
> ret += r;
> data = (const uint8_t*) data + r;
> size -= (size_t) r;
> }
>
> return ret; }
>
> int main(int argc, char*argv[]) {
> /* The sample type to use */
> static const pa_sample_spec ss = {
> .format = PA_SAMPLE_S16LE,
> .rate = 44100,
> .channels = 2
> };
> pa_simple *s = NULL;
> int ret = 1;
> int error;
>
> /* Create the recording stream */
> if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL,
> "record", &ss, NULL, NULL, &error))) {
> fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n",
> pa_strerror(error));
> goto finish;
> }
>
> for (;;) {
> uint8_t buf[BUFSIZE];
>
> /* Record some data ... */
> if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
> fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n",
> pa_strerror(error));
> goto finish;
> }
>
> /* And write it to STDOUT */
> if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) {
> fprintf(stderr, __FILE__": write() failed: %s\n",
> strerror(errno));
> goto finish;
> }
> }
>
> ret = 0;
>
> finish:
>
> if (s)
> pa_simple_free(s);
>
> return ret; }