Ticket #8110: sog.diff

File sog.diff, 8.4 KB (added by SF/dschepler, 19 years ago)

monster.sog support in scummvm

  • scumm/sound.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
    retrieving revision 1.43
    diff -u -r1.43 sound.cpp
     
    738738        int rate, comp;
    739739        byte *data;
    740740
    741 #ifdef USE_MAD
     741#ifdef COMPRESSED_SOUND_FILE
    742742        if (file_size > 0) {
    743                 data = (byte *)calloc(file_size + MAD_BUFFER_GUARD, 1);
     743                int alloc_size = file_size;
     744#ifdef USE_MAD
     745                if (! _vorbis_mode)
     746                        alloc_size += MAD_BUFFER_GUARD;
     747#endif
     748                data = (byte *)calloc(alloc_size, 1);
    744749
    745750                if (file->read(data, file_size) != (uint)file_size) {
    746751                        /* no need to free the memory since error will shut down */
    747752                        error("startSfxSound: cannot read %d bytes", size);
    748753                        return -1;
    749754                }
    750                 return playSfxSound_MP3(data, file_size);
     755                if (_vorbis_mode)
     756                        return playSfxSound_Vorbis(data, file_size);
     757                else
     758                        return playSfxSound_MP3(data, file_size);
    751759        }
    752760#endif
    753761        if (file->read(ident, 8) != 8)
     
    805813#ifdef COMPRESSED_SOUND_FILE
    806814        offset_table = NULL;
    807815
     816#ifdef USE_MAD
    808817        sprintf(buf, "%s.so3", _scumm->_exe_name);
    809818        if (!file->open(buf, _scumm->getGameDataPath())) {
    810819                file->open("monster.so3", _scumm->getGameDataPath());
    811820        }
     821        if (file->isOpen())
     822                _vorbis_mode = false;
     823        else
     824#endif
     825#ifdef USE_VORBIS
     826                {
     827                        sprintf(buf, "%s.sog", _scumm->_exe_name);
     828                        if (!file->open(buf, _scumm->getGameDataPath()))
     829                                file->open("monster.sog", _scumm->getGameDataPath());
     830                        if (file->isOpen())
     831                                _vorbis_mode = true;
     832                }
     833#endif
     834
    812835        if (file->isOpen() == true) {
    813836                /* Now load the 'offset' index in memory to be able to find the MP3 data
    814837
     
    11241147        return -1;
    11251148}
    11261149
     1150#ifdef USE_VORBIS
     1151// Provide a virtual file to vorbisfile based on preloaded data
     1152struct data_file_info {
     1153        char *data;
     1154        uint32 size;
     1155        int curr_pos;
     1156};
     1157
     1158static size_t read_data(void *ptr, size_t size, size_t nmemb, void *datasource) {
     1159        data_file_info *f = (data_file_info *) datasource;
     1160
     1161        nmemb *= size;
     1162        if (f->curr_pos < 0)
     1163                return (size_t) -1;
     1164        if (f->curr_pos > (int) f->size)
     1165                nmemb = 0;
     1166        else if (f->curr_pos + nmemb > f->size)
     1167                nmemb = f->size - f->curr_pos;
     1168
     1169        memcpy(ptr, f->data + f->curr_pos, nmemb);
     1170        f->curr_pos += nmemb;
     1171        return nmemb / size;
     1172}
     1173
     1174static int seek_data(void *datasource, ogg_int64_t offset, int whence) {
     1175        data_file_info *f = (data_file_info *) datasource;
     1176
     1177        switch (whence) {
     1178        case SEEK_SET:
     1179                f->curr_pos = offset;
     1180                break;
     1181        case SEEK_CUR:
     1182                f->curr_pos += offset;
     1183                break;
     1184        case SEEK_END:
     1185                f->curr_pos = f->size + offset;
     1186                break;
     1187        default:
     1188                return -1;
     1189        }
     1190        return f->curr_pos;
     1191}
     1192
     1193static int close_data(void *datasource) {
     1194        data_file_info *f = (data_file_info *) datasource;
     1195
     1196        free(f->data);
     1197        delete f;
     1198        return 0;
     1199}
     1200
     1201static long tell_data(void *datasource) {
     1202        data_file_info *f = (data_file_info *) datasource;
     1203
     1204        return f->curr_pos;
     1205}
     1206
     1207static ov_callbacks data_wrap = {
     1208        read_data, seek_data, close_data, tell_data
     1209};
     1210#endif
     1211
     1212int Sound::playSfxSound_Vorbis(void *sound, uint32 size) {
     1213#ifdef USE_VORBIS
     1214        if (_soundsPaused)
     1215                return -1;
     1216
     1217        OggVorbis_File *ov_file = new OggVorbis_File;
     1218        data_file_info *f = new data_file_info;
     1219        f->data = (char *) sound;
     1220        f->size = size;
     1221        f->curr_pos = 0;
     1222
     1223        if (ov_open_callbacks((void *) f, ov_file, NULL, 0, data_wrap) < 0) {
     1224                warning("Invalid file format");
     1225                delete ov_file;
     1226                delete f;
     1227                return -1;
     1228        }
     1229
     1230        return _scumm->_mixer->playVorbis(NULL, ov_file, 0, false);
     1231#endif
     1232        return -1;
     1233}
     1234
    11271235// We use a real timer in an attempt to get better sync with CD tracks. This is
    11281236// necessary for games like Loom CD.
    11291237
     
    15251633}
    15261634
    15271635int Sound::VorbisTrackInfo::play(SoundMixer *mixer, int start, int delay) {
    1528         ov_time_seek(&_ov_file, start / 75.0);
    1529         return mixer->playVorbisCDTrack(NULL, &_ov_file, delay / 75.0);
     1636        ov_pcm_seek(&_ov_file, start * ov_info(&_ov_file, -1)->rate / 75);
     1637        return mixer->playVorbis(NULL, &_ov_file,
     1638                                 delay * ov_info(&_ov_file, -1)->rate / 75,
     1639                                 true);
    15301640}
    15311641
    15321642Sound::VorbisTrackInfo::~VorbisTrackInfo() {
  • scumm/sound.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/sound.h,v
    retrieving revision 1.15
    diff -u -r1.15 sound.h
     
    6868#ifdef COMPRESSED_SOUND_FILE
    6969        MP3OffsetTable *offset_table;   // SO3 MP3 compressed audio
    7070        int num_sound_effects;          // SO3 MP3 compressed audio
     71        bool _vorbis_mode;      // true if using SOG, false if using SO3
    7172
    7273        #define CACHE_TRACKS 10
    7374
     
    171172        byte * readCreativeVocFile(byte * ptr, uint32 & size, uint32 & rate, uint32 & loops);
    172173        int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned);
    173174        int playSfxSound_MP3(void *sound, uint32 size);
     175        int playSfxSound_Vorbis(void *sound, uint32 size);
    174176
    175177        int readCDTimer();
    176178        void startCDTimer();
  • sound/mixer.cpp

    RCS file: /cvsroot/scummvm/scummvm/sound/mixer.cpp,v
    retrieving revision 1.21
    diff -u -r1.21 mixer.cpp
     
    145145#endif
    146146
    147147#ifdef USE_VORBIS
    148 int SoundMixer::playVorbisCDTrack(PlayingSoundHandle * handle, OggVorbis_File * ov_file, double duration) {
     148int SoundMixer::playVorbis(PlayingSoundHandle * handle, OggVorbis_File * ov_file, int duration, bool is_cd_track) {
    149149        for (int i = _beginSlots; i != NUM_CHANNELS; i++) {
    150150                if (_channels[i] == NULL) {
    151                         return insertAt(handle, i, new ChannelVorbis(this, ov_file, duration));
     151                        return insertAt(handle, i, new ChannelVorbis(this, ov_file, duration, is_cd_track));
    152152                }
    153153        }
    154154
     
    977977#endif
    978978
    979979#ifdef USE_VORBIS
    980 SoundMixer::ChannelVorbis::ChannelVorbis(SoundMixer * mixer, OggVorbis_File * ov_file, double duration) {
     980SoundMixer::ChannelVorbis::ChannelVorbis(SoundMixer * mixer, OggVorbis_File * ov_file, int duration, bool is_cd_track) {
    981981        _mixer = mixer;
    982982        _ov_file = ov_file;
    983983
    984984        if (duration)
    985                 _end_pos = ov_time_tell(ov_file) + duration;
     985                _end_pos = ov_pcm_tell(ov_file) + duration;
    986986        else
    987987                _end_pos = 0;
    988988
    989989        _eof_flag = false;
     990        _is_cd_track = is_cd_track;
    990991        _toBeDestroyed = false;
    991992}
    992993
     
    10051006        uint len_left = len * channels * 2;
    10061007        int16 *samples = new int16[len_left / 2];
    10071008        char *read_pos = (char *) samples;
    1008         int volume = _mixer->_musicVolume;
     1009        int volume = _is_cd_track ? _mixer->_musicVolume :
     1010                _mixer->_volumeTable[1];
    10091011
    10101012        // Read the samples
    10111013        while (len_left > 0) {
     
    10211023                        memset(read_pos, 0, len_left);
    10221024                        break;
    10231025                }
     1026                else if (result == OV_HOLE) {
     1027                        // Possibly recoverable, just warn about it
     1028                        warning("Corrupted data in Vorbis file");
     1029                }
    10241030                else if (result < 0) {
    10251031                        debug(1, "Decode error %d in Vorbis file", result);
    10261032                        // Don't delete it yet, that causes problems in
     
    10451051        }
    10461052
    10471053        delete [] samples;
     1054
     1055        if (_eof_flag && ! _is_cd_track)
     1056                realDestroy();
    10481057}
    10491058
    10501059void SoundMixer::ChannelVorbis::realDestroy() {
     
    10541063
    10551064bool SoundMixer::ChannelVorbis::soundFinished() {
    10561065        return _eof_flag || (_end_pos > 0 &&
    1057                              ov_time_tell(_ov_file) >= _end_pos);
     1066                             ov_pcm_tell(_ov_file) >= _end_pos);
    10581067}
    10591068
    10601069#endif
  • sound/mixer.h

    RCS file: /cvsroot/scummvm/scummvm/sound/mixer.h,v
    retrieving revision 1.11
    diff -u -r1.11 mixer.h
     
    146146        class ChannelVorbis : public Channel {
    147147                SoundMixer * _mixer;
    148148                OggVorbis_File * _ov_file;
    149                 double _end_pos;
    150                 bool _eof_flag;
     149                int _end_pos;
     150                bool _eof_flag, _is_cd_track;
    151151
    152152        public:
    153                 ChannelVorbis(SoundMixer * mixer, OggVorbis_File * ov_file, double duration);
     153                ChannelVorbis(SoundMixer * mixer, OggVorbis_File * ov_file, int duration, bool is_cd_track);
    154154
    155155                void mix(int16 * data, uint len);
    156156                void realDestroy();
     
    212212        int playMP3CDTrack(PlayingSoundHandle * handle, File * file, mad_timer_t duration);
    213213#endif
    214214#ifdef USE_VORBIS
    215         int playVorbisCDTrack(PlayingSoundHandle * handle, OggVorbis_File * ov_file, double duration);
     215        int playVorbis(PlayingSoundHandle * handle, OggVorbis_File * ov_file, int duration, bool is_cd_track);
    216216#endif
    217217
    218218        /* Premix procedure, useful when using fmopl adlib */