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