Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [code]
- #ifndef SIGNALAUDIOPLAYER_H
- #define SIGNALAUDIOPLAYER_H
- #include <QObject>
- #include <QThread>
- #include <QIODevice>
- #include <QAudioOutput>
- #include <QPointer>
- #include <QtEndian>
- #include "datapipe.h"
- class SignalAudioPlayer : public QIODevice
- {
- Q_OBJECT
- public:
- SignalAudioPlayer();
- ~SignalAudioPlayer();
- qint64 readData(char *data, qint64 maxlen);
- qint64 writeData(const char *data, qint64 len);
- qint64 bytesAvailable() const;
- public slots:
- void start();
- void stop();
- void dataInput(RawDataPipe* pipe);
- private slots:
- void processing();
- private:
- QThread t;
- Q_INVOKABLE void init_inthread();
- Q_INVOKABLE void close_inthread();
- Q_INVOKABLE void start_inthread();
- Q_INVOKABLE void stop_inthread();
- QByteArray inputData;
- QByteArray outputData;
- QByteArray dataSlice;
- QAudioFormat audioFormat;
- QPointer<QAudioOutput> audioOutput;
- bool fIsOk;
- bool fPlay;
- int scaleFactor;
- };
- #endif // SIGNALAUDIOPLAYER_H
- [/code]
- [code]
- #include "signalaudioplayer.h"
- #include "trace_macro.h"
- SignalAudioPlayer::SignalAudioPlayer()
- {
- _TRACE("");
- moveToThread(&t);
- t.start();
- QMetaObject::invokeMethod(this,"init_inthread",Qt::BlockingQueuedConnection);
- }
- SignalAudioPlayer::~SignalAudioPlayer()
- {
- _TRACE("");
- QMetaObject::invokeMethod(this,"close_inthread",Qt::BlockingQueuedConnection);
- t.quit();
- t.wait();
- }
- qint64 SignalAudioPlayer::readData(char *data, qint64 maxlen)
- {
- //_TRACE(maxlen);
- if(outputData.isEmpty()) return 0;
- qint64 len = qMin(maxlen,(qint64)outputData.size());
- memcpy(data,outputData.constData(),len);
- if(fPlay
- && audioOutput->state() == QAudio::ActiveState
- && outputData.size() < qMax(audioOutput->bufferSize(),audioOutput->bytesFree())/4)
- {
- _TRACE("stop");
- audioOutput->stop();
- }
- outputData.remove(0,len);
- //_TRACE(outputData.size());
- //_TRACE(audioOutput->bufferSize() << audioOutput->bytesFree());
- return len;
- }
- qint64 SignalAudioPlayer::writeData(const char *data, qint64 len)
- {
- _TRACE("");
- Q_UNUSED(data)
- Q_UNUSED(len)
- return 0;
- }
- qint64 SignalAudioPlayer::bytesAvailable() const
- {
- _TRACE("");
- // int size = outputData.size();
- // size -= 2048*8;
- // if(size < 0)
- // {
- // size = 0;
- // }
- // return size;
- return outputData.size() + QIODevice::bytesAvailable();
- }
- void SignalAudioPlayer::start()
- {
- QMetaObject::invokeMethod(this,"start_inthread",Qt::QueuedConnection);
- }
- void SignalAudioPlayer::stop()
- {
- QMetaObject::invokeMethod(this,"stop_inthread",Qt::QueuedConnection);
- }
- void SignalAudioPlayer::dataInput(RawDataPipe *pipe)
- {
- pipe->getData(&inputData);
- if(!fIsOk || !fPlay)
- {
- inputData.clear();
- return;
- }
- QMetaObject::invokeMethod(this,"processing",Qt::QueuedConnection);
- }
- void SignalAudioPlayer::processing()
- {
- if(!fIsOk || inputData.isEmpty()) return;
- if(inputData.size() % 8 != 0)
- {
- _ERROR("inputData.size() % 8 != 0");
- return;
- }
- dataSlice.resize(inputData.size()/2);
- char* srcMem = (char*)inputData.constData();
- char* dstMem = (char*)dataSlice.constData();
- int k = 0;
- int sample;
- int maxSample = 0;
- for(int i=0;i<dataSlice.size();i+=4)
- {
- sample = qFromLittleEndian<qint32>(srcMem+k);
- if(abs(sample) > maxSample)
- {
- maxSample = abs(sample);
- }
- k+=8;
- }
- // for(int i=0;i<dataSlice.size();i+=2)
- // {
- // sample = qFromLittleEndian<qint16>(srcMem+k);
- // if(abs(sample) > maxSample)
- // {
- // maxSample = abs(sample);
- // }
- // k+=4;
- // }
- scaleFactor = std::round((((double)INT_MAX)*0.7)/(double)maxSample);
- if(scaleFactor < 1)
- {
- scaleFactor = 1;
- }
- //_TRACE(maxSample << scaleFactor);
- k = 0;
- for(int i=0;i<dataSlice.size();i+=4)
- {
- sample = qFromLittleEndian<qint32>(srcMem+k);
- sample = sample * scaleFactor;
- memcpy(dstMem+i,&sample,4);
- k+=8;
- }
- // for(int i=0;i<dataSlice.size();i+=2)
- // {
- // sample = qFromLittleEndian<qint32>(srcMem+k);
- // sample = sample * scaleFactor;
- // memcpy(dstMem+i,&sample,2);
- // k+=4;
- // }
- inputData.clear();
- outputData.append(dataSlice);
- if(outputData.size() > 1024000)
- {
- _TRACE("clear data!");
- outputData.clear();
- }
- if(fPlay
- && (audioOutput->state() == QAudio::StoppedState || audioOutput->state() == QAudio::IdleState)
- && outputData.size() > qMax(audioOutput->bufferSize(),audioOutput->bytesFree()))
- {
- _TRACE("start");
- audioOutput->start(this);
- }
- }
- void SignalAudioPlayer::init_inthread()
- {
- _TRACE("");
- fIsOk = true;
- fPlay = false;
- scaleFactor = 1;
- audioFormat.setSampleRate(48000);
- audioFormat.setChannelCount(1);
- audioFormat.setSampleSize(32);
- audioFormat.setCodec("audio/pcm");
- audioFormat.setByteOrder(QAudioFormat::LittleEndian);
- audioFormat.setSampleType(QAudioFormat::SignedInt);
- if(!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(audioFormat))
- {
- _ERROR("Audio format not supported");
- fIsOk = false;
- return;
- }
- audioOutput = new QAudioOutput(audioFormat);
- open(QIODevice::ReadOnly);
- }
- void SignalAudioPlayer::close_inthread()
- {
- _TRACE("");
- delete audioOutput;
- close();
- }
- void SignalAudioPlayer::start_inthread()
- {
- _TRACE("");
- fPlay = true;
- }
- void SignalAudioPlayer::stop_inthread()
- {
- _TRACE("");
- fPlay = false;
- audioOutput->stop();
- inputData.clear();
- outputData.clear();
- }
- [/code]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement