Beispiel #1
0
        private SoundHandle InsertChannel(Channel chan)
        {
            var index = -1;

            for (var i = 0; i != NumChannels; i++)
            {
                if (_channels[i] == null)
                {
                    index = i;
                    break;
                }
            }
            if (index == -1)
            {
                throw new InvalidOperationException("MixerImpl::out of mixer slots");
            }

            _channels[index] = chan;

            var chanHandle = new SoundHandle
            {
                Value = index + _handleSeed * NumChannels
            };

            chan.Handle = chanHandle;
            _handleSeed++;
            return(chanHandle);
        }
Beispiel #2
0
 public bool IsSoundHandleActive(SoundHandle handle)
 {
     lock (_gate)
     {
         var index = handle.Value % NumChannels;
         return(_channels[index] != null && _channels[index].Handle.Value == handle.Value);
     }
 }
Beispiel #3
0
        public int GetChannelVolume(SoundHandle handle)
        {
            var index = handle.Value % NumChannels;

            if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
            {
                return(0);
            }
            return(_channels[index].Volume);
        }
Beispiel #4
0
        private Timestamp GetElapsedTime(SoundHandle handle)
        {
            lock (_gate)
            {
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                {
                    return(new Timestamp(0, OutputRate));
                }

                return(_channels[index].GetElapsedTime());
            }
        }
Beispiel #5
0
        public void SetChannelVolume(SoundHandle handle, int volume)
        {
            lock (_gate)
            {
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                {
                    return;
                }

                _channels[index].Volume = volume;
            }
        }
Beispiel #6
0
        public void SetChannelBalance(SoundHandle handle, int balance)
        {
            lock (_gate)
            {
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                {
                    return;
                }

                _channels[index].Balance = balance;
            }
        }
Beispiel #7
0
        public void PauseHandle(SoundHandle handle, bool paused)
        {
            lock (_gate)
            {
                // Simply ignore (un)pause requests for sounds that already terminated
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                {
                    return;
                }

                _channels[index].Pause(paused);
            }
        }
Beispiel #8
0
        public void StopHandle(SoundHandle handle)
        {
            lock (_gate)
            {
                // Simply ignore stop requests for handles of sounds that already terminated
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                {
                    return;
                }

                _channels[index] = null;
            }
        }
Beispiel #9
0
        public int GetChannelBalance(SoundHandle handle)
        {
            var index = handle.Value % NumChannels;
            if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                return 0;

            return _channels[index].Balance;
        }
Beispiel #10
0
 public int GetSoundElapsedTime(SoundHandle handle)
 {
     return(GetElapsedTime(handle).Milliseconds);
 }
