Пример #1
0
        public unsafe int DecodePCM(SoundSample sample, int sampleOffset44k, int sampleCount44k, float *dest)
        {
            lastFormat = WAVE_FORMAT_TAG.PCM;
            lastSample = sample;

            var shift        = 22050 / sample.objectInfo.nSamplesPerSec;
            var sampleOffset = sampleOffset44k >> shift;
            var sampleCount  = sampleCount44k >> shift;

            if (sample.nonCacheData == null)
            {
                Debug.Assert(false); failed = true; return(0);
            }                                                                                   // this should never happen ( note: I've seen that happen with the main thread down in idGameLocal::MapClear clearing entities - TTimo )
            if (!sample.FetchFromCache(sampleOffset * sizeof(short), out var first, out var pos, out var size, false))
            {
                failed = true; return(0);
            }

            var readSamples = size - pos < sampleCount * sizeof(short) ? (size - pos) / sizeof(short) : sampleCount;

            // duplicate samples for 44kHz output
            fixed(byte *_ = &first.v[first.o + pos]) Simd.UpSamplePCMTo44kHz(dest, (short *)_, readSamples, sample.objectInfo.nSamplesPerSec, sample.objectInfo.nChannels);

            return(readSamples << shift);
        }
Пример #2
0
        OggVorbis_File ogg;             // OggVorbis file

        public unsafe virtual void Decode(SoundSample sample, int sampleOffset44k, int sampleCount44k, float *dest)
        {
            if (sample.objectInfo.wFormatTag != lastFormat || sample != lastSample)
            {
                ClearDecoder();
            }

            lastDecodeTime = soundSystemLocal.CurrentSoundTime;

            if (failed)
            {
                UnsafeX.InitBlock(dest, 0, sampleCount44k * sizeof(float)); return;
            }

            // samples can be decoded both from the sound thread and the main thread for shakes
            ISystem.EnterCriticalSection(CRITICAL_SECTION.SECTION_ONE);
            var readSamples44k = sample.objectInfo.wFormatTag switch
            {
                WAVE_FORMAT_TAG.PCM => DecodePCM(sample, sampleOffset44k, sampleCount44k, dest),
                WAVE_FORMAT_TAG.OGG => DecodeOGG(sample, sampleOffset44k, sampleCount44k, dest),
                _ => 0,
            };

            ISystem.LeaveCriticalSection(CRITICAL_SECTION.SECTION_ONE);

            if (readSamples44k < sampleCount44k)
            {
                UnsafeX.InitBlock(dest + readSamples44k, 0, (sampleCount44k - readSamples44k) * sizeof(float));
            }
        }
Пример #3
0
        /// <summary>
        /// Initializes sound files.
        /// </summary>
        public static void Initialize(IGameConfig config)
        {
            int id = 0;

            Clear1      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Clear1.mp3"));
            Clear2      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Clear2.mp3"));
            Click1      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Click1.mp3"));
            Click2      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Click2.mp3"));
            Click3      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Click3.mp3"));
            Error1      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Error1.mp3"));
            Explode1    = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Explode1.mp3"));
            Explode2    = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Explode2.mp3"));
            Explode3    = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Explode3.mp3"));
            Hit1        = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Hit1.mp3"));
            Hit2        = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Hit2.mp3"), 0.8f);
            LevelUp1    = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "LevelUp1.mp3"));
            MenuBack1   = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "MenuBack1.mp3"));
            MenuMove1   = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "MenuMove1.mp3"));
            MenuMove2   = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "MenuMove2.mp3"));
            MenuSelect1 = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "MenuSelect1.mp3"));
            MenuSelect2 = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "MenuSelect2.mp3"));
            Music1      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Music1.mp3"), 0.1f, true);
            Music2      = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Music2.mp3"), 0.2f, true);
            Send1       = new SoundSample(++id, Path.Combine(config.AudioSampleFolder, "Send1.mp3"));
        }
