今天接到個(gè)任務(wù),讓我用Qt播放PCM蛹头,這個(gè)簡(jiǎn)單顿肺,隨便一百度就有了。
#ifndef PLAYPCM_H
#define PLAYPCM_H
#include <QObject>
#include <QAudioOutput>
#include <QIODevice>
class PlayPCM : public QObject
{
Q_OBJECT
QAudioOutput *audioOutput = nullptr;
QIODevice *streamOut = nullptr;
#endif
public:
explicit PlayPCM(int sampleRate = 44100, int channels = 2, int sampleSize = 16, QObject *parent = nullptr);
~PlayPCM();
signals:
public slots:
void writePCM(QByteArray array);
};
#endif // PLAYPCM_H
#include "playpcm.h"
#include <QDebug>
#include <QAudioFormat>
#include <QAudioDeviceInfo>
PlayPCM::PlayPCM(int sampleRate, int channels, int sampleSize, QObject *parent) : QObject(parent)
{
//設(shè)置采樣格式
QAudioFormat audioFormat;
//設(shè)置采樣率
audioFormat.setSampleRate(sampleRate);
//設(shè)置通道數(shù)
audioFormat.setChannelCount(channels);
//設(shè)置采樣大小渣蜗,一般為8位或16位
audioFormat.setSampleSize(sampleSize);
//設(shè)置編碼方式
audioFormat.setCodec("audio/pcm");
//設(shè)置字節(jié)序
audioFormat.setByteOrder(QAudioFormat::LittleEndian);
//設(shè)置樣本數(shù)據(jù)類型
audioFormat.setSampleType(QAudioFormat::UnSignedInt);
//音頻設(shè)備信息
QList<QAudioDeviceInfo> list = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
foreach (QAudioDeviceInfo info, list) {
if (info.isFormatSupported(audioFormat)) {
audioOutput = new QAudioOutput(audioFormat, this);
streamOut = audioOutput->start();
break;
}
}
}
PlayPCM::~PlayPCM()
{
delete audioOutput;
audioOutput = nullptr;
streamOut = nullptr;
}
void PlayPCM::writePCM(QByteArray array)
{
if (streamOut)
streamOut->write(array);
}
#endif
不過在運(yùn)行的時(shí)候出了問題
ALSA lib pcm_hw.c:1788:(_snd_pcm_hw_open) Unknown field slave
嘶~ 好像是alsa源碼出了問題屠尊,但是又不想去看源碼......
我記得arm板上有了aplay這個(gè)程序,試試它能不能播WAV耕拷,可以的話就參考它的源碼自己寫一個(gè)PCM播放
# aplay -D hw:0,0 a.wav
Playing WAVE 'a.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
可以讼昆! 再把WAV掐掉頭變成PCM
# aplay -D hw:0,0 a.pcm
Playing raw data 'a.pcm' : Unsigned 8 bit, Rate 8000 Hz, Mono
aplay: set_params:1297: Sample format non available
Available formats:
- S16_LE
- S24_LE
......看來需要指定參數(shù)
aplay -D hw:0,0 -r 44100 -c 2 -f s16 a.pcm
Playing raw data 'a.pcm' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
可以播了,去參考參考(復(fù)制)aplay的源碼斑胜,然后發(fā)現(xiàn)了aplay輸入源可以是 stdin控淡,這就舒服了啊,這下連代碼都不用參考了
#ifndef PLAYPCM_H
#define PLAYPCM_H
#include <QObject>
#include <QProcess>
class PlayPCM : public QObject
{
Q_OBJECT
QProcess process;
public:
explicit PlayPCM(int sampleRate = 44100, int channels = 2, int sampleSize = 16, QObject *parent = nullptr);
~PlayPCM();
signals:
public slots:
void writePCM(QByteArray array);
};
#endif // PLAYPCM_H
#include "playpcm.h"
#include <QDebug>
PlayPCM::PlayPCM(int sampleRate, int channels, int sampleSize, QObject *parent) : QObject(parent)
{
char cmd[128];
sprintf(cmd, "aplay -D hw:0,0 -r %d -c %d -f s%d", sampleRate, channels, sampleSize);
process.start(cmd);
if (process.waitForStarted()){
//qDebug() << "PCM player is ready.";
}
}
PlayPCM::~PlayPCM()
{
process.kill();
}
void PlayPCM::writePCM(QByteArray array)
{
if (process.isOpen())
process.write(array);
}
參考:
一定要仔細(xì)看的help
aplay -h