sound effects!

This commit is contained in:
Royce551 2022-08-27 10:10:40 -05:00
parent 6686913c31
commit 185d87a560
10 changed files with 197 additions and 16 deletions

View file

@ -28,12 +28,19 @@ namespace TestGame.Screens
}
else if (e.Key == Microsoft.Xna.Framework.Input.Keys.E)
{
Game.Audio.PlayTrack("Assets/03. Dream Walker.mp3");
Game.Audio.SwitchToTrack("Assets/03. Dream Walker.mp3");
}
else if (e.Key == Microsoft.Xna.Framework.Input.Keys.R)
{
SoundEffect.MasterVolume = 0.5f;
SoundEffect.FromFile("Assets/you_あ、見つかりましたぁ.wav").Play();
Game.Audio.PlayEffect("Assets/you_あ、見つかりましたぁ.wav", true, 1, -1);
}
else if (e.Key == Microsoft.Xna.Framework.Input.Keys.T)
{
Game.Audio.PlayEffect("Assets/you_あ、見つかりましたぁ.wav", true, 1, 0);
}
else if (e.Key == Microsoft.Xna.Framework.Input.Keys.Y)
{
Game.Audio.PlayEffect("Assets/you_あ、見つかりましたぁ.wav", true, 1, 1);
}
}

View file

@ -15,6 +15,8 @@ namespace Water.Audio
{
public List<IAudioTrack> Tracks { get; private set; } = new();
public List<IEffectTrack> Effects { get; private set; } = new();
public double MasterVolume { get; set; } = 1;
public double MusicVolume { get; set; } = 0.5;
public double EffectVolume { get; set; } = 1;
@ -39,11 +41,28 @@ namespace Water.Audio
return audioService?.Initialize() ?? false;
}
public void PlayTrack(string filePath) => audioService.PlayTrack(filePath);
public void PlayTrack(string filePath) => audioService?.PlayTrack(filePath);
public void SwitchToTrack(string filePath)
{
StopPlayingAllTracks();
PlayTrack(filePath);
}
public void StopPlayingAllTracks()
{
foreach (var track in Tracks)
{
track.Stop();
}
}
public void PlayEffect(string filePath, bool canOnlyPlayOnce, float rate = 0f, float pan = 0f) => audioService?.PlayEffect(filePath, canOnlyPlayOnce, rate, pan);
private List<IAudioTrack> tracksToRemove = new();
private List<IEffectTrack> effectsToRemove = new();
public void Update(GameTime gameTime)
public void Update()
{
foreach (var track in Tracks)
{
@ -60,9 +79,20 @@ namespace Water.Audio
}
}
foreach (var effect in Effects)
{
if (effect.IsLeftOver)
effect.Dispose();
effectsToRemove.Add(effect);
}
foreach (var track in tracksToRemove)
Tracks.Remove(track);
tracksToRemove.Clear();
foreach (var effect in effectsToRemove)
Effects.Remove(effect);
effectsToRemove.Clear();
}
}
}

View file

@ -0,0 +1,35 @@
using ManagedBass;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Water.Audio.BASS
{
public class BASSAudioSample : IDisposable
{
public int Id { get; }
public bool HasPlayed { get; set; }
public bool OnlyCanPlayOnce { get; }
public bool IsDisposed { get; private set; }
public BASSAudioSample(string path, bool onlyCanPlayOnce = false)
{
OnlyCanPlayOnce = onlyCanPlayOnce;
Id = Load(path, 10);
}
private int Load(string path, int concurrentPlaybacks)
{
return Bass.SampleLoad(path, 0, 0, concurrentPlaybacks, BassFlags.Default | BassFlags.SampleOverrideLongestPlaying);
}
public void Dispose()
{
Bass.SampleFree(Id);
IsDisposed = true;
}
}
}

View file

@ -31,6 +31,13 @@ namespace Water.Audio.BASS
else return true;
}
public void PlayTrack(string filePath) => new BASSAudioTrack(Audio, filePath).Play();
public void PlayTrack(string filePath) => new BASSMusicTrack(Audio, filePath).Play();
public void PlayEffect(string filePath, bool canOnlyPlayOnce, float rate = 0f, float pan = 0f)
{
var x = new BASSEffectTrack(new(filePath, canOnlyPlayOnce), rate, pan);
x.Play();
Audio.Effects.Add(x);
}
}
}

