Fmod spectrum analisys

Signaler
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
-
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
-
salut, je programme un player mp3 avec wxWidegets et Fmod et je veux y mettre un spectrum, mais voila, aucune info sur le web et moi c'est la premiere fois que je veux faire ca.Je comprends pas la marche a suivre aprés avoir recupéré mes 512 canaux.

donc si qqu' un a un tuto ou des infos sur le sujet a faire toourner faites suivre car je crois que c sans issue!

thx ++

20 réponses

Messages postés
571
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
5 décembre 2013

En fait ya plusieur methodes comment tu recupere tes canaux ??



en fait quand tu fait const float *spectrum = FSOUND_DSP_GetSpectrum( );

tu recupete toute tes valeurs dans un tableau (de 512 valeurs) dont le pointeur est spectrum

apres il te suffit de faire une boucle pour en faire ce que tu veut



int spectrumValue

for ( int i = 0; i < 512; ++i )

{

spectrumValue = int(100 * spectrum[ i ] );



[.....]

}



Par contre tu verra a l'essai pour le spectographe il vaut mieux rester
sur une plage ex ( 100 -> 512) plutot que de faire la totalité du
tableau ( a certaines frequences ca ne corespond plus a rien )



Pour avoir un truc encore plus precis tu peut meme faire une moyenne de valeurs ex plutot faire

int spectrumValue


for ( int i = 0; i < 512; i +5 )


{

spectrumValue =
int(100 * (spectrum[ i ] + spectrum[ i +1 ] + spectrum[ i+2 ] +
spectrum[ i+3 ] + spectrum[ i+4 ] )) / 5;





[.....]


}

A la place de [....] tu met code comme par exemple le dessin d'un point
au coordonnées (i,spectrumValue) ici tu auras un spectrographe a point
de taille (512,100)
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
merci, c'est deja un bon debut mais je n' y arrive tjrs pas.lol.
Je te met le code du spectrum

#include "Mp3PlayerFrm.h"



//ici la vrai fonction du spectre
void Mp3PlayerFrm::spectrumData(int winx, int winy)
{
const float *spectrum = FSOUND_DSP_GetSpectrum();
int spectrumValue;


for ( int i = 0; i < 512; i +5 )
{
spectrumValue = int(100 * (spectrum[ i ] + spectrum[ i +1 ] + spectrum[ i+2 ] + spectrum[ i+3 ] + spectrum[ i+4 ] )) / 5;
bande->DrawPoint(i, spectrumValue); //
}
}


/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*Clik sur spectrum dans le menu
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::MnuSpectrum(wxCommandEvent& event)
{
FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true);
if (!FSOUND_DSP_GetActive(FSOUND_DSP_GetFFTUnit()))
{wxString msg;
msg.Printf( _T("Oups spectrum pas actif\nLe spectrum ne fonctionne que lorsqu' un stream est ouvert\nOuvrez un fichier"));
wxMessageBox(msg, _T("Infos"), wxOK | wxICON_EXCLAMATION | wxCENTRE, this);return;
}//si le spectrum est actif....
this->SetSize(380, 280, 690, 380);
FSOUND_DSP_SetPriority(FSOUND_DSP_GetFFTUnit(), 150);
FSOUND_DSP_GetSpectrum();
}

//dans le .h, en rapport avec le spectre:
FSOUND_DSPUNIT *spectre;
wxDC *bande;

bon, je sias que ce code ne renvoie pas spectrumData ds MnuSpectrum mais a force de trafiquer je l'ai remis de maniere lisible.

Un peu plus d' infos sur dessinner un point aux coordonnées i, spectvalue stp.
et comment fais pour mettre ce spectrum en adequation avec les cannaux?

a l'aide!!!Putain de web! ya 0 infos sur les spectrums

enfin, merci pour ton aide!
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
#include "Mp3PlayerFrm.h"
#include <wx/gdicmn.h>



//ici la vrai fonction du spectre


void Mp3PlayerFrm::spectrum01 ( wxCommandEvent& event )
{
const float *spectrumData = FSOUND_DSP_GetSpectrum(); //recupere les 512 cannaux separés
int spectrumValue;



for ( int i = 0; i < 512; ++i )
{
spectrumValue = int(100 * spectrumData[ i ] );
point = new wxPoint(i, spectrumValue);
this->point;
}
}


