2012-03-27 1 views
4

Я пытаюсь создать программу голосового чата с использованием OpenAL. Сетевая сторона вещей, похоже, в порядке, но я буду советоваться с этим =]Воспроизведение в режиме OpenAL с записанными аудио данными C++

Проблема, которую я сейчас испытываю, заключается в попытке воспроизведения захваченных аудиоданных с микрофона. Я следил за кодом, найденным here, чтобы получить вход микрофона и повторить его для динамиков.

Это работает нормально, но я не могу воспроизвести полностью записанный звук после завершения захвата.

Когда какой-то звук был захвачен я сохраняю его в список, как так ...

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

, а затем после захвата закончил я пытался (и не удалось) использовать следующий код, чтобы играть в том, что аудио назад

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

при отладке я могу видеть, что playbackBuffer имеет много данных в нем и есть раскол второго шума играл в этой точке, но далеко не то, что был взят в плен.

EDIT: Я добавил линию

alGenBuffers(1, &tempPlayback); 

после создания tempPlayback и перед вызовом alBufferData (...), и это в настоящее время играет за правильное количество времени, но все, что я слышу высокий -pitched шум весь путь.

ответ

0
// Compile as: g++ p.cpp -lalut -lopenal -o p 
//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

Спасибо за ваш ответ, но я чувствую, что я, возможно, не объяснил себя должным образом. Я получил код в ссылке, которую я опубликовал для работы, которая воспроизводит звук одновременно с записью, мне нужно сохранить записанный звук, а затем, когда запись закончена, затем воспроизведите ее. Как уже упоминалось, окончательным результатом этого проекта будет программа стиля голосового чата, поэтому я планирую записать фрагмент звука, отправив этот фрагмент по сети во время записи следующего, а затем этот фрагмент будет воспроизводиться с другой стороны. Опять же, спасибо за помощь. – Ralara

0

Единственные программы, запись с микрофона, что я мог бы найти на веб-сайте, являются один вы начали и один я послал к вам. Я как бы иду в том же направлении, что и вы. код I, отправленный вами, является одним из . Я пытаюсь изменить. И я иду от stackoverflow. Я нашел код, который нам нужен, на искривленном языке программирования BASIC, , но я не очень хороший язык. ссылка является:

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

Не удалось найти ни одного из тех, кто работает, как хотелось: = \ на хорошей стороне мне удалось что-то сделать, используя TeamSpeak 3 sdk [link] (http://www.teamspeak.com/), это очень хорошо обрабатывает захват/сеть/воспроизведение, и документация также полезна. Это бесплатно для любителей использовать (не уверен, что это покрывает себя), но требует лицензии для коммерческого использования. – Ralara

5

Вот очень простая программа, которая захватывает аудио в течение 5 секунд, пауз, затем захватывает больше 5 секунд звука, и, наконец, играет все его обратно (я использовал его для отладки проблемы с захватить один раз).

Он работал на ноутбуке с ноутбуком mint 13 linux. Мята, как убунту 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 с этим:

g++ p.cpp -lalut -lopenal -o p 

 Смежные вопросы

  • Нет связанных вопросов^_^