Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
843 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Fmod, probleme avec channel->getSpectrum()

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Fmod, probleme avec channel->getSpectrum()

n°1375439
l3eleg
cosmik connection
Posté le 26-05-2006 à 12:11:59  profilanswer
 

bonjour à tous,
je cherche à obtenir le spectre d'un fichier wav ouvert sous mathlab, afin d'effectuer une analyse spectrale visant à identifier les notes. J'ai besoin de quelqu'un ayant déjà utiliser FMODex auparavant.
Je me base sur l'exemple d'fmodex s'intitulant "pitchdetection", cet exemple permet d'effectuer une FFT sur le signal et d'en déduire le spectre.
 

Code :
  1. /*===============================================================================================
  2. Pitch detection example.
  3. Copyright (c), Firelight Technologies Pty, Ltd 2004-2005.
  4. This example combines recording with spectrum analysis to determine the pitch of the sound
  5. being recorded.
  6. ===============================================================================================*/
  7. #include "inc/fmod.hpp"
  8. #include "inc/fmod_errors.h"
  9. #include <windows.h>
  10. #include <stdio.h>
  11. #include <conio.h>
  12. #include <math.h>
  13. void ERRCHECK(FMOD_RESULT result, int i)
  14. {
  15.     if (result != FMOD_OK)
  16.     {
  17.         printf("(l:%i) FMOD error! (%d) %s\n", i, result, FMOD_ErrorString(result));
  18.         exit(-1);
  19.     }
  20. }
  21. static const char *note[120] =
  22. {
  23.     "C 0", "C#0", "D 0", "D#0", "E 0", "F 0", "F#0", "G 0", "G#0", "A 0", "A#0", "B 0", 
  24.     "C 1", "C#1", "D 1", "D#1", "E 1", "F 1", "F#1", "G 1", "G#1", "A 1", "A#1", "B 1", 
  25.     "C 2", "C#2", "D 2", "D#2", "E 2", "F 2", "F#2", "G 2", "G#2", "A 2", "A#2", "B 2", 
  26.     "C 3", "C#3", "D 3", "D#3", "E 3", "F 3", "F#3", "G 3", "G#3", "A 3", "A#3", "B 3", 
  27.     "C 4", "C#4", "D 4", "D#4", "E 4", "F 4", "F#4", "G 4", "G#4", "A 4", "A#4", "B 4", 
  28.     "C 5", "C#5", "D 5", "D#5", "E 5", "F 5", "F#5", "G 5", "G#5", "A 5", "A#5", "B 5", 
  29.     "C 6", "C#6", "D 6", "D#6", "E 6", "F 6", "F#6", "G 6", "G#6", "A 6", "A#6", "B 6", 
  30.     "C 7", "C#7", "D 7", "D#7", "E 7", "F 7", "F#7", "G 7", "G#7", "A 7", "A#7", "B 7", 
  31.     "C 8", "C#8", "D 8", "D#8", "E 8", "F 8", "F#8", "G 8", "G#8", "A 8", "A#8", "B 8", 
  32.     "C 9", "C#9", "D 9", "D#9", "E 9", "F 9", "F#9", "G 9", "G#9", "A 9", "A#9", "B 9"
  33. };
  34. static const float notefreq[120] =
  35. {
  36.       16.35f,   17.32f,   18.35f,   19.45f,    20.60f,    21.83f,    23.12f,    24.50f,    25.96f,    27.50f,    29.14f,    30.87f,
  37.       32.70f,   34.65f,   36.71f,   38.89f,    41.20f,    43.65f,    46.25f,    49.00f,    51.91f,    55.00f,    58.27f,    61.74f,
  38.       65.41f,   69.30f,   73.42f,   77.78f,    82.41f,    87.31f,    92.50f,    98.00f,   103.83f,   110.00f,   116.54f,   123.47f,
  39.      130.81f,  138.59f,  146.83f,  155.56f,   164.81f,   174.61f,   185.00f,   196.00f,   207.65f,   220.00f,   233.08f,   246.94f,
  40.      261.63f,  277.18f,  293.66f,  311.13f,   329.63f,   349.23f,   369.99f,   392.00f,   415.30f,   440.00f,   466.16f,   493.88f,
  41.      523.25f,  554.37f,  587.33f,  622.25f,   659.26f,   698.46f,   739.99f,   783.99f,   830.61f,   880.00f,   932.33f,   987.77f,
  42.     1046.50f, 1108.73f, 1174.66f, 1244.51f,  1318.51f,  1396.91f,  1479.98f,  1567.98f,  1661.22f,  1760.00f,  1864.66f,  1975.53f,
  43.     2093.00f, 2217.46f, 2349.32f, 2489.02f,  2637.02f,  2793.83f,  2959.96f,  3135.96f,  3322.44f,  3520.00f,  3729.31f,  3951.07f,
  44.     4186.01f, 4434.92f, 4698.64f, 4978.03f,  5274.04f,  5587.65f,  5919.91f,  6271.92f,  6644.87f,  7040.00f,  7458.62f,  7902.13f,
  45.     8372.01f, 8869.84f, 9397.27f, 9956.06f, 10548.08f, 11175.30f, 11839.82f, 12543.85f, 13289.75f, 14080.00f, 14917.24f, 15804.26f
  46. };
  47. #define OUTPUTRATE          44100
  48. #define SPECTRUMSIZE        8192
  49. #define SPECTRUMRANGE       ((float)OUTPUTRATE / 2.0f)      /* 0 to nyquist */
  50. #define BINSIZE      (SPECTRUMRANGE / (float)SPECTRUMSIZE)
  51. int main(int argc, char *argv[])
  52. {
  53.     FMOD::System          *system  = 0;
  54.     FMOD::Sound           *sound   = 0;
  55. FMOD::Sound     *sound2  = 0;
  56.     FMOD::Channel         *channel = 0;
  57.     FMOD::Channel         *channel2 = 0;
  58.     FMOD_RESULT            result;
  59.     FMOD_CREATESOUNDEXINFO exinfo;
  60.     int                    key, driver, numdrivers, count, bin;
  61.     unsigned int           version;   
  62. int        i=0;
  63.     /*
  64.         Create a System object and initialize.
  65.     */
  66.     result = FMOD::System_Create(&system);
  67.     ERRCHECK(result,1);
  68.     result = system->getVersion(&version);
  69.     ERRCHECK(result,2);
  70.     if (version < FMOD_VERSION)
  71.     {
  72.         printf("Error!  You are using an old version of FMOD %08x.  This program requires %08x\n", version, FMOD_VERSION);
  73.         return 0;
  74.     }
  75.     /*  
  76.         System initialization
  77.     */
  78.     printf("---------------------------------------------------------\n" );   
  79.     printf("Select OUTPUT type\n" );   
  80.     printf("---------------------------------------------------------\n" );   
  81.     printf("1 :  DirectSound\n" );
  82.     printf("2 :  Windows Multimedia WaveOut\n" );
  83.     printf("3 :  ASIO\n" );
  84.     printf("---------------------------------------------------------\n" );
  85.     printf("Press a corresponding number or ESC to quit\n" );
  86.     do
  87.     {
  88.         key = getch();
  89.     } while (key != 27 && key < '1' && key > '5');
  90.    
  91.     switch (key)
  92.     {
  93.         case '1' :  result = system->setOutput(FMOD_OUTPUTTYPE_DSOUND);
  94.                     break;
  95.         case '2' :  result = system->setOutput(FMOD_OUTPUTTYPE_WINMM);
  96.                     break;
  97.         case '3' :  result = system->setOutput(FMOD_OUTPUTTYPE_ASIO);
  98.                     break;
  99.         default  :  return 1;
  100.     } 
  101.     ERRCHECK(result,3);
  102.    
  103.     /*
  104.         Enumerate playback devices
  105.     */
  106.     result = system->getNumDrivers(&numdrivers);
  107.     ERRCHECK(result,4);
  108.     printf("---------------------------------------------------------\n" );   
  109.     printf("Choose a PLAYBACK driver\n" );
  110.     printf("---------------------------------------------------------\n" );   
  111.     for (count=0; count < numdrivers; count++)
  112.     {
  113.         char name[256];
  114.         result = system->getDriverName(count, name, 256);
  115.         ERRCHECK(result,5);
  116.         printf("%d : %s\n", count + 1, name);
  117.     }
  118.     printf("---------------------------------------------------------\n" );
  119.     printf("Press a corresponding number or ESC to quit\n" );
  120.     do
  121.     {
  122.         key = getch();
  123.         if (key == 27)
  124.         {
  125.             return 0;
  126.         }
  127.         driver = key - '1';
  128.     } while (driver < 0 || driver >= numdrivers);
  129.     result = system->setDriver(driver);
  130.     ERRCHECK(result,6);
  131.     /*
  132.         Enumerate record devices
  133.     */
  134.     result = system->getRecordNumDrivers(&numdrivers);
  135.     ERRCHECK(result,7);
  136.     printf("---------------------------------------------------------\n" );   
  137.     printf("Choose a RECORD driver\n" );
  138.     printf("---------------------------------------------------------\n" );   
  139.     for (count=0; count < numdrivers; count++)
  140.     {
  141.         char name[256];
  142.         result = system->getRecordDriverName(count, name, 256);
  143.         ERRCHECK(result,8);
  144.         printf("%d : %s\n", count + 1, name);
  145.     }
  146.     printf("---------------------------------------------------------\n" );
  147.     printf("Press a corresponding number or ESC to quit\n" );
  148.     do
  149.     {
  150.         key = getch();
  151.         if (key == 27)
  152.         {
  153.             return 0;
  154.         }
  155.         driver = key - '1';
  156.     } while (driver < 0 || driver >= numdrivers);
  157.     printf("\n" );
  158.     result = system->setRecordDriver(driver);
  159.     ERRCHECK(result,9);
  160.     result = system->setSoftwareFormat(OUTPUTRATE, FMOD_SOUND_FORMAT_PCM16, 1, 0, FMOD_DSP_RESAMPLER_LINEAR);
  161.     ERRCHECK(result,10);
  162.     result = system->init(32, FMOD_INIT_NORMAL, 0);
  163.     ERRCHECK(result,11);
  164.     /*
  165.         Create a sound to record to.
  166.     */
  167.     memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
  168.     exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
  169.     exinfo.numchannels      = 1;
  170.     exinfo.format           = FMOD_SOUND_FORMAT_PCM16;
  171.     exinfo.defaultfrequency = OUTPUTRATE;
  172.     exinfo.length           = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 5;
  173.    
  174.     result = system->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &sound);
  175.     ERRCHECK(result,12);
  176. result = system->createSound("do.wav", FMOD_2D | FMOD_SOFTWARE, &exinfo, &sound2);
  177.     ERRCHECK(result,13);
  178.     /*
  179.         Start the interface
  180.     */
  181.     printf("=========================================================================\n" );
  182.     printf("Pitch detection example.  Copyright (c) Firelight Technologies 2004-2005.\n" );
  183.     printf("=========================================================================\n" );
  184.     printf("\n" );
  185.     printf("Record something through the selected recording device and FMOD will\n" );
  186.     printf("Determine the pitch.  Sustain the tone for at least a second to get an\n" );
  187.     printf("accurate reading.\n" );
  188.     printf("Press 'Esc' to quit\n" );
  189.     printf("\n" );
  190.     result = system->recordStart(sound, true);
  191.     ERRCHECK(result,14);
  192.    
  193.     Sleep(200);      /* Give it some time to record something */
  194.    
  195. result = system->playSound(FMOD_CHANNEL_FREE, sound2, false, &channel2);
  196.     ERRCHECK(result,15);
  197.     result = system->playSound(FMOD_CHANNEL_REUSE, sound, false, &channel);
  198.     ERRCHECK(result,16);
  199.     /* Dont hear what is being recorded otherwise it will feedback.  Spectrum analysis is done before volume scaling in the DSP chain */
  200.     result = channel2->setVolume(0);
  201.     ERRCHECK(result,17);
  202.     bin = 0;
  203.     /*
  204.         Main loop.
  205.     */
  206.     do
  207.     {
  208.         static float spectrum[SPECTRUMSIZE];
  209.         float        dominanthz = 0;
  210.         float        max;
  211.         int          dominantnote = 0;
  212.         float        binsize = BINSIZE;
  213.         if (kbhit())
  214.         {
  215.             key = getch();
  216.         }
  217.         result = channel2->getSpectrum(spectrum, SPECTRUMSIZE, 0, FMOD_DSP_FFT_WINDOW_TRIANGLE);
  218.         ERRCHECK(result,18);
  219.         max = 0;
  220.         for (count = 0; count < SPECTRUMSIZE; count++)
  221.         {
  222.             if (spectrum[count] > 0.01f && spectrum[count] > max)
  223.             {
  224.                 max = spectrum[count];
  225.                 bin = count;
  226.             }
  227.         }       
  228.         dominanthz  = (float)bin * BINSIZE;       /* dominant frequency min */
  229.         dominantnote = 0;
  230.         for (count = 0; count < 120; count++)
  231.         {
  232.              if (dominanthz >= notefreq[count] && dominanthz < notefreq[count + 1])
  233.              {
  234.                 /* which is it closer to.  This note or the next note */
  235.                 if (fabs(dominanthz - notefreq[count]) < fabs(dominanthz - notefreq[count+1]))
  236.                 {
  237.                     dominantnote = count;
  238.                 }
  239.                 else
  240.                 {
  241.                     dominantnote = count + 1;
  242.                 }
  243.                 break;
  244.              }
  245.         }
  246.         printf("Detected rate : %7.1f -> %7.1f hz.  Detected musical note. %-3s (%7.1f hz)\r", dominanthz, ((float)bin + 0.99f) * BINSIZE, note[dominantnote], notefreq[dominantnote]);
  247.         system->update();
  248.         Sleep(10);
  249.     } while (key != 27);
  250.     printf("\n" );
  251.     /*
  252.         Shut down
  253.     */
  254.     result = sound->release();
  255.     ERRCHECK(result,17);
  256.     result = system->release();
  257.     ERRCHECK(result,18);
  258.     return 0;
  259. }


 
 