/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*Clik sur spectrum dans le menu
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::MnuSpectrum(wxCommandEvent& event)
{
FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true);
if (!FSOUND_DSP_GetActive(FSOUND_DSP_GetFFTUnit()))
{wxString msg;
msg.Printf( _T("Oups le spectrum n' est pas actif\nLe spectrum ne fonctionne que lorsqu' un stream est ouvert\nOuvrez un fichier"));
wxMessageBox(msg, _T("Infos"), wxOK | wxICON_EXCLAMATION | wxCENTRE, this);return;
}//si le spectrum est actif....
this->SetSize(0, 0, 800, 380);
this->Center();
spectrum01 (event);
}

"statement has no effect"

Un ti tuto sur le spectrum SVP!!!!!!!!!!!!!!!!!!!!!!

o sinon, explike un peu la démarche pour dessiner un point aux coordonées x, y
car
point = new wxPoint(i, spectrumValue);
this->point;

ne marche pâs

allé bon dimanche !
++
Messages postés
571
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
5 décembre 2013

Perso moi je ne me sers pas de FSOUND_DSP_SetPriority(FSOUND_DSP_GetFFTUnit(), 150);



Mais je croit pas que cette fonction change grand chose !!



Pour trouver le prb passe en mode debug et surveille la fonction

bande->DrawPoint

i doit bien aller de 0 a 512

et spectrumValue de 0 a 100 sinon utilise un coefficient pour le remonter (moi 64 mais je sais plus pourquoi).



Sinon un exmple de fonction tres simple



void affpoint ( HDC hdc,int x ,int y) {

SetPixel(hdc,x,100-y)

}



Par contre autre chose le spectrographe est tres gourmand en ressource
(et tres lente) donc la commande setpixel ne te servira que pour tes
test ou avancer un peu. Mais au final il vaut mieux passer par la
gestion "des bits d affichages" , je sais pas comment expliquer ca,
c'est l exemple de demo de la librairie, et en cherchant "setpixel" sur
ce site ya un topic qui s'apelle "setpixel plus rapide" ou un truc
comme ca. La prochaine fois je te passerais le lien si tu trouve pas,
la en ce moment la fonction recherche deconne encore sur ce forum !!!



"et comment fais pour mettre ce spectrum en adequation avec les cannaux?"

Tu travailles avec des mp3 ??? Pasque cette fonction fait juste un tableau de 512 valeur avec les frequences

ex si tu traite de 1 hz a 22000

spectrum[1] = 1hz a 42 hz

spectru[2] = 42 hz a 84 hz

etc ...



Function to return a pointer to the current spectrum buffer. The buffer contains
512 floating

point values that represent each frequency band's amplitude for
the current FMOD SoundSystem

mixing buffer. The range of frequencies covered
by the spectrum is 1 to the nyquist frequency

or half of the output rate. So
if the output rate is 44100, then frequencies provided are up

to 22050.
(entry 511)



Remarks

Note that hardware sounds, MIDI, files do not register on the
spectrum graph as they are not run through FMODs DSP system.

Note that to use
this you have to turn on the FSOUND FFT DSP unit. This is achieved by calling
FSOUND_DSP_GetFFTUnit, then using FSOUND_DSP_SetActive to turn it on.
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
yo ! merci!

on a ecrit en meme temps je crois ce quia donné une impression d' instantaneité!lol!

bon ben je vais essayer tt ca merci pour les précisions , c'est supa cool
quand j' orai fini , je la mettrai ici car g pas vu dee player mp3 que en wxWidgets et fmod ( ou g mal vu)

allé a ++
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
heuuuuuu, en fait pour dessinner le spectrum, il faut que je creer une zone speciale???? une bipmap????????
ou est ce qu' il n' ya rien a ajouter car je vois pas ou spectre peut se placer sur ma page

je te met le code

#include "Mp3PlayerFrm.h"
#include <wx/gdicmn.h>


//ici la vrai fonction du spectre


void Mp3PlayerFrm::spectrum01 ( wxCommandEvent& event )
{
const float *spectrumData = FSOUND_DSP_GetSpectrum(); //recupere les 512 cannaux separés
int spectrumValue;


for ( int i = 0; i < 512; ++i )
{
spectrumValue = int(100 * spectrumData[ i ] );
SetPixel(hdc, i, spectrumValue, COLORREF RGB( 100, 174, 100 ));
}
}


