在Linux上录制麦克风到wav或mp3文件?

时间:2011-02-28 22:33:13

标签: c linux audio-recording

我不知道从哪里开始,我试图在linux上录制麦克风输入,是否可能,我的意思是我知道一切都是linux下的文件描述符,它会像用fopen / fread读取文件一样简单吗?还需要root吗?

感谢。

2 个答案:

答案 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; }