[Qt-interest] "Decoding" PCM samples from QAudioInput

Josiah Bryan jbryan at productiveconcepts.com
Tue Oct 6 14:24:38 CEST 2009


Hi All -

I've got this idea to listen to incoming audio and analyze it for beats 
inorder to add some "life" to my onscreen animation. I envision a class 
where I can just connect to a signal like "beatDetected(float strength)" 
and let the beat algorithm and audio code sit on one side of the wall, 
and the animation on the other. All well and good.

So, to start out, I've taken a look at QAudioInput and friends from Qt 
4.6. Compiles great, runs fine. I can only get the "audio/pcm" codec to 
work on windows. According to this block, it's all that my computer 
supports anyway (or at least, Qt supports):

	QList<QAudioDeviceId> list = 
QAudioDeviceInfo::deviceList(QAudio::AudioInput);
	foreach(QAudioDeviceId devid, list)
	{
		QAudioDeviceInfo deviceInfo(devid);
		qDebug() << "Device name: " << deviceInfo.deviceName();
		QStringList codecs = deviceInfo.supportedCodecs();
		qDebug() << "       Supported Codecs: "<<codecs;
	}

The part I'm having trouble with, and that I'd like to get advice on is 
this:

How do I get at the individual sample values in the output buffer?

Here's what I've tried:

I've set up my format like this:

	format.setFrequency(8000);
	format.setChannels(1);
	format.setSampleSize(8);

	format.setCodec("audio/pcm");
	format.setByteOrder(QAudioFormat::LittleEndian);
	format.setSampleType(QAudioFormat::UnSignedInt);

Then I use a QBuffer to wrap a QByteArray, and pass the QBuffer to the 
QAudioInput::start() method, then set a timer to check the QBuffer every 
X ms (right now, 50ms).

Here's where I get stuck:

With this code, I was just trying to print out an average of the samples 
in the buffer. I thought since this was one channel and (it seems) 8 
bits to a sample, then the below code should work to average it out. The 
sample represents a "volume" of sort ("energy" I guess), so the below 
code, you could say, should print the avg volume of each 50ms sample.

	int sz = byteArray.size();
	int sum = 0;
	char * data = byteArray.data();
	for(int i=0;i<sz;i++)
	    sum += (int)data[i];
	int avg = sz == 0 ? 0 : sum / sz;
	byteArray.clear();
	buffer.seek(0);

	qDebug() << "SampleIO: bytes: "<<sz<<", avg:"<<avg;

Now, the more "low level" I get, the worse off my working knowledge gets 
- so I'm sure I'm making some wrong assumptions and or just plain stupid 
mistakes up there - but where? The code compiles and runs fine - just 
the numbers jump positive to negative and back - and they don't seem to 
respond to extreme environmental sound changes (e.g. a clap or what not.)

Thanks for your time. Cheers!
-josiah

-- 

-=-=-=-=-=-=-=-=-=-=-=-=-
Josiah Bryan
Productive Concepts, Inc.
jbryan at pciint.com
(765) 964-6009, ext. 224




More information about the Qt-interest-old mailing list