A game framework written with osu! in mind.
at master 201 lines 6.6 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.Linq; 5using ManagedBass; 6using ManagedBass.Fx; 7using NUnit.Framework; 8using osu.Framework.Allocation; 9using osu.Framework.Audio.Sample; 10using osu.Framework.Bindables; 11using osu.Framework.Graphics; 12using osu.Framework.Graphics.Audio; 13using osu.Framework.Graphics.Containers; 14using osu.Framework.Graphics.Shapes; 15using osu.Framework.Graphics.Sprites; 16using osu.Framework.Input.Events; 17using osuTK; 18using osuTK.Graphics; 19 20namespace osu.Framework.Tests.Visual.Audio 21{ 22 public class TestSceneAudioMixer : FrameworkTestScene 23 { 24 [SetUp] 25 public void Setup() => Schedule(() => 26 { 27 ContainerWithEffect noEffectContainer; 28 FillFlowContainer<ContainerWithEffect> effectContainers; 29 30 Child = noEffectContainer = new ContainerWithEffect("no effect", Color4.Black) 31 { 32 RelativeSizeAxes = Axes.Both, 33 Size = new Vector2(1), 34 Child = new Container 35 { 36 RelativeSizeAxes = Axes.Both, 37 Padding = new MarginPadding(20), 38 Child = effectContainers = new FillFlowContainer<ContainerWithEffect> 39 { 40 RelativeSizeAxes = Axes.Both, 41 } 42 } 43 }; 44 45 for (int i = 0; i < 50; i++) 46 { 47 float centre = 150 + 50 * i; 48 49 effectContainers.Add(new ContainerWithEffect($"<{centre}Hz", Color4.Blue) 50 { 51 Size = new Vector2(100), 52 Effects = 53 { 54 new BQFParameters 55 { 56 lFilter = BQFType.LowPass, 57 fCenter = centre 58 } 59 } 60 }); 61 } 62 63 AudioBox audioBox; 64 noEffectContainer.Add(audioBox = new AudioBox(noEffectContainer, effectContainers)); 65 66 Add(audioBox.CreateProxy()); 67 }); 68 69 private class AudioBox : CompositeDrawable 70 { 71 private readonly Container<Drawable> defaultParent; 72 private readonly Container<ContainerWithEffect> effectContainers; 73 74 public AudioBox(Container<Drawable> defaultParent, Container<ContainerWithEffect> effectContainers) 75 { 76 this.defaultParent = defaultParent; 77 this.effectContainers = effectContainers; 78 79 currentContainer = defaultParent; 80 81 Origin = Anchor.Centre; 82 Size = new Vector2(50); 83 84 InternalChild = new CircularContainer 85 { 86 RelativeSizeAxes = Axes.Both, 87 Masking = true, 88 Children = new Drawable[] 89 { 90 new Box 91 { 92 RelativeSizeAxes = Axes.Both, 93 Colour = Color4.HotPink, 94 }, 95 new SpriteIcon 96 { 97 Anchor = Anchor.Centre, 98 Origin = Anchor.Centre, 99 RelativeSizeAxes = Axes.Both, 100 Size = new Vector2(0.5f), 101 Icon = FontAwesome.Solid.VolumeUp, 102 } 103 } 104 }; 105 } 106 107 [BackgroundDependencyLoader] 108 private void load(ISampleStore samples) 109 { 110 samples.Volume.Value = 0.5f; 111 112 DrawableSample sample; 113 AddInternal(sample = new DrawableSample(samples.Get("long.mp3"))); 114 115 var channel = sample.GetChannel(); 116 channel.Looping = true; 117 channel.Play(); 118 } 119 120 protected override bool OnDragStart(DragStartEvent e) 121 { 122 return true; 123 } 124 125 protected override void OnDrag(DragEvent e) 126 { 127 Position += e.Delta; 128 } 129 130 private Container<Drawable> currentContainer; 131 132 protected override void Update() 133 { 134 base.Update(); 135 136 Vector2 centre = ScreenSpaceDrawQuad.Centre; 137 138 Container<Drawable> targetContainer = effectContainers.FirstOrDefault(c => c.Contains(centre)) ?? defaultParent; 139 if (targetContainer == currentContainer) 140 return; 141 142 currentContainer.Remove(this); 143 targetContainer.Add(this); 144 145 Position = Parent.ToLocalSpace(centre); 146 147 currentContainer = targetContainer; 148 } 149 } 150 151 private class ContainerWithEffect : Container 152 { 153 protected override Container<Drawable> Content => content; 154 155 private readonly DrawableAudioMixer mixer; 156 private readonly Container content; 157 158 private readonly Drawable background; 159 160 public ContainerWithEffect(string name, Color4 colour) 161 { 162 Anchor = Anchor.Centre; 163 Origin = Anchor.Centre; 164 165 InternalChild = mixer = new DrawableAudioMixer 166 { 167 RelativeSizeAxes = Axes.Both, 168 Children = new[] 169 { 170 background = new Box 171 { 172 RelativeSizeAxes = Axes.Both, 173 Colour = colour, 174 Alpha = 0.2f 175 }, 176 new SpriteText 177 { 178 Anchor = Anchor.TopCentre, 179 Origin = Anchor.TopCentre, 180 Text = name, 181 Font = FrameworkFont.Regular.With(size: 18) 182 }, 183 content = new Container 184 { 185 RelativeSizeAxes = Axes.Both 186 } 187 } 188 }; 189 } 190 191 public BindableList<IEffectParameter> Effects => mixer.Effects; 192 193 protected override void Update() 194 { 195 base.Update(); 196 197 background.Alpha = content.Count > 0 ? 1 : 0.2f; 198 } 199 } 200 } 201}