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\MusicList.cs" />
|
||||||
<Compile Include="Zer01HD\Audio\SupportedFormats.cs" />
|
<Compile Include="Zer01HD\Audio\SupportedFormats.cs" />
|
||||||
<Compile Include="Zer01HD\Audio\TransparentSampleProvider.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\MainMenu\MainPage.cs" />
|
||||||
<Compile Include="Zer01HD\Screens\Transitions\FadeAwayTransition.cs" />
|
<Compile Include="Zer01HD\Screens\Transitions\FadeAwayTransition.cs" />
|
||||||
<Compile Include="Zer01HD\Utilities\Camera\Camera2D.cs" />
|
<Compile Include="Zer01HD\Utilities\Camera\Camera2D.cs" />
|
||||||
@ -151,9 +152,7 @@
|
|||||||
<None Include="app.manifest" />
|
<None Include="app.manifest" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup />
|
||||||
<Folder Include="Zer01HD\Audio\Visualizer\" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.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')" />
|
<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
|
namespace RhythmBullet.Zer01HD.Audio
|
||||||
{
|
{
|
||||||
internal class MusicController
|
internal class MusicController : IDisposable
|
||||||
{
|
{
|
||||||
MusicList musicList;
|
MusicList musicList;
|
||||||
WaveOutEvent outputDevice;
|
WaveOutEvent outputDevice;
|
||||||
@ -105,5 +105,10 @@ namespace RhythmBullet.Zer01HD.Audio
|
|||||||
return audioInput.CurrentTime;
|
return audioInput.CurrentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
audioInput?.Dispose();
|
||||||
|
outputDevice?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ namespace RhythmBullet.Zer01HD.Audio
|
|||||||
private readonly int m;
|
private readonly int m;
|
||||||
private ISampleProvider source;
|
private ISampleProvider source;
|
||||||
private Complex[] fftBuffer;
|
private Complex[] fftBuffer;
|
||||||
private float[] spectrum;
|
private volatile bool updatedSpectrum;
|
||||||
|
private readonly float[] currentSpectrum;
|
||||||
private int channelCount;
|
private int channelCount;
|
||||||
public bool performFFT;
|
public bool performFFT;
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ namespace RhythmBullet.Zer01HD.Audio
|
|||||||
source = sampleProvider;
|
source = sampleProvider;
|
||||||
channelCount = sampleProvider.WaveFormat.Channels;
|
channelCount = sampleProvider.WaveFormat.Channels;
|
||||||
fftBuffer = new Complex[FFT_SIZE];
|
fftBuffer = new Complex[FFT_SIZE];
|
||||||
spectrum = new float[FFT_SIZE];
|
currentSpectrum = new float[FFT_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
public WaveFormat WaveFormat
|
public WaveFormat WaveFormat
|
||||||
@ -38,12 +39,20 @@ 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)
|
public int Read(float[] buffer, int offset, int count)
|
||||||
@ -57,14 +66,11 @@ namespace RhythmBullet.Zer01HD.Audio
|
|||||||
{
|
{
|
||||||
if (s >= FFT_SIZE)
|
if (s >= FFT_SIZE)
|
||||||
{
|
{
|
||||||
FastFourierTransform.FFT(true, m, fftBuffer);
|
lock (fftBuffer)
|
||||||
lock (spectrum)
|
|
||||||
{
|
{
|
||||||
for (int binID = 0; binID < spectrum.Length; binID++)
|
FastFourierTransform.FFT(true, m, fftBuffer);
|
||||||
{
|
|
||||||
spectrum[binID] = fftBuffer[binID].X;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
updatedSpectrum = true;
|
||||||
fftOffset -= FFT_SIZE;
|
fftOffset -= FFT_SIZE;
|
||||||
}
|
}
|
||||||
float greatestVal = 0;
|
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));
|
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.");
|
if (alpha <= 0 && alpha > 1f) throw new ArgumentException("Alpha can't be greater than 1f, less than or equal to 0.");
|
||||||
Position.X = MathHelper.Lerp(Position.X, targetPosition.X, alpha);
|
|
||||||
Position.Y = MathHelper.Lerp(Position.Y, targetPosition.Y, alpha);
|
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;
|
Rectangle targetBounds = targetPage.Bounds;
|
||||||
position.X = targetBounds.X + (targetBounds.Width * 0.5f);
|
position.X = targetBounds.X + (targetBounds.Width * 0.5f);
|
||||||
position.Y = targetBounds.Y + (targetBounds.Height * 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)
|
if (camera.Position == position)
|
||||||
{
|
{
|
||||||
targetPage = null;
|
targetPage = null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user