View file

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ManagedBass;
namespace Water.Audio.BASS
{
public class BASSEffectTrack : IEffectTrack
{
private BASSAudioSample sample;
private int id;
public bool HasPlayed { get; private set; }
public bool IsPlaying { get; }
public bool IsPaused { get; }
public bool IsStopped => Bass.ChannelIsActive(id) == PlaybackState.Stopped;
public bool HasStopped { get; private set; }
public bool IsLeftOver => HasPlayed && IsStopped;
public bool AutoDispose { get; }
public double Volume
{
get => Bass.ChannelGetAttribute(id, ChannelAttribute.Volume);
set => Bass.ChannelSetAttribute(id, ChannelAttribute.Volume, value);
}
public double Time { get; }
public BASSEffectTrack(BASSAudioSample sample, float rate = 1f, float pan = 0f)
{
this.sample = sample;
if (sample.IsDisposed)
throw new Exception("Kyaa! Sample already disposed!");
id = Bass.SampleGetChannel(sample.Id);
if (rate != 1f)
{
var frequency = Bass.ChannelGetInfo(id).Frequency;
Bass.ChannelSetAttribute(id, ChannelAttribute.Frequency, frequency * rate);
}
if (pan != 0f)
Bass.ChannelSetAttribute(id, ChannelAttribute.Pan, pan);
}
public void Dispose()
{
sample.Dispose();
}
public void Pause()
{
Bass.ChannelPause(id);
}
public void Play()
{
if (sample.HasPlayed && sample.OnlyCanPlayOnce)
throw new Exception("Kyaa! >.< you can't play a sample more than once");
if (sample.IsDisposed)
throw new Exception("Kyaa! >.< you can't play a sample that's disposed!");
Bass.ChannelPlay(id);
sample.HasPlayed = true;
HasPlayed = true;
}
public void Stop()
{
if (HasStopped)
throw new Exception("Kyaa! Already stopped!");
if (sample.IsDisposed)
throw new Exception("Kyaa! Already disposed!");
Bass.ChannelStop(id);
HasStopped = true;
}
}
}

View file

@ -7,7 +7,7 @@ using ManagedBass;
namespace Water.Audio.BASS
{
public class BASSAudioTrack : IAudioTrack
public class BASSMusicTrack : IAudioTrack
{
public string FilePath { get; }
@ -65,7 +65,7 @@ namespace Water.Audio.BASS
public double Time => Bass.ChannelBytes2Seconds(Stream, Bass.ChannelGetPosition(Stream) * 1000);
private AudioManager audioManager;
public BASSAudioTrack(AudioManager audioManager, string path, bool autoDispose = true)
public BASSMusicTrack(AudioManager audioManager, string path, bool autoDispose = true)
{
this.audioManager = audioManager;
FilePath = path;

View file

@ -13,5 +13,7 @@ namespace Water.Audio
public bool Initialize();
public void PlayTrack(string filePath);
public void PlayEffect(string filePath, bool canOnlyPlayOnce, float rate = 1f, float pan = 0f);
}
}

View file

@ -35,11 +35,5 @@ namespace Water.Audio
public double Volume { get; set; }
public double Time { get; }
public void Play();
public void Pause();
public void Stop();
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Water.Audio
{
public interface IEffectTrack : IPlayable
{
public bool IsPlaying { get; }
public bool IsPaused { get; }
public bool IsStopped { get; }
public bool HasStopped { get; }
public bool IsLeftOver { get; }
}
}

View file

@ -56,11 +56,11 @@ namespace Water.Graphics
public void Update(GameTime gameTime)
{
Input.Update();
Audio.Update(gameTime);
Audio.Update();
foreach (var obj in AllObjects)
obj.Update(gameTime);
MainGame.Window.Title = $"{TimeSpan.FromSeconds(Audio.Tracks.Count != 0 ? Audio.Tracks[0].Position : 1)}";
AllObjects.AddRange(objectsToAdd);
objectsToAdd.Clear();
foreach (var obj in objectsToRemove)