l3eleg cosmik connection | 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 :
- // Base from Record.cpp and Brett copie_Sample_Micro_vers_ring_buffer_micro() function
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #if defined(WIN32) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__)
- #include <conio.h>
- #include <windows.h>
- #define __PACKED /*dummy*/
- #else
- #include "FMOD/wincompat.h"
- #include <string.h>
- #define __PACKED __attribute__((packed)) /* gcc packed */
- #endif
- #include "FMOD/fmod.h"
- #include "FMOD/fmod_errors.h" /* optional */
- // definir un buffer de 0.1ms -> impossible, solution : buffer 1s dont on découpe les parties
- // successives ?
- #define PI 3.141517
- #define RECORDRATE 44100
- #define RECORDLEN (RECORDRATE * 10) /* 1 seconds at RECORDRATE khz */
- #define OUTPUTRATE 44100
- int BufferSize=4096*3;
- int Frequency=44100;
- signed short MICRO_INPUT=0;
- FSOUND_SAMPLE *samp1;
- FSOUND_STREAM *stream;
- int mylength_bytes=44100*400;
- signed short mybuffer[44100*400+10];
- unsigned int myoffset_bytes=0;
- signed char F_CALLBACKAPI instrument_callback(FSOUND_STREAM *stream, void *buff, int len, void *param);
- int copie_Sample_Micro_vers_ring_buffer_micro();
- //DEBUT DU MAIN
- int main(int argc, char *argv[])
- {
- signed char key;
- int driver, i, channel, originalfreq;
- if (FSOUND_GetVersion() < FMOD_VERSION)
- {
- printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION);
- return 0;
- }
- /*
- SELECT OUTPUT METHOD
- */
- printf("---------------------------------------------------------\n" );
- printf("Output Type\n" );
- printf("---------------------------------------------------------\n" );
- #if defined(WIN32) || defined(_WIN64) || defined(__CYGWIN32__) || defined(__WATCOMC__)
- printf("1 - Direct Sound\n" );
- printf("2 - Windows Multimedia Waveout\n" );
- printf("3 - NoSound\n" );
- #elif defined(__linux__)
- printf("1 - OSS - Open Sound System\n" );
- printf("2 - ESD - Elightment Sound Daemon\n" );
- printf("3 - ALSA 0.9 - Advanced Linux Sound Architecture\n" );
- #endif
- printf("---------------------------------------------------------\n" ); /* print driver names */
- printf("Press a corresponding number or ESC to quit\n" );
-
- do
- {
- key = getch();
- }
- while (key != 27 && key < '1' && key > '4');
-
- switch (key)
- {
- #if defined(WIN32) || defined(_WIN64) || defined(__CYGWIN32__) || defined(__WATCOMC__)
- case '1' : FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
- break;
- case '2' : FSOUND_SetOutput(FSOUND_OUTPUT_WINMM);
- break;
- case '3' : FSOUND_SetOutput(FSOUND_OUTPUT_NOSOUND);
- break;
- #elif defined(__linux__)
- case '1' : FSOUND_SetOutput(FSOUND_OUTPUT_OSS);
- break;
- case '2' : FSOUND_SetOutput(FSOUND_OUTPUT_ESD);
- break;
- case '3' : FSOUND_SetOutput(FSOUND_OUTPUT_ALSA);
- break;
- #endif
- default : return 0;
- }
-
- /*
- SELECT OUTPUT DRIVER
- */
-
- /* The following list are the drivers for the output method selected above. */
- printf("---------------------------------------------------------\n" );
- switch (FSOUND_GetOutput())
- {
- case FSOUND_OUTPUT_NOSOUND: printf("NoSound" ); break;
- case FSOUND_OUTPUT_WINMM: printf("Windows Multimedia Waveout" ); break;
- case FSOUND_OUTPUT_DSOUND: printf("Direct Sound" ); break;
- case FSOUND_OUTPUT_OSS: printf("Open Sound System" ); break;
- case FSOUND_OUTPUT_ESD: printf("Enlightment Sound Daemon" ); break;
- case FSOUND_OUTPUT_ALSA: printf("ALSA" ); break;
- };
- printf(" Driver list\n" );
- printf("---------------------------------------------------------\n" );
-
- for (i=0; i < FSOUND_GetNumDrivers(); i++)
- {
- printf("%d - %s\n", i+1, FSOUND_GetDriverName(i)); /* print driver names */
- }
- printf("---------------------------------------------------------\n" ); /* print driver names */
- printf("Press a corresponding number or ESC to quit\n" );
-
- do
- {
- key = getch();
- if (key == 27)
- {
- FSOUND_Close();
- return 0;
- }
- driver = key - '1';
- }
- while (driver < 0 || driver >= FSOUND_GetNumDrivers());
-
- FSOUND_SetDriver(driver); /* Select sound card (0 = default) */
-
- /*
- SELECT MIXER
- */
-
- FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT);
-
- /*
- INITIALIZE
- */
- if (!FSOUND_Init(OUTPUTRATE, 64, FSOUND_INIT_ACCURATEVULEVELS))
- {
- printf("Error!\n" );
- printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
- return 0;
- }
-
-
- /*
- SELECT INPUT DRIVER (can be done before or after init)
- */
-
- /* The following list are the drivers for the output method selected above. */
- printf("---------------------------------------------------------\n" );
- switch (FSOUND_GetOutput())
- {
- case FSOUND_OUTPUT_NOSOUND: printf("NoSound" ); break;
- case FSOUND_OUTPUT_WINMM: printf("Windows Multimedia Waveout" ); break;
- case FSOUND_OUTPUT_DSOUND: printf("Direct Sound" ); break;
- case FSOUND_OUTPUT_OSS: printf("Open Sound System" ); break;
- case FSOUND_OUTPUT_ESD: printf("Enlightment Sound Daemon" ); break;
- case FSOUND_OUTPUT_ALSA: printf("ALSA" ); break;
- };
- printf(" Recording device driver list\n" );
- printf("---------------------------------------------------------\n" );
-
- for (i=0; i < FSOUND_Record_GetNumDrivers(); i++)
- {
- printf("%d - %s\n", i+1, FSOUND_Record_GetDriverName(i)); /* print driver names */
- }
- printf("---------------------------------------------------------\n" ); /* print driver names */
- printf("Press a corresponding number or ESC to quit\n" );
-
- do
- {
- key = getch();
- if (key == 27)
- return 0;
- driver = key - '1';
- }
- while (driver < 0 || driver >= FSOUND_Record_GetNumDrivers());
-
- if (!FSOUND_Record_SetDriver(driver)) /* Select input sound card (0 = default) */
- {
- printf("Error!\n" );
- printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
- FSOUND_Close();
- return 0;
- }
-
- /*
- DISPLAY HELP
- */
-
- printf("FSOUND Output Method : " );
- switch (FSOUND_GetOutput())
- {
- case FSOUND_OUTPUT_NOSOUND: printf("FSOUND_OUTPUT_NOSOUND\n" ); break;
- case FSOUND_OUTPUT_WINMM: printf("FSOUND_OUTPUT_WINMM\n" ); break;
- case FSOUND_OUTPUT_DSOUND: printf("FSOUND_OUTPUT_DSOUND\n" ); break;
- case FSOUND_OUTPUT_OSS: printf("FSOUND_OUTPUT_OSS\n" ); break;
- case FSOUND_OUTPUT_ESD: printf("FSOUND_OUTPUT_ESD\n" ); break;
- case FSOUND_OUTPUT_ALSA: printf("FSOUND_OUTPUT_ALSA\n" ); break;
- };
-
- printf("FSOUND Mixer : " );
- switch (FSOUND_GetMixer())
- {
- case FSOUND_MIXER_BLENDMODE: printf("FSOUND_MIXER_BLENDMODE\n" ); break;
- case FSOUND_MIXER_MMXP5: printf("FSOUND_MIXER_MMXP5\n" ); break;
- case FSOUND_MIXER_MMXP6: printf("FSOUND_MIXER_MMXP6\n" ); break;
- case FSOUND_MIXER_QUALITY_FPU: printf("FSOUND_MIXER_QUALITY_FPU\n" ); break;
- case FSOUND_MIXER_QUALITY_MMXP5:printf("FSOUND_MIXER_QUALITY_MMXP5\n" ); break;
- case FSOUND_MIXER_QUALITY_MMXP6:printf("FSOUND_MIXER_QUALITY_MMXP6\n" ); break;
- };
- printf("FSOUND Driver : %s\n", FSOUND_GetDriverName(FSOUND_GetDriver()));
- printf("FSOUND Record Driver : %s\n", FSOUND_Record_GetDriverName(FSOUND_Record_GetDriver()));
-
- // My stream for my synthetiseur circuit (wich need to be feeded by the micro)
- stream = FSOUND_Stream_Create(instrument_callback, BufferSize, FSOUND_16BITS | FSOUND_SIGNED | FSOUND_STEREO |FSOUND_NONBLOCKING, Frequency, (void *)NULL);
- if (!stream)
- {
- printf("Error!\n" );
- printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
- exit(1);
- }
- // Play the synthetiseur channel cause we wanna hear some good sounds
- if (FSOUND_Stream_Play(FSOUND_FREE, stream) == -1) {printf("Error!\n" );printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));exit(1);}
-
- /*
- Create a sample to record into
- */
- if (FSOUND_GetOutput() == FSOUND_OUTPUT_OSS)
- {
- samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_MONO | FSOUND_8BITS | FSOUND_UNSIGNED, RECORDRATE, 255, 128, 255);
- }
- else
- {
- samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_STEREO | FSOUND_16BITS , RECORDRATE, 255, 128, 255);
- }
-
- printf("\n" );
- printf("=========================================================================\n" );
- printf("Press a key to start recording 5 seconds worth of data\n" );
- printf("=========================================================================\n" );
-
- if (!FSOUND_Record_StartSample(samp1, FALSE)) /* it will record into this sample for 5 seconds then stop */
- {
- printf("Error!\n" );
- printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
- FSOUND_Close();
- return 0;
- }
-
-
- FSOUND_Sample_SetMode(samp1, FSOUND_LOOP_NORMAL); /* make it a looping sample */
- if (!FSOUND_Record_StartSample(samp1, TRUE)) /* start recording and make it loop also */
- {
- printf("Error!\n" );
- printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
-
- FSOUND_Close();
- return 0;
- }
- while(1);
- FSOUND_StopSound(channel);
- FSOUND_Record_Stop();
- FSOUND_Sample_Free(samp1);
- FSOUND_Close();
- return 0;
- // FIN DU MAIN
- }
- // This Came From Brett, The super man of Fmod
- // Retour : Position a jouer (car dernier morceau copie)
- int copie_Sample_Micro_vers_ring_buffer_micro()
- {
- static int oldposition = 0;
- int newposition = FSOUND_Record_GetPosition();
- int offs=0;
- if (newposition != oldposition)
- {
- void *ptr1, *ptr2;
- unsigned int len1, len2;
- int length = newposition - oldposition;
- if (length < 0) // new position might have wrapped around to 0!
- {
- length += FSOUND_Sample_GetLength(samp1);
- }
- FSOUND_Sample_Lock(samp1, oldposition * 4, length * 4, &ptr1, &ptr2, &len1, &len2); // *4 = 16bit stereo
-
- offs=myoffset_bytes;
- if (myoffset_bytes + len1 <= mylength_bytes)
- {
- memcpy(mybuffer + myoffset_bytes, ptr1, len1);
- myoffset_bytes += len1;
- }
- else
- {
- // mybuffer wraps around
- memcpy(mybuffer + myoffset_bytes, ptr1, mylength_bytes - myoffset_bytes);
- // memcpy(mybuffer, ptr1 + (mylength_bytes - myoffset_bytes), len1 - (mylength_bytes - myoffset_bytes));
- memcpy(mybuffer,
- (signed short*)ptr1 + (mylength_bytes - myoffset_bytes),
- len1 - (mylength_bytes - myoffset_bytes)
- );
-
- myoffset_bytes += len1;
- myoffset_bytes -= mylength_bytes;
- }
-
- if (len2)
- {
- if (myoffset_bytes + len2 <= mylength_bytes)
- {
- memcpy(mybuffer + myoffset_bytes, ptr2, len2);
- myoffset_bytes += len2;
- }
- else
- {
- // mybuffer wraps around
- memcpy(mybuffer + myoffset_bytes, ptr2, mylength_bytes - myoffset_bytes);
- memcpy(mybuffer, (signed short*)ptr2 + (mylength_bytes - myoffset_bytes), len2 - (mylength_bytes - myoffset_bytes));
-
- myoffset_bytes += len2;
- myoffset_bytes -= mylength_bytes;
- }
- }
-
- FSOUND_Sample_Unlock(samp1, ptr1, ptr2, len1, len2);
-
- oldposition += length;
- if (oldposition >= FSOUND_Sample_GetLength(samp1) )
- {
- oldposition -= FSOUND_Sample_GetLength(samp1);
- }
- }
- return(offs);
- }
-
- signed char F_CALLBACKAPI instrument_callback(FSOUND_STREAM *stream, void *buff, int len, void *param) {
- {
- static float MX=0;
- signed short *stereo16bitbuffer = (signed short *)buff;
- static float t=0,dx=0;
- int i=0;
- int channel=0;
- // I do it there to be sure of the sync, it seem to work not less than if that were in main ...
- int offs = copie_Sample_Micro_vers_ring_buffer_micro();
- float osc_result= 0;
- for (float x=0;x<len>>2;x++)
- {
- t++;
- // Obtain actual micro value (to normally give it to synth but not there)
- MICRO_INPUT = (signed short)mybuffer[(int)offs];
- // Here normally i generate sound with my synthesizer class, but i brief a lot ...
- //osc_result=(float)(rand()%100)/100; // For Tv like Noise
- osc_result=sin(t*2*PI/180); // For Sinusoidal VCO
-
-
- // I modulate the Synth signal with MicroInput in this exemple (AM)
- *stereo16bitbuffer = ((float)MICRO_INPUT/32767)*(osc_result*32767);
- *(stereo16bitbuffer+1) =((float)MICRO_INPUT/32767)*(osc_result*32767);
-
- // Fait avancer le ring buffer du micro et evite le depassement (ring buffer offset++)
- offs+=2;
- if((offs >= mylength_bytes) && (offs < 0) )
- {
- offs = 0;
- }
- stereo16bitbuffer+=2;
- }
- }
- return(1);
- }
|
Message édité par l3eleg le 24-05-2006 à 13:37:47
|