2016-09-07 07:36:43 +01:00
# include "isobuffer.h"
2016-09-28 01:15:18 +01:00
# include "isodriver.h"
2016-09-07 07:36:43 +01:00
2016-09-28 01:15:18 +01:00
isoBuffer : : isoBuffer ( int bufferLen , isoDriver * caller , unsigned char channel_value )
2016-09-07 07:36:43 +01:00
{
buffer = ( short * ) calloc ( bufferLen * 2 , sizeof ( short ) ) ;
bufferEnd = bufferLen - 1 ;
samplesPerSecond = ( double ) bufferLen / ( double ) 21 ;
samplesPerSecond = samplesPerSecond / 375 * 374 ; //BABABOOEY
2016-09-28 01:15:18 +01:00
parent = caller ;
channel = channel_value ;
2016-09-07 07:36:43 +01:00
}
void isoBuffer : : openFile ( QString newFile )
{
if ( fptr ! = NULL ) {
fclose ( fptr ) ;
}
if ( newFile . isEmpty ( ) ) {
fptr = NULL ;
}
else {
QByteArray temp = newFile . toLatin1 ( ) ;
char * fileName = temp . data ( ) ;
fptr = fopen ( fileName , " w " ) ;
if ( fptr = = NULL ) qFatal ( " Null fptr in isoBuffer::openFile " ) ;
qDebug ( ) < < " opening file " < < fileName ;
qDebug ( ) < < " fptr = " < < fptr ;
}
}
void isoBuffer : : writeBuffer_char ( char * data , int len )
{
2016-09-28 01:15:18 +01:00
double convertedSample ;
2016-09-07 07:36:43 +01:00
for ( int i = 0 ; i < len ; i + + ) {
//qDebug() << "i = " << i;
buffer [ back ] = ( short ) data [ i ] ;
if ( back = = bufferEnd ) {
back = 0 ;
firstTime = false ;
}
else back + + ;
2016-09-26 05:17:41 +01:00
//Output to CSV
if ( fileIOEnabled ) {
2016-09-28 01:15:18 +01:00
convertedSample = sampleConvert ( data [ i ] , 128 , channel = = 1 ? parent - > AC_CH1 : parent - > AC_CH2 ) ;
2016-09-26 05:17:41 +01:00
char numStr [ 32 ] ;
2016-09-28 01:15:18 +01:00
sprintf ( numStr , " %f, " , convertedSample ) ;
2016-09-26 05:17:41 +01:00
currentFile - > write ( numStr ) ;
currentColumn + + ;
if ( currentColumn > COLUMN_BREAK ) {
currentFile - > write ( " \n " ) ;
currentColumn = 0 ;
}
}
2016-09-07 07:36:43 +01:00
}
return ;
}
void isoBuffer : : writeBuffer_short ( short * data , int len )
{
//for (int i=(len-1);i>-1;i--){
for ( int i = 0 ; i < len ; i + + ) {
//qDebug() << "i = " << i;
buffer [ back ] = ( short ) data [ i ] > > 4 ; //Because it's a left adjust value!
if ( back = = bufferEnd ) {
back = 0 ;
firstTime = false ;
}
else back + + ;
}
return ;
}
short * isoBuffer : : readBuffer ( double sampleWindow , int numSamples , bool singleBit , double delayOffset )
{
//ignore singleBit for now
double timeBetweenSamples = ( double ) sampleWindow * ( double ) samplesPerSecond / ( double ) numSamples ;
double accumulatedDelay = 0 ;
int delaySamples = ( int ) ( ( double ) delayOffset * ( double ) samplesPerSecond ) ;
int front = back - 1 - delaySamples ;
if ( front < 0 ) front = 0 ;
int idx , subIdx ;
if ( readData ! = NULL ) free ( readData ) ;
readData = ( short * ) calloc ( numSamples , sizeof ( short ) ) ;
if ( singleBit ) {
for ( int i = 0 ; i < numSamples ; i + + ) {
if ( timeBetweenSamples > ( double ) front ) {
accumulatedDelay - = ( double ) front ;
front = bufferEnd ;
}
idx = ( int ) floor ( ( ( double ) front - accumulatedDelay ) ) ;
subIdx = ( int ) floor ( 8 * ( ( ( double ) front - accumulatedDelay ) - floor ( ( ( double ) front - accumulatedDelay ) ) ) ) ;
if ( idx < 0 ) {
accumulatedDelay - - ;
accumulatedDelay - = ( double ) front ;
front = bufferEnd ;
idx = ( int ) round ( ( ( double ) front - accumulatedDelay ) ) ;
}
readData [ i ] = buffer [ idx ] & ( 1 < < subIdx ) ;
accumulatedDelay + = timeBetweenSamples ;
}
} else {
for ( int i = 0 ; i < numSamples ; i + + ) {
if ( timeBetweenSamples > ( double ) front ) {
accumulatedDelay - = ( double ) front ;
front = bufferEnd ;
}
idx = ( int ) round ( ( ( double ) front - accumulatedDelay ) ) ;
if ( idx < 0 ) {
accumulatedDelay - - ;
accumulatedDelay - = ( double ) front ;
front = bufferEnd ;
idx = ( int ) round ( ( ( double ) front - accumulatedDelay ) ) ;
}
readData [ i ] = buffer [ idx ] ;
accumulatedDelay + = timeBetweenSamples ;
}
}
return readData ;
}
void isoBuffer : : clearBuffer ( )
{
for ( int i = 0 ; i < bufferEnd ; i + + ) {
buffer [ i ] = 0 ;
}
back = 0 ;
serialPtr = 0 ;
serialDecodingSymbol = false ;
symbolCurrent = 0 ;
symbol = 0 ;
firstTime = true ;
}
void isoBuffer : : gainBuffer ( int gain_log )
{
qDebug ( ) < < " Buffer shifted by " < < gain_log ;
for ( int i = 0 ; i < bufferEnd ; i + + ) {
if ( gain_log = = - 1 ) buffer [ i ] * = 2 ;
else buffer [ i ] / = 2 ;
}
}
void isoBuffer : : glitchInsert ( short type )
{
}
2016-09-28 01:15:18 +01:00
void isoBuffer : : serialDecode ( double baudRate )
2016-09-07 07:36:43 +01:00
{
double dist_seconds = ( double ) serialDistance ( ) / samplesPerSecond ;
double bitPeriod_seconds = 1 / baudRate ;
unsigned short * tempPtr ;
unsigned short tempShort ;
unsigned char tempChar ;
if ( channel = = 1 ) console = console1 ;
else if ( channel = = 2 ) console = console2 ;
else qFatal ( " Nonexistant console requested in isoBuffer::serialDecode " ) ;
while ( dist_seconds > ( bitPeriod_seconds + SERIAL_DELAY ) ) {
tempPtr = ( unsigned short * ) readBuffer ( 0 , 1 , false , dist_seconds - bitPeriod_seconds ) ;
tempShort = * ( tempPtr ) ;
tempShort = tempShort & 0xff ;
tempChar = tempShort & ( 1 < < serialPhase ) ? 0 : 1 ;
if ( serialDecodingSymbol ) {
//if((tempShort != 0) && (tempShort!= 255)) qDebug() << "tempShort = " << tempShort;
qDebug ( ) < < numOnes ( tempShort ) ;
decodeSymbol ( numOnes ( tempShort ) > 4 ) ;
}
else serialDecodingSymbol = ( numOnes ( tempShort ) < 8 ) ;
marchSerialPtr ( bitPeriod_seconds * samplesPerSecond ) ;
dist_seconds = ( double ) serialDistance ( ) / samplesPerSecond ;
}
}
int isoBuffer : : serialDistance ( )
{
if ( back > = serialPtr ) {
return back - serialPtr ;
} else return bufferEnd - serialPtr + back ;
}
void isoBuffer : : serialBegin ( )
{
serialPtr = back ;
}
void isoBuffer : : decodeSymbol ( unsigned char newBit ) //Slow but works.
{
if ( symbolCurrent = = symbolMax ) { //Last bit in symbol
console - > insertPlainText ( QString ( QChar ( ( char ) symbol ) ) ) ;
if ( serialAutoScroll ) {
//http://stackoverflow.com/questions/21059678/how-can-i-set-auto-scroll-for-a-qtgui-qtextedit-in-pyqt4 DANKON
QTextCursor c = console - > textCursor ( ) ;
c . movePosition ( QTextCursor : : End ) ;
console - > setTextCursor ( c ) ;
// txtedit.ensureCursorVisible(); // you might need this also
}
symbolCurrent + + ;
return ;
}
if ( symbolCurrent > symbolMax ) { //Wait for stop bit. Stops over the top calculation when you get a string of zeroes...
if ( newBit = = 1 ) {
serialDecodingSymbol = false ;
symbolCurrent = 0 ;
symbol = 0 ;
}
return ;
}
//otherwise
symbol | = newBit < < symbolCurrent ;
symbolCurrent + + ;
}
void isoBuffer : : marchSerialPtr ( int bitPeriod_samples )
{
int halfPeriod = bitPeriod_samples * 0.6 ;
int sampleDistance = - 1 ;
serialPtr + = bitPeriod_samples ;
if ( serialPtr > = bufferEnd ) {
serialPtr - = bufferEnd ;
}
if ( ! serialDecodingSymbol ) {
return ;
}
if ( ( serialPtr < = halfPeriod ) | | ( serialPtr > ( bufferEnd - halfPeriod ) ) ) return ; //Don't bother readjusting. Too hard.
//otherwise...
if ( buffer [ serialPtr ] ! = buffer [ serialPtr - halfPeriod ] ) { //use LHS to calibrate
for ( int i = halfPeriod ; i > = 0 ; i - - ) {
if ( buffer [ serialPtr ] = = buffer [ serialPtr - i ] ) {
sampleDistance = i ;
break ;
}
}
if ( sampleDistance ! = - 1 ) serialPtr + = ( bitPeriod_samples / 2 ) - sampleDistance ;
}
if ( sampleDistance = = - 1 ) {
if ( buffer [ serialPtr ] ! = buffer [ serialPtr + halfPeriod ] ) { //same as above but with RHS
for ( int i = halfPeriod ; i > = 0 ; i - - ) {
if ( buffer [ serialPtr ] = = buffer [ serialPtr + i ] ) {
sampleDistance = i ;
break ;
}
}
if ( sampleDistance ! = - 1 ) serialPtr - = ( bitPeriod_samples / 2 ) - sampleDistance ;
}
}
}
unsigned char isoBuffer : : numOnes ( unsigned short var ) {
return ( ( var & 0x01 ) ? 1 : 0 ) + ( ( var & 0x02 ) ? 1 : 0 ) + ( ( var & 0x04 ) ? 1 : 0 ) + ( ( var & 0x08 ) ? 1 : 0 ) + ( ( var & 0x10 ) ? 1 : 0 ) + ( ( var & 0x20 ) ? 1 : 0 ) + ( ( var & 0x40 ) ? 1 : 0 ) + ( ( var & 0x80 ) ? 1 : 0 ) ;
}
2016-09-26 05:17:41 +01:00
void isoBuffer : : enableFileIO ( QFile * file ) {
file - > open ( QIODevice : : WriteOnly ) ;
currentFile = file ;
fileIOEnabled = true ;
return ;
}
void isoBuffer : : disableFileIO ( ) {
fileIOEnabled = false ;
currentColumn = 0 ;
currentFile - > close ( ) ;
return ;
}
2016-09-28 01:15:18 +01:00
double isoBuffer : : sampleConvert ( short sample , int TOP , bool AC ) {
double scope_gain = ( double ) ( parent - > driver - > scopeGain ) ;
double voltageLevel ;
voltageLevel = ( sample * ( vcc / 2 ) ) / ( R4 / ( R3 + R4 ) * scope_gain * TOP ) ;
if ( parent - > driver - > deviceMode ! = 7 ) voltageLevel + = vcc * ( R2 / ( R1 + R2 ) ) ;
# ifdef INVERT_MM
if ( parent - > driver - > deviceMode = = 7 ) voltageLevel * = - 1 ;
# endif
if ( AC ) {
voltageLevel - = parent - > currentVmean ; //This is old (1 frame in past) value and might not be good for signals with large variations in DC level (although the cap should filter that anyway)??
}
return voltageLevel ;
}