使用OpenAL记录最低质量?

时间:2015-12-30 04:08:10

标签: c++ audio openal

我目前正在使用这些设置与OpenAL并从Mic录制:

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

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

2 个答案:

答案 0 :(得分:0)

我不确定但对我来说FREQ是输出频率而不是采样率。 定义采样率48000 请看这个链接:http://supertux.lethargik.org/wiki/OpenAL_Configuration

答案 1 :(得分:0)

好吧,所以这是我写过的一些最讨厌的代码,我真的希望没有一个心智正常的人在生产中使用它......只是太多糟糕的事情。

但是为了回答你的问题,我已经能够将质量降低到825Moo录制到11025.然而,我从麦克风录制的所有内容都带有大量静电,我不完全确定我知道为什么。我已经生成了8bit karplus强劲的弦乐音色,听起来很棒,所以它可能只是我的录音设备。

#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);

我已经证实了这种情况。对于演示代码,我可以把这个例子放在那里,但我不会在生产中使用它。