writing a sound input to frequency lib using FHT.h

I am trying to write a lib for my rgb cube with a function which returns a array of frequencys and their amplitude. I'd like to usethe FHT.h lib for this. So i tried creating a simple Class called Sound which includes the FHT.h and so on but i can't compile it in any way.

So i read the article about the fht and just tried to "copy past" it. I am not sure if it even would work with my Arduino Mega 2560 like this but its a start:

#pragma once
#include "Arduino.h"

#define LOG_OUT = 1
#define FHT_N = 128
#include "FHT.h"

class Sound
{
public:
    Sound()
    {
        ADCSRA = 0xe5; // set the adc to free running mode
        ADMUX = 0x40; // use adc0
        DIDR0 = 0x01; // turn off the digital input for adc0
    };
    ~Sound();

    inline void getValues(uint8_t *data)
    {
        for (int i = 0; i < FHT_N; i++)   // save 256 samples
        {
            while (!(ADCSRA & 0x10)); // wait for adc to be ready
            ADCSRA = 0xf5; // restart adc
            byte m = ADCL; // fetch adc data
            byte j = ADCH;
            int k = (j << 8) | m; // form into an int
            k -= 0x0200; // form into a signed int
            k <<= 6; // form into a 16b signed int
            fht_input[i] = k; // put real data into bins

        }
        fht_window(); // window the data for better frequency response
        fht_reorder(); // reorder the data before doing the fht
        fht_run(); // process the data in the fht
        fht_mag_log(); // take the output of the fht

	//need a copy here...
        data = fht_log_out;//not correct!
    };
};
  • Is it even possible like this or do i need to include the fht in global scope?
  • Moreover can i use this "enabling freerun" and so on at my Mega2560?
  • How do i set the analogpin?

I am going to use the MAX4466 from adafruit....

BennX:
[ I ] tried creating a simple Class ... but i can't compile it in any way.

Here are some things you could do to help us understand the issue:

  • Post a complete sketch. We should be able to take your code, paste it into the IDE, and get the error messages that you see.
  • Post a minimal sketch that demonstrates the problem. If you post a huge sketch, a lot of readers will move on to another post.
  • Be specific in describing the problem. "It won't compile," doesn't provide many clues, especially if we don't have a complete sketch.
  • Provide a link to any libraries you use that aren't included with the IDE. I think that you're using the openmusiclabs library at this link - attachment:ArduinoFHT.zip of ArduinoFHT - Open Music Labs Wiki - but I can't be sure.

I'll recommend that you read the sticky post, "How to use this forum - please read." You can find it at the top of the listing for each section of the forum.

That said, here's what I see:

    inline void getValues(uint8_t *data)
        ...
	//need a copy here...
        data = fht_log_out;//not correct!

It looks like you're trying to make some kind of copy of the array fht_log_out. I don't know whether you want to copy the contents of fht_log_out in to some array called data, or whether you want to copy the value of the pointer fht_log_out into a pointer called data. If you want to assign the value of pointer fht_log_out to pointer data, the function definition should reference data as a pointer to a pointer, like this:

    void getValues(uint8_t **data)
        ...
	//need a copy here...
        *data = fht_log_out;

As it is, when you call getValues(), a copy of the pointer data is sent to the function. The function dutifully makes the assignment to the copy, and then discards the result when it returns. You want to send the address of the pointer data to the function, which can then access that address and change the value fo the pointer. You'd have to call it like this:

  getValues(&data);

We can't see the declaration of pointer data in this code, so we don't know how you're doing it. If you declare data as an array, like this:

uint8_t data[64];

then pointer data will be a constant, and you won't be able to make an assignment to it. If you declare it as a pointer to uint8_t, like this:

uint8_t *data;

the assignment will work. Note, though, that the memory referenced by data will be the same as that referenced by fht_log_out, and any operations you perform on either will affect the values referenced by the other. You won't be making a copy of the array, only a copy of the pointer.

If you want to copy the values of the array fht_out in to array data, you'll need to explicitly copy each element with a loop, or use a function like memcpy(). You'll also need to ensure that space is allocated for that purpose, either by declaring data as an array with a defined number of elements, or by allocating memory dynamically.