Beispiel #11
0
        SoundHandle StartTalkSound(int offset, int b, int mode)
        {
            Stream file;
            SoundHandle handle = new SoundHandle();
            var id = -1;

            if (vm.Game.GameId == GameId.CurseOfMonkeyIsland)
            {
                sfxMode |= mode;
                return handle;
            }
            else if (vm.Game.GameId == GameId.Dig)
            {
                sfxMode |= mode;
                if (!(vm.Game.Features.HasFlag(GameFeatures.Demo)))
                    return handle;
                throw new NotImplementedException();
            }
            else
            {
                if (_sfxFilename == null)
                {
                    //                    Console.Error.WriteLine("StartTalkSound: SFX file not found");
                    return handle;
                }

                // Some games frequently assume that starting one sound effect will
                // automatically stop any other that may be playing at that time. So
                // that is what we do here, but we make an exception for speech.
                if (mode == 1 && (vm.Game.GameId == GameId.Tentacle || vm.Game.GameId == GameId.SamNMax))
                {
                    id = 777777 + _talkSoundChannel;
                    _mixer.StopID(id);
                }

                int num = 0;
                if (b > 8)
                {
                    num = (b - 8) >> 1;
                }

                offset += 8;

                _mouthSyncTimes = new ushort[num + 1];
                file = ServiceLocator.FileStorage.OpenFileRead(_sfxFilename);
                var br = new BinaryReader(file);
                file.Seek(offset, SeekOrigin.Begin);
                for (int i = 0; i < num; i++)
                {
                    _mouthSyncTimes[i] = br.ReadUInt16BigEndian();
                }

                // Adjust offset to account for the mouth sync times. It is noteworthy
                // that we do not adjust the size here for compressed streams, since
                // they only set size to the size of the compressed sound data.
                offset += num * 2;
                // TODO: In case we ever set up the size for VOC streams, we should
                // really check whether the size contains the _mouthSyncTimes.
                // if (SoundMode == SoundMode.VOCMode)
                //      size -= num * 2;

                _mouthSyncTimes[num] = 0xFFFF;
                sfxMode |= mode;
                _curSoundPos = 0;
                _mouthSyncMode = true;
            }

            var input = new VocStream(file, true);

            var iMuseDigital = vm.MusicEngine as IMuseDigital;
            if (iMuseDigital != null)
            {
                iMuseDigital.StartVoice(TalkSoundID, input);
            }
            else
            {
                if (mode == 1)
                {
                    handle = _mixer.PlayStream(SoundType.SFX, input, id);
                }
                else
                {
                    handle = _mixer.PlayStream(SoundType.Speech, input, id);
                }
            }
            return handle;
        }
Beispiel #12
0
        public bool StartSpeech(ushort textNum)
        {
            if (!SystemVars.Instance.SystemFlags.HasFlag(SystemFlags.AllowSpeech))
                return false;
            var speechFileNum = (ushort)(_speechConvertTable[textNum >> 12] + (textNum & 0xFFF));

            var speechData = _skyDisk.LoadFile(speechFileNum + 50000);
            if (speechData == null)
            {
                // TODO: debug(9, "File %d (speechFile %d from section %d) wasn't found", speechFileNum + 50000, textNum & 0xFFF, textNum >> 12);
                return false;
            }

            var header = ServiceLocator.Platform.ToStructure<DataFileHeader>(speechData, 0);
            var speechSize = header.s_tot_size - ServiceLocator.Platform.SizeOf<DataFileHeader>();
            var playBuffer = new byte[speechSize];
            Array.Copy(speechData, ServiceLocator.Platform.SizeOf<DataFileHeader>(), playBuffer, 0, speechSize);

            // Workaround for BASS bug #897775 - some voice-overs are played at
            // half speed in 0.0368 (the freeware CD version), in 0.0372 they sound
            // just fine.

            int rate;
            if (_skyDisk.DetermineGameVersion().Version.Minor == 368 && (textNum == 20905 || textNum == 20906))
                rate = 22050;
            else
                rate = 11025;

            _mixer.StopID(SoundSpeech);

            var stream = new RawStream(AudioFlags.Unsigned, rate, true, new MemoryStream(playBuffer, 0, speechSize));
            _ingameSpeech = _mixer.PlayStream(SoundType.Speech, stream, SoundSpeech);
            return true;
        }
Beispiel #13
0
        // TODO:
        public void Start(Timestamp limit)
        {
            Stop();
            throw new NotImplementedException();
            var stream = AudioStream;
            if (stream == null) throw new InvalidOperationException("stream should not be null");

            //    stream = new LimitingAudioStream(stream, limit, false);

            _handle = Mixer.PlayStream(SoundType, stream, -1, _muted ? 0 : Volume, Balance, true);

            // Pause the audio again if we're still paused
            if (IsPaused)
                Mixer.PauseHandle(_handle, true);
        }
Beispiel #14
0
        public void StopHandle(SoundHandle handle)
        {
            lock (_gate)
            {
                // Simply ignore stop requests for handles of sounds that already terminated
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                    return;

                _channels[index] = null;
            }
        }
Beispiel #15
0
        public void SetChannelBalance(SoundHandle handle, int balance)
        {
            lock (_gate)
            {
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                    return;

                _channels[index].Balance = balance;
            }
        }