On ouvre donc le fichier do.wav, jusque ici aucun probleme, on le définit en FMOD_SOFTWARE sinon getSpectrum ne fonctionne pas

Code :
  1. result = system->createSound("do.wav", FMOD_2D | FMOD_SOFTWARE, &exinfo, &sound2);
  2.     ERRCHECK(result,13);


 
Le problème se situe donc ici :

Code :
  1. result = channel2->getSpectrum(spectrum, SPECTRUMSIZE, 0, FMOD_DSP_FFT_WINDOW_TRIANGLE);
  2.         ERRCHECK(result,18);


Si je soumet a getSpectrum le channel2 (le fichier wav) le programme plante lors de l'execution (erreur memoire), si je founis channel (l'entrée micro) tout marche parfaitement (mais je ne peux pas analyser le fichier son forcément ... :p)
 
Quelqu'un a déjà essayer de faire cela ?

mood
Publicité
Posté le 26-05-2006 à 12:11:59  profilanswer
 

n°1376235
nargy
Posté le 28-05-2006 à 16:35:39  profilanswer
 

à vue de nez, tu as un problème avec le format de fichier son.
vérifie que tu alloue bien la quantité de mémoire necessaire suivant la taille de l'échantillonage.

n°1382017
megagob
Posté le 06-06-2006 à 13:32:26  profilanswer
 