Пример #4
0
    public void SingleSound(SoundSample sound)
    {
        switch (sound)
        {
        case SoundSample.explosion:
            source.PlayOneShot(explosion, 1.0f);
            break;

        case SoundSample.drink:
            source.PlayOneShot(drink, 1.0f);
            break;

        case SoundSample.mix:
            source.PlayOneShot(mix, 1.0f);
            break;

        case SoundSample.die_enemy:
            source.PlayOneShot(die_enemy, 0.6f);
            break;

        case SoundSample.hit_player:
            source.PlayOneShot(hit_player, 1.0f);
            break;

        case SoundSample.die_player:
            source.PlayOneShot(die_player, 1.0f);
            break;
        }
    }
Пример #5
0
        /// <summary>
        /// Plays the specified sound sample, looping until stop.
        /// Stops any existing loop.
        /// </summary>
        public static void Loop(SoundSample sound, long position = 0)
        {
            if (sound == Sound.Music1)
            {
                _musicMode = MusicMode.Music1;
            }
            else if (sound == Sound.Music2)
            {
                _musicMode = MusicMode.Music2;
            }
            else
            {
                _musicMode = MusicMode.None;
            }

            if ((sound.IsMusic) && (!GameConfig.Instance.Music))
            {
                return;
            }
            if ((!sound.IsMusic) && (!GameConfig.Instance.SoundEffects))
            {
                return;
            }

            _manager?.PlayLoop(id: sound.ID, stopOtherLoops: true, position: position);
        }
Пример #6
0
 public void Clear()
 {
     failed           = false;
     lastFormat       = WAVE_FORMAT_TAG.PCM;
     lastSample       = null;
     lastSampleOffset = 0;
     lastDecodeTime   = 0;
 }
Пример #7
0
    public void playOnce(string file)
    {
        SoundSample snd = new SoundSample(this, file, file, 1, false);

        snd.playonce       = true;
        soundSamples[file] = snd;
        play(file);
    }
Пример #8
0
        /// <summary>
        /// Plays the specified sound sample.
        /// </summary>
        public static void Play(SoundSample sound)
        {
            if ((sound.IsMusic) && (!GameConfig.Instance.Music))
            {
                return;
            }
            if ((!sound.IsMusic) && (!GameConfig.Instance.SoundEffects))
            {
                return;
            }

            _manager?.PlaySound(sound.ID);
        }
Пример #9
0
    public List <string> getPlayingSamples()
    {
        List <string> samples = new List <string>();

        foreach (KeyValuePair <string, SoundSample> sample in soundSamples)
        {
            SoundSample snd = sample.Value;
            if (snd.playing)
            {
                samples.Add(snd.name);
            }
        }
        return(samples);
    }
Пример #10
0
    // Update is called once per frame
    void Update()
    {
        List <string> removes = new List <string>();

        foreach (KeyValuePair <string, SoundSample> sample in soundSamples)
        {
            SoundSample snd = sample.Value;
            if (snd.playing)
            {
                snd.tick();
                snd.checkInjects();
                if (snd.checkFinished())
                {
                    finished.Invoke(snd.name);
                    //Debug.Log("yes, in update finish "+snd.name);
                    if (snd.callback != null)
                    {
                        Debug.Log("execute callback !" + snd.callback);
                        if (snd.callbackName != null)
                        {
                            snd.callback(snd.callbackName, "completed");
                        }
                        else
                        {
                            snd.callback(snd.name, "completed");
                        }

                        //snd.callback = null;
                    }

                    if (snd.playonce)
                    {
                        removes.Add(sample.Key);
                    }
                }
            }
        }

        foreach (string remove in removes)
        {
            soundSamples.Remove(remove);
        }
    }