Beispiel #16
0
        public void SetChannelVolume(SoundHandle handle, int volume)
        {
            lock (_gate)
            {
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                    return;

                _channels[index].Volume = volume;
            }
        }
Beispiel #17
0
 public int GetSoundElapsedTime(SoundHandle handle)
 {
     return GetElapsedTime(handle).Milliseconds;
 }
Beispiel #18
0
        public void PauseHandle(SoundHandle handle, bool paused)
        {
            lock (_gate)
            {
                // Simply ignore (un)pause requests for sounds that already terminated
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                    return;

                _channels[index].Pause(paused);
            }
        }
Beispiel #19
0
 public bool IsSoundHandleActive(SoundHandle handle)
 {
     lock (_gate)
     {
         var index = handle.Value % NumChannels;
         return _channels[index] != null && _channels[index].Handle.Value == handle.Value;
     }
 }
Beispiel #20
0
        private Timestamp GetElapsedTime(SoundHandle handle)
        {
            lock (_gate)
            {
                var index = handle.Value % NumChannels;
                if (_channels[index] == null || _channels[index].Handle.Value != handle.Value)
                    return new Timestamp(0, OutputRate);

                return _channels[index].GetElapsedTime();
            }
        }
Beispiel #21
0
        private SoundHandle InsertChannel(Channel chan)
        {
            var index = -1;
            for (var i = 0; i != NumChannels; i++)
            {
                if (_channels[i] == null)
                {
                    index = i;
                    break;
                }
            }
            if (index == -1)
            {
                throw new InvalidOperationException("MixerImpl::out of mixer slots");
            }

            _channels[index] = chan;

            var chanHandle = new SoundHandle
            {
                Value = index + _handleSeed * NumChannels
            };
            chan.Handle = chanHandle;
            _handleSeed++;
            return chanHandle;
        }
