OpenAL Playback from C ++ Audio Data

I am trying to create a voice chat program using OpenAL. The network side of things seems to be in order, but I will consult this =]

Currently, the problem is trying to play the captured audio data from the microphone. I executed the code here to get the mic input and respond to the speakers.

This works fine, but I cannot play a fully recorded sound after the recording is complete.

When a sound is captured, I store it on a list like this ...

for (int i = 0; i < CAP_SIZE; i++) { playbackBuffer.push_back( buffer[i] ); } 

and then after the capture was completed I tried (and could not) use the following code to play this sound back

 ALuint playbackSource; alGenSources(1, &playbackSource); errorCode = alGetError(); ALuint tempPlayback; alBufferData(tempPlayback, AL_FORMAT_MONO16, &playbackBuffer.front(), playbackBuffer.size()*sizeof(ALuint), FREQ); // Attach the playback buffer to the new playback source alSourcei(playbackSource, AL_BUFFER, tempPlayback); alSourcePlay(playbackSource); ALint sState = 0; do { alGetSourcei(playbackSource, AL_SOURCE_STATE, &sState); } while ((sState == AL_PLAYING)); 

When debugging, I see that the Buffer playback has a lot of data, and at that moment there is a fraction of a second noise, but nowhere near what was recorded.

EDIT: I added a line

 alGenBuffers(1, &tempPlayback); 

after creating tempPlayback and before calling alBufferData (...), and now it plays for the required amount of time, but all I hear is the high noise all the way.

+4
source share
3 answers

Here's a really simple program that captures audio for 5 seconds, pauses, then captures another 5 seconds of audio, and finally plays it back (I used it to debug the capture problem once).

He worked on a linux laptop for mint 13. Mint is similar to ubuntu 12.04

 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <AL/al.h> #include <AL/alc.h> #include <sys/time.h> #include <ctime> int main(void) { const ALCchar * devices; const ALCchar * ptr; ALCdevice * mainDev; ALCcontext * mainContext; ALCdevice * captureDev; ALubyte captureBuffer[1048576]; ALubyte *captureBufPtr; ALint samplesAvailable; ALint samplesCaptured; time_t currentTime; time_t lastTime; ALuint buffer; ALuint source; ALint playState; int i; // Print the list of capture devices printf("Available playback devices:\n"); devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER); ptr = devices; //while (ptr[0] != NULL) while (*ptr) { printf(" %s\n", ptr); ptr += strlen(ptr) + 1; } // Open a playback device and create a context first printf("Opening playback device:\n"); mainDev = alcOpenDevice(NULL); if (mainDev == NULL) { printf("Unable to open playback device!\n"); exit(1); } devices = alcGetString(mainDev, ALC_DEVICE_SPECIFIER); printf(" opened device '%s'\n", devices); mainContext = alcCreateContext(mainDev, NULL); if (mainContext == NULL) { printf("Unable to create playback context!\n"); exit(1); } printf(" created playback context\n"); // Make the playback context current alcMakeContextCurrent(mainContext); alcProcessContext(mainContext); // Print the list of capture devices printf("Available capture devices:\n"); devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); ptr = devices; //while (ptr[0] != NULL) while (*ptr) { printf(" %s\n", ptr); ptr += strlen(ptr) + 1; } // Open the default device printf("Opening capture device:\n"); captureDev = alcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO16, 800); if (captureDev == NULL) { printf(" Unable to open device!\n"); exit(1); } devices = alcGetString(captureDev, ALC_CAPTURE_DEVICE_SPECIFIER); printf(" opened device %s\n", devices); // Wait for three seconds to prompt the user for (i = 3; i > 0; i--) { printf("Starting capture in %d...\r", i); fflush(stdout); lastTime = time(NULL); currentTime = lastTime; while (currentTime == lastTime) { currentTime = time(NULL); usleep(100000); } } printf("Starting capture NOW!\n"); fflush(stdout); lastTime = currentTime; // Capture (roughly) five seconds of audio alcCaptureStart(captureDev); samplesCaptured = 0; captureBufPtr = captureBuffer; while (currentTime < (lastTime + 5)) { // Get the number of samples available alcGetIntegerv(captureDev, ALC_CAPTURE_SAMPLES, 1, &samplesAvailable); // Copy the samples to our capture buffer if (samplesAvailable > 0) { alcCaptureSamples(captureDev, captureBufPtr, samplesAvailable); samplesCaptured += samplesAvailable; printf("Captured %d samples (adding %d)\r", samplesCaptured, samplesAvailable); fflush(stdout); // Advance the buffer (two bytes per sample * number of samples) captureBufPtr += samplesAvailable * 2; } // Wait for a bit usleep(10000); // Update the clock currentTime = time(NULL); } printf("\nPausing capture.\n"); alcCaptureStop(captureDev); // Wait for three seconds to prompt the user for (i = 3; i > 0; i--) { printf("Resuming capture in %d...\r", i); fflush(stdout); lastTime = time(NULL); currentTime = lastTime; while (currentTime == lastTime) { currentTime = time(NULL); usleep(100000); } } printf("Resuming capture NOW!\n"); fflush(stdout); lastTime = currentTime; // Capture (roughly) five seconds of audio alcCaptureStart(captureDev); while (currentTime < (lastTime + 5)) { // Get the number of samples available alcGetIntegerv(captureDev, ALC_CAPTURE_SAMPLES, 1, &samplesAvailable); // Copy the samples to our capture buffer if (samplesAvailable > 0) { alcCaptureSamples(captureDev, captureBufPtr, samplesAvailable); samplesCaptured += samplesAvailable; printf("Captured %d samples (adding %d)\r", samplesCaptured, samplesAvailable); fflush(stdout); // Advance the buffer (two bytes per sample * number of samples) captureBufPtr += samplesAvailable * 2; } // Wait for a bit usleep(10000); // Update the clock currentTime = time(NULL); } printf("\nDone capturing.\n"); alcCaptureStop(captureDev); // Play back the captured data printf("Starting playback...\n"); fflush(stdout); // Generate an OpenAL buffer for the captured data alGenBuffers(1, &buffer); alGenSources(1, &source); alBufferData(buffer, AL_FORMAT_MONO16, captureBuffer,samplesCaptured*2, 8000); alSourcei(source, AL_BUFFER, buffer); alSourcePlay(source); // Wait for the source to stop playing playState = AL_PLAYING; while (playState == AL_PLAYING) { printf(" source %d is playing...\r", source); fflush(stdout); alGetSourcei(source, AL_SOURCE_STATE, &playState); usleep(100000); } printf("\nDone with playback.\n"); fflush(stdout); // Shut down OpenAL alDeleteSources(1, &source); alDeleteBuffers(1, &buffer); alcMakeContextCurrent(NULL); alcCloseDevice(mainDev); alcCaptureCloseDevice(captureDev); } 

