Merge remote-tracking branch 'origin/audio'

audio-improve-offer
Harald Wolff 2017-05-08 14:59:41 +02:00
commit 451ca5ec34
22 changed files with 752 additions and 11 deletions

View File

@ -8,6 +8,7 @@ using OpenTK;
using OpenTK.Audio.OpenAL;
using OpenTK.Audio;
using nhengine.Audio;
using ImageSharp;
using ImageSharp.Processing;
@ -38,6 +39,7 @@ namespace nhengine
public BootStrap()
{
bootGraphics();
bootAudio();
bootMap();
}
@ -54,9 +56,19 @@ namespace nhengine
}
public void bootAudio(){
AL.Enable(ALCapability.Invalid);
AudioDelegate.init();
AudioDelegate.DistanceModel("exponential", true);
nhBuffers.addSearchPath("./sounds");
nhBuffers.loadSound("HowFire", "HowHit", "st1");
//AudioDelegate.test();
}
public void bootMap(){
ImageSharp.Image i = ImageSharp.Image.Load( new FileStream("M3-wip.png",FileMode.Open));
i.Flip(ImageSharp.Processing.FlipType.Vertical);
@ -80,6 +92,7 @@ namespace nhengine
public void run(){
glWindow.MakeCurrent();
glWindow.Run(25,25);
}

View File

@ -238,6 +238,7 @@ namespace nhengine
private void fireBallistic(){
Console.WriteLine("Fire Ballistic...");
BallisticActor ba = new BallisticActor(0);
ba.fire();
ba.Position = BootStrap.instance().SquaredMap.ground(new Vector2(10,10));
ba.Velocity = new Vector3(0,1,1);// + (Matrix4.CreateRotationZ(arcLeftRight) * Vector4.UnitY).Xyz;

View File

@ -65,8 +65,12 @@
<Compile Include="TextureManager.cs" />
</ItemGroup>
<ItemGroup>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
<None Include="OpenTK.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="shader\simple_fragment.shader" />
<None Include="shader\simple_vertex.shader" />
<None Include="M3-wip.bmp">
@ -82,6 +86,21 @@
<None Include="models\ballistisch.obj">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="sounds\seq03.wav" />
<None Include="sounds\seq02.wav" />
<None Include="sounds\seq01.wav" />
<None Include="sounds\st2.wav" />
<None Include="sounds\st1.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="sounds\sfx2.wav" />
<None Include="sounds\sfx1.wav" />
<None Include="sounds\HowHit.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="sounds\HowFire.wav">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\org.niclasundharald.engine\org.niclasundharald.engine.csproj">
@ -93,5 +112,8 @@
<Name>org.hwo.contracts</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="sounds\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,6 +4,8 @@ using System.Collections.Generic;
using OpenTK;
using org.niclasundharald.engine.graphics;
using nhengine.Audio;
namespace org.niclasundharald.engine
{
@ -12,13 +14,19 @@ namespace org.niclasundharald.engine
public static List<Actor> activeActors = new List<Actor>();
public static List<Actor> finishedActors = new List<Actor>();
public static void updateAll(float timespan){
foreach (Actor a in activeActors){
public static void updateAll(float timespan)
{
foreach (Actor a in activeActors)
{
a.update(timespan);
}
foreach (Actor a in finishedActors){
foreach (Actor a in finishedActors)
{
activeActors.Remove(a);
}
finishedActors.Clear();
@ -31,10 +39,16 @@ namespace org.niclasundharald.engine
Console.WriteLine("New Actor: {0} / {1}",id,this);
this.id = id;
activeActors.Add(this);
_player = new nhPlayer();
activePlayers.Add(_player);
}
public void destroy(){
finishedActors.Add(this);
_player.deletePlayer();
}
public Vector3 Heading { get; set; }
@ -68,5 +82,53 @@ namespace org.niclasundharald.engine
return Model3D;
}
//>>>>>>>>AUDIO
private static List<nhPlayer> activePlayers = new List<nhPlayer>();
private static Dictionary<string,int> aBuffers = new Dictionary<string,int>();
private nhPlayer _player;
public bool isPlaying = false;
public void setDistanceAttenuation(float rollOf = 2.0f, float refDistance = 1.0f, float maxDistance = 100.0f)
{
_player.setDistanceAttenuation(rollOf, refDistance, maxDistance);
}
public void setBuffers(params string[] buffers)
{
foreach (string i in buffers)
{
if(!aBuffers.ContainsKey(i))
aBuffers.Add(i, nhBuffers.buffers[i]);
}
}
public void playSound(string sound, float gain = 1.0f, bool loop = false)
{
_player.position = this.Position;
_player.velocity = this.Velocity;
_player.play(aBuffers[sound], gain, loop);
}
public void setPlayerPosition(Vector3 positon, Vector3 velocity)
{
_player.setPosition(positon);
_player.setVelocity(velocity);
}
public void updateSoundState()
{
isPlaying = _player.state();
}
}
}

View File

@ -4,6 +4,8 @@ using org.niclasundharald.engine.graphics;
using OpenTK;
namespace org.niclasundharald.engine
{
public class BallisticActor : Actor
@ -18,12 +20,19 @@ namespace org.niclasundharald.engine
}
this.Model3D.rebind();
setBuffers("HowFire", "HowHit");
setDistanceAttenuation(2, 200, 800);
}
byte hit = 0;
public override void update(float timespan)
{
base.update(timespan);
Velocity += (Physics.Gravitation * timespan);
Position += Velocity * timespan;
Scale = Matrix4.CreateScale(3.0f);
@ -32,18 +41,42 @@ namespace org.niclasundharald.engine
Console.WriteLine("BallisticActor update: {0} / {1}",Position,Velocity);
updateSoundState();
Console.WriteLine("Playing:" + isPlaying);
try{
Vector3 ground = SquaredMap.activeMap.ground(Position.Xy);
if (Position.Z <= ground.Z){
destroy();
if(hit != 1)
{
playSound("HowHit");
updateSoundState();
hit = 1;
}
if(!isPlaying)
{
destroy();
}
}
} catch (OutOfWorldException e){
} catch (OutOfWorldException e){
if(!isPlaying)
destroy();
}
}
public void fire()
{
playSound("HowFire");
}
}
}

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Threading;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using OpenTK;
namespace nhengine.Audio
{
public static class AudioDelegate
{
//private static bool debug = true;
public static AudioContext context = new AudioContext();
//public static EffectsExtension efx = new EffectsExtension();
/* <<<<<<<<<<<INITIALIZE>>>>>>>>>>> */
public static void init()
{
nhBuffers.init();
DistanceModel();
//nhAux reverb = new nhAux();
Console.WriteLine("nhengine.Audio initialized.");
}
public static void test()
{
nhPlayer testPlayer = new nhPlayer();
testPlayer.play(nhBuffers.buffers["st1"]);
}
public static void DistanceModel(string distanceModel = "exponential", bool clamped = false)
{
if (!clamped)
{
switch (distanceModel)
{
case "exponential":
AL.DistanceModel(ALDistanceModel.ExponentDistance);
break;
case "inverse":
AL.DistanceModel(ALDistanceModel.InverseDistance);
break;
case "linear":
AL.DistanceModel(ALDistanceModel.LinearDistance);
break;
}
}
else if (clamped)
{
switch (distanceModel)
{
case "exponential":
AL.DistanceModel(ALDistanceModel.ExponentDistanceClamped);
break;
case "inverse":
AL.DistanceModel(ALDistanceModel.InverseDistanceClamped);
break;
case "linear":
AL.DistanceModel(ALDistanceModel.LinearDistanceClamped);
break;
}
}
else
{
throw new NotSupportedException("DistanceModel not supported!");
}
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using OpenTK;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
namespace nhengine.Audio
{
public class nhAux
{
public nhAux()
{
}
}
}

View File

@ -0,0 +1,150 @@
using System;
using System.IO;
using System.Collections.Generic;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using org.niclasundharald.engine;
namespace nhengine.Audio
{
public static class nhBuffers
{
//public static List<int> buffers = new List<int>();
//public static List<string> buffersNames = new List<string>();
public static Dictionary<string, int> buffers = new Dictionary<string, int>();
private static List<string> _files = new List<string>();
private static List<string> _searchPaths = new List<string>();
//private static string filepath;
public static void init()
{
buffers.Clear();
_files.Clear();
//_searchPaths = new List<string>();
_searchPaths.Add(".");
}
public static void addSearchPath(string sPath)
{
_searchPaths.Add(sPath);
}
public static void loadSound(params string[] sName)
{
foreach(string a in sName)
{
string fullName = FileHelper.findFile(String.Format("{0}.wav", a), _searchPaths.ToArray());
Console.WriteLine("TEST: " + fullName);
if (fullName != null)
{
Console.WriteLine("Sound found: {0}", fullName);
_createBuffer(fullName, a);
}else
throw new FileNotFoundException("File not found.");
}
}
private static void _createBuffer(string path, string sName)
{
Stream stream = File.Open(path, FileMode.Open);
string name = sName;
if (stream == null)
throw new ArgumentNullException(nameof(stream));
using (BinaryReader reader = new BinaryReader(stream))
{
//RIFF HEADER
string signature = new string(reader.ReadChars(4));
if (signature != "RIFF")
throw new NotSupportedException("File is not RIFF.");
reader.ReadInt32();
string format = new string(reader.ReadChars(4));
if (format != "WAVE")
throw new NotSupportedException("File is not WAVE.");
//WAVE HEADER
string format_sig = new string(reader.ReadChars(4));
if (format_sig != "fmt ")
throw new NotSupportedException("File is not supported.");
//Format Chunk Size
reader.ReadInt32();
//Format
reader.ReadInt16();
int channels = reader.ReadInt16();
int sample_rate = reader.ReadInt32();
//Byterate
reader.ReadInt32();
reader.ReadInt16();
//Block allign
int bits = reader.ReadInt16();
string data_sig = new string(reader.ReadChars(4));
if (data_sig != "data")
throw new NotSupportedException("File is not supported");
//Data chunk Size
reader.ReadInt32();
byte[] soundData = reader.ReadBytes((int)reader.BaseStream.Length);
ALFormat fileFormat;
switch (channels)
{
case 1:
fileFormat = bits == 8 ? ALFormat.Mono8 : ALFormat.Mono16;
break;
case 2:
fileFormat = bits == 8 ? ALFormat.Stereo8 : ALFormat.Stereo16;
break;
default: throw new NotSupportedException("File is not supported.");
}
int buffer = AL.GenBuffer();
AL.BufferData(buffer, fileFormat, soundData, soundData.Length, sample_rate);
buffers.Add(name, buffer);
}
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using OpenTK;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
namespace nhengine.Audio
{
public static class nhListener
{
private static Vector3 _pos = new Vector3(0.0f, 0.0f, 0.0f);
private static Vector3 _vel = new Vector3(0.0f, 0.0f, 0.0f);
private static Vector3 _top = new Vector3(0.0f, 0.0f, -1.0f);
private static Vector3 _view = new Vector3(0.0f, 1.0f, 0.0f);
private static void _setValues()
{
AL.Listener(ALListener3f.Position, _pos.X, _pos.Y, _pos.Z);
AL.Listener(ALListener3f.Velocity, _vel.X, _vel.Y, _vel.Z);
AL.Listener(ALListenerfv.Orientation, ref _view, ref _top);
Console.WriteLine("listener:" + _pos);
}
public static void setListener(Vector3 position, Vector3 velocity, Vector3 orientationUp, Vector3 orientationAt)
{
_pos = position;
_vel = velocity;
_top = orientationUp;
_view = orientationAt;
_setValues();
}
public static void setPosition(Vector3 position)
{
_pos = position;
_setValues();
}
public static void setVelocity(Vector3 velocity)
{
_vel = velocity;
_setValues();
}
public static void setTop(Vector3 Top)
{
_top = Top;
_setValues();
}
public static void setView(Vector3 View)
{
_view = View;
_setValues();
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Threading;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using System.Windows.Forms;
namespace nhengine.Audio
{
public static class nhMixer
{
public static void init(){
}
}
}

View File

@ -0,0 +1,228 @@
using System;
using System.Threading;
//using System.Threading.Tasks;
using OpenTK;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
namespace nhengine.Audio
{
public class nhPlayer
{
private int _source = AL.GenSource();
public int source
{
get
{return _source;}
}
private static int _playerNumber;
public int number
{
get
{ return _playerNumber;}
}
//private static EffectsExtension _efx;
//private int _filter;
private float _gain = 1.0f;
public float gain
{
set
{
if (value <= 0.0f)
{
_gain = 0.0f;
}
else if (value >= 1.0f)
{
_gain = 1.0f;
}else
{
_gain = value;
}
}
get
{return _gain;}
}
public Vector3 position = new Vector3(0.0f, 0.0f, 0.0f);
public Vector3 velocity = new Vector3(0.0f, 0.0f, 0.0f);
//public bool loop = false;
private float _rollOf = 2.0f;
private float _refDist = 0.0f;
private float _maxDist = 100.0f;
private int _state;
//private int[] _seqBuffer = { };
public nhPlayer()
{
//_filter = _efx.GenFilter();
//_efx.BindFilterToSource(_source, _filter);
AL.Source(_source, ALSourcef.RolloffFactor, _rollOf);
AL.Source(_source, ALSourcef.ReferenceDistance, _refDist);
AL.Source(_source, ALSourcef.MaxDistance, _maxDist);
//AL.Source(_source, ALSourcei.EfxDirectFilter, _filter);
//AL.Source(_source, ALSourcei.EfxDirectFilter, )
//_filterEfx.Filter(_filter, EfxFilteri.FilterType, EfxFilterType.Lowpass);
//_efx.Filter(_filter, EfxFilterf.LowpassGainHF, 0.5f);
Interlocked.Increment(ref _playerNumber);
}
//>>>>>>>>>>>>>>>>>METHODS
public bool state()
{
AL.GetSource(_source, ALGetSourcei.SourceState, out _state);
if ((ALSourceState)_state == ALSourceState.Playing)
{
return true;
}else if((ALSourceState)_state == ALSourceState.Stopped)
{
return false;
}else
{
return false;
}
}
public void play(int buffer = 0, float gain = 1.0f, bool loop = false)
{
_gain = gain;
AL.Source(_source, ALSourcef.RolloffFactor, _rollOf);
AL.Source(_source, ALSourcef.ReferenceDistance, _refDist);
AL.Source(_source, ALSourcef.MaxDistance, _maxDist);
if (buffer != 0)
{
AL.Source(_source, ALSourcei.Buffer, buffer);
}else{
throw new NotSupportedException("Not existing Buffer.");
}
AL.Source(_source, ALSourceb.Looping, loop);
AL.SourcePlay(_source);
AL.Source(_source, ALSourcef.Gain, _gain);
AL.Source(_source, ALSource3f.Position, position.X, position.Y, position.Z);
AL.Source(_source, ALSource3f.Velocity, velocity.X, velocity.Y, velocity.Z);
}
public void stop()
{
AL.SourceStop(_source);
}
public void setDistanceAttenuation(float rollOf = 2.0f, float refDistance = 1.0f, float maxDistance = 100.0f)
{
_rollOf = rollOf;
_refDist = refDistance;
_maxDist = maxDistance;
}
public void setPosition(Vector3 position)
{
this.position = position;
}
public void setVelocity(Vector3 velocity)
{
this.velocity = velocity;
}
/*
public void playSeq(int buffer01, int buffer02, int buffer03)
{
_seqBuffer[0] = buffer01;
_seqBuffer[1] = buffer02;
_seqBuffer[2] = buffer03;
Thread _playThread = new Thread(_playSeq);
_playThread.Start();
}
private void _playSeq()
{
int _buffersToProcess = 3;
AL.Source(_source, ALSourcei.Buffer, _buffer);
AL.Source(_source, ALSourceb.Looping, loop);
AL.SourceQueueBuffers(_source, 3, _seqBuffer);
AL.SourcePlay(_source);
//_isplaying = true;
AL.Source(_source, ALSourcef.Gain, _gain);
AL.Source(_source, ALSource3f.Position, position[0], position[1], position[2]);
AL.Source(_source, ALSource3f.Velocity, velocity[0], velocity[1], velocity[2]);
do
{
Thread.Sleep(16);
AL.GetSource(_source, ALGetSourcei.SourceState, out _state);
AL.GetSource(_source, ALGetSourcei.BuffersProcessed, out _buffersToProcess);
while(_buffersToProcess != 0)
{
//AL.SourceUnqueueBuffers(_source, 1, );
}
}
while ((ALSourceState)_state == ALSourceState.Playing);
AL.SourceStop(_source);
}
*/
public void deletePlayer()
{
AL.DeleteSource(_source);
}
}
}

View File

@ -3,6 +3,7 @@
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
using OpenTK;
using nhengine.Audio;
namespace org.niclasundharald.engine.graphics
{
@ -16,6 +17,8 @@ namespace org.niclasundharald.engine.graphics
vView,
vTop;
public GLCamera()
{
fov = MathHelper.PiOver2;
@ -57,18 +60,18 @@ namespace org.niclasundharald.engine.graphics
public Vector3 Position
{
get { return new Vector3(vPosition); }
set { this.vPosition = new Vector3(value); buildMatrices(); }
set { this.vPosition = new Vector3(value); buildMatrices(); nhListener.setPosition(this.vPosition);}
}
public Vector3 View
{
get { return new Vector3(vView); }
set { this.vView = new Vector3(value).Normalized(); buildMatrices(); }
set { this.vView = new Vector3(value).Normalized(); buildMatrices(); nhListener.setView(this.vView); }
}
public Vector3 Top
{
get { return new Vector3(vTop); }
set { this.vTop = new Vector3(value).Normalized(); buildMatrices(); }
set { this.vTop = new Vector3(value).Normalized(); buildMatrices(); nhListener.setTop(this.vTop);}
}
private void buildMatrices(){
@ -132,5 +135,8 @@ namespace org.niclasundharald.engine.graphics
return pr;
}
}
}

View File

@ -34,6 +34,15 @@
<Reference Include="OpenTK.GLControl">
<HintPath>..\packages\OpenTK.GLControl.1.1.2349.61993\lib\NET40\OpenTK.GLControl.dll</HintPath>
</Reference>
<Reference Include="ImageSharp">
<HintPath>contrib\ImageSharp.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Buffers">
<HintPath>..\packages\System.Buffers.4.3.0\lib\netstandard1.1\System.Buffers.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
@ -59,6 +68,10 @@
<Compile Include="Physics.cs" />
<Compile Include="graphics\SquaredMap.cs" />
<Compile Include="exceptions\OutOfWorldException.cs" />
<Compile Include="audio\nhPlayer.cs" />
<Compile Include="audio\AudioDelegate.cs" />
<Compile Include="audio\nhBuffers.cs" />
<Compile Include="audio\nhListener.cs" />
<Compile Include="ArrayHelper.cs" />
<Compile Include="Geometry.cs" />
<Compile Include="Linear.cs" />
@ -67,10 +80,16 @@
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
<None Include="Gameplay Object Tree.txt" />
<None Include="audio\nhAux.cs" />
<None Include="audio\nhMixer.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="graphics\" />
<Folder Include="graphics\primitives\" />
<Folder Include="contrib\" />
<Folder Include="contrib\ImageSharp.dll">
</Folder>
<Folder Include="exceptions\" />
<Folder Include="audio\" />
</ItemGroup>
<ItemGroup>