summaryrefslogtreecommitdiff
path: root/library/sound.cpp
Unidiff
Diffstat (limited to 'library/sound.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/sound.cpp2
1 files changed, 0 insertions, 2 deletions
diff --git a/library/sound.cpp b/library/sound.cpp
index 5b67995..ee2aabc 100644
--- a/library/sound.cpp
+++ b/library/sound.cpp
@@ -1,224 +1,222 @@
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#include "config.h"
37#include <qmessagebox.h>
38#ifndef QT_NO_SOUND 36#ifndef QT_NO_SOUND
39static int WAVsoundDuration(const QString& filename) 37static int WAVsoundDuration(const QString& filename)
40{ 38{
41 // bad solution 39 // bad solution
42 40
43 // most of this is copied from qsoundqss.cpp 41 // most of this is copied from qsoundqss.cpp
44 42
45 QFile input(filename); 43 QFile input(filename);
46 if ( !input.open(IO_ReadOnly) ) 44 if ( !input.open(IO_ReadOnly) )
47 return 0; 45 return 0;
48 46
49 struct QRiffChunk { 47 struct QRiffChunk {
50 char id[4]; 48 char id[4];
51 Q_UINT32 size; 49 Q_UINT32 size;
52 char data[4/*size*/]; 50 char data[4/*size*/];
53 } chunk; 51 } chunk;
54 52
55 struct { 53 struct {
56 Q_INT16 formatTag; 54 Q_INT16 formatTag;
57 Q_INT16 channels; 55 Q_INT16 channels;
58 Q_INT32 samplesPerSec; 56 Q_INT32 samplesPerSec;
59 Q_INT32 avgBytesPerSec; 57 Q_INT32 avgBytesPerSec;
60 Q_INT16 blockAlign; 58 Q_INT16 blockAlign;
61 Q_INT16 wBitsPerSample; 59 Q_INT16 wBitsPerSample;
62 } chunkdata; 60 } chunkdata;
63 61
64 int total = 0; 62 int total = 0;
65 63
66 while(1) { 64 while(1) {
67 // Keep reading chunks... 65 // Keep reading chunks...
68 const int n = sizeof(chunk)-sizeof(chunk.data); 66 const int n = sizeof(chunk)-sizeof(chunk.data);
69 if ( input.readBlock((char*)&chunk,n) != n ) 67 if ( input.readBlock((char*)&chunk,n) != n )
70 break; 68 break;
71 if ( qstrncmp(chunk.id,"data",4) == 0 ) { 69 if ( qstrncmp(chunk.id,"data",4) == 0 ) {
72 total += chunkdata.avgBytesPerSec ? 70 total += chunkdata.avgBytesPerSec ?
73 chunk.size * 1000 / chunkdata.avgBytesPerSec : 0; 71 chunk.size * 1000 / chunkdata.avgBytesPerSec : 0;
74//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);
75 input.at(input.at()+chunk.size-4); 73 input.at(input.at()+chunk.size-4);
76 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) { 74 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
77 char d[4]; 75 char d[4];
78 if ( input.readBlock(d,4) != 4 ) 76 if ( input.readBlock(d,4) != 4 )
79 return 0; 77 return 0;
80 if ( qstrncmp(d,"WAVE",4) != 0 ) { 78 if ( qstrncmp(d,"WAVE",4) != 0 ) {
81 // skip 79 // skip
82//qDebug("skip %.4s RIFF chunk",d); 80//qDebug("skip %.4s RIFF chunk",d);
83 if ( chunk.size < 10000000 ) 81 if ( chunk.size < 10000000 )
84 (void)input.at(input.at()+chunk.size-4); 82 (void)input.at(input.at()+chunk.size-4);
85 } 83 }
86 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) { 84 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
87 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) 85 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) )
88 return 0; 86 return 0;
89#define WAVE_FORMAT_PCM 1 87#define WAVE_FORMAT_PCM 1
90 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) { 88 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
91 //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag); 89 //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
92 return 0; 90 return 0;
93 } 91 }
94 } else { 92 } else {
95//qDebug("skip %.4s chunk",chunk.id); 93//qDebug("skip %.4s chunk",chunk.id);
96 // ignored chunk 94 // ignored chunk
97 if ( chunk.size < 10000000 ) 95 if ( chunk.size < 10000000 )
98 (void)input.at(input.at()+chunk.size); 96 (void)input.at(input.at()+chunk.size);
99 } 97 }
100 } 98 }
101 99
102//qDebug("%dms",total); 100//qDebug("%dms",total);
103 return total; 101 return total;
104} 102}
105 103
106class SoundData : public QSound { 104class SoundData : public QSound {
107public: 105public:
108 SoundData ( const QString& name ) : 106 SoundData ( const QString& name ) :
109 QSound ( Resource::findSound ( name )), 107 QSound ( Resource::findSound ( name )),
110 filename ( Resource::findSound ( name )) 108 filename ( Resource::findSound ( name ))
111 { 109 {
112 loopsleft=0; 110 loopsleft=0;
113 ms = WAVsoundDuration(filename); 111 ms = WAVsoundDuration(filename);
114 } 112 }
115 113
116 void playLoop ( int loopcnt = -1 ) 114 void playLoop ( int loopcnt = -1 )
117 { 115 {
118 // needs server support 116 // needs server support
119 loopsleft = loopcnt; 117 loopsleft = loopcnt;
120 118
121 if ( ms ) 119 if ( ms )
122 startTimer ( ms > 50 ? ms-50 : 0 ); // 50 for latency 120 startTimer ( ms > 50 ? ms-50 : 0 ); // 50 for latency
123 play ( ); 121 play ( );
124 } 122 }
125 123
126 void timerEvent ( QTimerEvent *e ) 124 void timerEvent ( QTimerEvent *e )
127 { 125 {
128 if ( loopsleft >= 0 ) { 126 if ( loopsleft >= 0 ) {
129 if ( --loopsleft <= 0 ) { 127 if ( --loopsleft <= 0 ) {
130 killTimer ( e-> timerId ( )); 128 killTimer ( e-> timerId ( ));
131 loopsleft = 0; 129 loopsleft = 0;
132 return; 130 return;
133 } 131 }
134 } 132 }
135 play(); 133 play();
136 } 134 }
137 135
138 bool isFinished ( ) const 136 bool isFinished ( ) const
139 { 137 {
140 return ( loopsleft == 0 ); 138 return ( loopsleft == 0 );
141 } 139 }
142 140
143private: 141private:
144 QString filename; 142 QString filename;
145 int loopsleft; 143 int loopsleft;
146 int ms; 144 int ms;
147}; 145};
148 146
149#endif 147#endif
150 148
151/*! Opens a wave sound file \a name for playing 149/*! Opens a wave sound file \a name for playing
152 * Resource is used for finding the file 150 * Resource is used for finding the file
153 **/ 151 **/
154Sound::Sound(const QString& name) 152Sound::Sound(const QString& name)
155{ 153{
156#ifndef QT_NO_SOUND 154#ifndef QT_NO_SOUND
157 d = new SoundData(name); 155 d = new SoundData(name);
158#endif 156#endif
159} 157}
160 158
161/*! Destroys the sound */ 159/*! Destroys the sound */
162Sound::~Sound() 160Sound::~Sound()
163{ 161{
164#ifndef QT_NO_SOUND 162#ifndef QT_NO_SOUND
165 delete d; 163 delete d;
166#endif 164#endif
167} 165}
168 166
169/*! Play the sound once */ 167/*! Play the sound once */
170void Sound::play() 168void Sound::play()
171{ 169{
172#ifndef QT_NO_SOUND 170#ifndef QT_NO_SOUND
173 d->playLoop(1); 171 d->playLoop(1);
174#endif 172#endif
175} 173}
176 174
177/*! Play the sound, repeatedly until stop() is called */ 175/*! Play the sound, repeatedly until stop() is called */
178void Sound::playLoop() 176void Sound::playLoop()
179{ 177{
180#ifndef QT_NO_SOUND 178#ifndef QT_NO_SOUND
181 d->killTimers(); 179 d->killTimers();
182 d->playLoop(); 180 d->playLoop();
183#endif 181#endif
184} 182}
185 183
186/*! Do not repeat the sound after it finishes. This will end a playLoop() */ 184/*! Do not repeat the sound after it finishes. This will end a playLoop() */
187void Sound::stop() 185void Sound::stop()
188{ 186{
189#ifndef QT_NO_SOUND 187#ifndef QT_NO_SOUND
190 d->killTimers(); 188 d->killTimers();
191#endif 189#endif
192} 190}
193 191
194bool Sound::isFinished() const 192bool Sound::isFinished() const
195{ 193{
196#ifndef QT_NO_SOUND 194#ifndef QT_NO_SOUND
197 return d->isFinished(); 195 return d->isFinished();
198#else 196#else
199 return true; 197 return true;
200#endif 198#endif
201} 199}
202 200
203/*! Sounds the audible system alarm. This is used for applications such 201/*! Sounds the audible system alarm. This is used for applications such
204 as Calendar when it needs to alarm the user of an event. 202 as Calendar when it needs to alarm the user of an event.
205*/ 203*/
206void Sound::soundAlarm() 204void Sound::soundAlarm()
207{ 205{
208#ifndef QT_NO_COP 206#ifndef QT_NO_COP
209 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" ); 207 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
210#endif 208#endif
211} 209}
212 210
213 211
214/*! \class Sound 212/*! \class Sound
215 \brief The Sound class plays WAVE sound files and can invoke the audible alarm. 213 \brief The Sound class plays WAVE sound files and can invoke the audible alarm.
216 214
217 The Sound class is constructed with the .wav music file name. The Sound 215 The Sound class is constructed with the .wav music file name. The Sound
218 class retrieves the sound file from the shared Resource class. This class 216 class retrieves the sound file from the shared Resource class. This class
219 ties together QSound and the available sound resources. 217 ties together QSound and the available sound resources.
220 218
221 To sound an audible system alarm, call the static method soundAlarm() 219 To sound an audible system alarm, call the static method soundAlarm()
222 220
223 \ingroup qtopiaemb 221 \ingroup qtopiaemb
224*/ 222*/