Ti C6x DSP intrinsics for optimising C code - optimization

I want to use C66x intrinsics to optimise my code .
Below is some C code what I want to optimise by using DSP intrinsics .
I am new to DSP intrinsic ,so not having full knowledge of which intrinsic use for below logic .
uint8 const src[40] = = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40};
uint32_t width = 8;
uint32_t axay1_6 = 112345;
uint32_t axay2_6 = 123456;
uint32_t axay3_6 = 134567;
uint32_t axay4_6 = 145678;
C code:
uint8_t const *cLine = src;
uint8_t const *nLine = cLine + width;
uint32_t res = 0;
const uint32_t a1 = (*cLine++) * axay1_6;
const uint32_t a3 = (*nLine++) * axay3_6;
res = a1 + a3;
const uint32_t a2 = (*cLine) * axay2_6;
const uint32_t a4 = (*nLine) * axay4_6;
res += a2 + a4;
C66x Intrinscics :
const uint8_t *Ix00, *Ix01, *Iy00,*Iy01;
uint32_t in1,in2;
uint64_t l1, l2;
__x128_t axay1_6 = _dup32_128(axay1_6); //112345 112345 112345 112345
__x128_t axay2_6 = _dup32_128(axay2_6); //123456 123456 123456 123456
__x128_t axay3_6 = _dup32_128(axay3_6); //134567 134567 134567 134567
__x128_t axay4_6 = _dup32_128(axay4_6); //145678 145678 145678 145678
Ix00 = src ;
Ix01 = Ix00 + 1 ;
Iy00 = src + width;
Iy01 = Iy00 + 1;
int64_t I_00 = _mem8_const(Ix00); //00 01 02 03 04 05 06 07
int64_t I_01 = _mem8_const(Ix01); //01 02 03 04 05 06 07 08
int64_t I_10 = _mem8_const(Iy00); //10 11 12 13 14 15 16 17
int64_t I_11 = _mem8_const(Iy01); //11 12 13 14 15 16 17 18
in1 = _loll(I_00); //00 01 02 03
l1 = _unpkbu4(in1); //00 01 02 03 (16x4)
in2 = _hill(I_00); //04 05 06 07
l2 = _unpkbu4(in2); //04 05 06 07 (16x4)
Here I want one something __x128 register with 32*4 value containg " 00 01 02 03 " data .
So I can multiply __x128 into __x128 bit register and get __x128 bit value .Presently i am planning to use _qmpy32
I am new to this C66x DSP intrinscic .
Can you tell me which intrinsic is suitable to get __x128 type of register with 32x4 values with 00 01 02 03 values.
(means how to convert 16 bit to 32 bit by using dsp intrinsic)

Use the _unpkhu2 instruction to expand the 16x4 to 32x4.
__x128_t src1_128, src2_128;
src1_128 = _llto128(_unpkhu2(_hill(l1)), _unpkhu2(_loll(l1)));
src2_128 = _llto128(_unpkhu2(_hill(l2)), _unpkhu2(_loll(l2)));
Be careful: Little-endian/Big-endian settings can make these sorts of things come out in a way you didn't expect.
Also, I wouldn't recommend naming a variable l1. In some fonts, lower-case L and the number 1 are indistinguishable.

Related

GNURadio PSK bit recovery

