~ubuntu-branches/debian/jessie/scummvm/jessie

« back to all changes in this revision

Viewing changes to engines/scumm/sound.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2010-05-07 18:57:09 UTC
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20100507185709-34v8yycywjrou5o3
Tags: upstream-1.1.1
ImportĀ upstreamĀ versionĀ 1.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 * along with this program; if not, write to the Free Software
19
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
20
 *
21
 
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-0-0/engines/scumm/sound.cpp $
22
 
 * $Id: sound.cpp 45144 2009-10-16 02:02:55Z Kirben $
 
21
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-1-1/engines/scumm/sound.cpp $
 
22
 * $Id: sound.cpp 48500 2010-04-04 09:39:40Z Kirben $
23
23
 *
24
24
 */
25
25
 
35
35
#include "scumm/sound.h"
36
36
#include "scumm/util.h"
37
37
 
38
 
#include "sound/adpcm.h"
 
38
#include "sound/decoders/adpcm.h"
39
39
#include "sound/audiocd.h"
40
 
#include "sound/flac.h"
 
40
#include "sound/decoders/flac.h"
41
41
#include "sound/mididrv.h"
42
42
#include "sound/mixer.h"
43
 
#include "sound/mp3.h"
44
 
#include "sound/voc.h"
45
 
#include "sound/vorbis.h"
46
 
#include "sound/wave.h"
 
43
#include "sound/decoders/mp3.h"
 
44
#include "sound/decoders/raw.h"
 
45
#include "sound/decoders/voc.h"
 
46
#include "sound/decoders/vorbis.h"
 
47
#include "sound/decoders/wave.h"
47
48
 
48
49
namespace Scumm {
49
50
 
159
160
 
160
161
void Sound::playSound(int soundID) {
161
162
        byte *ptr;
162
 
        char *sound;
 
163
        byte *sound;
 
164
        Audio::AudioStream *stream;
163
165
        int size = -1;
164
166
        int rate;
165
 
        byte flags = Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE;
166
 
 
167
 
        // FIXME: Sound resources are currently missing
168
 
        if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)
 
167
 
 
168
        if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
 
169
                if (soundID >= 13 && soundID <= 32) {
 
170
                        static const char tracks[20] = {3, 4, 5, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 19, 20, 21};
 
171
 
 
172
                        _currentCDSound = soundID;
 
173
                        playCDTrack(tracks[soundID - 13], 1, 0, 0);
 
174
                } else {
 
175
                        if (_vm->_musicEngine) {
 
176
                                _vm->_musicEngine->startSound(soundID);
 
177
                        }
 
178
                }
169
179
                return;
 
180
        }
170
181
 
171
182
        debugC(DEBUG_SOUND, "playSound #%d (room %d)", soundID,
172
183
                _vm->getResourceRoomNr(rtSound, soundID));
189
200
                ptr += 0x72;
190
201
 
191
202
                // Allocate a sound buffer, copy the data into it, and play
192
 
                sound = (char *)malloc(size);
 
203
                sound = (byte *)malloc(size);
193
204
                memcpy(sound, ptr, size);
194
 
                _mixer->playRaw(Audio::Mixer::kSFXSoundType, NULL, sound, size, rate, flags, soundID);
 
205
 
 
206
                stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED);
 
207
                _mixer->playInputStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
195
208
        }
196
209
        // WORKAROUND bug # 1311447
197
210
        else if (READ_BE_UINT32(ptr) == 0x460e200d) {
211
224
                ptr += 0x26;
212
225
 
213
226
                // Allocate a sound buffer, copy the data into it, and play
214
 
                sound = (char *)malloc(size);
 
227
                sound = (byte *)malloc(size);
215
228
                memcpy(sound, ptr, size);
216
 
                _mixer->playRaw(Audio::Mixer::kSFXSoundType, NULL, sound, size, rate, flags, soundID);
 
229
                stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED);
 
230
                _mixer->playInputStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
217
231
        }
218
232
        // Support for sampled sound effects in Monkey Island 1 and 2
