Recent

Author Topic: dmath fft, got empty OutArray  (Read 2024 times)

senglit

  • Full Member
  • ***
  • Posts: 131
dmath fft, got empty OutArray
« on: October 28, 2022, 09:33:53 am »
hi,

i need to transform a signal from time domain to freq domain and I find dmath can do it. This is my code:
Code: Pascal  [Select][+][-]
  1. procedure CalcSpec(data:string);
  2. var
  3.   NumSamples,MaxIndex:integer;          
  4.   InArray, OutArray : TCompVector;
  5.   I                 : Integer;
  6.   dataInt:array of integer;
  7. begin      
  8.   NumSamples := data.Length div 4;
  9.   MaxIndex := NumSamples-1;  // I missed this in original post
  10.   SetLength(dataInt,NumSamples);
  11.   Move(data[1],dataInt[0],data.Length);  
  12.   DimCompVector(InArray, MaxIndex);
  13.   DimCompVector(OutArray, MaxIndex);
  14.   for i := 0 to NumSamples - 1 do
  15.     begin
  16.       InArray[I].X := dataInt[I]/256.0;      
  17.     end;
  18.   FFT(NumSamples, InArray, OutArray);
  19. end;        
  20.  

After running this procedure, I found everything in OutArray is 0. With debuger I can see the data like this:
InArray = (COMPLEX (X = -15430;Y = 0), COMPLEX (X = -15730;Y = 0), COMPLEX (X = -15900;Y = 0), COMPLEX (X = -16510;Y = 0);......)
OutArray = (COMPLEX (X = 0;Y = 0), COMPLEX (X = 0;Y = 0), COMPLEX (X = 0;Y = 0), COMPLEX (X = 0;Y = 0), COMPLEX (X = 0;Y = 0), .......)

How to get the correct result?
« Last Edit: October 28, 2022, 10:17:05 am by senglit »
I use Win10 + Lazarus 2.2.0 + FPC 3.2.2. All 64bit.

Nitorami

  • Hero Member
  • *****
  • Posts: 503
Re: dmath fft, got empty OutArray
« Reply #1 on: October 28, 2022, 11:25:09 am »
Have you checked if the procedure sets an error flag ? I believe dmath does not throw exceptions in case of errors but just sets a flag you need to check. Use function utypes.matherr for that.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11459
  • FPC developer.
Re: dmath fft, got empty OutArray
« Reply #2 on: October 28, 2022, 11:41:54 am »
Don't move an array of integer into an array of complex ? Run a loop and assign them one at a time.

Iow the MOVE() statement is wrong.
« Last Edit: October 28, 2022, 03:48:49 pm by marcov »

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: dmath fft, got empty OutArray
« Reply #3 on: October 28, 2022, 03:39:53 pm »
Just to make sure that the fft of dmath is working I wrote the attached small project which syntesizes some input waves, performs the FFT and displays input and output data in charts. (The required dmath units are included in the project, therefore, it should compile even if you don't have dmath on your system). - The result looks reasonable (I did not care about normalization of the output wave amplitudes).

As for your issue: You pass your data to the analyses function in a very unusual way. Input comes as a string, but it does not seem to be an "ordinary" string of characters, but an array of 4-byte integers. Why don't you use a simple dynamic array or one of the "vector" types of dmath? But anyway, I rewrote the above-mentioned demo to handle data in this "string" way and to use much of your code -- and it works correctly. Therefore, I guess your problem is outside, in the routine which stuffs the original data into the string passed to the CalcSpec method.
« Last Edit: October 28, 2022, 04:08:17 pm by wp »

glorfin

  • Full Member
  • ***
  • Posts: 148
  • LMath supporter
Re: dmath fft, got empty OutArray
« Reply #4 on: October 28, 2022, 04:54:39 pm »
I don't quite understand one thing: OutArray is local variable in this procedure. How do you get data out of it? Do you look in the debugger immediately after call to FFT or after the return from your procedure?

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: dmath fft, got empty OutArray
« Reply #5 on: October 28, 2022, 05:43:58 pm »
Iow the MOVE() statement is wrong.
No, I think he abuses a string as storage for integers. The string passed as argument "data" is understood as an array of integer, having a quarter of the string length, i.e. the first integer value (dataInt[0]) consists of the "characters" data[1], data[2], data[3], data[4], etc.

glorfin

  • Full Member
  • ***
  • Posts: 148
  • LMath supporter
Re: dmath fft, got empty OutArray
« Reply #6 on: October 28, 2022, 05:59:29 pm »
His InArray is not empty. It may contain something weird - I completely agree that use of string for transfer of the data is strange technique, but nevertheless, if you feed non-zero InArray to FFT, it must return non-zero OutArray. And normally it does, FFT works pretty well in DMath/LMath.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: dmath fft, got empty OutArray
« Reply #7 on: October 28, 2022, 07:24:57 pm »
His InArray is not empty.
Right. But we don't know about his signal, and we don't know which part of the data is covered by the debugger snippet in the first post. It could be a very high-frequency signal with zero in the low-frequency part of the FFT and the higher components appearing only further up in the output array

glorfin

  • Full Member
  • ***
  • Posts: 148
  • LMath supporter
Re: dmath fft, got empty OutArray
« Reply #8 on: October 28, 2022, 11:53:14 pm »
That's true, which means that both problems may be of importance. Let's wait for his reply :)

