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

  FORUM HardWare.fr
  Programmation
  C++

  Utiliser Fmod pour acquérir des données sonores

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Utiliser Fmod pour acquérir des données sonores

n°1374066
l3eleg
cosmik connection
Posté le 24-05-2006 à 13:35:47  profilanswer
 

Bonjour à tous,
je travaille sur un projet consistant à analyser en temps réel un flux audio en provenance de l'entrée micro de la carte son afin de détecter des séquences de notes et ainsi déclencher en temps réel des séquences MIDI.
 
J'utilise pour cela la librairie FMOD, mais j'avoue etre un peu perdu concernant son utilisation et surtout le contenu des données.
Je m'explique : J'arrive a enregistrer des données en provenance de l'entrée micro, mais c'est au niveau du découpage que je sèche ... En effet, mon collègue chargé de l'analyse sonore me demande de lui donner un buffer contenant 0.1ms de son au maximum (longueur d'une note sur un tempo de 200 je crois). Ma question est donc, comment découper le buffer de 1 seconde en temps réel en portions de 0.1ms pour analyse.
En vous remerciant pour vos suggestions,
 
ci joint le code :

Code :
  1. // Base from Record.cpp and Brett copie_Sample_Micro_vers_ring_buffer_micro() function
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #if defined(WIN32) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__)
  6. #include <conio.h>
  7. #include <windows.h>
  8. #define __PACKED /*dummy*/
  9. #else
  10. #include "FMOD/wincompat.h"
  11. #include <string.h>
  12. #define __PACKED __attribute__((packed)) /* gcc packed */
  13. #endif
  14. #include "FMOD/fmod.h"
  15. #include "FMOD/fmod_errors.h" /* optional */
  16. // definir un buffer de 0.1ms -> impossible, solution : buffer 1s dont on découpe les parties
  17. // successives ?
  18. #define PI 3.141517
  19. #define RECORDRATE 44100
  20. #define RECORDLEN (RECORDRATE * 10) /* 1 seconds at RECORDRATE khz */
  21. #define OUTPUTRATE 44100
  22. int BufferSize=4096*3;
  23. int Frequency=44100;
  24. signed short MICRO_INPUT=0;
  25. FSOUND_SAMPLE *samp1;
  26. FSOUND_STREAM *stream;
  27. int mylength_bytes=44100*400;
  28. signed short mybuffer[44100*400+10];
  29. unsigned int myoffset_bytes=0;
  30. signed char F_CALLBACKAPI instrument_callback(FSOUND_STREAM *stream, void *buff, int len, void *param);
  31. int copie_Sample_Micro_vers_ring_buffer_micro();
  32. //DEBUT DU MAIN
  33. int main(int argc, char *argv[])
  34. {
  35.     signed char key;
  36.     int driver, i, channel, originalfreq;
  37.     if (FSOUND_GetVersion() < FMOD_VERSION)
  38.     {
  39.        printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION);
  40.        return 0;
  41.     }
  42.     /*
  43.     SELECT OUTPUT METHOD
  44.     */
  45.     printf("---------------------------------------------------------\n" );
  46.     printf("Output Type\n" );
  47.     printf("---------------------------------------------------------\n" );
  48.     #if defined(WIN32) || defined(_WIN64) || defined(__CYGWIN32__) || defined(__WATCOMC__)
  49.     printf("1 - Direct Sound\n" );
  50.     printf("2 - Windows Multimedia Waveout\n" );
  51.     printf("3 - NoSound\n" );
  52.     #elif defined(__linux__)
  53.     printf("1 - OSS - Open Sound System\n" );
  54.     printf("2 - ESD - Elightment Sound Daemon\n" );
  55.     printf("3 - ALSA 0.9 - Advanced Linux Sound Architecture\n" );
  56.     #endif
  57.     printf("---------------------------------------------------------\n" ); /* print driver names */
  58.     printf("Press a corresponding number or ESC to quit\n" );
  59.    
  60.     do
  61.     {
  62.       key = getch();
  63.     }
  64.     while (key != 27 && key < '1' && key > '4');
  65.    
  66.     switch (key)
  67.     {
  68.         #if defined(WIN32) || defined(_WIN64) || defined(__CYGWIN32__) || defined(__WATCOMC__)
  69.         case '1' : FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
  70.         break;
  71.         case '2' : FSOUND_SetOutput(FSOUND_OUTPUT_WINMM);
  72.         break;
  73.         case '3' : FSOUND_SetOutput(FSOUND_OUTPUT_NOSOUND);
  74.         break;
  75.         #elif defined(__linux__)
  76.         case '1' : FSOUND_SetOutput(FSOUND_OUTPUT_OSS);
  77.         break;
  78.         case '2' : FSOUND_SetOutput(FSOUND_OUTPUT_ESD);
  79.         break;
  80.         case '3' : FSOUND_SetOutput(FSOUND_OUTPUT_ALSA);
  81.         break;
  82.         #endif
  83.         default : return 0;
  84.     }
  85.    
  86.     /*
  87.     SELECT OUTPUT DRIVER
  88.     */
  89.    
  90.     /* The following list are the drivers for the output method selected above. */
  91.     printf("---------------------------------------------------------\n" );
  92.     switch (FSOUND_GetOutput())
  93.     {
  94.         case FSOUND_OUTPUT_NOSOUND: printf("NoSound" ); break;
  95.         case FSOUND_OUTPUT_WINMM: printf("Windows Multimedia Waveout" ); break;
  96.         case FSOUND_OUTPUT_DSOUND: printf("Direct Sound" ); break;
  97.         case FSOUND_OUTPUT_OSS: printf("Open Sound System" ); break;
  98.         case FSOUND_OUTPUT_ESD: printf("Enlightment Sound Daemon" ); break;
  99.         case FSOUND_OUTPUT_ALSA: printf("ALSA" ); break;
  100.     };
  101.     printf(" Driver list\n" );
  102.     printf("---------------------------------------------------------\n" );
  103.    
  104.     for (i=0; i < FSOUND_GetNumDrivers(); i++)
  105.     {
  106.         printf("%d - %s\n", i+1, FSOUND_GetDriverName(i)); /* print driver names */
  107.     }
  108.     printf("---------------------------------------------------------\n" ); /* print driver names */
  109.     printf("Press a corresponding number or ESC to quit\n" );
  110.    
  111.     do
  112.     {
  113.         key = getch();
  114.         if (key == 27)
  115.         {
  116.             FSOUND_Close();
  117.             return 0;
  118.         }
  119.         driver = key - '1';
  120.     }
  121.     while (driver < 0 || driver >= FSOUND_GetNumDrivers());
  122.    
  123.     FSOUND_SetDriver(driver); /* Select sound card (0 = default) */
  124.    
  125.     /*
  126.     SELECT MIXER
  127.     */
  128.    
  129.     FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT);
  130.    
  131.     /*
  132.     INITIALIZE
  133.     */
  134.     if (!FSOUND_Init(OUTPUTRATE, 64, FSOUND_INIT_ACCURATEVULEVELS))
  135.     {
  136.         printf("Error!\n" );
  137.         printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
  138.         return 0;
  139.     }
  140.    
  141.    
  142.     /*
  143.     SELECT INPUT DRIVER (can be done before or after init)
  144.     */
  145.    
  146.     /* The following list are the drivers for the output method selected above. */
  147.     printf("---------------------------------------------------------\n" );
  148.     switch (FSOUND_GetOutput())
  149.     {
  150.         case FSOUND_OUTPUT_NOSOUND: printf("NoSound" ); break;
  151.         case FSOUND_OUTPUT_WINMM: printf("Windows Multimedia Waveout" ); break;
  152.         case FSOUND_OUTPUT_DSOUND: printf("Direct Sound" ); break;
  153.         case FSOUND_OUTPUT_OSS: printf("Open Sound System" ); break;
  154.         case FSOUND_OUTPUT_ESD: printf("Enlightment Sound Daemon" ); break;
  155.         case FSOUND_OUTPUT_ALSA: printf("ALSA" ); break;
  156.     };
  157.     printf(" Recording device driver list\n" );
  158.     printf("---------------------------------------------------------\n" );
  159.    
  160.     for (i=0; i < FSOUND_Record_GetNumDrivers(); i++)
  161.     {
  162.         printf("%d - %s\n", i+1, FSOUND_Record_GetDriverName(i)); /* print driver names */
  163.     }
  164.     printf("---------------------------------------------------------\n" ); /* print driver names */
  165.     printf("Press a corresponding number or ESC to quit\n" );
  166.    
  167.     do
  168.     {
  169.         key = getch();
  170.         if (key == 27)
  171.         return 0;
  172.         driver = key - '1';
  173.     }
  174.     while (driver < 0 || driver >= FSOUND_Record_GetNumDrivers());
  175.    
  176.     if (!FSOUND_Record_SetDriver(driver)) /* Select input sound card (0 = default) */
  177.     {
  178.         printf("Error!\n" );
  179.         printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
  180.         FSOUND_Close();
  181.         return 0;
  182.     }
  183.    
  184.     /*
  185.     DISPLAY HELP
  186.     */
  187.    
  188.     printf("FSOUND Output Method : " );
  189.     switch (FSOUND_GetOutput())
  190.     {
  191.         case FSOUND_OUTPUT_NOSOUND: printf("FSOUND_OUTPUT_NOSOUND\n" ); break;
  192.         case FSOUND_OUTPUT_WINMM: printf("FSOUND_OUTPUT_WINMM\n" ); break;
  193.         case FSOUND_OUTPUT_DSOUND: printf("FSOUND_OUTPUT_DSOUND\n" ); break;
  194.         case FSOUND_OUTPUT_OSS: printf("FSOUND_OUTPUT_OSS\n" ); break;
  195.         case FSOUND_OUTPUT_ESD: printf("FSOUND_OUTPUT_ESD\n" ); break;
  196.         case FSOUND_OUTPUT_ALSA: printf("FSOUND_OUTPUT_ALSA\n" ); break;
  197.     };
  198.    
  199.     printf("FSOUND Mixer : " );
  200.     switch (FSOUND_GetMixer())
  201.     {
  202.         case FSOUND_MIXER_BLENDMODE: printf("FSOUND_MIXER_BLENDMODE\n" ); break;
  203.         case FSOUND_MIXER_MMXP5: printf("FSOUND_MIXER_MMXP5\n" ); break;
  204.         case FSOUND_MIXER_MMXP6: printf("FSOUND_MIXER_MMXP6\n" ); break;
  205.         case FSOUND_MIXER_QUALITY_FPU: printf("FSOUND_MIXER_QUALITY_FPU\n" ); break;
  206.         case FSOUND_MIXER_QUALITY_MMXP5:printf("FSOUND_MIXER_QUALITY_MMXP5\n" ); break;
  207.         case FSOUND_MIXER_QUALITY_MMXP6:printf("FSOUND_MIXER_QUALITY_MMXP6\n" ); break;
  208.     };
  209.     printf("FSOUND Driver : %s\n", FSOUND_GetDriverName(FSOUND_GetDriver()));
  210.     printf("FSOUND Record Driver : %s\n", FSOUND_Record_GetDriverName(FSOUND_Record_GetDriver()));
  211.    
  212.     // My stream for my synthetiseur circuit (wich need to be feeded by the micro)
  213.     stream = FSOUND_Stream_Create(instrument_callback, BufferSize, FSOUND_16BITS | FSOUND_SIGNED | FSOUND_STEREO |FSOUND_NONBLOCKING, Frequency, (void *)NULL);
  214.     if (!stream)
  215.     {
  216.         printf("Error!\n" );
  217.         printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
  218.         exit(1);
  219.     }
  220.     // Play the synthetiseur channel cause we wanna hear some good sounds
  221.     if (FSOUND_Stream_Play(FSOUND_FREE, stream) == -1) {printf("Error!\n" );printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));exit(1);}
  222.    
  223.     /*
  224.     Create a sample to record into
  225.     */
  226.     if (FSOUND_GetOutput() == FSOUND_OUTPUT_OSS)
  227.     {
  228.         samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_MONO | FSOUND_8BITS | FSOUND_UNSIGNED, RECORDRATE, 255, 128, 255);
  229.     }
  230.     else
  231.     {
  232.         samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_STEREO | FSOUND_16BITS , RECORDRATE, 255, 128, 255);
  233.     }
  234.    
  235.     printf("\n" );
  236.     printf("=========================================================================\n" );
  237.     printf("Press a key to start recording 5 seconds worth of data\n" );
  238.     printf("=========================================================================\n" );
  239.    
  240.     if (!FSOUND_Record_StartSample(samp1, FALSE)) /* it will record into this sample for 5 seconds then stop */
  241.     {
  242.         printf("Error!\n" );
  243.         printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
  244.         FSOUND_Close();
  245.         return 0;
  246.     }
  247.    
  248.    
  249.     FSOUND_Sample_SetMode(samp1, FSOUND_LOOP_NORMAL); /* make it a looping sample */
  250.     if (!FSOUND_Record_StartSample(samp1, TRUE)) /* start recording and make it loop also */
  251.     {
  252.         printf("Error!\n" );
  253.         printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
  254.        
  255.         FSOUND_Close();
  256.         return 0;
  257.     }
  258.     while(1); 
  259.     FSOUND_StopSound(channel);
  260.     FSOUND_Record_Stop();
  261.     FSOUND_Sample_Free(samp1);
  262.     FSOUND_Close();
  263.     return 0;
  264. // FIN DU MAIN
  265. }
  266. // This Came From Brett, The super man of Fmod
  267. // Retour : Position a jouer (car dernier morceau copie)
  268. int copie_Sample_Micro_vers_ring_buffer_micro()
  269. {
  270.     static int oldposition = 0;
  271.     int newposition = FSOUND_Record_GetPosition();
  272.     int offs=0;
  273.     if (newposition != oldposition)
  274.     {
  275.         void *ptr1, *ptr2;
  276.         unsigned int len1, len2;
  277.         int length = newposition - oldposition;
  278.         if (length < 0) // new position might have wrapped around to 0!
  279.         {
  280.             length += FSOUND_Sample_GetLength(samp1);
  281.         }
  282.         FSOUND_Sample_Lock(samp1, oldposition * 4, length * 4, &ptr1, &ptr2, &len1, &len2); // *4 = 16bit stereo
  283.        
  284.         offs=myoffset_bytes;
  285.         if (myoffset_bytes + len1 <= mylength_bytes)
  286.         {
  287.             memcpy(mybuffer + myoffset_bytes, ptr1, len1);
  288.             myoffset_bytes += len1;
  289.         }
  290.         else
  291.         {
  292.             // mybuffer wraps around
  293.             memcpy(mybuffer + myoffset_bytes, ptr1, mylength_bytes - myoffset_bytes);
  294.             // memcpy(mybuffer, ptr1 + (mylength_bytes - myoffset_bytes), len1 - (mylength_bytes - myoffset_bytes));
  295.             memcpy(mybuffer,
  296.             (signed short*)ptr1 + (mylength_bytes - myoffset_bytes),
  297.             len1 - (mylength_bytes - myoffset_bytes)
  298.             );
  299.            
  300.             myoffset_bytes += len1;
  301.             myoffset_bytes -= mylength_bytes;
  302.         }
  303.        
  304.         if (len2)
  305.         {
  306.             if (myoffset_bytes + len2 <= mylength_bytes)
  307.             {
  308.                 memcpy(mybuffer + myoffset_bytes, ptr2, len2);
  309.                 myoffset_bytes += len2;
  310.             }
  311.             else
  312.             {
  313.                 // mybuffer wraps around
  314.                 memcpy(mybuffer + myoffset_bytes, ptr2, mylength_bytes - myoffset_bytes);
  315.                 memcpy(mybuffer, (signed short*)ptr2 + (mylength_bytes - myoffset_bytes), len2 - (mylength_bytes - myoffset_bytes));
  316.                
  317.                 myoffset_bytes += len2;
  318.                 myoffset_bytes -= mylength_bytes;
  319.             }
  320.         }
  321.    
  322.         FSOUND_Sample_Unlock(samp1, ptr1, ptr2, len1, len2);
  323.        
  324.         oldposition += length;
  325.         if (oldposition >= FSOUND_Sample_GetLength(samp1) )
  326.         {
  327.             oldposition -= FSOUND_Sample_GetLength(samp1);
  328.         }
  329.     }
  330.     return(offs);
  331. }
  332.    
  333. signed char F_CALLBACKAPI instrument_callback(FSOUND_STREAM *stream, void *buff, int len, void *param) {
  334. {
  335.     static float MX=0;
  336.     signed short *stereo16bitbuffer = (signed short *)buff;
  337.     static float t=0,dx=0;
  338.     int i=0;
  339.     int channel=0;
  340.     // I do it there to be sure of the sync, it seem to work not less than if that were in main ...
  341.     int offs = copie_Sample_Micro_vers_ring_buffer_micro();
  342.     float osc_result= 0;
  343.     for (float x=0;x<len>>2;x++)
  344.     {
  345.         t++;
  346.         // Obtain actual micro value (to normally give it to synth but not there)
  347.         MICRO_INPUT = (signed short)mybuffer[(int)offs];
  348.         // Here normally i generate sound with my synthesizer class, but i brief a lot ...
  349.         //osc_result=(float)(rand()%100)/100; // For Tv like Noise
  350.         osc_result=sin(t*2*PI/180); // For Sinusoidal VCO
  351.        
  352.        
  353.         // I modulate the Synth signal with MicroInput in this exemple (AM)
  354.         *stereo16bitbuffer = ((float)MICRO_INPUT/32767)*(osc_result*32767);
  355.         *(stereo16bitbuffer+1) =((float)MICRO_INPUT/32767)*(osc_result*32767);
  356.        
  357.         // Fait avancer le ring buffer du micro et evite le depassement (ring buffer offset++)
  358.         offs+=2;
  359.         if((offs >= mylength_bytes) && (offs < 0) )
  360.         {
  361.            offs = 0;
  362.         }
  363.         stereo16bitbuffer+=2;
  364.     }
  365. }
  366.     return(1);
  367. }


