00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #ifndef SOUND_H
00016 #define SOUND_H
00017
00018 #include <SDL/SDL.h>
00019 #include <vorbis/codec.h>
00020 #include <vorbis/vorbisfile.h>
00021 #include <adsomath.h>
00022
00023 #define MAX_AUDIO_CHANNELS 64
00024 #define SOUND_PROCESS_NUM 2
00025 #define SOUND_PHOTON_NUM 3
00026 #define SOUNDWAVE_MAX_WAVES 4
00027
00029
00031
00033
00034 #define FormatID 'fmt '
00035 #define DataID 'data'
00036
00037 typedef char ChunkID[4];
00038
00039 #define checkID(a,b) (a[0]==b[0] && a[1]==b[1] && a[2]==b[2] && a[3]==b[3])
00040
00041 struct FileChunk {
00042 ChunkID RiffID;
00043 int chunkSize;
00044 ChunkID WaveID;
00045 };
00046
00047 struct ChunkHeader {
00048 ChunkID chunkID;
00049 long chunkSize;
00050 };
00051
00052 struct FormatChunk {
00053 short wFormatTag;
00054 unsigned short wChannels;
00055 unsigned long dwSamplesPerSec;
00056 unsigned long dwAvgBytesPerSec;
00057 unsigned short wBlockAlign;
00058 unsigned short wBitsPerSample;
00059 };
00060
00062
00064
00065 struct WaveData {
00066 int samplesPerSec;
00067 int bitsPerSample;
00068 int channels;
00069 int length;
00070 unsigned char *data;
00071 };
00072
00073 WaveData *readWav(FILE *file, int maxDataSize);
00074 WaveData *readRaw(FILE *file, char *filename);
00075 int isWavFile(FILE *file);
00076
00077 class StereoSample {
00078 public:
00079 short left,right;
00080 StereoSample(short l, short r) { left = l; right = r; }
00081 };
00082
00084
00086
00087 class Sound {
00088 protected:
00089 int active;
00090 int starting;
00091 int stereo;
00092 v3f pos;
00093 int positional;
00094
00095
00096 double lpf_alpha, lpf_beta;
00097 double lpf_x1, lpf_y1;
00098
00099 double currentFreq, targetFreq;
00100 double currentVol, targetVol;
00101 double currentVelocity, targetVelocity;
00102 double currentAttLeft, targetAttLeft;
00103 double currentAttRight, targetAttRight;
00104
00105 public:
00106 virtual short nextSample(double fragPos);
00107 virtual void startFill();
00108 virtual StereoSample nextStereoSample(double fragPos);
00109 virtual void play();
00110 virtual void playVelocity(double v);
00111 virtual void stop();
00112 int isActive(){return active;}
00113 void setFreq(double f);
00114 void setVol(double v);
00115 void setVelocity(double v);
00116 void setPos(v3f p);
00117 int isPlaying(){return active;}
00118 Sound();
00119
00120 friend void fillAudio(void *udata, Uint8 *stream, int len);
00121 friend class AudioServer;
00122 };
00123
00124 #define SOUNDSYNTH_BELL 0
00125 #define SOUNDSYNTH_ENGINE 1
00126 #define SOUNDSYNTH_BEEP 2
00127
00129
00131
00132 class SoundSynth : public Sound {
00133 int type;
00134 int samplePos;
00135 double wavePos;
00136 public:
00137 short nextSample(double fragPos);
00138 void play();
00139 void playVelocity(double v);
00140 void stop();
00141 void setType(int);
00142 };
00143
00145
00147
00148 struct Dobbler {
00149 double t, v, y;
00150 v3f d_r;
00151
00152 static const double v_s;
00153 Dobbler(v3f pos, v3f vel);
00154 Dobbler(){}
00155 };
00156
00157 class SoundWave : public Sound {
00158 int loop;
00159 int samplePos;
00160 double wavePos;
00161 WaveData *wave;
00162 WaveData *waveList[SOUNDWAVE_MAX_WAVES];
00163 int nWaves, activeWave;
00164 int dobblerEnabled;
00165 Dobbler dobbler;
00166
00167 int *ptimeArray, *pwiArray;
00168 double *pvelArray;
00169 Dobbler *pdobArray;
00170 int ptimeMax, ptimeHead, ptimeTail, playTimed;
00171 int lastFillTime, setFillTime;
00172
00173 public:
00174 short nextSample(double fragPos);
00175 StereoSample nextStereoSample(double fragPos);
00176 void startFill();
00177 void play();
00178 void playVelocity(double v);
00179 void playDobbler(double,Dobbler);
00180 void enableDobbler(){ dobblerEnabled = 1; stereo = 1; }
00181 void enableTimedPlay();
00182 void stop();
00183 int loadWave(char*);
00184 int loadMultiWave(char*);
00185 void setActiveWave(int i){ if(i<nWaves) activeWave = i; }
00186 void setLoop(int);
00187 SoundWave(){ wave = 0; loop = 0; playTimed = 0; nWaves = 0; activeWave = 0; dobblerEnabled = 0; }
00188 };
00189
00191
00193
00194 struct SoundOggTrack {
00195 int streamPos;
00196 int pcm_length;
00197 int bars;
00198 int pre;
00199 };
00200
00201 struct SoundOggSong {
00202 short *trackList;
00203 int length;
00204 int loopStart;
00205 };
00206
00207 struct SoundOggMemFile {
00208 char *data;
00209 size_t size;
00210 long pos;
00211 };
00212
00213 class SoundOgg : public Sound {
00214 OggVorbis_File *vf0,*vf1;
00215 vorbis_info *vi;
00216 SoundOggTrack *tracks;
00217 int trackCount;
00218 int bpm;
00219 int spb;
00220
00221 char *waveBuffer0, *waveBuffer1;
00222 int buf0Index, buf0Len, buf1Index, buf1Len, bufSize;
00223 int buf0TrackPos, buf1TrackPos;
00224 int buf0TrackNum, buf1TrackNum;
00225 int stream0seek, stream1seek;
00226
00227 int current_section;
00228
00229 int rate_44100;
00230
00231 SoundOggSong *song;
00232 int songPos;
00233
00234 int nextTrack();
00235
00236 public:
00237 short nextSample(double fragPos);
00238 StereoSample nextStereoSample(double fragPos);
00239 void play();
00240 void stop();
00241 int init(char *filename);
00242 void setSong(SoundOggSong *);
00243 SoundOgg();
00244 };
00245
00246 void fillAudio(void *udata, Uint8 *stream, int len);
00247
00248
00250
00252
00253 class AudioServer {
00254 unsigned int samplePos;
00255 Sound *ch[MAX_AUDIO_CHANNELS];
00256 int nChannel;
00257 int initialized;
00258 public:
00259
00260 int init();
00261 void close();
00262 int isInitialized(){return initialized;}
00263 int addChannel(Sound *s);
00264 void setHeadPos(v3f pos, v3f d_r);
00265 void lockAudio(){
00266 if(initialized) SDL_LockAudio();
00267 }
00268 void unlockAudio(){
00269 if(initialized) SDL_UnlockAudio();
00270 }
00271
00272 AudioServer(){
00273 nChannel = 0;
00274 initialized = 0;
00275 }
00276
00277 friend void fillAudio(void *udata, Uint8 *stream, int len);
00278 };
00279
00281
00283
00284 struct OggPage {
00285 char id[4];
00286 char pad[22];
00287 unsigned char segmentCount;
00288 unsigned char segments[255];
00289 };
00290
00291
00292 class SaStream {
00293 public:
00294 FILE *file;
00295 int startPos, endPos;
00296
00297 int nextStream();
00298 SaStream(FILE *f){ file = f; startPos = 0; endPos = -1; }
00299 };
00300
00301 struct SoundArchiveEntry {
00302 char *name;
00303 char *data;
00304 int length;
00305 int rate;
00306 int channels;
00307 };
00308
00309 class SoundArchive {
00310 public:
00311 SoundArchiveEntry *entries;
00312 int entryCount;
00313
00314 WaveData *lookup(char *name);
00315
00316 int load(char *);
00317
00318 SoundArchive(){ entries = 0; entryCount = 0; }
00319 };
00320
00321 void initSound();
00322
00323 extern AudioServer audio;
00324
00325 extern SoundArchive soundArchive;
00326
00327 extern SoundSynth soundBell;
00328 extern SoundWave soundProcess[SOUND_PROCESS_NUM];
00329 extern SoundWave soundOppScore;
00330 extern SoundWave soundLogon;
00331 extern SoundWave soundCallRescue;
00332 extern SoundWave soundRescue;
00333 extern SoundWave soundRescueDeny;
00334 extern SoundWave soundTurboOn;
00335 extern SoundWave soundTurboOff;
00336 extern SoundWave soundKey;
00337 extern SoundWave soundDeadKey;
00338 extern SoundWave soundEpsilonSucces;
00339 extern SoundWave soundScreenPrint;
00340 extern SoundWave soundNetLink;
00341 extern SoundWave soundChatPrint;
00342 extern SoundWave soundUfo;
00343 extern SoundWave soundUfoBeam;
00344 extern SoundWave soundUfoHit;
00345 extern SoundWave soundPhoton[SOUND_PHOTON_NUM];
00346 extern SoundOgg soundMusic;
00347
00348 extern SoundOggSong themePrelude;
00349 extern SoundOggSong themeBriefing;
00350 extern SoundOggSong themeMissionPart1;
00351 extern SoundOggSong themeMissionPart2;
00352 extern SoundOggSong themeSuccess;
00353
00354 #endif
00355