hartley transform

Hey, Has anyone been able to use http://wiki.openmusiclabs.com/wiki/ArduinoFHT to do an inverse FHT or used ArduinoFFT - Open Music Labs Wiki to do a inverse FFT?

Yes. Countless people.

The DHT (FHT) is its own inverse, except for a scale factor.

I know. My code works on matlab. But I havent been able to use the ArduinoFHT libary to do it. I tried different setting but newer get the original signal mostly just zeros. I just other FHT libraries but their to slow.

If you want help, provide more information. See the “How to get the best out of the forum” post for instructions.

State which Arduino you are using, post the code, using code tags, and the details about what you expected to happen and what happens instead.

Hey,
I’m arduino nano.

I been using this code to try different setting. I trying to get the origina signal back.
After running the code I mostly get 1 and 0.

#include <FHT.h>
#define SCALE 128
#define OCT_NORM false
#define LIN_OUT false
#define FHT_N 128
#define WINDOW true
#define REORDER true
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);

for (int i=0;i<128;i+=1){
  double y = random(1,10);
  fht_input[i]=y;
  
 Serial.print(fht_input[i]);
  Serial.print(" "); 
}
Serial.println("");
Serial.println("");
fht_window();
fht_reorder();
fht_run();

fht_window();
fht_reorder();
fht_run();

}

for (int i=0;i<128;i+=2){
 Serial.print((fht_input[i]);
 Serial.print(" ");
}

 */
}

void loop() {
  // put your main code here, to run repeatedly:
}

Please post code that will compile without errors. What you have posted needs some work to get to that point.

For example, there seem to be extra braces and lines outside of functions:

for (int i=0;i<128;i+=2){
 Serial.print((fht_input[i]);
 Serial.print(" ");
} */
}

Note: definitions like the following MUST precede the #include <FHT.h> statement.

#define FHT_N 128

It is a good idea to get the library examples working first, and make sure you understand them.

This works as expected, using the OpenMusicLabs FHT.

#define FHT_N 16
#include <FHT.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Input FHT");
  for (int i = 0; i < FHT_N; i ++) {
    fht_input[i] = 1000.0*cos(2 * PI * i / FHT_N);
    Serial.println(fht_input[i]);
  }

  fht_reorder();
  fht_run();

  Serial.println("Output");
  for (int i = 0; i < FHT_N; i++) {
    Serial.println(fht_input[i]);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

Hey, The problem is that I need to be able to return the given signal back to the original one.
I’m using the fht to turn an audio signal for time domain to frequency domain and manipulate it that turn it back to
time domain using inverse fht.

tried the example code with a bigger input FHT_N 128 and did a inverse fht.

#define FHT_N 128
#include <FHT.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Input FHT");
  for (int i = 0; i < FHT_N; i ++) {
    fht_input[i] = 1000.0*cos(2 * PI * i / FHT_N);
    Serial.print(fht_input[i]);
    Serial.print(" ");
  }
  Serial.println();
  Serial.println();
  fht_reorder();
  fht_run();
  fht_reorder();
  fht_run();
  Serial.println("Output");
  for (int i = 0; i < FHT_N; i++) {
    Serial.print(fht_input[i]);
    Serial.print(" ");
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

OUTPUT:

Input FHT
1000 998 995 989 980 970 956 941 923 903 881 857 831 803 773 740 707 671 634 595 555 514 471 427 382 336 290 242 195 146 98 49 0 -49 -98 -146 -195 -242 -290 -336 -382 -427 -471 -514 -555 -595 -634 -671 -707 -740 -773 -803 -831 -857 -881 -903 -923 -941 -956 -970 -980 -989 -995 -998 -1000 -998 -995 -989 -980 -970 -956 -941 -923 -903 -881 -857 -831 -803 -773 -740 -707 -671 -634 -595 -555 -514 -471 -427 -382 -336 -290 -242 -195 -146 -98 -49 0 49 98 146 195 242 290 336 382 427 471 514 555 595 634 671 707 740 773 803 831 857 881 903 923 941 956 970 980 989 995 998 

Output
5 4 5 5 6 5 6 5 5 5 5 4 4 4 5 4 4 3 3 3 2 2 2 2 1 1 0 0 0 -1 -1 -1 0 -2 -2 -2 -4 -3 -4 -4 -5 -4 -6 -5 -6 -6 -6 -6 -6 -7 -7 -7 -8 -7 -8 -8 -9 -8 -8 -9 -9 -9 -9 -9 -7 -6 -7 -7 -8 -7 -8 -7 -7 -7 -7 -6 -6 -6 -7 -6 -4 -5 -5 -5 -4 -4 -4 -4 -3 -3 -2 -2 -2 -1 -1 -1 0 2 2 2 2 3 4 4 3 4 4 5 4 6 4 6 6 7 7 7 6 7 8 8 7 10 8 9 7 9 9 9

You forgot about the scale factor.

This works approximately as expected, but as FHT_N increases, the error gets much worse. It looks like the code reduces an intermediate result to an eight bit fraction somewhere, then scales back up. So, the Open Music Labs code is not the way to go. Or, write to the author of the web page. Perhaps they will fix it.

#define FHT_N 32
#include <FHT.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Input FHT");
  for (int i = 0; i < FHT_N; i += 1) {
    fht_input[i] = 1000.0*cos(2 * PI * i / FHT_N);
    Serial.println(fht_input[i]);
  }

  fht_reorder();
  fht_run();
  fht_reorder();
  fht_run();
  Serial.println("Output");
  for (int i = 0; i < FHT_N; i += 1) {
    Serial.println(FHT_N*fht_input[i]);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

Hey, Thanks for the help. Have to see can I contact the maker an ask about it.

There are many, many other Hartley transform codes published on line.

Havent found any as fast as ArduinoFHT that you can use in arduino. Most other are made using c.

usagi_87:
Havent found any as fast as ArduinoFHT that you can use in arduino. Most other are made using c.

You can use c code in an Arduino sketch. Usually there are only very minor changes needed. Did you mean they use floating point arithmetic, expecting there to be a co-processor, perhaps?

No using arduino nano. Tried fht implemented in c takes almost 100ms insted arduinoFHT 4 ms. Programmed in assembly.

Why do you care about speed?

If it is a serious issue, use a faster microprocessor. The Teensy 4.0 costs $20 and runs at 600 MHz.

usagi_87:
No using arduino nano. Tried fht implemented in c takes almost 100ms insted arduinoFHT 4 ms. Programmed in assembly.

I highly suspect that this is not a one to one comparison, the same precision and throughput. There is seldom any significant difference between assembly and C coded programs, with a modern optimizing compiler like GCC. However it does take thoughtful, efficient C programming to achieve the greatest speed.

Probably, the greatest bottleneck for an FFT/FHT on a basic Arduino like the UNO, would be the multiplication itself, as there is no native multiply instruction. The "butterfly" transform and elements like that, really don't have a lot of overhead in any language.

Good point.

The Teensy has a native multiply, as well as a floating point processor (FPU) built in, and is 328 times faster than the Arduino Mega for the CoreMark benchmark.