I have followed the wonderful GNURadio Guided Tutorial PSK Demodulation:
https://wiki.gnuradio.org/index.php/Guided_Tutorial_PSK_Demodulation
I've created a very simple DBPSK modulator
I feed in a series of bits that are sliding. So the first byte I feed in is 0x01, the next byte is 0x02, 0x04, 0x08 and so on. This is the output of hd:
00000000 00 00 ac 0e d0 f0 20 40 81 02 04 08 10 00 20 40 |...... #...... #|
00000010 81 02 04 08 10 00 20 40 81 02 04 08 10 00 20 40 |...... #...... #|
*
00015000
The first few bytes are garbage, but then you can see the pattern. Looking at the second line you see:
0x81, 0x02, 0x04, 0x08, 0x10, 0x00, 0x20, 0x40, 0x81
The walking ones is there, but after 0x10, the PSK demodulator receives a 0x00, then a few bytes later is receives a 0x81. It almost seems like the timing recovery is off.
Has anyone else seen something like this?
OK, I figured it out. Below is my DBPSK modulation.
If you let this run, the BER will continue to drop. Some things to keep in mind. The PSK Mod takes an 8-bit value (or perhaps an short or int as well). It grabs the bits and modulates them. Then the PSK Demod does the same. If you save this to a file, you will not get the exact bits out. You will need to shift the bits to align them. I added the Vector Insert block to generate a preamble of sorts.
Then I wrote some Python to find my preamble:
import numpy as np
import matplotlib.pyplot as plt
def findPreamble(preamble, x):
for i in range(0, len(x) - len(preamble)):
check = 0
for j in range(0, len(preamble)):
check += x[i + j] - preamble[j]
if (check == 0):
print("Found a preamble at {0}".format(i))
x = x[i + len(preamble)::]
break
return check == 0, x
def shiftBits(x):
for i in range (0, len(x) - 1):
a = x[i]
a = a << 1
if x[i + 1] & 0x80:
a = a | 1
x[i] = (a & 0xFF)
return x
f = open('test.bits', 'rb')
x = f.read();
f.close()
preamble = [0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]
searchForBit = True
x = np.frombuffer(x, dtype='uint8')
x = x.astype('int')
print(x)
while searchForBit:
x = shiftBits(x)
print(x)
found, y = findPreamble(preamble, x)
if found:
searchForBit = False
y = y.astype('uint8')
f = open('test.bits', 'wb')
f.write(y)
f.close()

Convert hex to latitude longitude from dashcam .MOV file