/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*Clik sur spectrum dans le menu
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::MnuSpectrum(wxCommandEvent& event)
{
FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true);
if (!FSOUND_DSP_GetActive(FSOUND_DSP_GetFFTUnit()))
{wxString msg;
msg.Printf( _T("Oups le spectrum n' est pas actif\nLe spectrum ne fonctionne que lorsqu' un stream est ouvert\nOuvrez un fichier"));
wxMessageBox(msg, _T("Infos"), wxOK | wxICON_EXCLAMATION | wxCENTRE, this);return;
}//si le spectrum est actif....
this->SetSize(0, 0, 800, 380);
this->Center();
spectrum01 (event);
}

"Perso moi je ne me sers pas de FSOUND_DSP_SetPriority(FSOUND_DSP_GetFFTUnit(), 150);

Mais je croit pas que cette fonction change grand chose !!" ----->>change gd choze ou pas gd choze???
d' aprés mon code tu crois que ca peut marcher??? je vois pas comment m'enfin bon,,

++passion
Messages postés
571
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
5 décembre 2013

Oui !!

il te faut creer un HDC !! ou en recuperer un si tu en as deja un !!!
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
oui HDC hdc c'est pour win32 mais moi je suis sous wxWidgets et c ca mon pb!
par contre, si ya moyen, comment creer un HDC et est ce que ce n'est pas equivalent au device context de wxWidgets? wxDC

thx
++
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
//---------------------------------------------------------------------------
//
// Name: spectrum.cpp
// Author: Nicolas Robert
// Created: 14/07/2005 17:42:55
//
//---------------------------------------------------------------------------


#include "Mp3PlayerFrm.h"


//ici la vrai fonction du spectre


void Mp3PlayerFrm::spectrum01 ( wxCommandEvent& event )
{
const float *spectrumData = FSOUND_DSP_GetSpectrum(); //recupere les 512 cannaux separés
int spectrumValue;
wxColour MaCouleur(0,0,255);
wxPen MonCrayon(MaCouleur,10,wxSOLID);

for ( int i = 0; i < 512; ++i )
{
spectrumValue = int( 100 * spectrumData[ i ] );
m_DC->SetPen(MonCrayon);
m_DC->DrawPoint(i, spectrumValue);
}
}


/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*Clik sur spectrum dans le menu
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::MnuSpectrum(wxCommandEvent& event)
{
FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true);
if (!FSOUND_DSP_GetActive(FSOUND_DSP_GetFFTUnit()))
{wxString msg;
msg.Printf( _T("Oups le spectrum n' est pas actif\nLe spectrum ne fonctionne que lorsqu' un stream est ouvert\nOuvrez un fichier"));
wxMessageBox(msg, _T("Infos"), wxOK | wxICON_EXCLAMATION | wxCENTRE, this);return;
}//si le spectrum est actif....
this->SetSize(0, 0, 800, 380);
this->Center();
spectrum01 (event);
}


m_DC pointe sur wxDC qui est le device context

et ds mon code qui creer les gui j' ai mis :

m_DC =new wxDC();
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
avec ce codej'arrive a dessinner ds un dialog: ouf.
maintenant le pb c'est que ca ne bouge pas j'ecrit un point aux coordonnées i, spectrumValue mais g une ligne, jusque la c ok mais la ligne ne bouge pas!!! ca te dis qque choze comme probleme???
j'ai pt'et oublié qque choze?

#include "Mp3PlayerFrm.h"


//ici la vrai fonction du spectre


void Mp3PlayerFrm::spectrum01(wxCommandEvent& event)
{
spectrWnd->Show(true);
spectrWnd->SetSize(-1, -1, 200, 200);
wxWindowDC dc(spectrWnd); //creer l'objet dc ds spectrWnd
DessineSpectre(dc);
}
//ici je dessine le spectre


void Mp3PlayerFrm::DessineSpectre (wxDC& dc)
{
FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true);
if (!FSOUND_DSP_GetActive(FSOUND_DSP_GetFFTUnit()))
{wxString msg;
msg.Printf( _T("Oups le spectrum n' est pas actif\nLe spectrum ne fonctionne que lorsqu' un stream est ouvert\nOuvrez un fichier"));
wxMessageBox(msg, _T("Infos"), wxOK | wxICON_EXCLAMATION | wxCENTRE, this);return;
}//si le spectrum est actif....

