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

发布于 2024-10-19 12:47:01 字数 113 浏览 1 评论 0原文

我不知道从哪里开始,我试图在Linux上记录麦克风输入,这可能吗,我的意思是我知道Linux下的一切都是文件描述符,它会像用fopen/fread读取文件一样容易吗?另外,需要root吗?

谢谢。

i didnt know where to start, im trying to record mic input on linux, is it possible, i mean i know that everything is a file descriptor under linux, will it be as easy as reading a file with fopen/fread? also, does it require root to be done?

thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情绪操控生活 2024-10-26 12:47:01

这当然是可能的,但它并不像从文件中读取那么简单。最简单的方法是使用库,例如​​ PortAudio。 PortAudio 是跨平台的并且使用起来相当简单。

PortAudio 可以让你从麦克风录音,但它不知道任何有关文件格式的信息。为此,您将需要另一个库。我从未使用过它,但 libsndfile 库 可能可以满足您的需求。

在任何情况下,您都必须从麦克风录制并将数据存储在缓冲区中,然后将该缓冲区写入文件(通过 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;
}

It certainly is possible but it's not as simple as reading from a file. The easiest way is to use a library, such as PortAudio. PortAudio is cross-platform and fairly simple to use.

PortAudio will let you record from the mic, but it doesn't know anything about file formats. For that you're going to need another library. I've never used it, but the libsndfile library might do what you need.

In any case, you're going to have to record from the mic and store the data in a buffer, then write that buffer to a file (via libsndfile or something similar).

EDIT: example PortAudio stuff (untested, but you should get the idea).

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;
}
小草泠泠 2024-10-26 12:47:01

如果您安装 PulseAudio 的开发包(在许多声音发行版中使用),这绝对是可行的,如果您将麦克风定义为 PA 接收器,您可以将数据从接收器传输到 FIFO 我还没有有很多相关经验,但 wiki 应该可以帮助

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

If you install the Dev package for PulseAudio (used in a number of distros for sound) this should definately be doable, if you define the mic as a PA sink you can just pipe data from the sink into a FIFO I've not had a lot of experience with it but the wiki should help

http://pulseaudio.org/wiki/DeveloperDocumentation

edit: some sample code from the documentation, looks like it does exactly what you want uses FD's etc

> /***   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; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文