Re: blocking / non-blocking capturing

Philipp Kraus <[email protected]> Sat, 28 Jul 2012 22:41:46 +0200
Newsgroups gmane.comp.lib.openal
Message-ID <[email protected]>
On 2012-07-28 00:03:54 +0200, Chris Robinson said:

> 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. :)


I have created this code:

std::vector<ALshort> l_buffer(p_buffersize);
for(std::size_t i=0; i < l_buffer.size(); )
{
	ALint l_samplesread = 0;
    alcGetIntegerv(l_capturedevice, ALC_CAPTURE_SAMPLES, 
static_cast<ALCsizei>(sizeof(ALint)), &l_samplesread);
            
	/*
    if ( (!l_samplesread) && (alcIsExtensionPresent(l_capturedevice, 
"ALC_EXT_disconnect")) )
    {
    	ALint l_connected = 0;
        alcGetIntegerv(l_capturedevice, ALC_CONNECTED, 
static_cast<ALCsizei>(sizeof(ALint)), &l_connected);
        if(!l_connected)
        	throw std::runtime_error("audio device is disconnected");
	}
    */
            
	if (l_samplesread > 0)
    {
    	l_samplesread = std::min( static_cast<std::size_t>(l_samplesread), 
l_buffer.size()-i);
        alcCaptureSamples(l_capturedevice, (ALCvoid*)(&l_buffer[i]), 
l_samplesread);
        i += l_samplesread;
	}
            
	boost::this_thread::yield();
}

If I show my l_buffer values, it generates always the same data, so it 
seems, I have created an error dyring the alcCaptureSamples
or the interface results wrong data. 
I have initializate my interface with the sampling frequency 44.1k and 
mono 8 bit. The interface is named on OSX with "CoreAudio Default".

Can you help my to find out which mistake I have made?

Thanks

Phil

_______________________________________________
Openal mailing list
[email protected]
http://opensource.creative.com/mailman/listinfo/openal