Hi Toradex Community,
I’m creating a separate topic from Audio output with TorizonCore - Technical Support - Toradex Community, but could still relate to the last few posts on that thread.
See below the configuration I am currently working with:
- Apalis iMX6
- Ixora Carrier Board v1.2
- TorizonCore v6.1.0 Build 1
- Custom container with Qt application
Here’s a bit of context:
I was working on outputting sounds to the correct ALSA device, but since the primitives classes of Qt, such as QSound, QSoundEffect and QMediaplayer, attempt to connect to a PulseAudio server by default, a simple play() call wasn’t an option in the case of Torizon images.
I therefore started to work on my own SoundManager with the use of QAudioOutput, QAudio format and QBuffer.
The main portion of my code to play a sound can be seen below. See under the code snippet for a summary.
QFile* m_audioFile;
QAudioOutput* audio;
QBuffer audio_buffer;
QByteArray audio_data;
void SoundManager::playAudio()
{
m_audioFile = new QFile("/eclipse_qml/startup-sound.wav");
if(m_audioFile->open(QIODevice::ReadOnly)) {
m_audioFile->seek(44); // skip wav header
audio_data = m_audioFile->readAll();
m_audioFile->close();
audio_buffer.setBuffer(&audio_data);
audio_buffer.open(QIODevice::ReadOnly);
qDebug() << "Audio Buffer Size: " << audio_buffer.size();
QAudioFormat format;
// Set up the format, eg.
format.setSampleRate(44100);
format.setChannelCount(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
// Fetch Audio Device List
QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
foreach (QAudioDeviceInfo i, devices){
// Find desired Audio device
if(i.deviceName() == "sysdefault:CARD=imx6qapalissgtl")
{
qDebug() << "Attempting to play on device: " << i.deviceName() << Qt::endl;
// Format support check
if (!i.isFormatSupported(format)) {
qDebug() << "Raw audio format not supported by backend, cannot play audio." << Qt::endl;
return;
}
else{
qDebug() << "Format supported" << Qt::endl;
// Load source file and play audio
audio = new QAudioOutput(i, format, this);
connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
audio->start(&audio_buffer);
qDebug() << "Sound Player Started" << Qt::endl;
break;
}
}
}
}
}
Basically, I execute the following:
- Read my .wav audio file into a buffer
- Setup the audio format supported by the iMX6 desired ALSA sound device
- Fetch the Audio Device Info and use it for my QAudioOutput object.
- Load and play the sound saved in my buffer.
Executing this works and I can now hear my application sounds.
However, I hear a few audio mishaps, pops and cracks and a bunch of ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred
messages.
Upon doing some research, I see that for some people playing Audio via QT on Linux ARM usually get this because the ALSA default buffer size isn’t large enough, so data is lost.
So my question is, is there a way on Torizon to help increase this buffer size? I’m posting here since I don’t think this issue is from Qt.