219
233
        else if (READ_BE_UINT32(ptr) == MKID_BE('SBL ')) {
282
296
                assert(voc_block_hdr.pack == 0);
283
297
 
284
298
                // Allocate a sound buffer, copy the data into it, and play
285
 
                sound = (char *)malloc(size);
 
299
                sound = (byte *)malloc(size);
286
300
                memcpy(sound, ptr + 6, size);
287
 
                _mixer->playRaw(Audio::Mixer::kSFXSoundType, NULL, sound, size, rate, flags, soundID);
 
301
                stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED);
 
302
                _mixer->playInputStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
288
303
        }
289
304
        else if ((_vm->_game.platform == Common::kPlatformFMTowns && _vm->_game.version == 3) || READ_BE_UINT32(ptr) == MKID_BE('SOUN') || READ_BE_UINT32(ptr) == MKID_BE('TOWS')) {
290
305
 
324
339
                                        warning("Wrong wave size in sound #%i: %i", soundID, waveSize);
325
340
                                        waveSize = size;
326
341
                                }
327
 
                                sound = (char *)malloc(waveSize);
 
342
                                sound = (byte *)malloc(waveSize);
328
343
                                for (int x = 0; x < waveSize; x++) {
329
 
                                        int b = *ptr++;
 
344
                                        byte b = *ptr++;
330
345
                                        if (b < 0x80)
331
346
                                                sound[x] = 0x7F - b;
332
347
                                        else
334
349
                                }
335
350
                                size -= waveSize;
336
351
 
337
 
                                if (loopEnd > 0)
338
 
                                        flags |= Audio::Mixer::FLAG_LOOP;
339
 
 
340
 
                                _mixer->playRaw(Audio::Mixer::kSFXSoundType, NULL, sound, waveSize, rate, flags, soundID, 255, 0, loopStart, loopEnd);
 
352
                                if (loopEnd > 0) {
 
353
                                        Audio::SeekableAudioStream *s = Audio::makeRawStream(sound, waveSize, rate, Audio::FLAG_UNSIGNED);
 
354
                                        stream = new Audio::SubLoopingAudioStream(s, 0, Audio::Timestamp(0, loopStart, rate), Audio::Timestamp(0, loopEnd, rate));
 
355
                                } else {
 
356
                                        stream = Audio::makeRawStream(sound, waveSize, rate, Audio::FLAG_UNSIGNED);
 
357
                                }
 
358
                                _mixer->playInputStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID, 255, 0);
341
359
                        }
342
360
                        break;
343
361
                case 1:
409
427
                // offset 26: ?  if != 0: stop current sound?
410
428
                // offset 27: ?  loopcount? 0xff == -1 for infinite?
411
429
 
412
 
                flags = Audio::Mixer::FLAG_AUTOFREE;
413
430
                size = READ_BE_UINT16(ptr + 12);
414
431
                assert(size);
415
 
                
 
432
 
416
433
                rate = 3579545 / READ_BE_UINT16(ptr + 20);
417
 
                sound = (char *)malloc(size);
 
434
                sound = (byte *)malloc(size);
418
435
                int vol = ptr[24] * 4;
419
436
                int loopStart = 0, loopEnd = 0;
420
437
                int loopcount = ptr[27];
 
438
 
 
439
                memcpy(sound, ptr + READ_BE_UINT16(ptr + 8), size);
 
440
                Audio::SeekableAudioStream *plainStream = Audio::makeRawStream(sound, size, rate, 0);
 
441
 
