Erste FIR Test Implementation

master
Harald Wolff 2017-10-21 09:46:52 +02:00
parent cc37e550cf
commit 3805a5163d
10 changed files with 121 additions and 15 deletions

View File

@ -1,6 +1,7 @@
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace AudioStreamer
{
public class AudioStreamer
@ -58,7 +59,11 @@ namespace AudioStreamer
Monitor.Exit(this);
foreach (AudioSource source in this.sources){
source.Source();
try {
source.Source();
} catch (Exception e) {
Console.WriteLine("pusher(): Exception: {0}", e);
}
}
Monitor.Enter(this);

View File

@ -45,15 +45,17 @@
<Compile Include="AudioOutput.cs" />
<Compile Include="AudioChannel.cs" />
<Compile Include="MultiChannelAudioConsumer.cs" />
<Compile Include="OpenALSource.cs" />
<Compile Include="AudioStreamer.cs" />
<Compile Include="AudioSource.cs" />
<Compile Include="BaseAudioSource.cs" />
<Compile Include="OpenALPlayback.cs" />
<Compile Include="Amplifier.cs" />
<Compile Include="BaseAudioOutput.cs" />
<Compile Include="BaseAudioProcessor.cs" />
<Compile Include="Echo.cs" />
<Compile Include="Sources\OpenALSource.cs" />
<Compile Include="Processors\Amplifier.cs" />
<Compile Include="Processors\Echo.cs" />
<Compile Include="Playbacks\OpenALPlayback.cs" />
<Compile Include="Processors\FIRFilter.cs" />
<Compile Include="ModuloList.cs" />
</ItemGroup>
<ItemGroup>
<None Include="OpenTK.dll.config">
@ -124,6 +126,11 @@
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Sources\" />
<Folder Include="Processors\" />
<Folder Include="Playbacks\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<MonoDevelop>

View File

@ -13,13 +13,15 @@ namespace AudioStreamer
{
if (NewAudioAvailable != null)
{
if (NewAudioAvailable.GetInvocationList().Length == 1){
if (NewAudioAvailable.GetInvocationList().Length == 0){
} else if (NewAudioAvailable.GetInvocationList().Length == 1){
NewAudioAvailable.Invoke(this, samples);
} else {
foreach (Delegate d in NewAudioAvailable.GetInvocationList()){
Int16[] copy = new Int16[samples.Length];
Array.Copy(samples,copy,samples.Length);
d.Method.Invoke(d.Target, new object[] { copy });
d.Method.Invoke(d.Target, new object[] { this, copy });
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Runtime.CompilerServices;
namespace AudioStreamer
{
public class ModuloList<T>
{
T[] buffer;
public ModuloList(int size)
{
buffer = new T[size];
}
public T this[int n]{
get {
n %= this.buffer.Length;
if (n<0){
n += this.buffer.Length;
}
return this.buffer[n];
}
set {
n %= this.buffer.Length;
if (n<0){
n += this.buffer.Length;
}
this.buffer[n] = value;
}
}
public int Size { get { return this.buffer.Length; } }
}
}

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using OpenTK.Audio.OpenAL;
using OpenTK.Audio;
namespace AudioStreamer
namespace AudioStreamer.Playbacks
{
public class OpenALPlayback : AudioInput
{

View File

@ -1,5 +1,5 @@
using System;
namespace AudioStreamer
namespace AudioStreamer.Processors
{
public class Amplifier : BaseAudioProcessor
{
@ -23,7 +23,7 @@ namespace AudioStreamer
protected override void process(ref short[] samples)
{
for (int n = 0; n < samples.Length;n++){
samples[n] = (Int16)(((UInt32)samples[n] * this.amplification) >> 16);
samples[n] = (Int16)(((Int32)samples[n] * this.amplification) >> 16);
}
}
}

View File

@ -1,5 +1,5 @@
using System;
namespace AudioStreamer
namespace AudioStreamer.Processors
{
public class Echo : BaseAudioProcessor
{

View File

@ -0,0 +1,50 @@
using System;
namespace AudioStreamer.Processors
{
public class FIRFilter : BaseAudioProcessor
{
Int32[] amplifications;
ModuloList<Int16> delay;
int delayPosition;
public FIRFilter(Int32[] amps)
{
this.amplifications = amps;
this.delay = new ModuloList<Int16>(amps.Length);
}
public FIRFilter(float[] amps)
{
this.amplifications = new Int32[amps.Length];
this.delay = new ModuloList<Int16>(amps.Length);
for (int n = 0; n < amps.Length;n++){
this.setAmplification(n,amps[n]);
}
}
public Int32[] Amplifications { get { return this.amplifications; } }
public float getAmplification(int n){
return ((float)this.amplifications[n]) / 65536.0f;
}
public void setAmplification(int n, float amp){
this.amplifications[n] = (Int32)(amp * 65536.0f);
}
protected override void process(ref short[] samples)
{
for (int n = 0; n < samples.Length; n++){
this.delay[n + delayPosition] = samples[n];
samples[n] = 0;
for (int pa = 0; pa < amplifications.Length; pa++){
samples[n] += (Int16)((this.amplifications[pa] * delay[delayPosition - pa])>>16);
}
}
delayPosition += samples.Length;
delayPosition %= this.amplifications.Length;
}
}
}

View File

@ -1,5 +1,8 @@
using System;
using System.Threading;
using AudioStreamer.Sources;
using AudioStreamer.Playbacks;
using AudioStreamer.Processors;
namespace AudioStreamer
{
@ -12,9 +15,12 @@ namespace AudioStreamer
OpenALSource source = new OpenALSource();
OpenALPlayback playback = new OpenALPlayback();
Amplifier amp = new Amplifier(2.0f);
Echo echo = new Echo(16000);
echo.FloatAmplification = 0.75f;
FIRFilter fir = new FIRFilter(new float[] { 0.013333f, 0.026665f, 0.013333f, -1.541256f, 0.594546f });
Amplifier amp = new Amplifier(0.75f);
Echo echo = new Echo(32);
echo.FloatAmplification = 0.85f;
streamer.addAudioSource(source);
@ -23,6 +29,8 @@ namespace AudioStreamer
amp.Connect(source);
echo.Connect(amp);
fir.Connect(echo);
playback.Connect(echo);
source.Start();

View File

@ -1,7 +1,7 @@
using System;
using OpenTK.Audio;
namespace AudioStreamer
namespace AudioStreamer.Sources
{
public class OpenALSource : BaseAudioSource, AudioOutput
{