LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Continuously updated (scrolling) intensity graph

I'm probably not the first guy to want to do this in CVI, but I can't find anything posted here or in the example finder of CVI 7.1.  I'm trying to create an intensity chart that displays a frequency vs. time plot.  The horizontal axis is frequency, while the vertical axis is time.  Each new FFT result gets appended to the bottom of the graph as a row of intensity data, and the entire chart "scrolls" up with each new row of data.  You've probably seen this mechanization if you've ever played with any of the FFT audio/signal analyzer software that's out there (e.g. Matlab "specgram" command).
 
Anyway, my first inclination was to set up a 2-D array in C, which could be "rotated" in one of the two dimensions.  For example, row 1 would move to row 2, row 2 to row 3, etc (i.e. circular shift with wrap-around).  It would then be a simple matter of replacing the first row with new spectral data and plotting the entire array using the intensity graph routine into a graph.  Unfortunately, there is no 2-D circular shift routine in CVI as far as I can tell.  Can someone point me to such a routine (CVI or elsewhere)?  If not, does anyone have a clever idea how I might do this (pointers?) efficiently and fast?  One could imagine moving data rows themselves, but this would be horribly inefficient.
 
Thanks!
0 Kudos
Message 1 of 5
(4,001 Views)

Hi calvinf15.

In the Advanced Analysis Library (assuming you have it**), you will find this function:

Prototype

AnalysisLibErrType Transpose (void *Input_Matrix, int Number_of_Rows, int Number_of_Columns, void *Output_Matrix);

Finds the transpose of a 2D input matrix. Transpose obtains the (i, j)th element of the resulting matrix using the following formula:

yi, j = xj, i

Note    If the input matrix has n-by-m dimensions, the output matrix must have m-by-n dimensions.

 

Use memmove() to make space in Input_Matrix for the new data, insert your latest result(s), then call Transpose(), and use Output_Matrix (separate array) as the data for the intensity plot.

Note that this will only work for arrays of doubles; for other data types, you could call ConvertArrayType() before Transpose().

Regards,
Colin.

** Otherwise, you could try TransposeData() from Programmer’s Toolbox. Unfortunately, this function operates on the data “in-place”, so you would need to call it twice per iteration.

 

Message Edited by cdk52 on 12-08-2005 08:56 AM

0 Kudos
Message 2 of 5
(3,988 Views)

Hi again.

I just read your post more carefully, and realised that you probably don't need to transpose your data; you just need to shift it.

Assuming that you are working with doubles, you could do something like this:
 
#define nRows 1000;
#define nColumns 1000;
 
double intensityData[nRows, nColumns];
double *source, *target, *fftResult;
int bytesToMove;
 
...
 
// Set up pointers etc.
fftResult = ???;
source = intensityData;
target = source + nColumns;
bytesToMove = (nRows - 1) * nColumns * sizeof(double);
...
// Each time new data is available:
// Make space
memmove (target, source, bytesToMove);
// Copy new data into space
Copy1D (fftResult, nColumns, intensityData);
// Call the plot routine
PlotIntensity (...); // or whatever

Hope that helps.

Regards,
Colin.

 


Message 3 of 5
(3,974 Views)
Thanks Colin. 

I was a bit unsure about the transpose operator also, but thought you might be referring to the way arrays are stored in memory.  I need to read up on how this is implemented in C.  Anyway, i'll give the memmove() command a try.  I was a bit hesitant to go down this path, under the assumption that a command such as memmove() actually *moves* bytes around between memory positions.  Hopefully, this is not the case, and the compiler merely keeps track of the data and efficiently sets up pointers to make it *appear* that the data is moving around in memory?  Otherwise, wouldn't this be fairly slow, given big 2-D arrays?  Or perhaps the time required to plot the array completely eclipses any inefficiencies of such movement?

Thanks for the help!  Calvin
0 Kudos
Message 4 of 5
(3,967 Views)

Hi Calvin.

Here is the function help text for memmove():

"This function copies a specified number of bytes from a source buffer to a target buffer.  Copying takes place as if the bytes to be copied are first copied into a temporary array that does not overlap the target and source buffers.  This allows this function to copy bytes even when overlap occurs."

...so there is no fiddling about with pointers here. Operations such as this in C are very efficient; I wouldn't be concerned about the time taken unless you are working with extremely large arrays and very short intervals between chart updates. Try it and let us know how you go.

Regards,
Colin.

 

0 Kudos
Message 5 of 5
(3,960 Views)