421
442
                if (loopcount > 1) {
422
 
                        // TODO: We can only loop once, or infinitely many times, but
423
 
                        // have no support for a finite number of repetitions.
424
 
                        // So far, I have seen only 1 and 255 (for infinite repetitions),
425
 
                        // so maybe this is not really a problem.
426
443
                        loopStart = READ_BE_UINT16(ptr + 10) - READ_BE_UINT16(ptr + 8);
427
444
                        loopEnd = READ_BE_UINT16(ptr + 14);
428
 
                        flags |= Audio::Mixer::FLAG_LOOP;
 
445
 
 
446
                        // TODO: Currently we will only ever play till "loopEnd", even when we only have
 
447
                        // a finite repetition count.
 
448
                        stream = new Audio::SubLoopingAudioStream(plainStream, loopcount == 255 ? 0 : loopcount, Audio::Timestamp(0, loopStart, rate), Audio::Timestamp(0, loopEnd, rate));
 
449
                } else {
 
450
                        stream = plainStream;
429
451
                }
430
452
 
431
 
                memcpy(sound, ptr + READ_BE_UINT16(ptr + 8), size);
432
 
                _mixer->playRaw(Audio::Mixer::kSFXSoundType, NULL, sound, size, rate,
433
 
                                flags, soundID, vol, 0, loopStart, loopEnd);
 
453
                _mixer->playInputStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID, vol, 0);
434
454
        }
