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