untested visualizer complete.
This commit is contained in:
parent
02d814b4f7
commit
57e76be95d
@ -51,6 +51,7 @@
|
||||
<Compile Include="Zer01HD\Audio\MusicList.cs" />
|
||||
<Compile Include="Zer01HD\Audio\SupportedFormats.cs" />
|
||||
<Compile Include="Zer01HD\Audio\TransparentSampleProvider.cs" />
|
||||
<Compile Include="Zer01HD\Audio\Visualizer\HorizontalVisualizer.cs" />
|
||||
<Compile Include="Zer01HD\Screens\MainMenu\MainPage.cs" />
|
||||
<Compile Include="Zer01HD\Screens\Transitions\FadeAwayTransition.cs" />
|
||||
<Compile Include="Zer01HD\Utilities\Camera\Camera2D.cs" />
|
||||
@ -151,9 +152,7 @@
|
||||
<None Include="app.manifest" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Zer01HD\Audio\Visualizer\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />
|
||||
<Import Project="..\packages\BulletSharp.0.11.1\build\net40-client\BulletSharp.targets" Condition="Exists('..\packages\BulletSharp.0.11.1\build\net40-client\BulletSharp.targets')" />
|
||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace RhythmBullet.Zer01HD.Audio
|
||||
{
|
||||
internal class MusicController
|
||||
internal class MusicController : IDisposable
|
||||
{
|
||||
MusicList musicList;
|
||||
WaveOutEvent outputDevice;
|
||||
@ -105,5 +105,10 @@ namespace RhythmBullet.Zer01HD.Audio
|
||||
return audioInput.CurrentTime;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
audioInput?.Dispose();
|
||||
outputDevice?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ namespace RhythmBullet.Zer01HD.Audio
|
||||
private readonly int m;
|
||||
private ISampleProvider source;
|
||||
private Complex[] fftBuffer;
|
||||
private float[] spectrum;
|
||||
private volatile bool updatedSpectrum;
|
||||
private readonly float[] currentSpectrum;
|
||||
private int channelCount;
|
||||
public bool performFFT;
|
||||
|
||||
@ -27,7 +28,7 @@ namespace RhythmBullet.Zer01HD.Audio
|
||||
source = sampleProvider;
|
||||
channelCount = sampleProvider.WaveFormat.Channels;
|
||||
fftBuffer = new Complex[FFT_SIZE];
|
||||
spectrum = new float[FFT_SIZE];
|
||||
currentSpectrum = new float[FFT_SIZE];
|
||||
}
|
||||
|
||||
public WaveFormat WaveFormat
|
||||
@ -38,13 +39,21 @@ namespace RhythmBullet.Zer01HD.Audio
|
||||
}
|
||||
}
|
||||
|
||||
public float GetSpectrumBin(int bin)
|
||||
public float[] GetCurrentSpectrum()
|
||||
{
|
||||
lock (spectrum)
|
||||
if (updatedSpectrum)
|
||||
{
|
||||
return spectrum[bin];
|
||||
lock (fftBuffer)
|
||||
{
|
||||
for (int binID = 0; binID < currentSpectrum.Length; binID++)
|
||||
{
|
||||
currentSpectrum[binID] = fftBuffer[binID].X;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentSpectrum;
|
||||
}
|
||||
|
||||
public int Read(float[] buffer, int offset, int count)
|
||||
{
|
||||
@ -56,15 +65,12 @@ namespace RhythmBullet.Zer01HD.Audio
|
||||
for (int s = 0; s < sampleCount; s += channelCount)
|
||||
{
|
||||
if (s >= FFT_SIZE)
|
||||
{
|
||||
lock (fftBuffer)
|
||||
{
|
||||
FastFourierTransform.FFT(true, m, fftBuffer);
|
||||
lock (spectrum)
|
||||
{
|
||||
for (int binID = 0; binID < spectrum.Length; binID++)
|
||||
{
|
||||
spectrum[binID] = fftBuffer[binID].X;
|
||||
}
|
||||
}
|
||||
updatedSpectrum = true;
|
||||
fftOffset -= FFT_SIZE;
|
||||
}
|
||||
float greatestVal = 0;
|
||||
|
109
RhythmBullet/Zer01HD/Audio/Visualizer/HorizontalVisualizer.cs
Normal file
109
RhythmBullet/Zer01HD/Audio/Visualizer/HorizontalVisualizer.cs
Normal file
@ -0,0 +1,109 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using RhythmBullet.Zer01HD.UI.Modular;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RhythmBullet.Zer01HD.Audio.Visualizer
|
||||
{
|
||||
internal class HorizontalVisualizer : UIModule, IDisposable
|
||||
{
|
||||
GraphicsDevice graphicsDevice;
|
||||
Texture2D barTexture;
|
||||
private const int BAR_COUNT = 70;
|
||||
private const int SMOOTH_RANGE = 3;
|
||||
private readonly int binsPerBar;
|
||||
private readonly int spaceBetweenBars;
|
||||
private Rectangle bar;
|
||||
private TransparentSampleProvider tsp;
|
||||
private int[] barValue;
|
||||
|
||||
internal HorizontalVisualizer(TransparentSampleProvider transparentSampleProvider, GraphicsDevice graphicsDevice)
|
||||
{
|
||||
this.graphicsDevice = graphicsDevice;
|
||||
tsp = transparentSampleProvider;
|
||||
bar.Width = (int)(graphicsDevice.Viewport.Width / 70f);
|
||||
spaceBetweenBars = (int)(0.25f * bar.Width);
|
||||
bar.Width -= spaceBetweenBars;
|
||||
|
||||
barTexture = new Texture2D(graphicsDevice, 1, 1);
|
||||
barTexture.SetData(new[] { Color.White });
|
||||
binsPerBar = tsp.GetCurrentSpectrum().Length / BAR_COUNT;
|
||||
barValue = new int[BAR_COUNT];
|
||||
}
|
||||
|
||||
public override void Update(GameTime gameTime)
|
||||
{
|
||||
UpdateBars((float)gameTime.ElapsedGameTime.TotalSeconds);
|
||||
AverageBars();
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch batch)
|
||||
{
|
||||
for (int i = 0; i < BAR_COUNT; i++)
|
||||
{
|
||||
bar.X = (i * (bar.Width + spaceBetweenBars)) + Bounds.X;
|
||||
bar.Y = Bounds.Y;
|
||||
|
||||
bar.Height = barValue[i];
|
||||
batch.Draw(barTexture, bar, Color);
|
||||
|
||||
bar.Height = -barValue[BAR_COUNT - i - 1];
|
||||
batch.Draw(barTexture, bar, Color);
|
||||
}
|
||||
base.Draw(batch);
|
||||
}
|
||||
|
||||
private void UpdateBars(float delta)
|
||||
{
|
||||
const float ALPHA = 0.5f;
|
||||
float[] spectrum = tsp.GetCurrentSpectrum();
|
||||
|
||||
for (int barID = 0; barID < BAR_COUNT; barID++)
|
||||
{
|
||||
int targetBarHeight = 0;
|
||||
|
||||
for (int bin = barID * binsPerBar; bin < (barID + 1) * (binsPerBar); bin++)
|
||||
{
|
||||
targetBarHeight += (int)spectrum[bin];
|
||||
}
|
||||
targetBarHeight /= binsPerBar;
|
||||
|
||||
int distance = targetBarHeight - barValue[barID];
|
||||
distance *= (int)Math.Round((1.0f - Math.Pow(1 - ALPHA, delta / 0.02f)));
|
||||
barValue[barID] += distance;
|
||||
}
|
||||
}
|
||||
|
||||
private void AverageBars()
|
||||
{
|
||||
for (int barID = 0; barID < BAR_COUNT; barID++)
|
||||
{
|
||||
int terms = 0;
|
||||
for (int pos = 0; pos < SMOOTH_RANGE; pos++)
|
||||
{
|
||||
if (barID + pos < BAR_COUNT)
|
||||
{
|
||||
barValue[barID] += barValue[barID + pos];
|
||||
terms++;
|
||||
}
|
||||
if (barID - pos > 0)
|
||||
{
|
||||
barValue[barID] += barValue[barID - pos];
|
||||
terms++;
|
||||
}
|
||||
}
|
||||
barValue[barID] /= terms;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
barTexture.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -32,11 +32,14 @@ namespace RhythmBullet.Zer01HD.Utilities.Camera
|
||||
Matrix.CreateTranslation(new Vector3(bounds.Width * 0.5f, bounds.Height * 0.5f, 0f));
|
||||
}
|
||||
|
||||
public void LinearInterpolationToPosition(float alpha, Vector2 targetPosition)
|
||||
public void LinearInterpolationToPosition(float alpha, Vector2 targetPosition, float delta)
|
||||
{
|
||||
if (alpha < 0 && alpha > 1f) throw new ArgumentException("Alpha can't be greater than 1f, or less than 0.");
|
||||
Position.X = MathHelper.Lerp(Position.X, targetPosition.X, alpha);
|
||||
Position.Y = MathHelper.Lerp(Position.Y, targetPosition.Y, alpha);
|
||||
if (alpha <= 0 && alpha > 1f) throw new ArgumentException("Alpha can't be greater than 1f, less than or equal to 0.");
|
||||
|
||||
Vector2 distance = targetPosition - Position;
|
||||
distance *= (float)(1.0f - Math.Pow(1 - alpha, delta / 0.02f));
|
||||
|
||||
Position += distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ namespace RhythmBullet.Zer01HD.UI.Book
|
||||
Rectangle targetBounds = targetPage.Bounds;
|
||||
position.X = targetBounds.X + (targetBounds.Width * 0.5f);
|
||||
position.Y = targetBounds.Y + (targetBounds.Height * 0.5f);
|
||||
camera.LinearInterpolationToPosition(0.4f, position);
|
||||
camera.LinearInterpolationToPosition(0.4f, position, (float)gameTime.ElapsedGameTime.TotalSeconds);
|
||||
if (camera.Position == position)
|
||||
{
|
||||
targetPage = null;
|
||||
|
Loading…
x
Reference in New Issue
Block a user