SafeDispatch/MotoRepeaterCore/AMBE.cs

172 lines
9.1 KiB
C#
Raw Permalink Normal View History

2024-02-22 16:43:59 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace MotoRepeater
{
class AMBE
{
private static String recSlot1FileName = null;
private static String recSlot2FileName = null;
private static String recSlot1FilePath = null;
private static String recSlot2FilePath = null;
public static int nrOfBadFrames = 0;
public static int nrOfFrames = 0;
public static int count = 0;
/// <summary>
/// Get the voice frames from the voice burst as described in devspec_NAI_audio_recording_0102.pdf
/// and then interleave the voice frames as in the AMBE-3000_Rates_33_34.pdf documents
/// </summary>
/// <param name="ambeVoice">The Voice Burst received from Motorola in WL_VC_VOICE_BURST</param>
/// <returns>The list with all voice frames interleaved as USB-3000 requires them</returns>
public static List<byte[]> Rate34PrepareForEncoding(byte[] ambeVoice)
{
List<byte[]> toReturn = new List<byte[]>(3);
toReturn.Add(new byte[7]);
toReturn.Add(new byte[7]);
toReturn.Add(new byte[7]);
byte errorByteFrame1 = GetBitsAsByte(ambeVoice[0], 0, 1);
byte errorByteFrame2 = GetBitsAsByte(ambeVoice[7], 6, 1);
byte errorByteFrame3 = GetBitsAsByte(ambeVoice[13], 4, 1);
if (count++ % 2 == 0)
{
/*
Utils.WriteLine("Frame 1 is " + (errorByteFrame1 != 1 ? "good" : "bad"), ConsoleColor.Cyan);
Utils.WriteLine("Frame 2 is " + (errorByteFrame2 != 1 ? "good" : "bad"), ConsoleColor.Cyan);
Utils.WriteLine("Frame 3 is " + (errorByteFrame3 != 1 ? "good" : "bad"), ConsoleColor.Cyan);
*/
if (errorByteFrame1 == 1)
nrOfBadFrames++;
if (errorByteFrame2 == 1)
nrOfBadFrames++;
if (errorByteFrame3 == 1)
nrOfBadFrames++;
nrOfFrames += 3;
}
List<byte> mb1 = new List<byte>();
List<byte> mb2 = new List<byte>();
List<byte> mb3 = new List<byte>();
try
{
#region GET FRAMES
//Utils.WriteLine("AMBE LENGTH " + ambeVoice.Length + " bytes", ConsoleColor.Magenta);
for (int i = 1; i < ambeVoice.Length; i++)
{
for (int j = 7; j >= 0; j--)
{
// if I am in rows with v1u_0
switch (i)
{
case 7:
{
if (j == 7)
mb1.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
else if (j != 6)
mb2.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
break;
}
case 13:
{
if (j > 4)
mb2.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
else if (j != 4)
mb3.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
break;
}
case 19:
{
if (j >= 3)
mb3.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
break;
}
default:
{
if ((i == 0) || (i == 7 && j == 6) || (i == 13 && j == 4))
{
// do nothing because these are bit error bits
}
else if (i <7)
mb1.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
else if (i >=8 && i<13)
mb2.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
else if (i >= 14)
mb3.Insert(0, GetBitsAsByte(ambeVoice[i], j, 1));
break;
}
}
}
}
#endregion
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Write("EXCEPTIE : " + ex.ToString());
Console.ForegroundColor = ConsoleColor.Gray;
}
// populate bytes
toReturn[0][00] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb1[48], mb1[30], mb1[12], mb1[47], mb1[29], mb1[11], mb1[46], mb1[28]), 2);
toReturn[0][01] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb1[10], mb1[45], mb1[27], mb1[09], mb1[44], mb1[26], mb1[08], mb1[43]), 2);
toReturn[0][02] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb1[25], mb1[07], mb1[42], mb1[24], mb1[06], mb1[41], mb1[23], mb1[05]), 2);
toReturn[0][03] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb1[40], mb1[22], mb1[04], mb1[39], mb1[21], mb1[03], mb1[38], mb1[20]), 2);
toReturn[0][04] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb1[02], mb1[37], mb1[19], mb1[01], mb1[36], mb1[18], mb1[00], mb1[35]), 2);
toReturn[0][05] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb1[17], mb1[34], mb1[16], mb1[33], mb1[15], mb1[32], mb1[14], mb1[31]), 2);
toReturn[0][06] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb1[13], 0, 0, 0, 0, 0, 0, 0), 2);
toReturn[1][00] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb2[48], mb2[30], mb2[12], mb2[47], mb2[29], mb2[11], mb2[46], mb2[28]), 2);
toReturn[1][01] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb2[10], mb2[45], mb2[27], mb2[09], mb2[44], mb2[26], mb2[08], mb2[43]), 2);
toReturn[1][02] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb2[25], mb2[07], mb2[42], mb2[24], mb2[06], mb2[41], mb2[23], mb2[05]), 2);
toReturn[1][03] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb2[40], mb2[22], mb2[04], mb2[39], mb2[21], mb2[03], mb2[38], mb2[20]), 2);
toReturn[1][04] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb2[02], mb2[37], mb2[19], mb2[01], mb2[36], mb2[18], mb2[00], mb2[35]), 2);
toReturn[1][05] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb2[17], mb2[34], mb2[16], mb2[33], mb2[15], mb2[32], mb2[14], mb2[31]), 2);
toReturn[1][06] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb2[13], 0, 0, 0, 0, 0, 0, 0), 2);
toReturn[2][00] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb3[48], mb3[30], mb3[12], mb3[47], mb3[29], mb3[11], mb3[46], mb3[28]), 2);
toReturn[2][01] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb3[10], mb3[45], mb3[27], mb3[09], mb3[44], mb3[26], mb3[08], mb3[43]), 2);
toReturn[2][02] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb3[25], mb3[07], mb3[42], mb3[24], mb3[06], mb3[41], mb3[23], mb3[05]), 2);
toReturn[2][03] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb3[40], mb3[22], mb3[04], mb3[39], mb3[21], mb3[03], mb3[38], mb3[20]), 2);
toReturn[2][04] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb3[02], mb3[37], mb3[19], mb3[01], mb3[36], mb3[18], mb3[00], mb3[35]), 2);
toReturn[2][05] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb3[17], mb3[34], mb3[16], mb3[33], mb3[15], mb3[32], mb3[14], mb3[31]), 2);
toReturn[2][06] = Convert.ToByte(String.Format("{0}{1}{2}{3}{4}{5}{6}{7}", mb3[13], 0, 0, 0, 0, 0, 0, 0), 2);
// return bytes
return toReturn;
}
/// <summary>
/// Gets a specific group of bits as a byte values. This process is created appling a
/// custom mask and then shifting the remaining bits to right
/// </summary>
/// <param name="b">The byte from which the bits will be extracted</param>
/// <param name="offset">The number of bits which will be skipped from right[LST]. O for no offset</param>
/// <param name="count">Number of bits which are required</param>
/// <returns>The byte value of the required bits. This values is generated shifting the bits towards LST</returns>
public static byte GetBitsAsByte(byte b, int offset, int count)
{
return (byte)((b >> offset) & ((1 << count) - 1));
}
}
}