sound.cpp
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 #include "config.h"
00037 #include <qmessagebox.h>
00038 #ifndef QT_NO_SOUND
00039 static int WAVsoundDuration(const QString& filename)
00040 {
00041
00042
00043
00044
00045 QFile input(filename);
00046 if ( !input.open(IO_ReadOnly) )
00047 return 0;
00048
00049 struct QRiffChunk {
00050 char id[4];
00051 Q_UINT32 size;
00052 char data[4];
00053 } chunk;
00054
00055 struct {
00056 Q_INT16 formatTag;
00057 Q_INT16 channels;
00058 Q_INT32 samplesPerSec;
00059 Q_INT32 avgBytesPerSec;
00060 Q_INT16 blockAlign;
00061 Q_INT16 wBitsPerSample;
00062 } chunkdata;
00063
00064 int total = 0;
00065
00066 while(1) {
00067
00068 const int n = sizeof(chunk)-sizeof(chunk.data);
00069 if ( input.readBlock((char*)&chunk,n) != n )
00070 break;
00071 if ( qstrncmp(chunk.id,"data",4) == 0 ) {
00072 total += chunkdata.avgBytesPerSec ?
00073 chunk.size * 1000 / chunkdata.avgBytesPerSec : 0;
00074
00075 input.at(input.at()+chunk.size-4);
00076 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
00077 char d[4];
00078 if ( input.readBlock(d,4) != 4 )
00079 return 0;
00080 if ( qstrncmp(d,"WAVE",4) != 0 ) {
00081
00082
00083 if ( chunk.size < 10000000 )
00084 (void)input.at(input.at()+chunk.size-4);
00085 }
00086 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
00087 if ( input.readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) )
00088 return 0;
00089 #define WAVE_FORMAT_PCM 1
00090 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
00091
00092 return 0;
00093 }
00094 } else {
00095
00096
00097 if ( chunk.size < 10000000 )
00098 (void)input.at(input.at()+chunk.size);
00099 }
00100 }
00101
00102
00103 return total;
00104 }
00105
00106 class SoundData : public QSound {
00107 public:
00108 SoundData ( const QString& name ) :
00109 QSound ( Resource::findSound ( name )),
00110 filename ( Resource::findSound ( name ))
00111 {
00112 loopsleft=0;
00113 ms = WAVsoundDuration(filename);
00114 }
00115
00116 void playLoop ( int loopcnt = -1 )
00117 {
00118
00119 loopsleft = loopcnt;
00120
00121 if ( ms )
00122 startTimer ( ms > 50 ? ms-50 : 0 );
00123 play ( );
00124 }
00125
00126 void timerEvent ( QTimerEvent *e )
00127 {
00128 if ( loopsleft >= 0 ) {
00129 if ( --loopsleft <= 0 ) {
00130 killTimer ( e-> timerId ( ));
00131 loopsleft = 0;
00132 return;
00133 }
00134 }
00135 play();
00136 }
00137
00138 bool isFinished ( ) const
00139 {
00140 return ( loopsleft == 0 );
00141 }
00142
00143 private:
00144 QString filename;
00145 int loopsleft;
00146 int ms;
00147 };
00148
00149 #endif
00150
00154 Sound::Sound(const QString& name)
00155 {
00156 #ifndef QT_NO_SOUND
00157 d = new SoundData(name);
00158 #endif
00159 }
00160
00162 Sound::~Sound()
00163 {
00164 #ifndef QT_NO_SOUND
00165 delete d;
00166 #endif
00167 }
00168
00170 void Sound::play()
00171 {
00172 #ifndef QT_NO_SOUND
00173 d->playLoop(1);
00174 #endif
00175 }
00176
00178 void Sound::playLoop()
00179 {
00180 #ifndef QT_NO_SOUND
00181 d->killTimers();
00182 d->playLoop();
00183 #endif
00184 }
00185
00187 void Sound::stop()
00188 {
00189 #ifndef QT_NO_SOUND
00190 d->killTimers();
00191 #endif
00192 }
00193
00194 bool Sound::isFinished() const
00195 {
00196 #ifndef QT_NO_SOUND
00197 return d->isFinished();
00198 #else
00199 return true;
00200 #endif
00201 }
00202
00206 void Sound::soundAlarm()
00207 {
00208 #ifndef QT_NO_COP
00209 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
00210 #endif
00211 }
00212
00213
This file is part of the documentation for OPIE Version 1.5.5.