使用 OpenAL 记录可能的最低质量?

Record Lowest quality possible with OpenAL?

我目前正在将这些设置与 OpenAL 一起使用并从麦克风录音:

BUFFERSIZE 4410 
FREQ 22050   // Sample rate
CAP_SIZE 10000 // How much to capture at a time (affects latency)
AL_FORMAT_MONO16

是否可以降低录音质量?我试过降低采样率,但最终结果是播放速度更快。

我不确定,但对我来说 FREQ 是输出频率而不是采样率。 定义 sampling-rate 48000 看到这个 link : http://supertux.lethargik.org/wiki/OpenAL_Configuration

好吧,这是我写过的最骇人听闻的代码之一,我真的希望没有任何头脑正常的人在生产中使用它……只是有太多不好的地方了。

但是为了回答你的问题,我已经能够在 11025 下将质量降低到 8bitMono 录音。但是,我从我的麦克风录制的所有内容都带有大量的静电,而且我并不完全我当然知道为什么。我生成了 8 位 karplus-strong 弦乐弹奏,听起来很棒,所以它可能只是我的录音设备。

#include <AL/al.h>
#include <AL/alc.h>
#include <conio.h>
#include <stdio.h>
#include <vector>
#include <time.h>

void sleep( clock_t wait )
{
   clock_t goal;
   goal = wait + clock();
   while( goal > clock() )
      ;
}

#define BUFFERSIZE  4410
const int SRATE = 11025;

int main()
{
    std::vector<ALchar> vBuffer;
    ALCdevice       *pDevice = NULL;
    ALCcontext      *pContext = NULL;
    ALCdevice       *pCaptureDevice;
    const ALCchar   *szDefaultCaptureDevice;
    ALint           iSamplesAvailable;
    ALchar          Buffer[BUFFERSIZE];
    ALint           iDataSize = 0;
    ALint           iSize;

    // NOTE : This code does NOT setup the Wave Device's Audio Mixer to select a recording input
    // or a recording level.

    pDevice = alcOpenDevice(NULL);
    pContext = alcCreateContext(pDevice, NULL);
    alcMakeContextCurrent(pContext);

    printf("Capture Application\n");

    if (pDevice == NULL)
    {
        printf("Failed to initialize OpenAL\n");
        //Shutdown code goes here
        return 0;
    }

    // Check for Capture Extension support
    pContext = alcGetCurrentContext();
    pDevice = alcGetContextsDevice(pContext);
    if (alcIsExtensionPresent(pDevice, "ALC_EXT_CAPTURE") == AL_FALSE){
        printf("Failed to detect Capture Extension\n");
        //Shutdown code goes here
        return 0;
    }

    // Get list of available Capture Devices
    const ALchar *pDeviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
    if (pDeviceList){
        printf("\nAvailable Capture Devices are:-\n");

        while (*pDeviceList)
        {
            printf("%s\n", pDeviceList);
            pDeviceList += strlen(pDeviceList) + 1;
        }
    }

    // Get the name of the 'default' capture device
    szDefaultCaptureDevice = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
    printf("\nDefault Capture Device is '%s'\n\n", szDefaultCaptureDevice);

    pCaptureDevice = alcCaptureOpenDevice(szDefaultCaptureDevice, SRATE, AL_FORMAT_MONO8, BUFFERSIZE);
    if (pCaptureDevice)
    {
        printf("Opened '%s' Capture Device\n\n", alcGetString(pCaptureDevice, ALC_CAPTURE_DEVICE_SPECIFIER));

        // Start audio capture
        alcCaptureStart(pCaptureDevice);

        // Wait for any key to get pressed before exiting
        while (!_kbhit())
        {
            // Release some CPU time ...
            sleep(1);

            // Find out how many samples have been captured
            alcGetIntegerv(pCaptureDevice, ALC_CAPTURE_SAMPLES, 1, &iSamplesAvailable);

            printf("Samples available : %d\r", iSamplesAvailable);

            // When we have enough data to fill our BUFFERSIZE byte buffer, grab the samples
            if (iSamplesAvailable > (BUFFERSIZE / 2))
            {
                // Consume Samples
                alcCaptureSamples(pCaptureDevice, Buffer, BUFFERSIZE / 2);

                // Write the audio data to a file
                //fwrite(Buffer, BUFFERSIZE, 1, pFile);
                for(int i = 0; i < BUFFERSIZE / 2; i++){
                    vBuffer.push_back(Buffer[i]);
                }

                // Record total amount of data recorded
                iDataSize += BUFFERSIZE / 2;
            }
        }

        // Stop capture
        alcCaptureStop(pCaptureDevice);

        // Check if any Samples haven't been consumed yet
        alcGetIntegerv(pCaptureDevice, ALC_CAPTURE_SAMPLES, 1, &iSamplesAvailable);
        while (iSamplesAvailable)
        {
            if (iSamplesAvailable > (BUFFERSIZE / 2))
            {
                alcCaptureSamples(pCaptureDevice, Buffer, BUFFERSIZE / 2);
                for(int i = 0; i < BUFFERSIZE/2; i++){
                    vBuffer.push_back(Buffer[i]);
                }
                iSamplesAvailable -= (BUFFERSIZE / 2);
                iDataSize += BUFFERSIZE;
            }
            else
            {
                //TODO::Fix
                alcCaptureSamples(pCaptureDevice, Buffer, iSamplesAvailable);
                for(int i = 0; i < BUFFERSIZE/2; i++){
                    vBuffer.push_back(Buffer[i]);
                }
                iDataSize += iSamplesAvailable * 2;
                iSamplesAvailable = 0;
            }
        }

        alcCaptureCloseDevice(pCaptureDevice);
    }

    //TODO::Make less hacky
    ALuint bufferID;                        // The OpenAL sound buffer ID
    ALuint sourceID;                        // The OpenAL sound source

    // Create sound buffer and source
    alGenBuffers(1, &bufferID);
    alGenSources(1, &sourceID);

    alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
    alSource3f(sourceID, AL_POSITION, 0.0f, 0.0f, 0.0f);

    alBufferData(bufferID, AL_FORMAT_MONO8, &vBuffer[0], static_cast<ALsizei>(vBuffer.size()), SRATE);

    // Attach sound buffer to source
    alSourcei(sourceID, AL_BUFFER, bufferID);

    // Finally, play the sound!!!
    alSourcePlay(sourceID);

    printf("Press any key to continue...");
    getchar();

    return 0;
}

从中可以看出:

alBufferData(bufferID, AL_FORMAT_MONO8, &vBuffer[0], static_cast<ALsizei>(vBuffer.size()), SRATE);

我已经确认是这样的。对于演示代码,我可以将此示例放在那里,但我永远不会在生产中使用它。