开发者

recording mic to a wav or mp3 file on linux?

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开发者_JS百科 under linux, will it be as easy as reading a file with fopen/fread? also, does it require root to be done?

thanks.


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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