Addressing your specific questions:

  • Is it even possible like this or do i need to include the fht in global scope? Response: I'll leave this question to guys who are better at the "++" aspects of C++ than I.
  • Moreover can i use this "enabling freerun" and so on at my Mega2560? Response: I've never used a Mega2650, so I'm not sure. But, looking at the datasheet, available from this page - http://arduino.cc/en/Main/ArduinoBoardMega2560 - it looks like this code will run on the Mega2560.
  • How do i set the analogpin? Response: The ADC pin used to acquire data can be set by manipulating register ADMUX. The number of the active pin is encoded into the lower 5 bits of that register. In your code, the pin is set to 0 when ADMUX is set. You can find more information in the datasheet in chapter 26, "ADC-Analog to Digital Converter."[/li]
  • [/list]*

First of all, thanks alot for the reply and sorry for some code down here. I can't post a whole scatch since it would be way to much. And thanks for the answers to the questions. (Helps alot!)

I am trying to create a class "Sound" which i can include into my scetch to fetch a array of frequencys and their amplitude. Todo so there is the Method getValue which writes the amplitudes to the "data" or how i called it now is frequencys. (I do it to keep my scetch clean for other stuff. I just want to fetch the data from the FHT to disply them with some leds)

An example of usage would be:

#include "Sound.h"
Sound sound;
uint8_t* frequencys;//out of your improvements 
void setup(){
}
void loop(){
  sound.getValues(&frequencys);
  //do something with the values
}

I changed the class depening on your improvements to this. As you mentiound it should worke like this with input of the microfone at ADC0:

#pragma once
#include "Arduino.h"
#define LOG_OUT 1
#define FHT_N 128
#include "FHT.h"

class Sound
{
public:
    Sound()
    {
        ADCSRA = 0xe5; // set the adc to free running mode
        ADMUX = 0x40; // use adc0 0 A_Input
        DIDR0 = 0x01; // turn off the digital input for adc0
    };
    ~Sound(){};

    inline void getValues(uint8_t **data)
    {
        for (int i = 0; i < FHT_N; i++)   // save 256 samples
        {
            while (!(ADCSRA & 0x10)); // wait for adc to be ready
            ADCSRA = 0xf5; // restart adc
            byte m = ADCL; // fetch adc data
            byte j = ADCH;
            int k = (j << 8) | m; // form into an int
            k -= 0x0200; // form into a signed int
            k <<= 6; // form into a 16b signed int
            fht_input[i] = k; // put real data into bins

        }
        fht_window(); // window the data for better frequency response
        fht_reorder(); // reorder the data before doing the fht
        fht_run(); // process the data in the fht
        fht_mag_log(); // take the output of the fht

        *data = fht_log_out;//FTH_N/h size array of uint8_t
    };
};

If i try to compile this i get some errors that there is no file FHT in sound.h:

In file included from sound.ino:1:
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:5:17: error: FHT.h: No such file or directory
In file included from sound.ino:1:
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h: In member function 'void Sound::getValues(uint8_t**)':
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:29: error: 'fht_input' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:32: error: 'fht_window' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:33: error: 'fht_reorder' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:34: error: 'fht_run' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:35: error: 'fht_mag_log' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:38: error: 'fht_log_out' was not declared in this scope

If i include the FHT.h in front of my sound.h in the scetch i get some redefinition warnings and that fht_log_out was not declared but it should be:

In file included from sound.ino:2:
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:3:1: warning: "LOG_OUT" redefined
In file included from sound.ino:1:
C:\Program Files (x86)\Arduino\libraries\FHT/FHT.h:38:1: warning: this is the location of the previous definition
In file included from sound.ino:2:
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:4:1: warning: "FHT_N" redefined
In file included from sound.ino:1:
C:\Program Files (x86)\Arduino\libraries\FHT/FHT.h:18:1: warning: this is the location of the previous definition
In file included from sound.ino:1:
C:\Program Files (x86)\Arduino\libraries\FHT/FHT.h:74: warning: only initialized variables can be placed into program memory area
In file included from sound.ino:1:
C:\Program Files (x86)\Arduino\libraries\FHT/FHT.h:89: warning: only initialized variables can be placed into program memory area
In file included from sound.ino:1:
C:\Program Files (x86)\Arduino\libraries\FHT/FHT.h:133: warning: only initialized variables can be placed into program memory area
In file included from sound.ino:2:
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h: In member function 'void Sound::getValues(uint8_t**)':
C:\Program Files (x86)\Arduino\libraries\Sound/Sound.h:38: error: 'fht_log_out' was not declared in this scope

