如何使用 openAL 将麦克风的实时音频输入录制到文件中? (里面有C++代码)

发布于 2024-09-30 11:09:14 字数 2631 浏览 3 评论 0原文

我有这样的代码,用于在 Windows 上使用 openAL 进行麦克风回声。

我想创建一些 CapturedAudioData 文件来写入循环期间捕获的所有音频数据。所以它就像未格式化的 PCM。我需要每秒填充 25 次。

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <al.h>
#include <alc.h>
using namespace std;
int main()
{
    ALCdevice *dev[2];
    ALCcontext *ctx;
    ALuint source, buffers[3];
    char data[5000]; 
    ALuint buf;
    ALint val;

    dev[0] = alcOpenDevice(NULL);
    ctx = alcCreateContext(dev[0], NULL);
    alcMakeContextCurrent(ctx);

    alGenSources(1, &source);
    alGenBuffers(3, buffers);

    /* Setup some initial silent data to play out of the source */
    alBufferData(buffers[0], AL_FORMAT_MONO16, data, sizeof(data), 22050);
    alBufferData(buffers[1], AL_FORMAT_MONO16, data, sizeof(data), 22050);
    alBufferData(buffers[2], AL_FORMAT_MONO16, data, sizeof(data), 22050);
    alSourceQueueBuffers(source, 3, buffers);

    /* If you don't need 3D spatialization, this should help processing time */
    alDistanceModel(AL_NONE); 

    dev[1] = alcCaptureOpenDevice(NULL, 22050, AL_FORMAT_MONO16, sizeof(data)/2);

    /* Start playback and capture, and enter the audio loop */
    alSourcePlay(source);
    alcCaptureStart(dev[1]);

    while(1) 
    {
        /* Check if any queued buffers are finished */
        alGetSourcei(source, AL_BUFFERS_PROCESSED, &val);
        if(val <= 0)
            continue;

        /* Check how much audio data has been captured (note that 'val' is the
        * number of frames, not bytes) */
        alcGetIntegerv(dev[1], ALC_CAPTURE_SAMPLES, 1, &val);

        /* Read the captured audio */
        alcCaptureSamples(dev[1], data, val);

        /* Pop the oldest finished buffer, fill it with the new capture data,
        then re-queue it to play on the source */
        alSourceUnqueueBuffers(source, 1, &buf);
        alBufferData(buf, AL_FORMAT_MONO16, data, val*2 /* bytes here, not
        frames */, 22050);
        alSourceQueueBuffers(source, 1, &buf);

        /* Make sure the source is still playing */
        alGetSourcei(source, AL_SOURCE_STATE, &val);

        if(val != AL_PLAYING)
        {

            alSourcePlay(source);
        }
    }

    /* Shutdown and cleanup */
    alcCaptureStop(dev[1]);
    alcCaptureCloseDevice(dev[1]);

    alSourceStop(source);
    alDeleteSources(1, &source);
    alDeleteBuffers(3, buffers);

    alcMakeContextCurrent(NULL);
    alcDestroyContext(ctx);
    alcCloseDevice(dev[0]); 

    return 0;
} 

如何创建这样的东西 - 我必须更改/添加什么到我的代码中?

I have such code for doing echo of microphone with openAL on windows.

I want to create some CapturedAudioData file to write all audio data captured during the loop. So its going to be like unformated PCM. And I need it to be filled up 25 times per second.

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <al.h>
#include <alc.h>
using namespace std;
int main()
{
    ALCdevice *dev[2];
    ALCcontext *ctx;
    ALuint source, buffers[3];
    char data[5000]; 
    ALuint buf;
    ALint val;

    dev[0] = alcOpenDevice(NULL);
    ctx = alcCreateContext(dev[0], NULL);
    alcMakeContextCurrent(ctx);

    alGenSources(1, &source);
    alGenBuffers(3, buffers);

    /* Setup some initial silent data to play out of the source */
    alBufferData(buffers[0], AL_FORMAT_MONO16, data, sizeof(data), 22050);
    alBufferData(buffers[1], AL_FORMAT_MONO16, data, sizeof(data), 22050);
    alBufferData(buffers[2], AL_FORMAT_MONO16, data, sizeof(data), 22050);
    alSourceQueueBuffers(source, 3, buffers);

    /* If you don't need 3D spatialization, this should help processing time */
    alDistanceModel(AL_NONE); 

    dev[1] = alcCaptureOpenDevice(NULL, 22050, AL_FORMAT_MONO16, sizeof(data)/2);

    /* Start playback and capture, and enter the audio loop */
    alSourcePlay(source);
    alcCaptureStart(dev[1]);

    while(1) 
    {
        /* Check if any queued buffers are finished */
        alGetSourcei(source, AL_BUFFERS_PROCESSED, &val);
        if(val <= 0)
            continue;

        /* Check how much audio data has been captured (note that 'val' is the
        * number of frames, not bytes) */
        alcGetIntegerv(dev[1], ALC_CAPTURE_SAMPLES, 1, &val);

        /* Read the captured audio */
        alcCaptureSamples(dev[1], data, val);

        /* Pop the oldest finished buffer, fill it with the new capture data,
        then re-queue it to play on the source */
        alSourceUnqueueBuffers(source, 1, &buf);
        alBufferData(buf, AL_FORMAT_MONO16, data, val*2 /* bytes here, not
        frames */, 22050);
        alSourceQueueBuffers(source, 1, &buf);

        /* Make sure the source is still playing */
        alGetSourcei(source, AL_SOURCE_STATE, &val);

        if(val != AL_PLAYING)
        {

            alSourcePlay(source);
        }
    }

    /* Shutdown and cleanup */
    alcCaptureStop(dev[1]);
    alcCaptureCloseDevice(dev[1]);

    alSourceStop(source);
    alDeleteSources(1, &source);
    alDeleteBuffers(3, buffers);

    alcMakeContextCurrent(NULL);
    alcDestroyContext(ctx);
    alcCloseDevice(dev[0]); 

    return 0;
} 

How to create such thing - what I have to change/add to my code?

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

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

发布评论

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

评论(1

朦胧时间 2024-10-07 11:09:14

看来您需要做的就是将 val 样本从 data 缓冲区写入文件,而不是将它们发送到输出。即用文件写入替换以“Pop the old...”注释开头的代码。计算您写入的样本:每当您达到(25 秒 * 22050 个样本/秒)值时,它就被“填满”。

It appears that all you need to do is write val samples from the data buffer to a file, instead of sending them to the output. i.e. replace the code starting with the "Pop the oldest..." coment with a file write. Count the samples you write: whenever you get to (25 sec * 22050 samples/sec) values, it is "filled up".

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