const float *spectrumData = FSOUND_DSP_GetSpectrum(); //recupere les 512 cannaux separés
int spectrumValue;

wxColour MaCouleur(120,0,15);
wxPen MonCrayon(MaCouleur,22,wxSOLID);
dc.SetPen(MonCrayon);

for ( int i = 0; i < 512; ++i )
{
spectrumValue = int( 150*spectrumData[ i ] );
dc.DrawPoint(i, 100-spectrumValue);
}
}
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*Clik sur spectrum dans le menu
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::MnuSpectrum(wxCommandEvent& event)
{
spectrum01(event);
}
Messages postés
571
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
5 décembre 2013

Passe en mode debug et regarde si i et spectrumValue passent bien les bne valeurs !! (ou mieux affiche les en direct !!)

i 0 -> 512

spectrumValue 0 -> 100
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
yo, en fait le spectrum marche mais il ne se reactualise pas! quand je le ferme et que je l' reouvre ca bouge donc il recoi du signal.

le truc c'est que le timer du spectrum n'a pas l'air de fonctionner .
ds la doc ils disent qu'an l'appel de [mk:@MSITStore:C:\Dev-Cpp\docs\FMOD.chm::/HTML/FSOUND_DSP_SetActive.html FSOUND_DSP_SetActive]([mk:@MSITStore:C:\Dev-Cpp\docs\FMOD.chm::/HTML/FSOUND_DSP_GetFFTUnit.html FSOUND_DSP_GetFFTUnit], TRUE);

le spectrum se met en route et est updaté ttes les 25ms or moi ca bouge po.

mon code:

#include "Mp3PlayerFrm.h"


/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*Clik sur spectrum dans le menu
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::MnuSpectrum(wxCommandEvent& event)
{
FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true);

if (!FSOUND_DSP_GetActive(FSOUND_DSP_GetFFTUnit()))
{wxString msg;
msg.Printf( _T("Oups le spectrum n' est pas actif\nLe spectrum ne fonctionne que lorsqu' un stream est ouvert\nOuvrez un fichier"));
wxMessageBox(msg, _T("Infos"), wxOK | wxICON_EXCLAMATION | wxCENTRE, this);return;
}//si le spectrum est actif....

wxWindowDC dc(spectrWnd);

spectrWnd->Show(true);
spectrWnd->SetSize(-1, -1, 200, 200);

const float *spectrumData = FSOUND_DSP_GetSpectrum(); //recupere les 512 cannaux separés
int spectrumValue;

wxColour MaCouleur(0,150,15);
wxPen MonCrayon(MaCouleur,10,wxSOLID);
dc.SetPen(MonCrayon);

for ( int i = 0; i < 512; i++ )
{
spectrumValue = int(100 * (spectrumData[ i ] + spectrumData[ i +1 ] + spectrumData[ i+2 ] + spectrumData[ i+3 ] + spectrumData[ i+4 ] )) / 5;
dc.DrawPoint(i, 100-spectrumValue);
}
}

merci bien pour ton aide
cool++
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
en fait si, le spectrum marche bien mais c'est mon dessin qui ne s'actualise pas: il dessine 1 fois et basta.

il faut timer la fenetre????????
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
bon c bon ca marche mais avec un timer!!!!!!
c'est normal?????

#include "Mp3PlayerFrm.h"


/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*Clik sur spectrum dans le menu
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::MnuSpectrum(wxCommandEvent& event)
{
FSOUND_DSP_SetActive(FSOUND_DSP_GetFFTUnit(), true); //active le spectrum.....

if (!FSOUND_DSP_GetActive(FSOUND_DSP_GetFFTUnit())) //si le spectre est pas actf...
{wxString msg;
msg.Printf( _T("Oups le spectrum n' est pas actif\nLe spectrum ne fonctionne que lorsqu' un stream est ouvert\nOuvrez un fichier"));
wxMessageBox(msg, _T("Infos"), wxOK | wxICON_EXCLAMATION | wxCENTRE, this);return;
}//si le spectrum est actif....

wxWindowDC dc(spectrWnd); //creer un device context sur spectrWnd...
spectrWnd->Show(true); //rend visible spectrWnd...
DessineSpectre(dc);


}


