A game framework written with osu! in mind.
at master 70 lines 2.5 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Collections.Concurrent; 6using System.Collections.Generic; 7using System.IO; 8using System.Threading.Tasks; 9using JetBrains.Annotations; 10using osu.Framework.Audio.Mixing; 11using osu.Framework.Audio.Mixing.Bass; 12using osu.Framework.IO.Stores; 13using osu.Framework.Statistics; 14 15namespace osu.Framework.Audio.Sample 16{ 17 internal class SampleStore : AudioCollectionManager<AdjustableAudioComponent>, ISampleStore 18 { 19 private readonly IResourceStore<byte[]> store; 20 private readonly AudioMixer mixer; 21 22 private readonly ConcurrentDictionary<string, SampleBassFactory> factories = new ConcurrentDictionary<string, SampleBassFactory>(); 23 24 public int PlaybackConcurrency { get; set; } = Sample.DEFAULT_CONCURRENCY; 25 26 internal SampleStore([NotNull] IResourceStore<byte[]> store, [NotNull] AudioMixer mixer) 27 { 28 this.store = store; 29 this.mixer = mixer; 30 31 (store as ResourceStore<byte[]>)?.AddExtension(@"wav"); 32 (store as ResourceStore<byte[]>)?.AddExtension(@"mp3"); 33 } 34 35 public Sample Get(string name) 36 { 37 if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(SampleStore)}"); 38 39 if (string.IsNullOrEmpty(name)) return null; 40 41 lock (factories) 42 { 43 if (!factories.TryGetValue(name, out SampleBassFactory factory)) 44 { 45 this.LogIfNonBackgroundThread(name); 46 47 byte[] data = store.Get(name); 48 factory = factories[name] = data == null ? null : new SampleBassFactory(data, (BassAudioMixer)mixer) { PlaybackConcurrency = { Value = PlaybackConcurrency } }; 49 50 if (factory != null) 51 AddItem(factory); 52 } 53 54 return factory?.CreateSample(); 55 } 56 } 57 58 public Task<Sample> GetAsync(string name) => Task.Run(() => Get(name)); 59 60 protected override void UpdateState() 61 { 62 FrameStatistics.Add(StatisticsCounterType.Samples, factories.Count); 63 base.UpdateState(); 64 } 65 66 public Stream GetStream(string name) => store.GetStream(name); 67 68 public IEnumerable<string> GetAvailableResources() => store.GetAvailableResources(); 69 } 70}