senglit

  • Full Member
  • ***
  • Posts: 131
Re: dmath fft, got empty OutArray
« Reply #9 on: October 29, 2022, 06:14:05 am »
hi, all

Thanks for your warmhearted reply.

There is a clarification: my InArray is not empty. I use string as integer buffer (following the recomandation from homepage of sysnapse). I think it's a good way to handle parameter transfer because you do not need to release the mem you allocated before. And there is some other advantage to use string as integer buffer to handle wave audio data. for example, you got data from a 24bit sound card like: 11 22 ff 00. it's actrually an 24 bit integer $ff2211, but stored in a 32 bit integer then you have to program to get the actual data when the signal level is negative. When you got 48K data per second it's easy to transfer the data as s:=char(0)+LeftStr(s,s.length-1). when you use the data, just do data:=data div 256. Or you can keep it 256 times higher to do fft and divide OutArray by 256.

Finally I found the problem: my sampling rate is 48k, but I forget to add zero to the sequence to make its length to 65536(2^16). And then FFT function just refuse to do the work and return directly!
« Last Edit: October 29, 2022, 08:17:05 am by senglit »
I use Win10 + Lazarus 2.2.0 + FPC 3.2.2. All 64bit.

senglit

  • Full Member
  • ***
  • Posts: 131
Re: dmath fft, got empty OutArray
« Reply #10 on: October 29, 2022, 08:29:53 am »
And one more thing:

it's ok to use lmath, but with dmath there is a problem:

dmath looks like be written in an FPC mode, and in the types.inc it defined:
Code: Pascal  [Select][+][-]
  1. {$IFDEF FPC}
  2.   MaxSize = 32767;       { 2^15 - 1 }
  3. {$ELSE}
  4.   MaxSize = 2147483647;  { 2^31 - 1 }
  5. {$ENDIF}
  6.  

in the lmath types.inc it defined:
Code: Pascal  [Select][+][-]
  1.   {$IFDef CPU32}
  2.   MaxSize = 2147483647;  {< 2^31 - 1 }
  3.   {$ELSE IF CPU64}
  4.   MaxSize = 9223372036854775807;
  5.   {$ENDIF}      
  6.  

Then dmath can not handle wave signals which require frequency analyze to 20k. To use dmath, you need to modify the source code. So it's better to use lmath.
« Last Edit: October 29, 2022, 08:32:21 am by senglit »
I use Win10 + Lazarus 2.2.0 + FPC 3.2.2. All 64bit.

glorfin

  • Full Member
  • ***
  • Posts: 148
  • LMath supporter
Re: dmath fft, got empty OutArray
« Reply #11 on: October 29, 2022, 09:36:43 pm »
"because you do not need to release the mem you allocated before."
Because String is managed or why? Dynamic arrays in FPC are also automatically deallocated when program leaves the scope. I still think that open array parameters is best way to handle it, and dynamic array can be passed to a procedure which gets open array.In fact, almost everything can, even slice of an array.

DMath development was stopped in 2012, LMath is its more modern continuation (technically a fork). That is why DMath of course could not use 64 bits.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6692
Re: dmath fft, got empty OutArray
« Reply #12 on: October 29, 2022, 09:51:34 pm »
Dynamic arrays in FPC are also automatically deallocated when program leaves the scope.

Hmm. Careful there: I believe they're deallocated when the refcount drops to zero, which is not necessarily the same thing.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

senglit

  • Full Member
  • ***
  • Posts: 131
Re: dmath fft, got empty OutArray
« Reply #13 on: October 30, 2022, 05:22:23 am »
"because you do not need to release the mem you allocated before."
Because String is managed or why? Dynamic arrays in FPC are also automatically deallocated when program leaves the scope. I still think that open array parameters is best way to handle it, and dynamic array can be passed to a procedure which gets open array.In fact, almost everything can, even slice of an array.

I can't explain it deep into FPC level. I just follow the suggestion from here: http://synapse.ararat.cz/doku.php/public:howto:binarystring
I use Win10 + Lazarus 2.2.0 + FPC 3.2.2. All 64bit.

glorfin

  • Full Member
  • ***
  • Posts: 148
  • LMath supporter
Re: dmath fft, got empty OutArray
« Reply #14 on: October 31, 2022, 12:49:45 pm »
Quote
I can't explain it deep into FPC level. I just follow the suggestion from here: http://synapse.ararat.cz/doku.php/public:howto:binarystring

Well, this recommendation was written in 2007, before managed dynamic arrays were introduced.
 
Such use of strings is stil possible, but is not necessary anymore, because nowadays dynamic arrays are managed exactly the same ways as strings, and I am pretty sure that passing numeric data as numeric arrays makes programs much more clear plus saves you some conversions.

 

TinyPortal © 2005-2018