I have an OEM dashcam that saves videos in .MOV format. I want to extract the embedded gps data from the video files programmatically. Upon opening the .mov file in a hex editor I found data packets with freeGPS headers and I can confirm that for my 7 seconds sample video there are 7 packets so I know this where the gps data comes from.
I already found the date and time but I got stuck with converting the hex values to latitude longitude. Below are the hex values and their equivalent coordinates when extracted using Registrator Viewer.
273108AC1C7996404E,0D022B873EA3C74045 - 14.637967,121.041475
516B9A771C7996404E,0D022B873EA3C74045 - 14.637963,121.041475
B9FC87F41B7996404E,52499D803EA3C74045 - 14.637955,121.041472
B9FC87F41B7996404E,52499D803EA3C74045 - 14.637955,121.041472
B459F5B91A7996404E,C442AD693EA3C74045 - 14.637935,121.041460
1DEBE2361A7996404E,ACADD85F3EA3C74045 - 14.637927,121.041455
08CE19511A7996404E,4FD1915C3EA3C74045 - 14.637928,121.041453
The bolded bytes directly translates to #N and #E so I think they are not part of the conversion. I already tried the below answers but I did not succeed in getting the correct coordinates.
How to convert GPS Longitude and latitude from hex
How to convert my binary (hex) data to latitude and longitude?
I already sent an email to the dashcam provider asking for their protocol documentation but it does not look like they have one since they sent Registrator Viewer when I asked for their own video player.
I will also include the first freeGPS packet in case I am looking at the wrong place.
00 00 80 00 66 72 65 65 47 50 53 20 98 00 00 00 78 2E 78 78 00 00 00 00 00 00 00 00 00 00 00 00 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 03 00 00 00 27 00 00 00 41 00 00 00 27 31 08 AC 1C 79 96 40 4E 00 00 00 00 00 00 00 0D 02 2B 87 3E A3 C7 40 45 00 00 00 00 00 00 00 8F C2 F5 28 5C 8F E2 3F 48 E1 7A 14 AE 07 68 40 11 00 00 00 06 00 00 00 14 00 00 00 76 00 00 00 88 00 00 00 DE 00 00 00 4D 00 00 00 49 00 00 00 4F 00 00 00 2D 00 00 00 2B 00 00 00 00 00 00 00
Data in bold extracted in order : freeGPS, time, latitude#N?, longitude#E?, date
I can confirm that time and date are correct. The speed is supposed to be 1km/h but I can't also find that.
Thanks in advance for those who can help.
EDIT:
Here is the link for the test video. Test Video
Not sure how helpful this is but if you convert the hex string (including the 0x40 at the end) into a little endian IEEE-754 double precision real, then you get approximately 100X the lat/lon.
In C, I did something like
printf( "%f\n", *(double*)"\x27\x31\x08\xAC\x1C\x79\x96\x40" );
printf( "%f\n", *(double*)"\x0D\x02\x2B\x87\x3E\xA3\xC7\x40" );
and got out
1438.278000
12102.488500
Update thanks to #TDG
If the 1438.278 is interpreted as 14 degrees 38.278 minutes then you get a decimal value of 14.6379666666666667. If 12102.4885 is interpreted as 121 degrees and 2.4885 minutes, the decimal equivalent is 121.041475.
Some example C code to do this
#include<stdio.h>
double convert( double input ) {
int i = input/100;
return ( input - i*100 ) / 60 + i;
}
int main(){
printf( "%f\n", convert( *(double*)"\x27\x31\x08\xAC\x1C\x79\x96\x40" ) );
printf( "%f\n", convert( *(double*)"\x0D\x02\x2B\x87\x3E\xA3\xC7\x40" ) );
}
Found this explanation of GPS data format, worked for me.
public static ViofoGpsPoint Parse(uint offset, uint size, byte[] file)
{
byte[] data = new byte[size];
Array.Copy(file, offset, data, 0, size);
uint pos = 0;
uint size1 = Box.ReadUintBE(data, pos); pos += 4;
string type = Encoding.ASCII.GetString(data, (int)pos, 4); pos += 4;
string magic = Encoding.ASCII.GetString(data, (int)pos, 4); pos += 4;
if (size != size1 || type != "free" || magic != "GPS ")
return null;
ViofoGpsPoint gps = new ViofoGpsPoint();
//# checking for weird Azdome 0xAA XOR "encrypted" GPS data.
//This portion is a quick fix.
uint payload_size = 254;
if (data[pos] == 0x05)
{
if (size < 254)
payload_size = size;
byte[] payload = new byte[payload_size];
pos += 6; //???
for (int i = 0; i < payload_size; i++)
{
payload[i] = (byte)(file[pos + i] ^ 0xAA);
}
}
else if ((char)data[pos] == 'L')
{
const uint OFFSET_V2 = 48, OFFSET_V1 = 16;
pos = OFFSET_V2;
//# Datetime data
int hour = (int)Box.ReadUintLE(data, pos); pos += 4;
int minute = (int)Box.ReadUintLE(data, pos); pos += 4;
int second = (int)Box.ReadUintLE(data, pos); pos += 4;
int year = (int)Box.ReadUintLE(data, pos); pos += 4;
int month = (int)Box.ReadUintLE(data, pos); pos += 4;
int day = (int)Box.ReadUintLE(data, pos); pos += 4;
try { gps.Date = new DateTime(2000 + year, month, day, hour, minute, second); }
catch (Exception err) { Debug.WriteLine(err.ToString()); return null; }
//# Coordinate data
char active = (char)data[pos]; pos++;
gps.IsActive = (active == 'A');
gps.Latitude_hemisphere = (char)data[pos]; pos++;
gps.Longtitude_hemisphere = (char)data[pos]; pos++;
gps.Unknown = data[pos]; pos++;
float lat = Box.ReadFloatLE(data, pos); pos += 4;
gps.Latitude = FixCoordinate(lat, gps.Latitude_hemisphere);
float lon = Box.ReadFloatLE(data, pos); pos += 4;
gps.Longtitude = FixCoordinate(lon, gps.Longtitude_hemisphere);
gps.Speed = Box.ReadFloatLE(data, pos); pos += 4;
gps.Bearing = Box.ReadFloatLE(data, pos); pos += 4;
return gps;
}
return null;
}
/// <summary>
/// # Novatek stores coordinates in odd DDDmm.mmmm format
/// </summary>
/// <param name="coord"></param>
/// <param name="hemisphere"></param>
/// <returns></returns>
private static double FixCoordinate(double coord, char hemisphere)
{
double minutes = coord % 100.0;
double degrees = coord - minutes;
double coordinate = degrees / 100.0 + (minutes / 60.0);
if (hemisphere == 'S' || hemisphere == 'W')
return -1 * (coordinate);
else
return (coordinate);
}

