#include #define USE_RWOPS #include #include #include #include #include "physfsrwops.h" #include //#include "wavestream2.h" class SoundDevice { public: SoundDevice(); ~SoundDevice(); void close(); void open(); void open(int r, Uint16 f, int c, int bs); const char* getCardName() { return cardName; } private: char cardName[50]; int rate; int channels; int bufSize; Uint16 format; int _status; }; SoundDevice::SoundDevice() { memset(cardName, 0, sizeof(cardName)); rate = 44100; channels = 2; bufSize = 4096; format = AUDIO_S16; _status = 0; } SoundDevice::~SoundDevice() { Mix_HaltGroup(-1); Mix_HaltMusic(); close(); } void SoundDevice::close() { if (!_status) return; Mix_CloseAudio(); } void SoundDevice::open() { if (_status) close(); if (Mix_OpenAudio(rate, format, channels, bufSize)) throw std::string(SDL_GetError()); SDL_AudioDriverName (cardName, sizeof (cardName)); Mix_QuerySpec(&rate, &format, &channels); fprintf (stderr, "opened %s at %d Hz %d bit %s (%i), %d bytes audio buffer\n", cardName, rate, format & 0xFF, channels > 1 ? "stereo" : "mono", channels, bufSize); _status = 1; } void SoundDevice::open(int r, Uint16 f, int c, int bs) { rate = r; format = f; channels = c; bufSize = bs; open(); } int music_volume=127; bool sound_enabled=false; bool playing_music=false; Sound_Sample *music_sound=0; int music_loops=1; int current_music_loop=0; void myMusicPlayer(void *udata, Uint8 *stream, int len) { int i,act=0; Sint16 *ptr2; if (stream == 0) throw std::string("Zero music stream :-("); ptr2=(Sint16 *)stream; if (playing_music) { while(actflags&SOUND_SAMPLEFLAG_EOF)) { /* End of file: */ if (music_loops!=-1) { current_music_loop++; if (current_music_loop>music_loops) { playing_music=false; if (music_sound!=0) Sound_FreeSample(music_sound); music_sound=0; } else { Sound_Rewind(music_sound); } /* if */ } else { Sound_Rewind(music_sound); } /* if */ } else { /* In the middle of the file: */ int decoded=0; Sint16 *ptr; Sound_SetBufferSize(music_sound, len-act); decoded=Sound_Decode(music_sound); ptr=(Sint16 *)music_sound->buffer; for(i=0;i o.idx_in_file) return false; return src_file < o.src_file; } }; struct ChunkData { Uint8 * mem_buf; Mix_Chunk * chunk; size_t ref; ChunkData(Uint8 * m, Mix_Chunk * c, size_t r = 1) : mem_buf(m), chunk(c), ref(r) {} ChunkData(const ChunkData & o) : mem_buf(o.mem_buf), chunk(o.chunk), ref(o.ref) {} }; typedef std::map< ChunkId, ChunkData > CacheType; CacheType cached; ChunkData & getChunk(std::string & file, size_t idx); void prepareDB(std::string db_file); OpenGTA::SoundsDB * getDB(std::string db_file); private: ChunkData loadChunk(std::string & file, size_t idx); typedef std::map< std::string, OpenGTA::SoundsDB* > LookupCache; LookupCache lookup; }; AudioChunkCache::ChunkData & AudioChunkCache::getChunk(std::string & file, size_t idx) { ChunkId id(file, idx); CacheType::iterator i = cached.find(id); if (i == cached.end()) { ChunkData c = loadChunk(file, idx); cached.insert(std::make_pair(id, c)); i = cached.find(id); } return i->second; } AudioChunkCache::ChunkData AudioChunkCache::loadChunk(std::string & file, size_t idx) { LookupCache::iterator j = lookup.find(file); if (j == lookup.end()) { prepareDB(file); j = lookup.find(file); } OpenGTA::SoundsDB & db = *j->second; OpenGTA::SoundsDB::Entry & e = db.getEntry(idx); size_t si; unsigned char* mem = db.getBuffered(idx); Uint8 *mem2 = (Uint8*)Audio::resample_new(mem, e.rawSize, si, e.sampleRate, 44100); Mix_Chunk * music = Mix_QuickLoad_RAW(mem2, si); return ChunkData(mem2, music, 1); } void AudioChunkCache::prepareDB(std::string db) { lookup[db] = new OpenGTA::SoundsDB(db); } int main(int argc, char *argv[]) { PHYSFS_init(argv[0]); PHYSFS_addToSearchPath("gtadata.zip", 1); PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1); Uint32 sdl_init_flags = SDL_INIT_AUDIO | SDL_INIT_VIDEO; if (SDL_Init(sdl_init_flags) == -1) { fprintf(stderr, "SDL_Init() failed!\n" " reason: [%s].\n", SDL_GetError()); return(42); } SoundDevice dev; dev.open(); if (argc == 3) { AudioChunkCache acc; std::string foo(argv[1]); AudioChunkCache::ChunkData & cd = acc.getChunk(foo, atoi(argv[2])); /* OpenGTA::SoundsDB db(argv[1]); OpenGTA::SoundsDB::Entry & e = db.getEntry(atoi(argv[2])); unsigned char* mem = db.getBuffered(atoi(argv[2])); size_t si; Uint8 *mem2 = (Uint8*)Audio::resample_new(mem, e.rawSize, si, e.sampleRate, 44100); //write(1, mem, e.rawSize+ 36 + 8); //SDL_RWops *handle = PHYSFSRWOPS_openRead(argv[1]); //SDL_RWops * handle = SDL_RWFromMem(mem, e.rawSize + 36 + 8); //assert(handle); //Mix_Chunk * music = Mix_LoadWAV_RW(handle, 1); Mix_Chunk * music = Mix_QuickLoad_RAW(mem2, si); if (!music) { fprintf(stderr, "Error loading music: %s\n", SDL_GetError()); } delete [] mem; Mix_PlayChannel(0,music,0); */ Mix_PlayChannel(0, cd.chunk, 0); } else { /* SDL_RWops * rw = PHYSFSRWOPS_openRead(argv[1]); assert(rw); Mix_Music * music = Mix_LoadMUS_RW(rw); assert(music); Mix_PlayMusic(music, 0); */ Sound_Init(); Sound_AudioInfo inf; #define AUDIO_BUFFER 4096 inf.format=AUDIO_S16; inf.channels=2; inf.rate=44100; SDL_RWops * rw = PHYSFSRWOPS_openRead(argv[1]); assert(rw); music_sound = Sound_NewSample(rw, "mp3" ,&inf,AUDIO_BUFFER); assert(music_sound); Mix_HookMusic(myMusicPlayer, 0); playing_music = true; } //while (Mix_Playing(0)) { while (playing_music) { SDL_Delay(1000); } //delete [] mem2; Mix_HaltMusic(); //Mix_FreeChunk(music); //music = NULL; SDL_Quit(); return(0); }