summaryrefslogtreecommitdiff
path: root/library/sound.cpp
Unidiff
Diffstat (limited to 'library/sound.cpp') (more/less context) (ignore 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/resource.h>
22#include <qpe/sound.h>
23#include <qpe/qcopenvelope_qws.h>
24
25#include <qsound.h>
26#include <qfile.h>
27
28#ifndef QT_NO_SOUND
29static int WAVsoundDuration(const QString& filename)
30{
31 // bad solution
32
33 // most of this is copied from qsoundqss.cpp
34
35 QFile input(filename);
36 if ( !input.open(IO_ReadOnly) )
37 return 0;
38
39 struct QRiffChunk {
40 char id[4];
41 Q_UINT32 size;
42 char data[4/*size*/];
43 } chunk;
44
45 struct {
46 Q_INT16 formatTag;
47 Q_INT16 channels;
48 Q_INT32 samplesPerSec;
49 Q_INT32 avgBytesPerSec;
50 Q_INT16 blockAlign;
51 Q_INT16 wBitsPerSample;
52 } chunkdata;
53
54 int total = 0;
55
56 while(1) {
57 // Keep reading chunks...
58 const int n = sizeof(chunk)-sizeof(chunk.data);
59 if ( input.readBlock((char*)&chunk,n) != n )
60 break;
61 if ( qstrncmp(chunk.id,"data",4) == 0 ) {
62 total += chunkdata.avgBytesPerSec ?
63 chunk.size * 1000 / chunkdata.avgBytesPerSec : 0;
64//qDebug("%d bytes of PCM (%dms)", chunk.size,chunkdata.avgBytesPerSec ? chunk.size * 1000 / chunkdata.avgBytesPerSec : 0);
65 input.at(input.at()+chunk.size-4);
66 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
67 char d[4];
68 if ( input.readBlock(d,4) != 4 )
69 return 0;
70 if ( qstrncmp(d,"WAVE",4) != 0 ) {
71 // skip
72//qDebug("skip %.4s RIFF chunk",d);
73 if ( chunk.size < 10000000 )
74 (void)input.at(input.at()+chunk.size-4);
75 }
76 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
77 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) )
78 return 0;
79#define WAVE_FORMAT_PCM 1
80 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
81 //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
82 return 0;
83 }
84 } else {
85//qDebug("skip %.4s chunk",chunk.id);
86 // ignored chunk
87 if ( chunk.size < 10000000 )
88 (void)input.at(input.at()+chunk.size);
89 }
90 }
91
92//qDebug("%dms",total);
93 return total;
94}
95
96class SoundData : public QSound {
97public:
98 SoundData(const QString& name) :
99 QSound(Resource::findSound(name)),
100 filename(Resource::findSound(name))
101 {
102 }
103
104 void playLoop()
105 {
106 // needs server support
107
108 int ms = WAVsoundDuration(filename);
109 if ( ms )
110 startTimer(ms > 50 ? ms-50 : 0); // 50 for latency
111 play();
112 }
113
114 void timerEvent(QTimerEvent*)
115 {
116 play();
117 }
118
119private:
120 QString filename;
121};
122#endif
123
124Sound::Sound(const QString& name)
125{
126#ifndef QT_NO_SOUND
127 d = new SoundData(name);
128#endif
129}
130
131Sound::~Sound()
132{
133#ifndef QT_NO_SOUND
134 delete d;
135#endif
136}
137
138void Sound::play()
139{
140#ifndef QT_NO_SOUND
141 d->killTimers();
142 d->play();
143#endif
144}
145
146void Sound::playLoop()
147{
148#ifndef QT_NO_SOUND
149 d->killTimers();
150 d->playLoop();
151#endif
152}
153
154void Sound::stop()
155{
156#ifndef QT_NO_SOUND
157 d->killTimers();
158#endif
159}
160
161
162void Sound::soundAlarm()
163{
164#ifdef QT_QWS_CUSTOM
165# ifndef QT_NO_COP
166 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
167# endif
168#else
169# ifndef QT_NO_SOUND
170 QSound::play(Resource::findSound("alarm"));
171# endif
172#endif
173}