Skip to content

Commit

Permalink
trying to make it work
Browse files Browse the repository at this point in the history
  • Loading branch information
wjw78879 committed Oct 14, 2021
1 parent aed5b17 commit 9741dde
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 25 deletions.
12 changes: 6 additions & 6 deletions Native-Modem/BitReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ namespace Native_Modem
{
public static class BitReader
{
public static BitArray DirtyReadBits(StreamReader stringStream)
public static BitArray ReadBits(StreamReader stringStream)
{
List<bool> bits = new List<bool>();

// Hack: Add 100 zeros for heating
Random rd = new Random();
for (var i=0;i < 300; ++i)
{
bits.Add(rd.Next(0,2) == 0);
}
//Random rd = new Random();
//for (var i=0;i < 300; ++i)
//{
// bits.Add(rd.Next(0,2) == 0);
//}


foreach (char c in stringStream.ReadLine())
Expand Down
1 change: 1 addition & 0 deletions Native-Modem/Native-Modem.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<ItemGroup>
<PackageReference Include="NAudio" Version="2.0.1" />
<PackageReference Include="STH1123.ReedSolomon" Version="2.1.0" />
</ItemGroup>

</Project>
38 changes: 32 additions & 6 deletions Native-Modem/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
using STH1123.ReedSolomon;

namespace Native_Modem
{
Expand All @@ -18,6 +19,7 @@ class Program
[STAThread]
static void Main()
{
//ReedSolomonTest();
//GenerateRandomBits();
//RecordAndPlay();
PreambleBuild(48000, 480, 1);
Expand All @@ -26,6 +28,32 @@ static void Main()
CompareResult();
}

static void ReedSolomonTest()
{
int[] input = new int[] { 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
foreach (int i in input)
{
Console.Write($"{i}, ");
}
Console.WriteLine();
GenericGF gf = new GenericGF(285, 256, 1);
ReedSolomonEncoder encoder = new ReedSolomonEncoder(gf);
encoder.Encode(input, 6);
foreach (int i in input)
{
Console.Write($"{i}, ");
}
Console.WriteLine();

ReedSolomonDecoder decoder = new ReedSolomonDecoder(gf);
Console.WriteLine(decoder.Decode(input, 6));
foreach (int i in input)
{
Console.Write($"{i}, ");
}
Console.WriteLine();
}

static void PreambleBuild(int SampleRate, int SampleCount, int amplitude)
{

Expand Down Expand Up @@ -92,7 +120,7 @@ static void SynchronousModemTest()
float[] header = new float[480];
for (int i = 0; i < 480; i++)
{
header[i] = (float)preamble[i] * 1f;
header[i] = preamble[i] * 1f;
}

Protocol protocol = new Protocol(
Expand Down Expand Up @@ -127,8 +155,7 @@ static void SynchronousModemTest()
foreach (bool bit in array)
{
Console.Write(bit ? 1 : 0);
if(frameCount > 2)
writer.Write(bit ? 1 : 0);
writer.Write(bit ? 1 : 0);
}
Console.WriteLine();
frameCount++;
Expand All @@ -139,8 +166,7 @@ static void SynchronousModemTest()

//Get input bits and transport
StreamReader inputStream = new StreamReader("../../../INPUT.txt");
BitArray bitArray =
BitReader.DirtyReadBits(inputStream);
BitArray bitArray = BitReader.ReadBits(inputStream);
inputStream.Close();
modem.Transport(bitArray);

Expand Down Expand Up @@ -196,7 +222,7 @@ static void ModemTest()
case 's':
//Get input bits
StreamReader inputStream = new StreamReader("../../../INPUT.txt");
BitArray bitArray = BitReader.DirtyReadBits(inputStream);
BitArray bitArray = BitReader.ReadBits(inputStream);
inputStream.Close();

//Modulate to samples
Expand Down
60 changes: 47 additions & 13 deletions Native-Modem/SynchronousModem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using STH1123.ReedSolomon;

namespace Native_Modem
{
Expand All @@ -24,6 +25,7 @@ enum ModemState
readonly Queue<BitArray> modulateQueue;

readonly float[] buffer = new float[1024];
readonly float[] preheater = new float[760];

ModemState modemState;
WaveFileWriter writer;
Expand All @@ -32,6 +34,15 @@ public SynchronousModem(Protocol protocol, string driverName)
{
this.protocol = protocol;

SinusoidalSignal preheaterSignal = new SinusoidalSignal(1f, 2000f);
float time = 0f;
float step = 1f / protocol.WaveFormat.SampleRate;
for (int i = 0; i < preheater.Length; i++)
{
preheater[i] = preheaterSignal.Evaluate(time);
time += step;
}

frameSampleCount = protocol.Header.Length + protocol.FrameSize * protocol.SamplesPerBit;
TxFIFO = new SampleFIFO(protocol.WaveFormat, frameSampleCount << 1);
RxFIFO = new SampleFIFO(protocol.WaveFormat, frameSampleCount);
Expand All @@ -53,7 +64,7 @@ public void Start(Action<BitArray> onFrameReceived, string saveRecordTo = null)

modemState = ModemState.Running;
_ = Modulate();
_ = Demodulate(onFrameReceived, 0.5f);
_ = Demodulate(onFrameReceived, 0.35f);

if (!string.IsNullOrEmpty(saveRecordTo))
{
Expand Down Expand Up @@ -99,6 +110,10 @@ public void Transport(BitArray bitArray)
void OnAsioOutAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
int sampleCount = e.GetAsInterleavedSamples(buffer);
if (!RxFIFO.AvailableFor(sampleCount))
{
Console.WriteLine("RxFIFO overflow!!!!!");
}
RxFIFO.Push(buffer, sampleCount);
if (writer != null)
{
Expand All @@ -125,7 +140,7 @@ void SetupAsioOut()
Console.WriteLine($"Output channel {i}: {asioOut.AsioOutputChannelName(i)}");
}
int outChannel = int.Parse(Console.ReadLine());
asioOut.ChannelOffset = outChannel; // Todo: Different from the sample
asioOut.ChannelOffset = outChannel;
Console.WriteLine($"Choosing the output channel: {asioOut.AsioOutputChannelName(outChannel)}");
}

Expand All @@ -147,14 +162,34 @@ void ModulateFrame(BitArray bitArray, int bitOffset)

async Task Modulate()
{
while (true)
if (modemState != ModemState.Running)
{
await TaskUtilities.WaitUntil(() => modulateQueue.Count > 0 || modemState != ModemState.Running);

if (modemState != ModemState.Running)
return;
}
else if (modulateQueue.Count != 0)
{
if (!await TaskUtilities.WaitUntilUnless(() => TxFIFO.AvailableFor(preheater.Length), () => modemState != ModemState.Running))
{
return;
}
TxFIFO.Push(preheater);
}

while (true)
{
if (modulateQueue.Count == 0)
{
if (!await TaskUtilities.WaitUntilUnless(() => modulateQueue.Count > 0, () => modemState != ModemState.Running))
{
return;
}

if (!await TaskUtilities.WaitUntilUnless(() => TxFIFO.AvailableFor(preheater.Length), () => modemState != ModemState.Running))
{
return;
}
TxFIFO.Push(preheater);
}

BitArray array = modulateQueue.Dequeue();

Expand All @@ -167,13 +202,13 @@ async Task Modulate()
int bitCount = 0;
for (int i = 0; i < frames; i++)
{
await TaskUtilities.WaitUntil(() => TxFIFO.AvailableFor(frameSampleCount));

if (!await TaskUtilities.WaitUntilUnless(() => TxFIFO.AvailableFor(frameSampleCount), () => modemState != ModemState.Running))
{
return;
}
TxFIFO.Push(protocol.Header);
await Task.Delay(10);
ModulateFrame(array, bitCount);
bitCount += protocol.FrameSize;
await Task.Delay(10);
}
}
}
Expand Down Expand Up @@ -208,8 +243,7 @@ async Task Demodulate(Action<BitArray> onFrameReceived, float syncPowerThreshold

while (true)
{
await TaskUtilities.WaitUntil(() => !RxFIFO.IsEmpty || modemState != ModemState.Running);
if (modemState != ModemState.Running)
if (!await TaskUtilities.WaitUntilUnless(() => !RxFIFO.IsEmpty, () => modemState != ModemState.Running))
{
return;
}
Expand All @@ -232,9 +266,9 @@ async Task Demodulate(Action<BitArray> onFrameReceived, float syncPowerThreshold
{
syncPower += gain * syncBuffer[j] * protocol.Header[j];
}
//Console.WriteLine($"syncPower: {syncPower}, localMax: {syncPowerLocalMax}, threshold: {protocol.HeaderPower * syncPowerThreshold}");
if (syncPower > protocol.HeaderPower * syncPowerThreshold && syncPower > syncPowerLocalMax)
{
//Console.WriteLine($"syncPower: {syncPower}, localMax: {syncPowerLocalMax}, threshold: {protocol.HeaderPower * syncPowerThreshold}");
syncPowerLocalMax = syncPower;
decode = true;
decodeFrame.Clear();
Expand Down
22 changes: 22 additions & 0 deletions Native-Modem/TaskUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,27 @@ public static async Task WaitUntil(Func<bool> untilTrue)
await Task.Delay(SMALL_DELAY);
}
}

/// <summary>
/// Wait until a condition is met (returns true), unless another condition is met (returns false)
/// </summary>
/// <param name="until"></param>
/// <param name="unless"></param>
/// <returns></returns>
public static async Task<bool> WaitUntilUnless(Func<bool> until, Func<bool> unless)
{
while (true)
{
if (until.Invoke())
{
return true;
}
if (unless.Invoke())
{
return false;
}
await Task.Delay(SMALL_DELAY);
}
}
}
}

0 comments on commit 9741dde

Please sign in to comment.