gpt4 book ai didi

c++ - OpenAL播放捕获的音频数据c++

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:47:42 27 4
gpt4 key购买 nike

我正在尝试使用 OpenAL 创建一个语音聊天程序。网络方面似乎没问题,但我会就此征求意见 =]

我目前遇到的问题是尝试播放从麦克风捕获的音频数据。我按照找到的代码 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 中有很多数据,此时播放了一秒钟的噪音,但与捕获的噪音相去甚远。

编辑:我添加了行

alGenBuffers(1, &tempPlayback);

在创建 tempPlayback 之后和调用 alBufferData(...) 之前,它现在播放了正确的时间量,但我听到的只是整个播放过程中的尖锐噪音。

最佳答案

这是一个非常简单的程序,可以捕获 5 秒的音频,暂停,然后再捕获 5 秒的音频,最后全部播放返回(我用它来调试一次捕获问题)。

它适用于 mint 13 linux 笔记本电脑。 Mint 就像 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);
}

用这个编译:

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

关于c++ - OpenAL播放捕获的音频数据c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9886668/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com