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; /// /// 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 /// /// The Voice Burst received from Motorola in WL_VC_VOICE_BURST /// The list with all voice frames interleaved as USB-3000 requires them public static List Rate34PrepareForEncoding(byte[] ambeVoice) { List toReturn = new List(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 mb1 = new List(); List mb2 = new List(); List mb3 = new List(); 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; } /// /// 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 /// /// The byte from which the bits will be extracted /// The number of bits which will be skipped from right[LST]. O for no offset /// Number of bits which are required /// The byte value of the required bits. This values is generated shifting the bits towards LST public static byte GetBitsAsByte(byte b, int offset, int count) { return (byte)((b >> offset) & ((1 << count) - 1)); } } }