Ticket #8110: sog.diff
File sog.diff, 8.4 KB (added by , 22 years ago) |
---|
-
scumm/sound.cpp
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v retrieving revision 1.43 diff -u -r1.43 sound.cpp
738 738 int rate, comp; 739 739 byte *data; 740 740 741 #ifdef USE_MAD741 #ifdef COMPRESSED_SOUND_FILE 742 742 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); 744 749 745 750 if (file->read(data, file_size) != (uint)file_size) { 746 751 /* no need to free the memory since error will shut down */ 747 752 error("startSfxSound: cannot read %d bytes", size); 748 753 return -1; 749 754 } 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); 751 759 } 752 760 #endif 753 761 if (file->read(ident, 8) != 8) … … 805 813 #ifdef COMPRESSED_SOUND_FILE 806 814 offset_table = NULL; 807 815 816 #ifdef USE_MAD 808 817 sprintf(buf, "%s.so3", _scumm->_exe_name); 809 818 if (!file->open(buf, _scumm->getGameDataPath())) { 810 819 file->open("monster.so3", _scumm->getGameDataPath()); 811 820 } 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 812 835 if (file->isOpen() == true) { 813 836 /* Now load the 'offset' index in memory to be able to find the MP3 data 814 837 … … 1124 1147 return -1; 1125 1148 } 1126 1149 1150 #ifdef USE_VORBIS 1151 // Provide a virtual file to vorbisfile based on preloaded data 1152 struct data_file_info { 1153 char *data; 1154 uint32 size; 1155 int curr_pos; 1156 }; 1157 1158 static 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 1174 static 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 1193 static 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 1201 static long tell_data(void *datasource) { 1202 data_file_info *f = (data_file_info *) datasource; 1203 1204 return f->curr_pos; 1205 } 1206 1207 static ov_callbacks data_wrap = { 1208 read_data, seek_data, close_data, tell_data 1209 }; 1210 #endif 1211 1212 int 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 1127 1235 // We use a real timer in an attempt to get better sync with CD tracks. This is 1128 1236 // necessary for games like Loom CD. 1129 1237 … … 1525 1633 } 1526 1634 1527 1635 int 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); 1530 1640 } 1531 1641 1532 1642 Sound::VorbisTrackInfo::~VorbisTrackInfo() { -
scumm/sound.h
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.h,v retrieving revision 1.15 diff -u -r1.15 sound.h
68 68 #ifdef COMPRESSED_SOUND_FILE 69 69 MP3OffsetTable *offset_table; // SO3 MP3 compressed audio 70 70 int num_sound_effects; // SO3 MP3 compressed audio 71 bool _vorbis_mode; // true if using SOG, false if using SO3 71 72 72 73 #define CACHE_TRACKS 10 73 74 … … 171 172 byte * readCreativeVocFile(byte * ptr, uint32 & size, uint32 & rate, uint32 & loops); 172 173 int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned); 173 174 int playSfxSound_MP3(void *sound, uint32 size); 175 int playSfxSound_Vorbis(void *sound, uint32 size); 174 176 175 177 int readCDTimer(); 176 178 void startCDTimer(); -
sound/mixer.cpp
RCS file: /cvsroot/scummvm/scummvm/sound/mixer.cpp,v retrieving revision 1.21 diff -u -r1.21 mixer.cpp
145 145 #endif 146 146 147 147 #ifdef USE_VORBIS 148 int SoundMixer::playVorbis CDTrack(PlayingSoundHandle * handle, OggVorbis_File * ov_file, double duration) {148 int SoundMixer::playVorbis(PlayingSoundHandle * handle, OggVorbis_File * ov_file, int duration, bool is_cd_track) { 149 149 for (int i = _beginSlots; i != NUM_CHANNELS; i++) { 150 150 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)); 152 152 } 153 153 } 154 154 … … 977 977 #endif 978 978 979 979 #ifdef USE_VORBIS 980 SoundMixer::ChannelVorbis::ChannelVorbis(SoundMixer * mixer, OggVorbis_File * ov_file, double duration) {980 SoundMixer::ChannelVorbis::ChannelVorbis(SoundMixer * mixer, OggVorbis_File * ov_file, int duration, bool is_cd_track) { 981 981 _mixer = mixer; 982 982 _ov_file = ov_file; 983 983 984 984 if (duration) 985 _end_pos = ov_ time_tell(ov_file) + duration;985 _end_pos = ov_pcm_tell(ov_file) + duration; 986 986 else 987 987 _end_pos = 0; 988 988 989 989 _eof_flag = false; 990 _is_cd_track = is_cd_track; 990 991 _toBeDestroyed = false; 991 992 } 992 993 … … 1005 1006 uint len_left = len * channels * 2; 1006 1007 int16 *samples = new int16[len_left / 2]; 1007 1008 char *read_pos = (char *) samples; 1008 int volume = _mixer->_musicVolume; 1009 int volume = _is_cd_track ? _mixer->_musicVolume : 1010 _mixer->_volumeTable[1]; 1009 1011 1010 1012 // Read the samples 1011 1013 while (len_left > 0) { … … 1021 1023 memset(read_pos, 0, len_left); 1022 1024 break; 1023 1025 } 1026 else if (result == OV_HOLE) { 1027 // Possibly recoverable, just warn about it 1028 warning("Corrupted data in Vorbis file"); 1029 } 1024 1030 else if (result < 0) { 1025 1031 debug(1, "Decode error %d in Vorbis file", result); 1026 1032 // Don't delete it yet, that causes problems in … … 1045 1051 } 1046 1052 1047 1053 delete [] samples; 1054 1055 if (_eof_flag && ! _is_cd_track) 1056 realDestroy(); 1048 1057 } 1049 1058 1050 1059 void SoundMixer::ChannelVorbis::realDestroy() { … … 1054 1063 1055 1064 bool SoundMixer::ChannelVorbis::soundFinished() { 1056 1065 return _eof_flag || (_end_pos > 0 && 1057 ov_ time_tell(_ov_file) >= _end_pos);1066 ov_pcm_tell(_ov_file) >= _end_pos); 1058 1067 } 1059 1068 1060 1069 #endif -
sound/mixer.h
RCS file: /cvsroot/scummvm/scummvm/sound/mixer.h,v retrieving revision 1.11 diff -u -r1.11 mixer.h
146 146 class ChannelVorbis : public Channel { 147 147 SoundMixer * _mixer; 148 148 OggVorbis_File * _ov_file; 149 double_end_pos;150 bool _eof_flag ;149 int _end_pos; 150 bool _eof_flag, _is_cd_track; 151 151 152 152 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); 154 154 155 155 void mix(int16 * data, uint len); 156 156 void realDestroy(); … … 212 212 int playMP3CDTrack(PlayingSoundHandle * handle, File * file, mad_timer_t duration); 213 213 #endif 214 214 #ifdef USE_VORBIS 215 int playVorbis CDTrack(PlayingSoundHandle * handle, OggVorbis_File * ov_file, double duration);215 int playVorbis(PlayingSoundHandle * handle, OggVorbis_File * ov_file, int duration, bool is_cd_track); 216 216 #endif 217 217 218 218 /* Premix procedure, useful when using fmopl adlib */