Re: blocking / non-blocking capturing
Chris Robinson <[email protected]> Fri, 27 Jul 2012 15:03:54 -0700
| Newsgroups | gmane.comp.lib.openal |
|---|---|
| Message-ID | <[email protected]> |
On 07/27/2012 07:51 AM, Kraus Philipp wrote:
> Hello,
>
> I'm new with OpenAL and I would like to record data to analyse the frequency of the data samples. I'm using also C++.
> So my first question is: Exists a blocking capture function?
There isn't. It's easy enough to make your own blocking capture
function, though.
> Is my example correct to read the data? This loops are within a thread, so after the data is received I normalized
> the data in [-1,1], so I think audio that will get by the device are not cached.
The main problems I see are:
> boost::shared_ptr<ALint> l_buffer( new ALint[p_buffersize] );
A shared_ptr isn't for arrays. It'll call delete when it's finished with
instead of delete[], and you should avoid mixing new[] with delete. I
think boost may have another type designed for arrays, though, or you
can put an std::vector in there instead.
Second, you should use a type matching the sample format. This is
typically 16-bit, which should be ALshort.
Also, it may be a good idea to check for the ALC_EXT_disconnect[1]
extension so you can detect if the device becomes lost, to avoid an
infinite loop while waiting for more data that never comes.
> AlUInt l_samplesread = 0;
> alcGetIntegerv(mydevice, ALC_CAPTURE_SAMPLES,
&l_samplesread);
> if (l_samplesread > 0) {
> alcCaptureSamples(mydevice,
(ALCvoid*)l_buffer+i, l_samplesread);
> i += l_samplesread;
> }
You should also clamp l_samplesread so you don't write past the end of
the buffer.
Something like this (untested!):
boost::shared_ptr< std::vector<ALshort> > l_buffer( new
std::vector<ALshort>(p_buffersize) );
while(m_capturing)
{
std::size_t i=0;
while(i < p_puffersize)
{
ALint l_samplesread = 0;
alcGetIntegerv(mydevice, ALC_CAPTURE_SAMPLES, &l_samplesread);
if(l_samplesread > 0)
{
l_samplesread = std::min(l_samplesread, p_buffersize-i);
alcCaptureSamples(mydevice, (ALCvoid*)(l_buffer->data()+i),
l_samplesread);
i += l_samplesread;
}
else if(alcIsExtensionPresent(mydevice, "ALC_EXT_disconnect")
{
ALint connected = 0;
alcGetIntegerv(mydevice, ALC_CONNECTED, &connected);
if(!connected)
{
std::fill(l_buffer->begin()+i, l_buffer->end(), 0);
m_capturing = false;
break;
}
}
// wait for other threads
boost::this_thread::yield();
}
... do something with the buffer....
}
Hopes that helps. :)
[1] http://icculus.org/alextreg/wiki/ALC_EXT_disconnect
_______________________________________________
Openal mailing list
[email protected]
http://opensource.creative.com/mailman/listinfo/openal