-rw-r--r-- | library/sound.cpp | 173 |
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 | ||
29 | static 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 | |||
96 | class SoundData : public QSound { | ||
97 | public: | ||
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 | |||
119 | private: | ||
120 | QString filename; | ||
121 | }; | ||
122 | #endif | ||
123 | |||
124 | Sound::Sound(const QString& name) | ||
125 | { | ||
126 | #ifndef QT_NO_SOUND | ||
127 | d = new SoundData(name); | ||
128 | #endif | ||
129 | } | ||
130 | |||
131 | Sound::~Sound() | ||
132 | { | ||
133 | #ifndef QT_NO_SOUND | ||
134 | delete d; | ||
135 | #endif | ||
136 | } | ||
137 | |||
138 | void Sound::play() | ||
139 | { | ||
140 | #ifndef QT_NO_SOUND | ||
141 | d->killTimers(); | ||
142 | d->play(); | ||
143 | #endif | ||
144 | } | ||
145 | |||
146 | void Sound::playLoop() | ||
147 | { | ||
148 | #ifndef QT_NO_SOUND | ||
149 | d->killTimers(); | ||
150 | d->playLoop(); | ||
151 | #endif | ||
152 | } | ||
153 | |||
154 | void Sound::stop() | ||
155 | { | ||
156 | #ifndef QT_NO_SOUND | ||
157 | d->killTimers(); | ||
158 | #endif | ||
159 | } | ||
160 | |||
161 | |||
162 | void 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 | } | ||