Beispiel #22
0
        public bool StartSpeech(ushort roomNo, ushort localNo)
        {
            if (_cowHeader == null || ServiceLocator.AudioManager == null)
            {
                // TODO: warning("Sound::startSpeech: COW file isn't open");
                return false;
            }

            uint locIndex = 0xFFFFFFFF;
            int sampleSize = 0;
            uint index = 0;

            //            if (_cowMode == CowPSX)
            //            {
            //                Common::File file;
            //                uint16 i;

            //                if (!file.open("speech.lis"))
            //                {
            //                    warning("Could not open speech.lis");
            //                    return false;
            //                }

            //                for (i = 0; !file.eos() && !file.err(); i++)
            //                    if (file.readUint16LE() == roomNo)
            //                    {
            //                        locIndex = i;
            //                        break;
            //                    }
            //                file.close();

            //                if (locIndex == 0xFFFFFFFF)
            //                {
            //                    warning("Could not find room %d in speech.lis", roomNo);
            //                    return false;
            //                }

            //                if (!file.open("speech.inf"))
            //                {
            //                    warning("Could not open speech.inf");
            //                    return false;
            //                }

            //                uint16 numRooms = file.readUint16LE(); // Read number of rooms referenced in this file

            //                file.seek(locIndex * 4 + 2); // 4 bytes per room, skip first 2 bytes

            //                uint16 numLines = file.readUint16LE();
            //                uint16 roomOffset = file.readUint16LE();

            //                file.seek(2 + numRooms * 4 + roomOffset * 2); // The offset is in terms of uint16's, so multiply by 2. Skip the room indexes too.

            //                locIndex = 0xFFFFFFFF;

            //                for (i = 0; i < numLines; i++)
            //                    if (file.readUint16LE() == localNo)
            //                    {
            //                        locIndex = i;
            //                        break;
            //                    }

            //                if (locIndex == 0xFFFFFFFF)
            //                {
            //                    warning("Could not find local number %d in room %d in speech.inf", roomNo, localNo);
            //                    return false;
            //                }

            //                file.close();

            //                index = _cowHeader[(roomOffset + locIndex) * 2];
            //                sampleSize = _cowHeader[(roomOffset + locIndex) * 2 + 1];
            //            }
            //            else {
            locIndex = _cowHeader[roomNo] >> 2;
            sampleSize = (int)_cowHeader[(int)(locIndex + (localNo * 2))];
            index = _cowHeader[(int)(locIndex + (localNo * 2) - 1)];
            //            }

            //            debug(6, "startSpeech(%d, %d): locIndex %d, sampleSize %d, index %d", roomNo, localNo, locIndex, sampleSize, index);

            IAudioStream stream = null;

            if (sampleSize != 0)
            {
                byte speechVol = (byte)((_speechVolR + _speechVolL) / 2);
                sbyte speechPan = (sbyte)((_speechVolR - _speechVolL) / 2);
                if ((_cowMode == CowMode.CowWave) || (_cowMode == CowMode.CowDemo))
                {
                    uint size;
                    var data = UncompressSpeech(index + _cowHeaderSize, (uint)sampleSize, out size);
                    if (data != null)
                    {
                        stream = new RawStream(SPEECH_FLAGS, 11025, true, new MemoryStream(data.Data, data.Offset, (int)size));
                        _speechHandle = _mixer.PlayStream(SoundType.Speech, stream, SOUND_SPEECH_ID, speechVol, speechPan);
                    }
                }
                //                else if (_cowMode == CowPSX && sampleSize != 0xffffffff)
                //                {
                //                    _cowFile.seek(index * 2048);
                //                    Common::SeekableReadStream* tmp = _cowFile.readStream(sampleSize);
                //                    assert(tmp);
                //                    stream = Audio::makeXAStream(tmp, 11025);
                //                    _mixer->playStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, stream, SOUND_SPEECH_ID, speechVol, speechPan);
                //                    // with compressed audio, we can't calculate the wave volume.
                //                    // so default to talking.
                //                    for (int cnt = 0; cnt < 480; cnt++)
                //                        _waveVolume[cnt] = true;
                //                    _waveVolPos = 0;
                //                }
                else if (_cowMode == CowMode.CowFLAC)
                {
                    _cowFile.BaseStream.Seek(index, SeekOrigin.Begin);
                    var tmp = _cowFile.ReadBytes(sampleSize);
                    stream = ServiceLocator.AudioManager.MakeFlacStream(new MemoryStream(tmp));
                    if (stream != null)
                    {
                        _speechHandle = _mixer.PlayStream(SoundType.Speech, stream, SOUND_SPEECH_ID, speechVol, speechPan);
                        // with compressed audio, we can't calculate the wave volume.
                        // so default to talking.
                        for (int cnt = 0; cnt < 480; cnt++)
                            _waveVolume[cnt] = true;
                        _waveVolPos = 0;
                    }
                }
                else if (_cowMode == CowMode.CowVorbis)
                {
                    _cowFile.BaseStream.Seek(index, SeekOrigin.Begin);
                    var tmp = _cowFile.ReadBytes(sampleSize);
                    stream = ServiceLocator.AudioManager.MakeVorbisStream(new MemoryStream(tmp));
                    if (stream != null)
                    {
                        _speechHandle = _mixer.PlayStream(SoundType.Speech, stream, SOUND_SPEECH_ID, speechVol, speechPan);
                        // with compressed audio, we can't calculate the wave volume.
                        // so default to talking.
                        for (int cnt = 0; cnt < 480; cnt++)
                            _waveVolume[cnt] = true;
                        _waveVolPos = 0;
                    }
                }
                else if (_cowMode == CowMode.CowMP3)
                {
                    _cowFile.BaseStream.Seek(index, SeekOrigin.Begin);
                    var tmp = _cowFile.ReadBytes(sampleSize);
                    stream = ServiceLocator.AudioManager.MakeMp3Stream(new MemoryStream(tmp));
                    if (stream != null)
                    {
                        _speechHandle = _mixer.PlayStream(SoundType.Speech, stream, SOUND_SPEECH_ID, speechVol, speechPan);
                        // with compressed audio, we can't calculate the wave volume.
                        // so default to talking.
                        for (int cnt = 0; cnt < 480; cnt++)
                            _waveVolume[cnt] = true;
                        _waveVolPos = 0;
                    }
                }
                return true;
            }
            else
                return false;
        }
