OpenAL回放捕获的音频数据c++
OpenAL playback captured audio data c++
我正在尝试使用OpenAL创建一个语音聊天程序。网络方面的事情似乎还可以,但我会接受这方面的建议
我现在遇到的问题是试图从麦克风播放捕获的音频数据。我按照这里找到的代码获取麦克风输入并将其回声到扬声器。
这还可以,但在捕获完成后,我似乎无法播放完全捕获的音频。
当捕捉到一些声音时,我会将其存储在一个列表中,比如…
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笔记本电脑上运行。薄荷就像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(" %sn", 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 contextn");
// 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(" %sn", 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 %sn", 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
// 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<< "fggggggggn";
/* 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;
}
我可以从麦克风录制的唯一程序在网上找到的是你刚开始的和我发给你的。我正朝着和你一样的方向前进。发送给你的I代码就是我正在尝试修改。我从斯塔克弗流开始。我用一种扭曲的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
相关文章:
- 捕获音频数据并保存到AudioFlinger中的原始PCM文件
- 如何将 cdparanoia 读取的 CD 音频数据移交给 ALSA 播放器?
- 如何将静默音频数据写入音频流
- 使用FFMPEG编写多线程视频和音频数据包
- 以选定的比特率发送音频数据 - 喊播
- 使用C 中的套接字通过网络发送音频数据
- C++将音频数据发送到Linux和Mac OS X上的扬声器输出
- 使用C++(基于C#程序)保存wav文件时,音频数据不正确
- FFmpeg:编码PCM 16音频数据分配错误
- 如何在Raspberry Pi上用C++将接收到的UDP音频数据正确写入ALSA
- 实时录制/转换音频数据到WAV
- 端口音频遍历音频数据
- 在 C++ 中使用 libsndfile 从 WAV 文件中提取原始音频数据
- 如何用音频数据填充AVFrame
- 如何获取 mp3 音频数据包以在 C/C++ 中流式传输
- OpenAL回放捕获的音频数据c++
- 如何从Tizen上的实时FFT中获得最准确的音频数据?
- 如何使用Windows内置的mp3解码器访问原始解码音频数据?
- 播放产生的音频数据在声音中有噪音和周期性的咔嗒声
- 音频数据?我需要一个典型的例子