diff options
author | Joost Peters | 2003-10-28 15:26:05 +0000 |
---|---|---|
committer | Joost Peters | 2003-10-28 15:26:05 +0000 |
commit | ee276b12b829a675043bfd12a92e3cb82b4ca064 (patch) | |
tree | 08631b163d52dcd93d65592d733a3a0da086f3d9 /queen/sound.cpp | |
parent | cb2306373d9b1be5d61e25999af249fb6632865d (diff) | |
download | scummvm-rg350-ee276b12b829a675043bfd12a92e3cb82b4ca064.tar.gz scummvm-rg350-ee276b12b829a675043bfd12a92e3cb82b4ca064.tar.bz2 scummvm-rg350-ee276b12b829a675043bfd12a92e3cb82b4ca064.zip |
add OGG playback to queen
svn-id: r10993
Diffstat (limited to 'queen/sound.cpp')
-rw-r--r-- | queen/sound.cpp | 104 |
1 files changed, 103 insertions, 1 deletions
diff --git a/queen/sound.cpp b/queen/sound.cpp index 1236da94a4..9938472d4e 100644 --- a/queen/sound.cpp +++ b/queen/sound.cpp @@ -30,6 +30,69 @@ namespace Queen { +#ifdef USE_VORBIS +// These are wrapper functions to allow using a File object to +// provide data to the OggVorbis_File object. + +struct file_info { + File *file; + int start, curr_pos; + size_t len; +}; + +static size_t read_wrap(void *ptr, size_t size, size_t nmemb, void *datasource) { + file_info *f = (file_info *) datasource; + int result; + + nmemb *= size; + if (f->curr_pos > (int) f->len) + nmemb = 0; + else if (nmemb > f->len - f->curr_pos) + nmemb = f->len - f->curr_pos; + result = f->file->read(ptr, nmemb); + if (result == -1) { + f->curr_pos = f->file->pos() - f->start; + return (size_t) -1; + } else { + f->curr_pos += result; + return result / size; + } +} + +static int seek_wrap(void *datasource, ogg_int64_t offset, int whence) { + file_info *f = (file_info *) datasource; + + if (whence == SEEK_SET) + offset += f->start; + else if (whence == SEEK_END) { + offset += f->start + f->len; + whence = SEEK_SET; + } + + f->file->seek(offset, whence); + f->curr_pos = f->file->pos() - f->start; + return f->curr_pos; +} + +static int close_wrap(void *datasource) { + file_info *f = (file_info *) datasource; + + f->file->close(); + delete f; + return 0; +} + +static long tell_wrap(void *datasource) { + file_info *f = (file_info *) datasource; + + return f->curr_pos; +} + +static ov_callbacks g_File_wrap = { + read_wrap, seek_wrap, close_wrap, tell_wrap +}; +#endif + Sound::Sound(SoundMixer *mixer, Input *input, Resource *resource) : _mixer(mixer), _input(input), _resource(resource), _sfxHandle(0) { } @@ -51,6 +114,13 @@ Sound *Sound::giveSound(SoundMixer *mixer, Input *input, Resource *resource, uin #endif break; + case COMPRESSION_OGG: + #ifndef USE_VORBIS + warning("Using OGG compressed datafile, but OGG support not compiled in"); + #else + return new OGGSound(mixer, input, resource); + #endif + break; default: warning("Unknown compression type"); return new SilentSound(mixer, input, resource); @@ -98,7 +168,39 @@ void MP3Sound::sfxPlay(const char *base) { _input->delay(10); if (_resource->exists(name)) - _mixer->playMP3(&_sfxHandle, _resource->giveMP3(name), _resource->fileSize(name)); + _mixer->playMP3(&_sfxHandle, _resource->giveCompressedSound(name), _resource->fileSize(name)); +} +#endif + +#ifdef USE_VORBIS +void OGGSound::sfxPlay(const char *base) { + char name[13]; + strcpy(name, base); + //alter filename to add zeros and append ".SB" + for (int i = 0; i < 8; i++) { + if (name[i] == ' ') + name[i] = '0'; + } + strcat(name, ".SB"); + + while(isPlaying()) + _input->delay(10); + + if (_resource->exists(name)) { + OggVorbis_File *oggFile = new OggVorbis_File; + file_info *f = new file_info; + + f->file = _resource->giveCompressedSound(name); + f->start = _resource->fileOffset(name); + f->len = _resource->fileSize(name); + f->curr_pos = 0; + + if (ov_open_callbacks((void *)f, oggFile, NULL, 0, g_File_wrap) < 0) { + delete oggFile; + delete f; + } else + _mixer->playVorbis(&_sfxHandle, oggFile, 0, false); + } } #endif |