Compile with this:

 g++ p.cpp -lalut -lopenal -op 
+5
source
 // Compile as: g++ p.cpp -lalut -lopenal -op //runs on ubuntu linux for around 2 seconds #include <AL/al.h> // OpenAL header files #include <AL/alc.h> //#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; float ttotal; unsigned int ccount; long int c1ount; c1ount =0; 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); //22050 mean 22.050 samples per second. or 44100 for 44.1 per second. /* Start playback and capture, and enter the audio loop */ alSourcePlay(source); alcCaptureStart(dev[1]); //starts ring buffer 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); //***** Process/filter captured data here *****// c1ount = c1ount +1; if(c1ount >= 33){ break; } //for (int ii=0;ii<val;++ii) { // data[ii]*=0.1; // Make it quieter //} //***** end Process/filter captured data here *****// /* 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); } } cout<< "fgggggggg\n"; /* Shutdown and cleanup */ alcCaptureStop(dev[1]); alcCaptureCloseDevice(dev[1]); alSourceStop(source); alDeleteSources(1, &source); alDeleteBuffers(3, buffers); alDeleteBuffers(1, &buf); alcMakeContextCurrent(NULL); alcDestroyContext(ctx); alcCloseDevice(dev[0]); return 0; 

}

0
source

The only programs that record from a microphone that I could find on the Internet are the one you started with and the one I sent you. I’m going in the same direction as you. The code you sent is what I am trying to change. And I come from stackoverflow. I found the code we want in the curved BASIC programming language, but I am not a good language. link:

  http://www.blitzbasic.com/Community/posts.php?topic=90830 If you can get it to work that would be great. And even better, if it could be change over to c/c++. I have been looking for microphone capture programs for around two years. Waiting for some thing simple to come along. So now I am focusing on the these programs to figure how they work with debugger and test subroutines figure out the dynamics of freealut. because I do not see any thing simple comming along any time soon. OpenAL is the only software I cold get to work. the documentation provided by Creative web site is good referance for some one who is already an expert with the software. I could not get FBOD, alas, SDL, Allegro4, or OSS to work because of a lack of working examples, or no good information. Good luck. keghn 
0
source

Source: https://habr.com/ru/post/1403620/


All Articles