[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