⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsoundqss_qws.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qsoundqss_qws.h"#ifndef QT_NO_SOUND#include <qbytearray.h>#include <qlist.h>#include <qsocketnotifier.h>#include <qfile.h>#include <qfileinfo.h>#include <qstringlist.h>#include <qevent.h>#include <qalgorithms.h>#include <qtimer.h>#include <qpointer.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/soundcard.h>#include <qdebug.h>extern int errno;#define QT_QWS_SOUND_16BIT 1 // or 0, or undefined for always 0#define QT_QWS_SOUND_STEREO 1 // or 0, or undefined for always 0// Zaurus SL5000D doesn't seem to return any error if setting to 44000 and it fails,// however 44100 works, 44100 is more common that 44000.static int sound_speed = 44100;#ifndef QT_NO_QWS_SOUNDSERVERextern int qws_display_id;#define SOUND_PIPE	"/tmp/.qt_soundserver-%1"#endifstatic char *zeroMem = 0;struct QRiffChunk {    char id[4];    quint32 size;    char data[4/*size*/];};#if defined(QT_QWS_IPAQ)static const int sound_fragment_size = 12;#elsestatic const int sound_fragment_size = 12;#endifstatic const int sound_buffer_size = 1 << sound_fragment_size;// nb. there will be an sound startup delay of//        2^sound_fragment_size / sound_speed seconds.// (eg. sound_fragment_size==12, sound_speed==44000 means 0.093s delay)#ifdef QT_QWS_SOUND_STEREOstatic int sound_stereo=QT_QWS_SOUND_STEREO;#elsestatic const int sound_stereo=0;#endif#ifdef QT_QWS_SOUND_16BITstatic bool sound_16bit=QT_QWS_SOUND_16BIT;#elsestatic const bool sound_16bit=false;#endif#ifndef QT_NO_QWS_SOUNDSERVERclass QWSSoundServerClient : public QObject {    Q_OBJECTpublic:    QWSSoundServerClient(QWS_SOCK_BASE *s, QObject* parent);    ~QWSSoundServerClient();public slots:    void sendSoundCompleted(int, int);    void sendDeviceReady(int, int);    void sendDeviceError(int, int, int);signals:    void play(int, int, const QString&);    void play(int, int, const QString&, int, int);    void playRaw(int, int, const QString&, int, int, int, int);    void pause(int, int);    void stop(int, int);    void resume(int, int);    void setVolume(int, int, int, int);    void setMute(int, int, bool);    void stopAll(int);    void playPriorityOnly(bool);    void setSilent( bool );private slots:    void tryReadCommand();private:    void sendClientMessage(QString msg);    int mCurrentID;    int left, right;    bool priExist;    static int lastId;    static int nextId() { return ++lastId; }    QPointer<QWS_SOCK_BASE> socket;};int QWSSoundServerClient::lastId = 0;QWSSoundServerClient::QWSSoundServerClient(QWS_SOCK_BASE *s, QObject* parent) :    QObject( parent ){    socket = s;    priExist = false;    mCurrentID = nextId();    connect(socket,SIGNAL(readyRead()),        this,SLOT(tryReadCommand()));    connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater()));}QWSSoundServerClient::~QWSSoundServerClient(){    if (priExist)	playPriorityOnly(false);    emit stopAll(mCurrentID);    if (socket)        socket->deleteLater();}static QString getStringTok(QString &in){    int pos = in.indexOf(QLatin1Char(' '));    QString ret;    if (pos > 0) {	ret = in.left(pos);	in = in.mid(pos+1);    } else {	ret = in;	in = QString::null;    }    return ret;}static int getNumTok(QString &in){    return getStringTok(in).toInt();}void QWSSoundServerClient::tryReadCommand(){    while ( socket->canReadLine() ) {	QString l = QString::fromAscii(socket->readLine());	l.truncate(l.length()-1); // chomp	QString functionName = getStringTok(l);	int soundid = getNumTok(l);	if (functionName == QLatin1String("PLAY")) {	    emit play(mCurrentID, soundid, l);	} else if (functionName == QLatin1String("PLAYEXTEND")) {	    int volume = getNumTok(l);	    int flags = getNumTok(l);	    emit play(mCurrentID, soundid, l, volume, flags);	} else if (functionName == QLatin1String("PLAYRAW")) {	    int chs = getNumTok(l);	    int freq = getNumTok(l);	    int bitspersample = getNumTok(l);	    int flags = getNumTok(l);	    emit playRaw(mCurrentID, soundid, l, freq, chs, bitspersample, flags);	} else if (functionName == QLatin1String("PAUSE")) {	    emit pause(mCurrentID, soundid);	} else if (functionName == QLatin1String("STOP")) {	    emit stop(mCurrentID, soundid);	} else if (functionName == QLatin1String("RESUME")) {	    emit resume(mCurrentID, soundid);	} else if (functionName == QLatin1String("SETVOLUME")) {	    int left = getNumTok(l);	    int right = getNumTok(l);	    emit setVolume(mCurrentID, soundid, left, right);	} else if (functionName == QLatin1String("MUTE")) {	    emit setMute(mCurrentID, soundid, true);	} else if (functionName == QLatin1String("UNMUTE")) {	    emit setMute(mCurrentID, soundid, false);	} else if (functionName == QLatin1String("PRIORITYONLY")) {	    bool sPri = soundid != 0;	    if (sPri != priExist) {		priExist = sPri;		emit playPriorityOnly(sPri);	    }	} else if(functionName == QLatin1String("SILENT")) {	    emit setSilent( soundid != 0 );	}    }}void QWSSoundServerClient::sendClientMessage(QString msg){#ifndef QT_NO_TEXTCODEC    QByteArray u = msg.toUtf8();#else    QByteArray u = msg.toLatin1();#endif    socket->write(u.data(), u.length());    socket->flush();}void QWSSoundServerClient::sendSoundCompleted(int gid, int sid){    if (gid == mCurrentID)        sendClientMessage(QLatin1String("SOUNDCOMPLETED ")                          + QString::number(sid) + QLatin1Char('\n'));}void QWSSoundServerClient::sendDeviceReady(int gid, int sid){    if (gid == mCurrentID)        sendClientMessage(QLatin1String("DEVICEREADY ")                          + QString::number(sid) + QLatin1Char('\n'));}void QWSSoundServerClient::sendDeviceError(int gid, int sid, int err){    if (gid == mCurrentID)        sendClientMessage(QLatin1String("DEVICEERROR ")                          + QString::number(sid) + QLatin1Char(' ')                          + QString::number(err) + QLatin1Char('\n'));}#endifstatic const int maxVolume = 100;static const int runinLength = 2*sound_buffer_size;class QWSSoundServerProvider {public:    QWSSoundServerProvider(int w, int s)	: mWid(w), mSid(s), mMuted(false)    {	leftVolume = maxVolume>>1;	rightVolume = maxVolume>>1;	isPriority = false;        samples_due = 0;	max1 = max2 = out = 0;//= sound_buffer_size;	data = data1;	max = &max1;	sampleRunin = 0;	dev = -1;    }    virtual ~QWSSoundServerProvider() {    }    int groupId() const { return mWid; }    int soundId() const { return mSid; }    void startSampleRunin() {	// inteded to provide even audio return from mute/pause/dead samples.	//sampleRunin = runinLength; // or more?    }    void setVolume(int lv, int rv) {	leftVolume = qMin(maxVolume, qMax(0, lv));	rightVolume = qMin(maxVolume, qMax(0, rv));    }    void setMute(bool m) { mMuted = m; }    bool muted() { return mMuted; }    void setPriority(bool p) {	if (p != isPriority) {	    isPriority = p; // currently meaningless.	}    }    static void setPlayPriorityOnly(bool p)    {	if (p)	    priorityExists++;	else	    priorityExists--;	if (priorityExists < 0)	    qDebug("QSS: got more priority offs than ons");    }    // return -1 for file broken, give up.    // else return sampels ready for playing.    // argument is max samples server is looking for,    // in terms of current device status.    virtual int readySamples(int) = 0;    int getSample(int off, int bps) {        return (bps == 1) ? (data[out+off] - 128) * 128 : ((short*)data)[(out/2)+off];    }    int add(int* mixl, int* mixr, int count)    {        int bytesPerSample = chunkdata.wBitsPerSample >> 3;        if ( mMuted ) {            sampleRunin -= qMin(sampleRunin,count);            while (count && (dev != -1)) {                if (out >= *max) {                    // switch buffers                    out = 0;                    if (data == data1 && max2 != 0) {                        data = data2;                        max = &max2;                        max1 = 0;                    } else if (data == data2 && max1 != 0) {                        data = data1;                        max = &max1;                        max2 = 0;                    } else {                        qDebug("QSS Read Error: both buffers empty");                        return 0;                    }                }                samples_due += sound_speed;                while (count && samples_due >= chunkdata.samplesPerSec) {                    samples_due -= chunkdata.samplesPerSec;                    count--;                }                out += bytesPerSample * chunkdata.channels;            }            return count;        }        // This shouldn't be the case        if ( !mixl || !mixr )            return 0;        int lVolNum = leftVolume, lVolDen = maxVolume;        int rVolNum = rightVolume, rVolDen = maxVolume;        if (priorityExists > 0 && !isPriority) {            lVolNum = 0; // later, make this gradually fade in and out.            lVolDen = 5;            rVolNum = 0;            rVolDen = 5;        }        while (count && (dev != -1)) {            if (out >= *max) {                // switch buffers                out = 0;                if (data == data1 && max2 != 0) {                    data = data2;                    max = &max2;                    max1 = 0;                } else if (data == data2 && max1 != 0) {                    data = data1;                    max = &max1;                    max2 = 0;                } else {                    qDebug("QSS Read Error: both buffers empty");                    return 0;                }            }            samples_due += sound_speed;            if (count && samples_due >= chunkdata.samplesPerSec) {                int l = getSample(0,bytesPerSample)*lVolNum/lVolDen;                int r = (chunkdata.channels == 2) ? getSample(1,bytesPerSample)*rVolNum/rVolDen : l;                if (!sound_stereo && chunkdata.channels == 2)                    l += r;		if (sampleRunin) {                    while (sampleRunin && count && samples_due >= chunkdata.samplesPerSec) {                        mixl++;                        if (sound_stereo)                            mixr++;                        samples_due -= chunkdata.samplesPerSec;		        sampleRunin--;                        count--;                    }                }                while (count && samples_due >= chunkdata.samplesPerSec) {                    *mixl++ += l;                    if (sound_stereo)                        *mixr++ += r;                    samples_due -= chunkdata.samplesPerSec;                    count--;                }            }            // optimize out manipulation of sample if downsampling and we skip it            out += bytesPerSample * chunkdata.channels;        }        return count;    }    virtual bool finished() const = 0;    bool equal(int wid, int sid)    {	return (wid == mWid && sid == mSid);    }protected:    char * prepareBuffer( int &size)    {	// keep reading as long as there is 50 % or more room in off buffer.	if (data == data1 && (max2<<1 < sound_buffer_size)) {	    size=sound_buffer_size - max2;	    return (char *)data2;	} else if (data == data2 && (max1<<1 < sound_buffer_size)) {	    size=sound_buffer_size - max1;	    return (char *)data1;	} else {	    size = 0;	    return 0;	}    }    void updateBuffer(int read)    {	// always reads to off buffer.	if (read >= 0) {	    if (data == data2) {		max1 = read;	    } else {		max2 = read;	    }	}    }    int devSamples()    {	int possible = (((max1+max2-out) / ((chunkdata.wBitsPerSample>>3)*chunkdata.channels))		*sound_speed)/chunkdata.samplesPerSec;	return possible;    }    struct {        qint16 formatTag;        qint16 channels;        qint32 samplesPerSec;        qint32 avgBytesPerSec;        qint16 blockAlign;        qint16 wBitsPerSample;    } chunkdata;    int dev;    int samples_due;private:    int mWid;    int mSid;    int leftVolume;    int rightVolume;    bool isPriority;    static int priorityExists;    int *max;    uchar *data;    uchar data1[sound_buffer_size+4]; // +4 to handle badly aligned input data    uchar data2[sound_buffer_size+4]; // +4 to handle badly aligned input data    int out, max1, max2;    int sampleRunin;    bool mMuted;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -