First Audio Extensions:

-active/finished Players Lists
-distanceAttenuation Properties
-setBuffers Method for assigning buffers to Actor
audio-streams
Niclas Thobaben 2017-05-05 20:42:00 +02:00
parent 0fe2fb1aeb
commit a95ec67a31
16 changed files with 793 additions and 6 deletions

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,21 +4,29 @@ using System.Collections.Generic;
using OpenTK;
using org.niclasundharald.engine.graphics;
using nhengine.Audio;
namespace org.niclasundharald.engine
{
public class Actor : WorldObject
{
public static List<Actor> activeActors = new List<Actor>();
public static List<Actor> finishedActors = new List<Actor>();
private static List<Actor> activeActors = new List<Actor>();
private 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,17 +39,22 @@ namespace org.niclasundharald.engine
Console.WriteLine("New Actor: {0} / {1}",id,this);
this.id = id;
activeActors.Add(this);
_player = new nhPlayer(("Actor" + id), Position);
activePlayers.Add(_player);
}
public void destroy(){
finishedActors.Add(this);
finishedPlayers.Add(_player);
}
public Vector3 Heading { get; set; }
public Vector3 Velocity { get; set; }
public float Weight { get; set; }
public virtual void update(float timespan){
protected virtual void update(float timespan){
}
public void setHeading(Vector3 heading,Vector3 top){
@ -68,5 +81,43 @@ namespace org.niclasundharald.engine
return Model3D;
}
//>>>>>>>>AUDIO
private static List<nhPlayer> activePlayers = new List<nhPlayer>();
private static List<nhPlayer> finishedPlayers = new List<nhPlayer>();
private static List<int> aBuffers = new List<int>();
private nhPlayer _player;
public float rollOf { get; set; }
public float refDistance { get; set; }
public float maxDistance { get; set; }
public void setDistanceAttenuation(float rollOf = 2.0f, float refDistance = 0.0f, float maxDistance = 100.0f)
{
this.rollOf = rollOf;
this.refDistance = refDistance;
this.maxDistance = maxDistance;
}
public void setBuffers(params string[] buffers)
{
for (int i = 0; i < buffers.Length; i++)
{
aBuffers.Add(nhBuffers.buffers[buffers[i]]);
}
}
public void playSound(string sound, float gain, bool loop)
{
_player.play(sound, gain, loop);
}
}
}

View File

@ -0,0 +1,219 @@
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();
//PLAYERS
public static readonly List<nhPlayer> players = new List<nhPlayer>();
public static readonly List<string> playerNames = new List<string>();
public static readonly List<int> playerNumbers = new List<int>();
/* <<<<<<<<<<<INITIALIZE>>>>>>>>>>> */
public static void init()
{
nhBuffers.init();
nhListener.init();
nhPlayer.init(efx);
//nhMixer.init();
DistanceModel();
//nhAux reverb = new nhAux();
for (int i = 0; i < nhBuffers.buffers.Count; i++)
{
addPlayer("testplayer", new Vector3(0.0f, 0.0f, 0.0f));
}
Console.WriteLine("nhengine.Audio initialized.");
}
/* <<<<<<<<<<<MAIN>>>>>>>>>>> */
public static void Main()
{
using (context)
{
init();
play(4, "st1.wav");
while (debug)
{
Thread.Sleep(40);
}
}
}
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!");
}
}
private static int getPlayerIndex(string playerName)
{
int _index = playerNames.IndexOf(playerName);
return _index;
}
private static int getPlayerIndex(int playerNumber)
{
int _index = playerNumbers.IndexOf(playerNumber);
return _index;
}
public static void play(string playerName, string buffer, float gain = 1.0f, bool loop = false)
{
if(playerName != null)
players[getPlayerIndex(playerName)].play(buffer, gain, loop);
else
{
throw new NotSupportedException("Not an existing Player.");
}
}
public static void play(int playerNumber, string buffer, float gain = 1.0f, bool loop = false)
{
if (playerNumber != 0)
players[getPlayerIndex(playerNumber)].play(buffer, gain, loop);
//Console.WriteLine("play player:" + )
else
{
throw new NotSupportedException("Not an existing Player.");
}
}
public static void setPlayerPosition(string playerName, Vector3 position)
{
if(playerName != null)
players[getPlayerIndex(playerName)].position = position;
else
{
throw new NotSupportedException("Not an existing Player.");
}
}
public static void setPlayerPosition(int playerNumber, Vector3 position)
{
if (playerNumber != 0)
players[getPlayerIndex(playerNumber)].position = position;
else
{
throw new NotSupportedException("Not an existing Player.");
}
}
public static void setPlayerVelocity(string playerName, Vector3 velocity)
{
if (playerName != null)
players[getPlayerIndex(playerName)].velocity = velocity;
else
{
throw new NotSupportedException("Not an existing Player.");
}
}
public static void setPlayerVelocity(int playerNumber, Vector3 velocity)
{
if (playerNumber != 0)
players[getPlayerIndex(playerNumber)].velocity = velocity;
else
{
throw new NotSupportedException("Not an existing Player.");
}
}
public static void addPlayer(string name, Vector3 position, float rollOf = 2.0f, float refDist = 0.0f, float maxDist = 100.0f)
{
nhPlayer _player = new nhPlayer(name, position, rollOf, refDist, maxDist);
players.Add(_player);
playerNames.Add(_player.name);
playerNumbers.Add(_player.number);
}
public static void deletePlayer(string name)
{
int _index = getPlayerIndex(name);
players[_index].deletePlayer();
players.RemoveAt(_index);
playerNames.RemoveAt(_index);
playerNumbers.RemoveAt(_index);
}
}
}

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,156 @@
using System;
using System.IO;
using System.Collections.Generic;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
namespace nhengine.Audio
{
public static class nhBuffers
{
public static List<int> buffers = new List<int>();
public static List<string> buffersNames = new List<string>();
private static List<string> _files = new List<string>();
private static string[] _folder;
//private static string filepath;
public static void init()
{
buffers.Clear();
buffersNames.Clear();
_files.Clear();
_openFiles();
}
private static void _openFiles()
{
//_files.Add(filepath);
_folder = Directory.GetFiles(Path.Combine("Data", "Audio", "Sounds"), "*.wav");
for (int i = 0; i < _folder.Length; i++)
{
_createBuffer(_folder[i]);
buffersNames.Add(Path.GetFileName(_folder[i]));
}
}
private static void _createBuffer(string path)
{
Stream stream = File.Open(path, FileMode.Open);
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(buffer);
}
}
public static string getBufferName(int bufferID){
return buffersNames[bufferID];
}
public static int getBufferID(string bufferName){
int _index = buffersNames.IndexOf(bufferName);
return buffers[_index];
}
}
}

View File

@ -0,0 +1,79 @@
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 _oUp = new Vector3(0.0f, 0.0f, -1.0f);
private static Vector3 _oAt = new Vector3(0.0f, 1.0f, 0.0f);
public static void init()
{
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 _oAt, ref _oUp);
}
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 _oAt, ref _oUp);
}
public static void setListener(Vector3 position, Vector3 velocity, Vector3 orientationUp, Vector3 orientationAt)
{
_pos = position;
_vel = velocity;
_oUp = orientationUp;
_oAt = orientationAt;
_setValues();
}
public static void setPosition(Vector3 position)
{
_pos = position;
_setValues();
}
public static void setVelocity(Vector3 velocity)
{
_vel = velocity;
_setValues();
}
public static void setOrientation(Vector3 Up, Vector3 At)
{
_oUp = Up;
_oAt = At;
_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,231 @@
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 int _buffer;
public string buffer
{
set
{_buffer = nhBuffers.getBufferID(value);}
get
{return _buffer.ToString();}
}
private string _name;
public string name
{
set
{_name = value + ".p" + _playerNumber ;}
get
{return _name;}
}
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;
private float _refDist;
private float _maxDist;
//private int _state;
//private int[] _seqBuffer = { };
public nhPlayer(string name, Vector3 position, float rollOf = 2.0f, float refDist = 0.0f, float maxDist = 100.0f)
{
this.name = name;
_rollOf = rollOf;
_refDist = refDist;
_maxDist = maxDist;
this.position = position;
_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);
printInfo();
Interlocked.Increment(ref _playerNumber);
}
//>>>>>>>>>>>>>>>>>METHODS
public static void init(EffectsExtension effectsExtension)
{
_efx = effectsExtension;
}
public void play(string buffer = null, float gain = 1.0f, bool loop = false)
{
_gain = gain;
this.buffer = buffer;
AL.Source(_source, ALSourcei.Buffer, _buffer);
AL.Source(_source, ALSourceb.Looping, loop);
AL.SourcePlay(_source);
//_isplaying = true;
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 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);
}
public void printInfo()
{
Console.WriteLine("<<<<PLAYER #" + _playerNumber + ">>>>");
Console.WriteLine("Name:" + _name);
Console.WriteLine("Buffer:" + _buffer);
Console.WriteLine("-----------");
}
}
}