435
455
        else {
436
456
 
437
457
                if (_vm->_game.id == GID_MONKEY_VGA || _vm->_game.id == GID_MONKEY_EGA
438
458
                        || (_vm->_game.id == GID_MONKEY && _vm->_game.platform == Common::kPlatformMacintosh)) {
439
 
                        // Sound is currently not supported at all in the amiga versions of these games
440
 
                        if (_vm->_game.platform == Common::kPlatformAmiga) {
441
 
                                int track = -1;
442
 
                                if (soundID == 50)
443
 
                                        track = 17;
444
 
                                else if (ptr[6] == 0x7F && ptr[7] == 0x00 && ptr[8] == 0x80) {
445
 
                                        static const char tracks[16] = {13,14,10,3,4,9,16,5,1,8,2,15,6,7,11,12};
446
 
                                        if (ptr[9] == 0x0E)
447
 
                                                track = 18;
448
 
                                        else
449
 
                                                track = tracks[ptr[9] - 0x23];
450
 
                                }
451
 
                                if (track != -1) {
452
 
                                        playCDTrack(track,((track < 5) || (track > 16)) ? 1 : -1,0,0);
453
 
                                        stopCDTimer();
454
 
                                        _currentCDSound = soundID;
455
 
                                }
456
 
                                return;
457
 
                        }
458
 
 
459
459
                        // Works around the fact that in some places in MonkeyEGA/VGA,
460
460
                        // the music is never explicitly stopped.
461
461
                        // Rather it seems that starting a new music is supposed to
638
638
 
639
639
                switch (_soundMode) {
640
640
                case kMP3Mode:
641
 
        #ifdef USE_MAD
 
641
#ifdef USE_MAD
642
642
                        assert(size > 0);
643
643
                        tmp = _sfxFile->readStream(size);
644
644
                        assert(tmp);
645
 
                        input = Audio::makeMP3Stream(tmp, true);
646
 
        #endif
 
645
                        input = Audio::makeMP3Stream(tmp, DisposeAfterUse::YES);
 
646
#endif
647
647
                        break;
648
648
                case kVorbisMode:
649
 
        #ifdef USE_VORBIS
 
649
#ifdef USE_VORBIS
650
650
                        assert(size > 0);
651
651
                        tmp = _sfxFile->readStream(size);
652
652
                        assert(tmp);
653
 
                        input = Audio::makeVorbisStream(tmp, true);
654
 
        #endif
 
653
                        input = Audio::makeVorbisStream(tmp, DisposeAfterUse::YES);
 
654
#endif
655
655
                        break;
656
 
                case kFlacMode:
657
 
        #ifdef USE_FLAC
 
656
                case kFLACMode:
 
657
#ifdef USE_FLAC
658
658
                        assert(size > 0);
659
659
                        tmp = _sfxFile->readStream(size);
660
660
                        assert(tmp);
661
 
                        input = Audio::makeFlacStream(tmp, true);
662
 
        #endif
 
661
                        input = Audio::makeFLACStream(tmp, DisposeAfterUse::YES);
 
662
#endif
663
663
                        break;
664
664
                default:
665
 
                        input = Audio::makeVOCStream(*_sfxFile, Audio::Mixer::FLAG_UNSIGNED);
 
665
                        input = Audio::makeVOCStream(*_sfxFile, Audio::FLAG_UNSIGNED);
666
666
                        break;
667
667
                }
668
668
 
933
933
 
934
934
        static const SoundFileExtensions extensions[] = {
935
935
                { "sou", kVOCMode },
936
 
        #ifdef USE_FLAC
937
 
                { "sof", kFlacMode },
938
 
        #endif
939
 
        #ifdef USE_VORBIS
 
936
#ifdef USE_FLAC
 
937
                { "sof", kFLACMode },
 
938
#endif
 
939
#ifdef USE_VORBIS
940
940
                { "sog", kVorbisMode },
941
 
        #endif
942
 
        #ifdef USE_MAD
 
941
#endif
 
942
#ifdef USE_MAD
943
943
                { "so3", kMP3Mode },
944
 
        #endif
 
944
#endif
945
945
                { 0, kVOCMode }
946
946
        };
947
947
 
965
965
        basename[1] = "monster.";
966
966
 
967
967
        if (_vm->_game.heversion >= 60) {
968
 
                if ((_vm->_game.heversion <= 61 && _vm->_game.platform == Common::kPlatformMacintosh) || (_vm->_game.heversion >= 70)) {
 
968
                if ((_vm->_game.heversion <= 62 && _vm->_game.platform == Common::kPlatformMacintosh) || (_vm->_game.heversion >= 70)) {
969
969
                        tmp = _vm->generateFilename(-2);
970
970
                } else {
971
971
                        tmp = basename[0] + "tlk";
972
972
                }
973
973
 
974
 
                if (file->open(tmp) && _vm->_game.heversion <= 73)
 
974
                if (file->open(tmp) && _vm->_game.heversion <= 74)
975
975
                        file->setEnc(0x69);
976
976
                _soundMode = kVOCMode;
977
977
        } else {
1287
1287
        return 0;
1288
1288
}
1289
1289
 
1290
 
// Adlib MIDI-SYSEX to set MIDI instruments for small header games.
 
1290
// AdLib MIDI-SYSEX to set MIDI instruments for small header games.
1291
1291
static const byte ADLIB_INSTR_MIDI_HACK[95] = {
1292
1292
        0x00, 0xf0, 0x14, 0x7d, 0x00,  // sysex 00: part on/off
1293
1293
        0x00, 0x00, 0x03,              // part/channel  (offset  5)
1411
1411
        memcpy(ptr, "MDhd", 4); ptr += 4;
1412
1412
        ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 8;
1413
1413
        ptr += 4;
1414
 
        memset(ptr, 0, 8), ptr += 8;
 
1414
        memset(ptr, 0, 8); ptr += 8;
1415
1415
        memcpy(ptr, "MThd", 4); ptr += 4;
1416
1416
        ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 6;
1417
1417
        ptr += 4;
2058
2058
                ptr = _res->createResource(rtSound, idx, ro_size + 2);
2059
2059
                memcpy(ptr, "RO", 2); ptr += 2;
2060
2060
                memcpy(ptr, src_ptr, ro_size - 4); ptr += ro_size - 4;
 
2061
                free(src_ptr);
2061
2062
                return 1;
2062
2063
        } else if (_game.features & GF_OLD_BUNDLE) {
2063
2064
                wa_offs = _fileHandle->pos();
2121
2122
                if (_game.features & GF_OLD_BUNDLE) {
2122
2123
                        _fileHandle->seek(wa_offs + wa_size + 6, SEEK_SET);
2123
2124
                        byte musType = _fileHandle->readByte();
2124
 
                
 
2125
 
2125
2126
                        if (musType == 0x80) {
2126
2127
                                _fileHandle->seek(ad_offs, SEEK_SET);
2127
2128
                                _fileHandle->read(_res->createResource(rtSound, idx, ad_size), ad_size);