/*/////////////////////////////////////////////////////////////////////////////////////////////////////
*dessine le spectrum ds le device context
*//////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::DessineSpectre(wxDC& dc)
{ dc.Clear();
//dessin du spectre.....
const float *spectrumData = FSOUND_DSP_GetSpectrum(); //recupere les 512 cannaux separés...
int spectrumValue;
wxColour MaCouleur(0,255,0);
wxPen MonCrayon(MaCouleur,10,wxSOLID);
dc.SetPen(MonCrayon);
for ( int i = 0; i < 512; i++ )
{
spectrumValue = int(300 * (spectrumData[ i ] + spectrumData[ i +1 ] + spectrumData[ i+2 ] + spectrumData[ i+3 ] + spectrumData[ i+4 ] )) / 5;
dc.DrawPoint(i, 100-spectrumValue); //dessine le spectre...
}
}


/*////////////////////////////////////////////////////////////////////////////////////////////////////////
*timer spectre
*////////////////////////////////////////////////////////////////////////////////////////////////////////


void Mp3PlayerFrm::OnTimerSpectr(wxTimerEvent& event)
{

wxWindowDC dc(spectrWnd); //creer un device context sur spectrWnd..
DessineSpectre(dc);
}
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
bon c good ca marche mais j'ai un gug d'affichage

tu veux bien regarder ma source????

http://satellitesound.free.fr/PlayerMp3.rar

merci
++
Messages postés
571
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
5 décembre 2013

Ben j'ai pas wxWidgets decrit moi plutot le bug d affichage !!

Sinon pour le timer c'est normal FSOUND_DSP_GetSpectrum() lui change
tout seul mais pour ton affichage il te faut un timer ou un thread, le
timer c'est le plus simple, il te suffit de mettre ta fonction de
dessin a WM_TIMER (en win 32)
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
bon, ca marche sans bug actually, j'ameliore le spectrum et c finish!!!
(enfin, pour la partie musique du player)

thanx all
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
comment tu fais pour dessinner l' interieur du spectre???
Messages postés
571
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
5 décembre 2013

Pour en revenir a setpixel ou DrawPoint ils sont trop lents pour etre
utile je retrouve plus le topic qui m'avait aidé mais cf
http://www.cppfrance.com/forum.v2.aspx?id=210072 tu va comprendre ce
que je veut dire, en terme de performance c'est vraiment pas comparable
( 10 fois plus rapide chronometré sur une fonction de decoupage de
bitmap)



Sinon je ne voit pas ce que tu veut dire par "colorier l'interieur"



Moi j'ai fait des barres avec une barre plus petite de 1 pixel de tout les coté a linterieur de la premiere.

Sinon pour faire des barre en degradé en win32 dans un RECT !!!!



RECT rect ; (coordonnées barre en degradé)

COLORREF ccouleurprog = ...... ;( ta valeur de degradé)



int deca deca rect.bottom - rect.top;





int fRed = (int)GetRValue(ccouleurprog);

int fBlue = (int)GetBValue(ccouleurprog);

int fGreen = (int)GetGValue(ccouleurprog);



HPEN currPen;

HPEN oldpen;



for ( ; i < deca; ++i) {

if (fRed) fRed -= 128 / deca;

if (fBlue) fBlue -= 128 / deca;

if (fGreen) fGreen -= 128 / deca;



currPen = CreatePen(PS_SOLID, 1, RGB(fRed, fGreen , fBlue));

oldpen=(HPEN)SelectObject(hdc,currPen);




MoveToEx(hdc, rect.left ,rect.bottom - i, (LPPOINT)
NULL);

LineTo(hdc, rect.right , rect.bottom - i);



SelectObject(hdc, oldpen);

DeleteObject( currPen );

}



Bon je sait pas si ca va marcher vu que j'ai pas mal modifié mon code pour virer le superflu !!
Messages postés
688
Date d'inscription
mercredi 6 avril 2005
Statut
Membre
Dernière intervention
2 juin 2006
1
merci mais désolé, je n'arrive pas a l'adapter a wxWIDGETS
je trouve pas les equivalents.
aîaîaî ya encore du travail !