Message édité par l3eleg le 24-05-2006 à 13:37:47
mood
Publicité
Posté le 24-05-2006 à 13:35:47  profilanswer
 

n°1375571
warnotte
Posté le 26-05-2006 à 14:39:20  profilanswer
 

Ecris la solution que je t'ai donnée tiens, ca pourra aider des gens ;)

n°1688725
Pitu45
Posté le 19-02-2008 à 17:07:39  profilanswer
 

Salut !
 
Si vous avez une solution pour le découpage en 0,1 ms je suis preneur !
Merci .

n°1968412
mrousse83
Posté le 23-02-2010 à 10:16:27  profilanswer
 

Bonjour,
 
Je suis également très intéressé par la réponse à cette question !
 
Merci,
Mathieu


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

  Utiliser Fmod pour acquérir des données sonores

 

Sujets relatifs
[ASP.NET] Utiliser un objet comme propriété d'un WebControlgénération de fichier XML à partir d'une base de données SQL ??
Quels composants utiliser?AWK: Probleme avec longueur des noms de fichiers de données
attacher base de donnéesDeux données dans un seul champ d'une table ?
creation et gestion base de donneesmoteur de recherche -> indexation des données !!!
Séparer les données d'une variable[MySQL] Importer des données venant d'un fichier texte.
Plus de sujets relatifs à : Utiliser Fmod pour acquérir des données sonores


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