Beispiel #23
0
        public void Clear()
        {
            TrackId = 0;
            pan = 0;
            vol = 0;
            VolFadeDest = 0;
            VolFadeStep = 0;
            VolFadeDelay = 0;
            VolFadeUsed = false;
//            SoundId = 0;
            SoundName = null;
            Used = false;
            ToBeRemoved = false;
            SouStreamUsed = false;
            SndDataExtComp = false;
            SoundPriority = 0;
            RegionOffset = 0;
            DataOffset = 0;
            CurRegion = 0;
            CurHookId = 0;
            VolGroupId = 0;
            SoundType = 0;
            FeedSize = 0;
            DataMod12Bit = 0;
            MixerFlags = AudioFlags.None;

            SoundDesc = null;
            MixChanHandle = new SoundHandle();
            Stream = null;
        }
Beispiel #24
0
 public Music(IMixer mixer, string directory)
 {
     _mixer = mixer;
     _sampleRate = mixer.OutputRate;
     _volumeL = _volumeR = 192;
     _soundHandle = _mixer.PlayStream(SoundType.Plain, this, -1, Mixer.MaxChannelVolume, 0, false, true);
     _handles = new MusicHandle[2];
     for (int i = 0; i < _handles.Length; i++)
     {
         _handles[i] = new MusicHandle(directory);
     }
 }
Beispiel #25
0
        public void PlaySound(ushort sound, ushort volume, byte channel)
        {
            if (channel == 0)
                _mixer.StopID(SoundChannel0);
            else
                _mixer.StopID(SoundChannel1);

            if (_soundData == null)
            {
                // TODO: warning
                //warning("Sound::playSound(%04X, %04X) called with a section having been loaded", sound, volume);
                return;
            }

            if (sound > _soundsTotal)
            {
                // TODO: debug
                //debug(5, "Sound::playSound %d ignored, only %d sfx in file", sound, _soundsTotal);
                return;
            }

            volume = (ushort)((volume & 0x7F) << 1);
            sound &= 0xFF;

            // Note: All those tables are big endian. Don't ask me why. *sigh*

            // Use the sample rate from game data, see bug #1507757.
            var sampleRate = _sampleRates.Data.ToUInt16BigEndian(_sampleRates.Offset + (sound << 2));
            if (sampleRate > 11025)
                sampleRate = 11025;
            var dataOfs = ScummHelper.SwapBytes(_sfxInfo[((sound << 3) + 0) / 2]) << 4;
            int dataSize = ScummHelper.SwapBytes(_sfxInfo[((sound << 3) + 2) / 2]);
            int dataLoop = ScummHelper.SwapBytes(_sfxInfo[((sound << 3) + 6) / 2]);
            dataOfs += _sfxBaseOfs;

            var stream = new RawStream(AudioFlags.Unsigned, sampleRate, false,
                new MemoryStream(_soundData, dataOfs, dataSize));

            IAudioStream output;
            if (dataLoop != 0)
            {
                var loopSta = dataSize - dataLoop;
                var loopEnd = dataSize;

                output = new SubLoopingAudioStream(stream, 0, new Timestamp(0, loopSta, sampleRate),
                    new Timestamp(0, loopEnd, sampleRate), true);
            }
            else
            {
                output = stream;
            }

            if (channel == 0)
                _ingameSound0 = _mixer.PlayStream(SoundType.SFX, output, SoundChannel0, volume, 0);
            else
                _ingameSound1 = _mixer.PlayStream(SoundType.SFX, output, SoundChannel1, volume, 0);
        }