summaryrefslogtreecommitdiff
path: root/library/sound.cpp
Unidiff
Diffstat (limited to 'library/sound.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/sound.cpp3
1 files changed, 2 insertions, 1 deletions
diff --git a/library/sound.cpp b/library/sound.cpp
index d1e2388..42f7698 100644
--- a/library/sound.cpp
+++ b/library/sound.cpp
@@ -1,253 +1,254 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 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 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 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 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. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include <qpe/resource.h> 21#include <qpe/resource.h>
22#include <qpe/sound.h> 22#include <qpe/sound.h>
23#include <qpe/qcopenvelope_qws.h> 23#include <qpe/qcopenvelope_qws.h>
24 24
25#include <qsound.h> 25#include <qsound.h>
26#include <qfile.h> 26#include <qfile.h>
27 27
28#include <unistd.h> 28#include <unistd.h>
29#include <fcntl.h> 29#include <fcntl.h>
30#include <sys/ioctl.h> 30#include <sys/ioctl.h>
31 31
32#ifndef QT_NO_SOUND 32#ifndef QT_NO_SOUND
33#include <sys/soundcard.h> 33#include <sys/soundcard.h>
34#endif 34#endif
35 35
36#ifndef QT_NO_SOUND 36#ifndef QT_NO_SOUND
37static int WAVsoundDuration(const QString& filename) 37static int WAVsoundDuration(const QString& filename)
38{ 38{
39 // bad solution 39 // bad solution
40 40
41 // most of this is copied from qsoundqss.cpp 41 // most of this is copied from qsoundqss.cpp
42 42
43 QFile input(filename); 43 QFile input(filename);
44 if ( !input.open(IO_ReadOnly) ) 44 if ( !input.open(IO_ReadOnly) )
45 return 0; 45 return 0;
46 46
47 struct QRiffChunk { 47 struct QRiffChunk {
48 char id[4]; 48 char id[4];
49 Q_UINT32 size; 49 Q_UINT32 size;
50 char data[4/*size*/]; 50 char data[4/*size*/];
51 } chunk; 51 } chunk;
52 52
53 struct { 53 struct {
54 Q_INT16 formatTag; 54 Q_INT16 formatTag;
55 Q_INT16 channels; 55 Q_INT16 channels;
56 Q_INT32 samplesPerSec; 56 Q_INT32 samplesPerSec;
57 Q_INT32 avgBytesPerSec; 57 Q_INT32 avgBytesPerSec;
58 Q_INT16 blockAlign; 58 Q_INT16 blockAlign;
59 Q_INT16 wBitsPerSample; 59 Q_INT16 wBitsPerSample;
60 } chunkdata; 60 } chunkdata;
61 61
62 int total = 0; 62 int total = 0;
63 63
64 while(1) { 64 while(1) {
65 // Keep reading chunks... 65 // Keep reading chunks...
66 const int n = sizeof(chunk)-sizeof(chunk.data); 66 const int n = sizeof(chunk)-sizeof(chunk.data);
67 if ( input.readBlock((char*)&chunk,n) != n ) 67 if ( input.readBlock((char*)&chunk,n) != n )
68 break; 68 break;
69 if ( qstrncmp(chunk.id,"data",4) == 0 ) { 69 if ( qstrncmp(chunk.id,"data",4) == 0 ) {
70 total += chunkdata.avgBytesPerSec ? 70 total += chunkdata.avgBytesPerSec ?
71 chunk.size * 1000 / chunkdata.avgBytesPerSec : 0; 71 chunk.size * 1000 / chunkdata.avgBytesPerSec : 0;
72//qDebug("%d bytes of PCM (%dms)", chunk.size,chunkdata.avgBytesPerSec ? chunk.size * 1000 / chunkdata.avgBytesPerSec : 0); 72//qDebug("%d bytes of PCM (%dms)", chunk.size,chunkdata.avgBytesPerSec ? chunk.size * 1000 / chunkdata.avgBytesPerSec : 0);
73 input.at(input.at()+chunk.size-4); 73 input.at(input.at()+chunk.size-4);
74 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) { 74 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
75 char d[4]; 75 char d[4];
76 if ( input.readBlock(d,4) != 4 ) 76 if ( input.readBlock(d,4) != 4 )
77 return 0; 77 return 0;
78 if ( qstrncmp(d,"WAVE",4) != 0 ) { 78 if ( qstrncmp(d,"WAVE",4) != 0 ) {
79 // skip 79 // skip
80//qDebug("skip %.4s RIFF chunk",d); 80//qDebug("skip %.4s RIFF chunk",d);
81 if ( chunk.size < 10000000 ) 81 if ( chunk.size < 10000000 )
82 (void)input.at(input.at()+chunk.size-4); 82 (void)input.at(input.at()+chunk.size-4);
83 } 83 }
84 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) { 84 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
85 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) 85 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) )
86 return 0; 86 return 0;
87#define WAVE_FORMAT_PCM 1 87#define WAVE_FORMAT_PCM 1
88 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) { 88 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
89 //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag); 89 //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
90 return 0; 90 return 0;
91 } 91 }
92 } else { 92 } else {
93//qDebug("skip %.4s chunk",chunk.id); 93//qDebug("skip %.4s chunk",chunk.id);
94 // ignored chunk 94 // ignored chunk
95 if ( chunk.size < 10000000 ) 95 if ( chunk.size < 10000000 )
96 (void)input.at(input.at()+chunk.size); 96 (void)input.at(input.at()+chunk.size);
97 } 97 }
98 } 98 }
99 99
100//qDebug("%dms",total); 100//qDebug("%dms",total);
101 return total; 101 return total;
102} 102}
103 103
104class SoundData : public QSound { 104class SoundData : public QSound {
105 Q_OBJECT 105 Q_OBJECT
106signals: 106signals:
107 void stopped(); 107 void stopped();
108public: 108public:
109 SoundData ( const QString& name ) : 109 SoundData ( const QString& name ) :
110 QSound ( Resource::findSound ( name )), 110 QSound ( Resource::findSound ( name )),
111 filename ( Resource::findSound ( name )) 111 filename ( Resource::findSound ( name ))
112 { 112 {
113 loopsleft=0; 113 loopsleft=0;
114 ms = WAVsoundDuration(filename); 114 ms = WAVsoundDuration(filename);
115 } 115 }
116 116
117 void playLoop ( int loopcnt = -1 ) 117 void playLoop ( int loopcnt = -1 )
118 { 118 {
119 // needs server support 119 // needs server support
120 loopsleft = loopcnt; 120 loopsleft = loopcnt;
121 121
122 if ( ms ) 122 if ( ms )
123 startTimer ( ms > 50 ? ms-50 : 0 ); // 50 for latency 123 startTimer ( ms > 50 ? ms-50 : 0 ); // 50 for latency
124 play ( ); 124 play ( );
125 } 125 }
126 126
127 void timerEvent ( QTimerEvent *e ) 127 void timerEvent ( QTimerEvent *e )
128 { 128 {
129 if ( loopsleft >= 0 ) { 129 if ( loopsleft >= 0 ) {
130 if ( --loopsleft <= 0 ) { 130 if ( --loopsleft <= 0 ) {
131 killTimer ( e-> timerId ( )); 131 killTimer ( e-> timerId ( ));
132 loopsleft = 0; 132 loopsleft = 0;
133 return; 133 return;
134 } 134 }
135 } 135 }
136 play(); 136 play();
137 } 137 }
138 138
139 bool isFinished ( ) const 139 bool isFinished ( ) const
140 { 140 {
141 return ( loopsleft == 0 ); 141 return ( loopsleft == 0 );
142 } 142 }
143 143
144 /* 144 /*
145 * non virtual reimplementation 145 * non virtual reimplementation
146 * @internal 146 * @internal
147 */ 147 */
148 void killTimers() { 148 void killTimers() {
149 QObject::killTimers(); 149 QObject::killTimers();
150 emit stopped(); 150 emit stopped();
151 } 151 }
152 152
153private: 153private:
154 QString filename; 154 QString filename;
155 int loopsleft; 155 int loopsleft;
156 int ms; 156 int ms;
157}; 157};
158 158
159#endif 159#endif
160 160
161 161
162/* 162/*
163 * @internal 163 * @internal
164 * Using sender() when the slot is called is unsafe! 164 * Using sender() when the slot is called is unsafe!
165 * 165 *
166 * @param snd instance 166 * @param snd instance
167 * @param obj The QObject to be called 167 * @param obj The QObject to be called
168 * @param slot connect SIGNAL(stopped()) to slot 168 * @param slot connect SIGNAL(stopped()) to slot
169 */ 169 */
170void register_qpe_sound_finished( Sound* snd, QObject* obj, const char* slot ) { 170void register_qpe_sound_finished( Sound* snd, QObject* obj, const char* slot ) {
171#ifndef QT_NO_SOUND 171#ifndef QT_NO_SOUND
172 QObject::connect(snd->d, SIGNAL(stopped()), obj, slot ); 172 QObject::connect(snd->d, SIGNAL(stopped()), obj, slot );
173#endif 173#endif
174} 174}
175 175
176/*! Opens a wave sound file \a name for playing 176/*! Opens a wave sound file \a name for playing
177 * Resource is used for finding the file 177 * Resource is used for finding the file
178 **/ 178 **/
179Sound::Sound(const QString& name) 179Sound::Sound(const QString& name)
180{ 180{
181#ifndef QT_NO_SOUND 181#ifndef QT_NO_SOUND
182 d = new SoundData(name); 182 d = new SoundData(name);
183#endif 183#endif
184} 184}
185 185
186/*! Destroys the sound */ 186/*! Destroys the sound */
187Sound::~Sound() 187Sound::~Sound()
188{ 188{
189#ifndef QT_NO_SOUND 189#ifndef QT_NO_SOUND
190 delete d; 190 delete d;
191#endif 191#endif
192} 192}
193 193
194/*! Play the sound once */ 194/*! Play the sound once */
195void Sound::play() 195void Sound::play()
196{ 196{
197#ifndef QT_NO_SOUND 197#ifndef QT_NO_SOUND
198 d->killTimers(); 198 d->killTimers();
199 d->playLoop(1); 199 d->playLoop(1);
200#endif 200#endif
201} 201}
202 202
203/*! Play the sound, repeatedly until stop() is called */ 203/*! Play the sound, repeatedly until stop() is called */
204void Sound::playLoop() 204void Sound::playLoop()
205{ 205{
206#ifndef QT_NO_SOUND 206#ifndef QT_NO_SOUND
207 d->killTimers(); 207 d->killTimers();
208 d->playLoop(); 208 d->playLoop();
209#endif 209#endif
210} 210}
211 211
212/*! Do not repeat the sound after it finishes. This will end a playLoop() */ 212/*! Do not repeat the sound after it finishes. This will end a playLoop() */
213void Sound::stop() 213void Sound::stop()
214{ 214{
215#ifndef QT_NO_SOUND 215#ifndef QT_NO_SOUND
216 d->killTimers(); 216 d->killTimers();
217#endif 217#endif
218} 218}
219 219
220bool Sound::isFinished() const 220bool Sound::isFinished() const
221{ 221{
222#ifndef QT_NO_SOUND 222#ifndef QT_NO_SOUND
223 return d->isFinished(); 223 return d->isFinished();
224#else 224#else
225 return true; 225 return true;
226#endif 226#endif
227} 227}
228 228
229/*! Sounds the audible system alarm. This is used for applications such 229/*! Sounds the audible system alarm. This is used for applications such
230 as Calendar when it needs to alarm the user of an event. 230 as Calendar when it needs to alarm the user of an event.
231*/ 231*/
232void Sound::soundAlarm() 232void Sound::soundAlarm()
233{ 233{
234#ifndef QT_NO_COP 234#ifndef QT_NO_COP
235 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" ); 235 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
236#endif 236#endif
237} 237}
238 238
239 239
240/*! \class Sound 240/*! \class Sound
241 \brief The Sound class plays WAVE sound files and can invoke the audible alarm. 241 \brief The Sound class plays WAVE sound files and can invoke the audible alarm.
242 242
243 The Sound class is constructed with the .wav music file name. The Sound 243 The Sound class is constructed with the .wav music file name. The Sound
244 class retrieves the sound file from the shared Resource class. This class 244 class retrieves the sound file from the shared Resource class. This class
245 ties together QSound and the available sound resources. 245 ties together QSound and the available sound resources.
246 246
247 To sound an audible system alarm, call the static method soundAlarm() 247 To sound an audible system alarm, call the static method soundAlarm()
248 248
249 \ingroup qtopiaemb 249 \ingroup qtopiaemb
250*/ 250*/
251 251
252 252#ifndef QT_NO_SOUND
253#include "sound.moc" 253#include "sound.moc"
254#endif