Openal: How to Create Simple "Microphone Echo" Programm

Record Lowest quality possible with OpenAL?

Alright, so this is some of the most hacky code I've ever written, and I truly hope no one in their right mind ever uses it in production... just sooooo many bad things.

But to answer your question, I've been able to get the quality down to 8bitMono recording at 11025. However, everything I've recorded from my mic comes with significant amounts of static, and I'm not entirely sure I know why. I've generated 8bit karplus-strong string plucks that sound fantastic, so it could just be my recording device.

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

As you can see from:

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

I've verified that this is the case. For demonstration code I'm okay throwing this example out there, but I wouldn't ever use it in production.

Circular buffers in OpenAL

Actually circular buffers in OpenAL are much different than for DirectSound.

In OpenAL, you must queue sound buffers, one after the other. You really only need 2 sound buffers then, and you just continuously call alSourceQueueBuffers and alSourceUnqueueBuffers.

Queuing Buffers on a Source
To continuously stream audio from a source without interruption, buffer queuing is required. To
use buffer queuing, the buffers and sources are generated in the normal way, but alSourcei is not
used to attach the buffers to the source. Instead, the functions alSourceQueueBuffers and
alSourceUnqueueBuffers are used. The program can attach a buffer or a set of buffers to a
source using alSourceQueueBuffers, and then call alSourcePlay on that source. While the
source is playing, alSourceUnqueueBuffers can be called to remove buffers which have already
played. Those buffers can then be filled with new data or discarded. New or refilled buffers can
then be attached to the playing source using alSourceQueueBuffers. As long as there is always
a new buffer to play in the queue, the source will continue to play.

Why such OpenAL code gives such Erros in Visual studio 2008?

You need to link the OpenAL library to your application.

Go into project properties->Linker->Input and add openal32.lib to the list.



Related Topics



Leave a reply



Submit