Converting Hex String to UInt8 Array in Objective-C

The String to bytes[]
NSString *strData = #"ca 20 fe c1 04 03 03 07 00 ac";
The Result is
UInt8 bytes[]= {0xca,0x20,0xfe,0xc1,0x04,0x03,0x03,0x07,0x01,0xac};
for swift code, how convert to Objective-C
let data = NSString(string : "ca 20 fe c1 04 03 03 07 01 ac");
let dataArr = data.componentsSeparatedByString(" ")
var bytes : [UInt8] = [];
for item in dataArr {
let byte = UInt8(item, radix: 16)
bytes.append(byte!);
}
let hexData = NSData(bytes: bytes, length: 10)

Frequently used symbol "|" in Objective-C

self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleWidth;
The source code is shown above.
Wonder what the symbol "|" stands for?
Will really appreciate your answer and thanks for the reply;)
In short: that is a bitwise OR operation.
It is tipically used in generating bitmasks.
With this operation you can combine flags into on binary number.
For example: possible flags for UIViewAutoresizing are:
enum {
UIViewAutoresizingNone = 0, // = 0b 0000 0000 = 0
UIViewAutoresizingFlexibleLeftMargin = 1 << 0, // = 0b 0000 0001 = 1
UIViewAutoresizingFlexibleWidth = 1 << 1, // = 0b 0000 0010 = 2
UIViewAutoresizingFlexibleRightMargin = 1 << 2, // = 0b 0000 0100 = 4
UIViewAutoresizingFlexibleTopMargin = 1 << 3, // = 0b 0000 1000 = 8
UIViewAutoresizingFlexibleHeight = 1 << 4, // = 0b 0001 0000 = 16
UIViewAutoresizingFlexibleBottomMargin = 1 << 5 // = 0b 0010 0000 = 32
};
typedef NSUInteger UIViewAutoresizing;
Statement:
self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleWidth;
is esentially the same as:
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
(since both operands are the same).
If you would ask about:
self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
this would set self.autoresizingMask to:
(1<<1)|(1<<4)=(0b 0000 0010)|(0b 0001 0000)=0b 0001 0010 = 9
Bitwise OR is not to be confused by Logical OR used with simple true/false algebra.
There is some relation between the two (bitwise or can be understood as a logical or between the bits on the same position) but that is about it.
| is the bitwise OR operator in C (and therefore in Objective-C).
See http://en.m.wikipedia.org/wiki/Bitwise_operations_in_C
In the context you asked about, it's being used to combine two flag values.
The | character denotes an inclusive-or bitwise operation. which operates under the premise with matching the bitstrings of two objects.
if you have a bitstring 1101 and another 1001 the inclusive or of the two would produce 1011. Basically if the current bit is the same in both strings then a 1 is outputted in its place otherwise a 0 is.
That is a bitwise OR operation, maybe this can help you : Bitwise operation

greatest common divisor Objective-C

I am new to ios programing. I have question about the GCD program.
01 // This program finds the greatest common divisor of two nonnegative integer values
02
03 #import <Foundation/Foundation.h>
04
05 int main (int argc, const char * argv[]) {
06 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
07 unsigned int u, v, temp;
08
09 NSLog(#"Please type in two nonnegative integers.");
10 scanf("%u%u", &u, &v);
11
12 while (v != 0) {
13 temp = u % v;
14 u = v;
15 v = temp;
16 }
17
18 NSLog(#"Their greatest common divisor is %u", u);
19
20 [pool drain];
21 return 0;
22 }
I don't understand this part:
while(v!=0)
temp = u%v
u =v;
v = temp;
What does that mean, in English?
That part actually calculates the greatest common divisor using the Euclidean algorithm.
% is the mod operator. Those three lines divide u by v and store the remainder in temp. Then u gets the value of v, and v gets the remainder. The process is repeated while v is not 0.
I see you are using euclideans algorithm
as you can see, temp = u%v % is a modulo operator where it divides the u and v and the remainder of it is stored at temp. then the value of is stored at the variable v and lastly the value of temp is stored at the variable v. and this whole process will repeat until the value of v is not equal to 0 or not 0.