Good morning @imeshsps and @jeremias.tx ,
I’ve attempted playing around with other Qt classes and seem to have something almost working.
Instead of using the primitive classes, such as QSound, QSoundEffect and QMediaPlayer, I went on the use QAudioFormat, QAudioOutput and QAudioDeviceInfo.
See below my code snippet of the class I drafted up real quick:
SoundManager.h
#ifndef SOUNDMANAGER_H
#define SOUNDMANAGER_H
#include <QObject>
#include <QAudioOutput>
#include <QAudioFormat>
#include <QFile>
class SoundManager : public QObject
{
Q_OBJECT
public:
static SoundManager* Instance();
void playAudio();
public slots:
void handleStateChanged(QAudio::State newState);
private:
explicit SoundManager(QObject *parent = nullptr);
static SoundManager* m_instance;
QFile* m_sourceFile;
QAudioOutput* audio;
};
#endif // SOUNDMANAGER_H
SoundManager.cpp
#include "soundmanager.h"
#include <QDebug>
SoundManager* SoundManager::m_instance = nullptr;
SoundManager::SoundManager(QObject *parent)
: QObject{parent}
{
}
SoundManager* SoundManager::Instance()
{
if(!m_instance){
m_instance = new SoundManager;
}
return m_instance;
}
void SoundManager::playAudio()
{
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;
QAudioDeviceInfo info(i);
// Print out supported format by device
qDebug() << "Supported Byte Orders: " << info.supportedByteOrders()
<< "Supported Channel Counts: " << info.supportedChannelCounts()
<< "Supported Codes: " << info.supportedCodecs()
<< "Supported Sample Rates: " << info.supportedSampleRates()
<< "Supported Sample Sizes: " << info.supportedSampleSizes()
<< "Supported Sample Types: " << info.supportedSampleTypes()
<< Qt::endl;
// Format support check
if (!info.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
m_sourceFile = new QFile("/eclipse_qml/startup-sound.wav");
audio = new QAudioOutput(i, format, this);
connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
m_sourceFile->open(QIODevice::ReadOnly);
audio->start(m_sourceFile);
break;
}
}
}
}
void SoundManager::handleStateChanged(QAudio::State newState)
{
switch (newState) {
case QAudio::IdleState:
// Finished playing (no more data)
audio->stop();
m_sourceFile->close();
delete audio;
break;
case QAudio::StoppedState:
if(audio->error() != QAudio::NoError){
// Error handling
qDebug() << "Reached Stopped state: " << QString(audio->error()) << Qt::endl;
}
break;
default:
break;
}
}
To figure out the parameters set in QAudioFormat format, I executed the ALSA command line aplay to print out the information and matched them in the code.
Then I iterated through all of my audio devices until I reach the one we’re looking for, in our case it’s sysdefault:CARD=imx6qapalissgtl
as @jeremias.tx showed me in one of my previous topic: TorizonCore Setting Audio Levels: No Simple Control detected by Amixer - Technical Support - Toradex Community. For code optimization, I’ll probably move up this device detection on application startup to avoid doing that everytime I want to play a sound.
From there I can simply call SoundManager::Instance()->playAudio(string audioFileName)
from anywhere in the code.
I’ve tested with my app startup sound. It works, but there’s a very small amount of pops and cracks I’m hearing, so the quality isn’t as great as playing on command line. I’ll check around on Qt Forums to see if there’s a way to optimize sound quality.
Let me know if you found another method.
Thanks,
Anthony