Bonjour, j'ai egalement un probleme avec le GetSpectrum. Je code une visualisation des frequences d'une musique, en C et opengl. J'arrive à lire la musique, mais si dans ma boucle principale j execute Channel_GetSpectrum avec les bons arguments, le programme segfault.
 
De plus gdb me dit que le segfault se produit lors de l appel a cette derniere fonction.
 
La documentation fournie a l air deprecated, et je trouve peu d aide sur google et pourtant le temps presse !
 
Alors aurais je oublié d'activer quelque chose ?peut etre ai je mal compris comment utiliser cette fonction ?
 
Dans l'attente d'une reponse precise (>2lignes), je vous remercie de l aide que vous saurez m apporter!


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Fmod, probleme avec channel->getSpectrum()

 

Sujets relatifs
Problème de boutons flash (lien avec internet explorer)Probleme tout simple : existence d'une valeur
probleme de compilation[Java] Problème échanges client-serveur (Résolu)
Probleme lors mise a jour de textarea : encodage ?problème de conception de graphiques dans une page jsp
probleme de boucleUtiliser Fmod pour acquérir des données sonores
Problème de décalage sur une pageprobleme Postgresql 8 et PHP5
Plus de sujets relatifs à : Fmod, probleme avec channel->getSpectrum()


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR