summaryrefslogtreecommitdiff
path: root/library/sound.cpp
Side-by-side diff
Diffstat (limited to 'library/sound.cpp') (more/less context) (show whitespace changes)
-rw-r--r--library/sound.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/library/sound.cpp b/library/sound.cpp
new file mode 100644
index 0000000..373fd4c
--- a/dev/null
+++ b/library/sound.cpp
@@ -0,0 +1,173 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/resource.h>
+#include <qpe/sound.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qsound.h>
+#include <qfile.h>
+
+#ifndef QT_NO_SOUND
+static int WAVsoundDuration(const QString& filename)
+{
+ // bad solution
+
+ // most of this is copied from qsoundqss.cpp
+
+ QFile input(filename);
+ if ( !input.open(IO_ReadOnly) )
+ return 0;
+
+ struct QRiffChunk {
+ char id[4];
+ Q_UINT32 size;
+ char data[4/*size*/];
+ } chunk;
+
+ struct {
+ Q_INT16 formatTag;
+ Q_INT16 channels;
+ Q_INT32 samplesPerSec;
+ Q_INT32 avgBytesPerSec;
+ Q_INT16 blockAlign;
+ Q_INT16 wBitsPerSample;
+ } chunkdata;
+
+ int total = 0;
+
+ while(1) {
+ // Keep reading chunks...
+ const int n = sizeof(chunk)-sizeof(chunk.data);
+ if ( input.readBlock((char*)&chunk,n) != n )
+ break;
+ if ( qstrncmp(chunk.id,"data",4) == 0 ) {
+ total += chunkdata.avgBytesPerSec ?
+ chunk.size * 1000 / chunkdata.avgBytesPerSec : 0;
+//qDebug("%d bytes of PCM (%dms)", chunk.size,chunkdata.avgBytesPerSec ? chunk.size * 1000 / chunkdata.avgBytesPerSec : 0);
+ input.at(input.at()+chunk.size-4);
+ } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
+ char d[4];
+ if ( input.readBlock(d,4) != 4 )
+ return 0;
+ if ( qstrncmp(d,"WAVE",4) != 0 ) {
+ // skip
+//qDebug("skip %.4s RIFF chunk",d);
+ if ( chunk.size < 10000000 )
+ (void)input.at(input.at()+chunk.size-4);
+ }
+ } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
+ if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) )
+ return 0;
+#define WAVE_FORMAT_PCM 1
+ if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
+ //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
+ return 0;
+ }
+ } else {
+//qDebug("skip %.4s chunk",chunk.id);
+ // ignored chunk
+ if ( chunk.size < 10000000 )
+ (void)input.at(input.at()+chunk.size);
+ }
+ }
+
+//qDebug("%dms",total);
+ return total;
+}
+
+class SoundData : public QSound {
+public:
+ SoundData(const QString& name) :
+ QSound(Resource::findSound(name)),
+ filename(Resource::findSound(name))
+ {
+ }
+
+ void playLoop()
+ {
+ // needs server support
+
+ int ms = WAVsoundDuration(filename);
+ if ( ms )
+ startTimer(ms > 50 ? ms-50 : 0); // 50 for latency
+ play();
+ }
+
+ void timerEvent(QTimerEvent*)
+ {
+ play();
+ }
+
+private:
+ QString filename;
+};
+#endif
+
+Sound::Sound(const QString& name)
+{
+#ifndef QT_NO_SOUND
+ d = new SoundData(name);
+#endif
+}
+
+Sound::~Sound()
+{
+#ifndef QT_NO_SOUND
+ delete d;
+#endif
+}
+
+void Sound::play()
+{
+#ifndef QT_NO_SOUND
+ d->killTimers();
+ d->play();
+#endif
+}
+
+void Sound::playLoop()
+{
+#ifndef QT_NO_SOUND
+ d->killTimers();
+ d->playLoop();
+#endif
+}
+
+void Sound::stop()
+{
+#ifndef QT_NO_SOUND
+ d->killTimers();
+#endif
+}
+
+
+void Sound::soundAlarm()
+{
+#ifdef QT_QWS_CUSTOM
+# ifndef QT_NO_COP
+ QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
+# endif
+#else
+# ifndef QT_NO_SOUND
+ QSound::play(Resource::findSound("alarm"));
+# endif
+#endif
+}