Пример #11
0
        private void FromStream(StreamReader reader)
        {
            if (reader.ReadLine() != "soundsfile version 3")
            {
                throw new Exception("可能不支持当前mod或该mod已损坏");
            }
            Samples = new List <SoundSample>(Convert.ToInt32(reader.ReadLine()));
            string[] s = reader.ReadToEnd().Split(new string[] { " ", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
            int      j = 0;

            for (int i = 0; i < Samples.Capacity; i++)
            {
                var smp = SoundSample.FromString(Module, s, ref j);
                Samples.Add(smp);
            }
            Sounds = new List <Sound>(Convert.ToInt32(s[j++]));
            for (int i = 0; i < Sounds.Capacity; i++)
            {
                var snd = Sound.FromString(Module, s, ref j);
                Sounds.Add(snd);
            }
        }
Пример #12
0
        public void Clear()
        {
            Stop();
            soundShader    = null;
            lastVolume     = 0f;
            triggerChannel = ISoundSystem.SCHANNEL_ANY;
            channelFade.Clear();
            diversity        = 0f;
            leadinSample     = null;
            trigger44kHzTime = 0;
            stopped          = false;
            for (var j = 0; j < 6; j++)
            {
                lastV[j] = 0f;
            }
            parms.memset();

            triggered                    = false;
            openalSource                 = 0;
            openalStreamingOffset        = 0;
            openalStreamingBuffer[0]     = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0;
            lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0;
        }
Пример #13
0
        public unsafe int DecodeOGG(SoundSample sample, int sampleOffset44k, int sampleCount44k, float *dest)
        {
            int readSamples, totalSamples;

            var shift        = 22050 / sample.objectInfo.nSamplesPerSec;
            var sampleOffset = sampleOffset44k >> shift;
            var sampleCount  = sampleCount44k >> shift;

            // open OGG file if not yet opened
            if (lastSample == null)
            {
                // make sure there is enough space for another decoder
                if (ISampleDecoder.decoderMemoryAllocator.FreeBlockMemory < ISampleDecoder.MIN_OGGVORBIS_MEMORY)
                {
                    return(0);
                }

                if (sample.nonCacheData == null)
                {
                    Debug.Assert(false); failed = true; return(0);
                }                                                                                  // this should never happen
                file.SetData(sample.nonCacheData, sample.objectMemSize);
                if (OggVorbis.ov_openFile(file, ogg) < 0)
                {
                    failed = true; return(0);
                }
                lastFormat = WAVE_FORMAT_TAG.OGG;
                lastSample = sample;
            }

            // seek to the right offset if necessary
            if (sampleOffset != lastSampleOffset && ov_pcm_seek(ogg, sampleOffset / sample.objectInfo.nChannels) != 0)
            {
                failed = true; return(0);
            }

            lastSampleOffset = sampleOffset;

            // decode OGG samples
            totalSamples = sampleCount;
            readSamples  = 0;
            do
            {
                float **samples;
                var     ret = (int)ov_read_float(ogg, &samples, totalSamples / sample.objectInfo.nChannels, null);
                if (ret == 0)
                {
                    failed = true; break;
                }
                if (ret < 0)
                {
                    failed = true; return(0);
                }
                ret *= sample.objectInfo.nChannels;

                Simd.UpSampleOGGTo44kHz(dest + (readSamples << shift), samples, ret, sample.objectInfo.nSamplesPerSec, sample.objectInfo.nChannels);

                readSamples  += ret;
                totalSamples -= ret;
            } while (totalSamples > 0);

            lastSampleOffset += readSamples;

            return(readSamples << shift);
        }
Пример #14
0
    public void addSample(string name, string sample, float volume = 1, bool loop = false)
    {
        SoundSample snd = new SoundSample(this, name, sample, volume, loop);

        soundSamples[name] = snd;
    }
Пример #15
0
 /// <summary>
 /// Returns current position in specified looping sound, or 0 if not looping sound.
 /// </summary>
 public static long GetLoopPosition(SoundSample sound)
 {
     return(_manager?.GetLoopPosition(sound.ID) ?? 0);
 }
Пример #16
0
 /// <summary>
 /// Stops specified sound, if it's looping.  Returns current position (if possible), or 0.
 /// </summary>
 public static long StopLoop(SoundSample sound)
 {
     return(_manager?.StopLoop(sound.ID) ?? 0);
 }