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