Can you compile and run the example code from this page - http://wiki.openmusiclabs.com/wiki/FHTExample?

tmd3:
Can you compile and run the example code from this page - FHTExample - Open Music Labs Wiki?

Yes i could compile that example and also tried it and it gives me some values.
I can't interpret them yet but it seems to work. (e.g. 125,151,137,81,69,55,53,46 with FHT_N 16. Some values seem to be always at ~180-200 even if its "quit")

I can't interpret them yet but it seems to work. (e.g. 125,151,137,81,69,55,53,46 with FHT_N 16. Some values seem to be always at ~180-200.

Only 8 amplitudes are output by an FHT of length 16. You should work on understanding the operation and its output rather completely, before attempting to write a library.

On the other hand, you haven't given a good reason to write one. You can simply use the results provided by the FHT library, which works as advertised. Save yourself the trouble.

OK. from the code and error messages that you posted, it looks like you've copied the FHT compiler directives - two #define's and an #include - from Sound.h to the sketch, while leaving the original compiler directives in Sound.h. If they're in the sketch, you don't want them in Sound.h; otherwise, you'll get a warning about a redefinition.

When I took the code you posted a couple of replies ago, and moved those lines from Sound.h to the sketch, it compiled. Indeed, I got warnings that only initialized variables can be put into program memory - presumably triggered by data tables in FHT.h - but I get those every time I use program memory, no matter how vigorously I initialize the variables.

BennX:
Yes i could compile that example ...

That suggests that the library is installed properly. It was worth a look.

... it gives me some values.
I can't interpret them yet ...

jremington has a point. If you don't know your way around a Fourier Transform, its unlikely that you'll be successful in this effort without a lot of frustration. If you can't resist going forward, you'll certainly want to continue reading up on the Fourier transform, the discrete Fourier transform, the Hartley transform, and the fast Fourier transform as you proceed. You'll also want to look at how the ADC is controlled, in the ATmega328 datasheet. The FHT example code sets the ADC to run at about 38 kHz. At that sample rate, a 16-sample period is only about half a millisecond, and the slowest signal you can see a whole cycle of is over 2 kHz. If your input signal is slower than that,l you'll get unexpected results.

I've seen posts that say that a library can't reference another library in the Arduino IDE, but they all looked to be old. Maybe it can do that now, I don't know.

(e.g. 125,151,137,81,69,55,53,46 with FHT_N 16. Some values seem to be always at ~180-200 even if its "quit")

I think you mean, "quiet." Is the analog input connected to a signal, or is it open-circuited?

jremington:
... you haven't given a good reason to write [a library]. You can simply use the results provided by the FHT library, which works as advertised.

jreminton has another point. You might well be just as happy using the FHT library as is, and doing whatever you need to do to make copies of data or pointers in a function in your own sketch. Unless you need to keep a copy of the original data, you can certainly use the values of fht_log_out, in place as they are.

Or maybe you have something else you want to accomplish?

If you don't completely understand Fourier transforms, I would not recommend Hartley transforms as a place to start learning. The theory is a bit more complicated and for use on an Arduino, the only advantage of the Hartley transform is the half-size input data array.

If all you want to do is display a frequency/amplitude spectrum on your LED array, then either will work fine and the theory of Fourier transforms is (in my view) easier to understand.

However, if you want to continue down the FHT path, then look for some examples of their use in audio spectrum analysis. Here is one specifically for AVR processors: Fast Hartley Transformation Library for AVR microcontrollers – Waiting for Friday