summaryrefslogtreecommitdiff
path: root/library/sound.cpp
Unidiff
Diffstat (limited to 'library/sound.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/sound.cpp40
1 files changed, 30 insertions, 10 deletions
diff --git a/library/sound.cpp b/library/sound.cpp
index 373fd4c..602fcf0 100644
--- a/library/sound.cpp
+++ b/library/sound.cpp
@@ -1,59 +1,66 @@
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>
29#include <fcntl.h>
30#include <sys/ioctl.h>
31#include <sys/soundcard.h>
32
33#include "config.h"
34#include <qmessagebox.h>
28#ifndef QT_NO_SOUND 35#ifndef QT_NO_SOUND
29static int WAVsoundDuration(const QString& filename) 36static int WAVsoundDuration(const QString& filename)
30{ 37{
31 // bad solution 38 // bad solution
32 39
33 // most of this is copied from qsoundqss.cpp 40 // most of this is copied from qsoundqss.cpp
34 41
35 QFile input(filename); 42 QFile input(filename);
36 if ( !input.open(IO_ReadOnly) ) 43 if ( !input.open(IO_ReadOnly) )
37 return 0; 44 return 0;
38 45
39 struct QRiffChunk { 46 struct QRiffChunk {
40 char id[4]; 47 char id[4];
41 Q_UINT32 size; 48 Q_UINT32 size;
42 char data[4/*size*/]; 49 char data[4/*size*/];
43 } chunk; 50 } chunk;
44 51
45 struct { 52 struct {
46 Q_INT16 formatTag; 53 Q_INT16 formatTag;
47 Q_INT16 channels; 54 Q_INT16 channels;
48 Q_INT32 samplesPerSec; 55 Q_INT32 samplesPerSec;
49 Q_INT32 avgBytesPerSec; 56 Q_INT32 avgBytesPerSec;
50 Q_INT16 blockAlign; 57 Q_INT16 blockAlign;
51 Q_INT16 wBitsPerSample; 58 Q_INT16 wBitsPerSample;
52 } chunkdata; 59 } chunkdata;
53 60
54 int total = 0; 61 int total = 0;
55 62
56 while(1) { 63 while(1) {
57 // Keep reading chunks... 64 // Keep reading chunks...
58 const int n = sizeof(chunk)-sizeof(chunk.data); 65 const int n = sizeof(chunk)-sizeof(chunk.data);
59 if ( input.readBlock((char*)&chunk,n) != n ) 66 if ( input.readBlock((char*)&chunk,n) != n )
@@ -70,104 +77,117 @@ static int WAVsoundDuration(const QString& filename)
70 if ( qstrncmp(d,"WAVE",4) != 0 ) { 77 if ( qstrncmp(d,"WAVE",4) != 0 ) {
71 // skip 78 // skip
72//qDebug("skip %.4s RIFF chunk",d); 79//qDebug("skip %.4s RIFF chunk",d);
73 if ( chunk.size < 10000000 ) 80 if ( chunk.size < 10000000 )
74 (void)input.at(input.at()+chunk.size-4); 81 (void)input.at(input.at()+chunk.size-4);
75 } 82 }
76 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) { 83 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
77 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) 84 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) )
78 return 0; 85 return 0;
79#define WAVE_FORMAT_PCM 1 86#define WAVE_FORMAT_PCM 1
80 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) { 87 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
81 //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag); 88 //qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
82 return 0; 89 return 0;
83 } 90 }
84 } else { 91 } else {
85//qDebug("skip %.4s chunk",chunk.id); 92//qDebug("skip %.4s chunk",chunk.id);
86 // ignored chunk 93 // ignored chunk
87 if ( chunk.size < 10000000 ) 94 if ( chunk.size < 10000000 )
88 (void)input.at(input.at()+chunk.size); 95 (void)input.at(input.at()+chunk.size);
89 } 96 }
90 } 97 }
91 98
92//qDebug("%dms",total); 99//qDebug("%dms",total);
93 return total; 100 return total;
94} 101}
95 102
96class SoundData : public QSound { 103class SoundData : public QSound {
97public: 104public:
98 SoundData(const QString& name) : 105 SoundData(const QString& name) :
99 QSound(Resource::findSound(name)), 106 QSound(Resource::findSound(name)),
100 filename(Resource::findSound(name)) 107 filename(Resource::findSound(name))
101 { 108 {
109 loopsleft=0;
102 } 110 }
103 111
104 void playLoop() 112 void playLoop(int loopcnt = -1)
105 { 113 {
106 // needs server support 114 // needs server support
115 loopsleft = loopcnt;
107 116
108 int ms = WAVsoundDuration(filename); 117 int ms = WAVsoundDuration(filename);
109 if ( ms ) 118 if ( ms )
110 startTimer(ms > 50 ? ms-50 : 0); // 50 for latency 119 startTimer(ms > 50 ? ms-50 : 0); // 50 for latency
111 play(); 120 play();
112 } 121 }
113 122
114 void timerEvent(QTimerEvent*) 123 void timerEvent ( QTimerEvent *e )
115 { 124 {
125 if (loopsleft >= 0) {
126 if (--loopsleft <= 0)
127 killTimer (e->timerId());
128 return;
129 }
116 play(); 130 play();
117 } 131 }
132
133 bool isFinished ( ) const
134 {
135 return ( loopsleft == 0 );
136 }
118 137
119private: 138private:
120 QString filename; 139 QString filename;
140 int loopsleft;
121}; 141};
122#endif 142#endif
123 143
124Sound::Sound(const QString& name) 144Sound::Sound(const QString& name)
125{ 145{
126#ifndef QT_NO_SOUND 146#ifndef QT_NO_SOUND
127 d = new SoundData(name); 147 d = new SoundData(name);
128#endif 148#endif
129} 149}
130 150
131Sound::~Sound() 151Sound::~Sound()
132{ 152{
133#ifndef QT_NO_SOUND 153#ifndef QT_NO_SOUND
134 delete d; 154 delete d;
135#endif 155#endif
136} 156}
137 157
138void Sound::play() 158void Sound::play()
139{ 159{
140#ifndef QT_NO_SOUND 160#ifndef QT_NO_SOUND
141 d->killTimers(); 161 d->killTimers();
142 d->play(); 162 d->playLoop(1);
143#endif 163#endif
144} 164}
145 165
146void Sound::playLoop() 166void Sound::playLoop()
147{ 167{
148#ifndef QT_NO_SOUND 168#ifndef QT_NO_SOUND
149 d->killTimers(); 169 d->killTimers();
150 d->playLoop(); 170 d->playLoop();
151#endif 171#endif
152} 172}
153 173
154void Sound::stop() 174void Sound::stop()
155{ 175{
156#ifndef QT_NO_SOUND 176#ifndef QT_NO_SOUND
157 d->killTimers(); 177 d->killTimers();
158#endif 178#endif
159} 179}
160 180
181bool Sound::isFinished() const
182{
183#ifndef QT_NO_SOUND
184 return d->isFinished();
185#endif
186}
161 187
162void Sound::soundAlarm() 188void Sound::soundAlarm()
163{ 189{
164#ifdef QT_QWS_CUSTOM 190#ifndef QT_NO_COP
165# ifndef QT_NO_COP
166 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" ); 191 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
167# endif
168#else
169# ifndef QT_NO_SOUND
170 QSound::play(Resource::findSound("alarm"));
171# endif
172#endif 192#endif
173} 193}