00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qpe/resource.h>
00022 #include <qpe/sound.h>
00023 #include <qpe/qcopenvelope_qws.h>
00024
00025 #include <qsound.h>
00026 #include <qfile.h>
00027
00028 #include <unistd.h>
00029 #include <fcntl.h>
00030 #include <sys/ioctl.h>
00031
00032 #ifndef QT_NO_SOUND
00033 #include <sys/soundcard.h>
00034 #endif
00035
00036 #ifndef QT_NO_SOUND
00037 static int WAVsoundDuration(const QString& filename)
00038 {
00039
00040
00041
00042
00043 QFile input(filename);
00044 if ( !input.open(IO_ReadOnly) )
00045 return 0;
00046
00047 struct QRiffChunk {
00048 char id[4];
00049 Q_UINT32 size;
00050 char data[4];
00051 } chunk;
00052
00053 struct {
00054 Q_INT16 formatTag;
00055 Q_INT16 channels;
00056 Q_INT32 samplesPerSec;
00057 Q_INT32 avgBytesPerSec;
00058 Q_INT16 blockAlign;
00059 Q_INT16 wBitsPerSample;
00060 } chunkdata;
00061
00062 int total = 0;
00063
00064 while(1) {
00065
00066 const int n = sizeof(chunk)-sizeof(chunk.data);
00067 if ( input.readBlock((char*)&chunk,n) != n )
00068 break;
00069 if ( qstrncmp(chunk.id,"data",4) == 0 ) {
00070 total += chunkdata.avgBytesPerSec ?
00071 chunk.size * 1000 / chunkdata.avgBytesPerSec : 0;
00072
00073 input.at(input.at()+chunk.size-4);
00074 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
00075 char d[4];
00076 if ( input.readBlock(d,4) != 4 )
00077 return 0;
00078 if ( qstrncmp(d,"WAVE",4) != 0 ) {
00079
00080
00081 if ( chunk.size < 10000000 )
00082 (void)input.at(input.at()+chunk.size-4);
00083 }
00084 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
00085 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) )
00086 return 0;
00087 #define WAVE_FORMAT_PCM 1
00088 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
00089
00090 return 0;
00091 }
00092 } else {
00093
00094
00095 if ( chunk.size < 10000000 )
00096 (void)input.at(input.at()+chunk.size);
00097 }
00098 }
00099
00100
00101 return total;
00102 }
00103
00104 class SoundData : public QSound {
00105 Q_OBJECT
00106 signals:
00107 void stopped();
00108 public:
00109 SoundData ( const QString& name ) :
00110 QSound ( Resource::findSound ( name )),
00111 filename ( Resource::findSound ( name ))
00112 {
00113 loopsleft=0;
00114 ms = WAVsoundDuration(filename);
00115 }
00116
00117 void playLoop ( int loopcnt = -1 )
00118 {
00119
00120 loopsleft = loopcnt;
00121
00122 if ( ms )
00123 startTimer ( ms > 50 ? ms-50 : 0 );
00124 play ( );
00125 }
00126
00127 void timerEvent ( QTimerEvent *e )
00128 {
00129 if ( loopsleft >= 0 ) {
00130 if ( --loopsleft <= 0 ) {
00131 killTimer ( e-> timerId ( ));
00132 loopsleft = 0;
00133 return;
00134 }
00135 }
00136 play();
00137 }
00138
00139 bool isFinished ( ) const
00140 {
00141 return ( loopsleft == 0 );
00142 }
00143
00144
00145
00146
00147
00148 void killTimers() {
00149 QObject::killTimers();
00150 emit stopped();
00151 }
00152
00153 private:
00154 QString filename;
00155 int loopsleft;
00156 int ms;
00157 };
00158
00159 #endif
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 void register_qpe_sound_finished( Sound* snd, QObject* obj, const char* slot ) {
00171 #ifndef QT_NO_SOUND
00172 QObject::connect(snd->d, SIGNAL(stopped()), obj, slot );
00173 #endif
00174 }
00175
00179 Sound::Sound(const QString& name)
00180 {
00181 #ifndef QT_NO_SOUND
00182 d = new SoundData(name);
00183 #endif
00184 }
00185
00187 Sound::~Sound()
00188 {
00189 #ifndef QT_NO_SOUND
00190 delete d;
00191 #endif
00192 }
00193
00195 void Sound::play()
00196 {
00197 #ifndef QT_NO_SOUND
00198 d->killTimers();
00199 d->playLoop(1);
00200 #endif
00201 }
00202
00204 void Sound::playLoop()
00205 {
00206 #ifndef QT_NO_SOUND
00207 d->killTimers();
00208 d->playLoop();
00209 #endif
00210 }
00211
00213 void Sound::stop()
00214 {
00215 #ifndef QT_NO_SOUND
00216 d->killTimers();
00217 #endif
00218 }
00219
00220 bool Sound::isFinished() const
00221 {
00222 #ifndef QT_NO_SOUND
00223 return d->isFinished();
00224 #else
00225 return true;
00226 #endif
00227 }
00228
00232 void Sound::soundAlarm()
00233 {
00234 #ifndef QT_NO_COP
00235 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
00236 #endif
00237 }
00238
00239
00252 #ifndef QT_NO_SOUND
00253 #include "sound.moc"
00254 #endif