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

  FORUM HardWare.fr
  Programmation
  C++

  moteur audio

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

moteur audio

n°1528430
gabuzomeuh​2
Posté le 14-03-2007 à 15:07:19  profilanswer
 

bonjour  
 
j'ai ecrit un moteur audio temps reel pour faire du traitement de signal en direct. J'ai ajouté un SetThreadPriority pour chaque procédure In et Out mais ca ne change rien, quand la fenêtre est réduite ou restaurée, il y a une courte interruption du processus. Quelqu'un a une piste ?
 

Code :
  1. #include <windows.h>
  2. #include "stdafx.h"
  3. #include "resource.h"
  4. #include <mmsystem.h>
  5. #include <malloc.h>
  6. #include <stdio.h>
  7. #include <commctrl.h>
  8. #define BUFFER_SIZE 16384
  9. #define SAMPLERATE 44100
  10. #define CANAUX 2
  11. #define OCTETS 2
  12. HWND DlgMain;
  13. PBYTE Buffer;
  14. HWAVEIN hWaveIn;
  15. HWAVEOUT hWaveOut;
  16. PBYTE pBufferIn1, pBufferIn2, pBufferIn3, pBufferOut1, pBufferOut2, pBufferOut3;
  17. PWAVEHDR pWaveHdrIn1, pWaveHdrIn2, pWaveHdrIn3, pWaveHdrOut1, pWaveHdrOut2, pWaveHdrOut3;
  18. WAVEFORMATEX waveform;
  19. BOOL flag_in_open = FALSE;
  20. BOOL flag_out_open = FALSE;
  21. HANDLE WorkerThreadHandleIn;
  22. DWORD WorkerThreadIdIn;
  23. HANDLE WorkerThreadHandleOut;
  24. DWORD WorkerThreadIdOut;
  25. //****************************************************************************
  26. DWORD WINAPI WorkerThreadProcIn (void *Arg)
  27. {
  28.   SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
  29.   MSG Msg;
  30.   while (GetMessage (&Msg, NULL, 0, 0) == TRUE)
  31.    {
  32.     switch (Msg.message)
  33.      {
  34.       case MM_WIM_OPEN:
  35.        {
  36.         MessageBox(DlgMain,"In open","RTA",MB_OK);
  37.         flag_in_open = TRUE;
  38.         waveInAddBuffer(hWaveIn,pWaveHdrIn1,sizeof(WAVEHDR));
  39.         waveInAddBuffer(hWaveIn,pWaveHdrIn2,sizeof(WAVEHDR));
  40.         waveInAddBuffer(hWaveIn,pWaveHdrIn3,sizeof(WAVEHDR));
  41.         waveInStart(hWaveIn);   
  42.         break;
  43.        }
  44.       case MM_WIM_DATA:
  45.        {
  46.         WAVEHDR *Hdr = (WAVEHDR *)Msg.lParam;
  47.         CopyMemory(Buffer,Hdr->lpData,BUFFER_SIZE);
  48.         waveInAddBuffer (hWaveIn, Hdr, sizeof (*Hdr));
  49.         break;
  50.        }
  51.      }
  52.    }
  53.   return 0;  
  54. }
  55. //****************************************************************************
  56. DWORD WINAPI WorkerThreadProcOut (void *Arg)
  57. {
  58.   SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
  59.   MSG Msg;
  60.   while (GetMessage (&Msg, NULL, 0, 0) == TRUE)
  61.    {
  62.     switch (Msg.message)
  63.      {
  64.       case MM_WOM_OPEN:
  65.        {
  66.         MessageBox(DlgMain,"Out open","RTA",MB_OK);
  67.         flag_out_open = TRUE;
  68.         waveOutPrepareHeader(hWaveOut,pWaveHdrOut1,sizeof(WAVEHDR));
  69.         waveOutWrite(hWaveOut,pWaveHdrOut1,sizeof(WAVEHDR));
  70.         waveOutPrepareHeader(hWaveOut,pWaveHdrOut2,sizeof(WAVEHDR));
  71.         waveOutWrite(hWaveOut,pWaveHdrOut2,sizeof(WAVEHDR));
  72.         waveOutPrepareHeader(hWaveOut,pWaveHdrOut3,sizeof(WAVEHDR));
  73.         waveOutWrite(hWaveOut,pWaveHdrOut3,sizeof(WAVEHDR));
  74.         break;
  75.        }
  76.       case MM_WOM_DONE:
  77.        {
  78.         WAVEHDR *Hdr = (WAVEHDR *)Msg.lParam;
  79.         waveOutPrepareHeader (hWaveOut, Hdr, sizeof (*Hdr));
  80.         waveOutWrite (hWaveOut, Hdr, sizeof (*Hdr));
  81.         CopyMemory(Hdr->lpData,Buffer,BUFFER_SIZE);
  82.         break;
  83.        }
  84.      }
  85.    }
  86.   return 0;  
  87. }
  88. //****************************************************************************
  89. BOOL CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  90. {   
  91.   static int volume_general;
  92.   if (msg == WM_INITDIALOG)
  93.    {
  94.     DlgMain = hWnd;
  95.     return 0;
  96.    }
  97.   if (msg == WM_COMMAND)
  98.    {
  99.     if (wParam == ID_START)
  100.      {
  101.       if(flag_in_open == TRUE)
  102.        {
  103.         MessageBox(hWnd,"périphérique déjà ouvert","Erreur",0);
  104.         return 0;
  105.        }
  106.        
  107.       WorkerThreadHandleIn = CreateThread (NULL, 0, WorkerThreadProcIn, NULL, 0, &WorkerThreadIdIn );
  108.       WorkerThreadHandleOut = CreateThread (NULL, 0, WorkerThreadProcOut, NULL, 0, &WorkerThreadIdOut );
  109.       pWaveHdrIn1 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  110.       pWaveHdrIn2 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  111.       pWaveHdrIn3 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  112.       pWaveHdrOut1 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  113.       pWaveHdrOut2 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  114.       pWaveHdrOut3 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  115.        
  116.       Buffer   = (PBYTE)malloc(BUFFER_SIZE);
  117.       pBufferIn1 = (PBYTE)malloc(BUFFER_SIZE);
  118.       pBufferIn2 = (PBYTE)malloc(BUFFER_SIZE);
  119.       pBufferIn3 = (PBYTE)malloc(BUFFER_SIZE);
  120.       pBufferOut1 = (PBYTE)malloc(BUFFER_SIZE);
  121.       pBufferOut2 = (PBYTE)malloc(BUFFER_SIZE);
  122.       pBufferOut3 = (PBYTE)malloc(BUFFER_SIZE);
  123.      
  124.       if(!pBufferIn1 || !pBufferIn2 || !pBufferIn3 || !pBufferOut1 || !pBufferOut2 || !pBufferOut3)
  125.        {
  126.         if(pBufferIn1) free (pBufferIn1);
  127.         if(pBufferIn2) free (pBufferIn2);
  128.         if(pBufferIn3) free (pBufferIn3);
  129.         if(pBufferOut1) free (pBufferOut1);
  130.         if(pBufferOut2) free (pBufferOut2);
  131.         if(pBufferOut3) free (pBufferOut3);
  132.         MessageBox(hWnd,"Erreur d'allocation de mémoire","Erreur",0);
  133.         return TRUE;
  134.        }     
  135.      
  136.       waveform.nChannels = CANAUX; // 1 pour mono 2 pour stereo
  137.       waveform.wBitsPerSample = 8 * OCTETS; // 8 ou 16 bit
  138.       waveform.nAvgBytesPerSec = SAMPLERATE * waveform.nChannels * waveform.wBitsPerSample/8; // nombre d'octets par seconde
  139.       waveform.wFormatTag = 1; // 1 pour PCM
  140.       waveform.nSamplesPerSec = SAMPLERATE; // frequence d'echantillonnage
  141.       waveform.nBlockAlign = 1;
  142.       waveform.cbSize = 0;
  143.       if(waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)WorkerThreadIdIn,0,CALLBACK_THREAD))
  144.        {
  145.         free(pBufferIn1);
  146.         free(pBufferIn2);
  147.         free(pBufferIn3);
  148.         MessageBox(hWnd,"ouverture du périphérique d'entrée impossible","WARNING",MB_OK);
  149.         return 0;
  150.        }
  151.       pWaveHdrIn1->lpData          = (LPSTR)pBufferIn1;
  152.       pWaveHdrIn1->dwBufferLength  = BUFFER_SIZE;
  153.       pWaveHdrIn1->dwBytesRecorded = 0;
  154.       pWaveHdrIn1->dwUser          = 0;
  155.       pWaveHdrIn1->dwFlags         = 0;
  156.       pWaveHdrIn1->dwLoops         = 0;
  157.       pWaveHdrIn1->lpNext          = NULL;
  158.       pWaveHdrIn1->reserved        = 0;     
  159.       waveInPrepareHeader(hWaveIn,pWaveHdrIn1,sizeof(WAVEHDR));
  160.      
  161.       pWaveHdrIn2->lpData          = (LPSTR)pBufferIn2;
  162.       pWaveHdrIn2->dwBufferLength  = BUFFER_SIZE;
  163.       pWaveHdrIn2->dwBytesRecorded = 0;
  164.       pWaveHdrIn2->dwUser          = 0;
  165.       pWaveHdrIn2->dwFlags         = 0;
  166.       pWaveHdrIn2->dwLoops         = 0;
  167.       pWaveHdrIn2->lpNext          = NULL;
  168.       pWaveHdrIn2->reserved        = 0;     
  169.       waveInPrepareHeader(hWaveIn,pWaveHdrIn2,sizeof(WAVEHDR));
  170.       pWaveHdrIn3->lpData          = (LPSTR)pBufferIn3;
  171.       pWaveHdrIn3->dwBufferLength  = BUFFER_SIZE;
  172.       pWaveHdrIn3->dwBytesRecorded = 0;
  173.       pWaveHdrIn3->dwUser          = 0;
  174.       pWaveHdrIn3->dwFlags         = 0;
  175.       pWaveHdrIn3->dwLoops         = 0;
  176.       pWaveHdrIn3->lpNext          = NULL;
  177.       pWaveHdrIn3->reserved        = 0;     
  178.       waveInPrepareHeader(hWaveIn,pWaveHdrIn3,sizeof(WAVEHDR));       
  179.       if(waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)WorkerThreadIdOut,0,CALLBACK_THREAD))
  180.        {
  181.         free(pBufferOut1);
  182.         free(pBufferOut2);
  183.         free(pBufferOut3);
  184.         MessageBox(hWnd,"ouverture du périphérique de sortie impossible","WARNING",MB_OK);
  185.         return 0;
  186.        }     
  187.       pWaveHdrOut1->lpData = (LPSTR)pBufferOut1;
  188.       pWaveHdrOut1->dwBufferLength = BUFFER_SIZE;
  189.       pWaveHdrOut1->dwBytesRecorded = 0;
  190.       pWaveHdrOut1->dwUser = 0;
  191.       pWaveHdrOut1->dwFlags = 0;
  192.       pWaveHdrOut1->dwLoops = 0;
  193.       pWaveHdrOut1->lpNext = NULL;
  194.       pWaveHdrOut1->reserved = 0;     
  195.       waveOutPrepareHeader(hWaveOut,pWaveHdrOut1,sizeof(WAVEHDR));
  196.      
  197.       pWaveHdrOut2->lpData = (LPSTR)pBufferOut2;
  198.       pWaveHdrOut2->dwBufferLength = BUFFER_SIZE;
  199.       pWaveHdrOut2->dwBytesRecorded = 0;
  200.       pWaveHdrOut2->dwUser = 0;
  201.       pWaveHdrOut2->dwFlags = 0;
  202.       pWaveHdrOut2->dwLoops = 0;
  203.       pWaveHdrOut2->lpNext = NULL;
  204.       pWaveHdrOut2->reserved = 0;     
  205.       waveOutPrepareHeader(hWaveOut,pWaveHdrOut2,sizeof(WAVEHDR));
  206.      
  207.       pWaveHdrOut3->lpData =(LPSTR)pBufferOut3;
  208.       pWaveHdrOut3->dwBufferLength =BUFFER_SIZE;
  209.       pWaveHdrOut3->dwBytesRecorded =0;
  210.       pWaveHdrOut3->dwUser =0;
  211.       pWaveHdrOut3->dwFlags =0;
  212.       pWaveHdrOut3->dwLoops =0;
  213.       pWaveHdrOut3->lpNext =NULL;
  214.       pWaveHdrOut3->reserved =0;     
  215.       waveOutPrepareHeader(hWaveOut,pWaveHdrOut3,sizeof(WAVEHDR));       
  216.       return 0;
  217.      }
  218.     if (wParam == IDCANCEL)
  219.      {
  220.       if(MessageBox(hWnd, "Voulez-vous vraiment arrêter l'application en cours ?", "Real Time Audio",MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2) == IDNO)
  221.        {
  222.         return TRUE;
  223.        }
  224.       EndDialog(hWnd, 0);
  225.       return 0;
  226.      }
  227.    }
  228.   return 0;
  229. }
  230. //****************************************************************************
  231.  
  232. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  233. {
  234.   InitCommonControls();
  235.   DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),HWND_DESKTOP,DlgProc);
  236.   return 0;
  237. }
  238. //****************************************************************************

mood
Publicité
Posté le 14-03-2007 à 15:07:19  profilanswer
 

n°1528605
karlkox
Posté le 14-03-2007 à 18:58:48  profilanswer
 

Hésite pas a augmenter ton buffer_size, je le fixera à 65536.
De plus, je ferais un sleep entre chaque filling de buffer tant que celui ci n'a pas son flag à WHDR_DONE.

n°1528640
gabuzomeuh​2
Posté le 14-03-2007 à 20:53:39  profilanswer
 

merci je vais essayer
65536 c'est super long comme retatd c'est plus vraiment du temps reel  :) Y' a pas mieux comme solution ?
 

karlkox a écrit :

Hésite pas a augmenter ton buffer_size, je le fixera à 65536.
De plus, je ferais un sleep entre chaque filling de buffer tant que celui ci n'a pas son flag à WHDR_DONE.


n°1528661
karlkox
Posté le 14-03-2007 à 21:57:01  profilanswer
 

Déjà, ce que tu peux faire, c'est un tableau de WAVEHDR, dans ton thread, tu incrémenteras une variable (à locker) qui indiquera le buffer en cours de traitement, tu pourras ainsi pointer sur le bon WAVEHDR, tu l'écrit sur le device puis tu attends que son flag soit sur WHDR_DONE.
C'est ce que fait la SDL (je me suis basé la dessus) et ça a réglé le même problème que le tient que j'ai eu. (mais j'ai du augmenter le buffer size, driver creative inside ...)

n°1528668
Ace17
Posté le 14-03-2007 à 22:10:27  profilanswer
 

C'est quoi le probleme avec les drivers creative rapport a la latence?

n°1528679
karlkox
Posté le 14-03-2007 à 22:31:40  profilanswer
 

Disons que Creative fait du bon matos mais que niveau ingénierie logiciel, ils peuvent mieux faire, ce n'est pas à la hauteur du matos qu'ils font en tout cas.

n°1528680
gabuzomeuh​2
Posté le 14-03-2007 à 22:33:45  profilanswer
 

bon bah moi en attendant je reécris comme tu as indiqué et je mettrais le nouveau code ici.

n°1528682
Ace17
Posté le 14-03-2007 à 22:41:39  profilanswer
 

J'aurais aime une reponse plus precise, car je fais de l'acquisition audio sur une carte creative avec une precision temporelle de l'ordre de la milliseconde avec un buffer de 96 echantillons, et ca marche plutot pas mal. Quelles sont les tares cachees du driver ?

n°1528688
karlkox
Posté le 14-03-2007 à 22:56:31  profilanswer
 

J'ai une Creative moi aussi et je tape dans du 2ms sans problème, ce n'est pas forcément un problème de latence mais un problème plus global : stabilité, grésillement possible, impossibilité de reprogrammer le spu sans passer par un sdk (qui n'est fournis que si on fait partis d'une grosse boite de dev).

n°1528689
Ace17
Posté le 14-03-2007 à 23:00:01  profilanswer
 

oui, maintenant que tu le dis, une fois sur dix environ, j'ai une acquisition qui foire, et a place du joli bip de reference que je suis cense enregistrer, j'ai des gresillements. Ca viendrait donc du driver ?

mood
Publicité
Posté le 14-03-2007 à 23:00:01  profilanswer
 

n°1528690
karlkox
Posté le 14-03-2007 à 23:11:15  profilanswer
 

Le problème de grésillement est assez récurant chez Creative malheureusement SAUF sur la X-Fi Elite Pro (que j'ai).

n°1529734
gabuzomeuh​2
Posté le 16-03-2007 à 21:41:57  profilanswer
 

Bonjour  
 
Moi je ne comprends pas tres bien comment introduire CreateEvent,  WaitForSingleObject, SetEvent, WHDR_DONE etc... dans mon code.
 
Quelqu'un peut il m'aider svp ?
 
merci

n°1529777
karlkox
Posté le 16-03-2007 à 23:24:40  profilanswer
 

Tu as ce qu'il te faut ici, ça utilise le WaveIn mais ça s'utilise exactement de la même manière pour le WaveOut.

n°1529781
gabuzomeuh​2
Posté le 16-03-2007 à 23:31:55  profilanswer
 

est ce que j'ai le droit de traiter le MM_WIM_DATA et le MM_WOM_DONE par le meme thread ?

n°1529784
bjone
Insert booze to continue
Posté le 16-03-2007 à 23:37:24  profilanswer
 

le directsound serait pas moins pire que le WaveOut ?
 
parceque quand j'entends parler de grésillements, et que je vois que c'est une approche par message, j'ai peur :D

n°1529844
Ace17
Posté le 17-03-2007 à 07:16:21  profilanswer
 

bjone a écrit :

le directsound serait pas moins pire que le WaveOut ?
 
parceque quand j'entends parler de grésillements, et que je vois que c'est une approche par message, j'ai peur :D


Y'a aussi possibilite d'utiliser des vrais callbacks dans WaveOut  

n°1529845
gabuzomeuh​2
Posté le 17-03-2007 à 07:18:11  profilanswer
 

Ah bon ? ca peut etre interessant que tu modifies mon code pour montrer comment
 
merci

n°1529847
Ace17
Posté le 17-03-2007 à 07:25:40  profilanswer
 

La fonction waveOutOpen accepte comme dernier parametre  
CALLBACK_FUNCTION au lieu de CALLBACK_THREAD. cf la msdn

n°1529848
gabuzomeuh​2
Posté le 17-03-2007 à 07:28:05  profilanswer
 

oui je connais CALLBACK_FUNCTION mais le probleme est d'introduire et gerer le partage des ressources avec CreateEvent, WaitForSingleObject, SetEvent, WHDR_DONE etc.

n°1529878
breizhbugs
Posté le 17-03-2007 à 11:26:45  profilanswer
 

Je sais pas si c'est adéquat, mais il y a moyen de trouver des drivers ASIO pour les creatives sur le net...
http://forum.hardware.fr/hfr/Video [...] 8445_1.htm


Message édité par breizhbugs le 17-03-2007 à 11:28:57
n°1529905
karlkox
Posté le 17-03-2007 à 13:54:13  profilanswer
 

gabuzomeuh2 a écrit :

est ce que j'ai le droit de traiter le MM_WIM_DATA et le MM_WOM_DONE par le meme thread ?


 
Oui bien sûr, aucun problème.
 
 
bjone>ce n'est pas tant un problème de driver de sortie son mais un problème d'implémentation de celui ci, il suffit de faire abstraction du driver avant de s'attaquer vraiment à la partie API sonore (dsound, winmm, oal ...).
Perso, j'utilise les threads et aucun problème, ça m'a aussi permis de ne plus avoir ce problème de grésillement qui est dû à une mauvaise synchronisation entre la notification windows et le buffer à remplir.
 
 
breizhbugs>les pilotes ASIO font partis intégrante des pilotes. (CTASIO)


Message édité par karlkox le 17-03-2007 à 13:54:39
n°1533313
gabuzomeuh​2
Posté le 25-03-2007 à 05:35:05  profilanswer
 

Voila j'ai tout réecrit. On dirait que ca marche.
Tu peux me dire ce que tu en penses KarLKox ?
 

Code :
  1. #include <windows.h>
  2. #include "stdafx.h"
  3. #include "resource.h"
  4. #include <mmsystem.h>
  5. #include <malloc.h>
  6. #define TAILLE_BLOC   4096
  7. #define NB_BUFFER     3
  8. #define CANAUX        2
  9. #define OCTETS        2
  10. #define BUFFER_SIZE   CANAUX * OCTETS * TAILLE_BLOC
  11. #define SAMPLERATE    44100
  12. BOOL OpenedIn = FALSE;
  13. HANDLE recordDone;
  14. HWAVEIN hWaveIn;
  15. DWORD threadidIn;
  16. HANDLE RecordHandle;
  17. PWAVEHDR pWaveHeaderIn[NB_BUFFER];
  18. PBYTE pBufferIn[NB_BUFFER];
  19. BOOL OpenedOut = FALSE;
  20. HANDLE playDone;
  21. HWAVEOUT hWaveOut;
  22. DWORD threadidOut;
  23. HANDLE PlayHandle;
  24. PWAVEHDR pWaveHeaderOut[NB_BUFFER];
  25. PBYTE pBufferOut[NB_BUFFER];
  26. char Buffer[BUFFER_SIZE];
  27. HWND DlgMain;
  28. CRITICAL_SECTION CriticalSection;
  29. //****************************************************************************
  30. void copier_buffer(char dest[], char src[], long taille)
  31. {
  32.   __asm
  33.    {
  34.        mov  ecx,   taille
  35.        cmp  ecx,   0
  36.        je   fin
  37.        mov  edi,   dest
  38.        mov  esi,   src
  39. debut: mov  al,    [esi]
  40.        mov  [edi], al
  41.        inc  esi
  42.        inc  edi
  43.        loop debut
  44. fin:       
  45.    }
  46. }
  47. //****************************************************************************
  48. void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
  49. {
  50.   if (uMsg == WIM_OPEN)
  51.    {
  52.     MessageBox(DlgMain,"WIM_OPEN","RTA",MB_OK);
  53.     OpenedIn = TRUE;
  54.    }
  55.   if (uMsg == WIM_CLOSE)
  56.    {
  57.     MessageBox(DlgMain,"WIM_CLOSE","RTA",MB_OK);
  58.    }
  59.   if (uMsg == WIM_DATA)  
  60.    {
  61.     SetEvent(recordDone);     
  62.    }
  63. }
  64. //****************************************************************************
  65. // 01 WHDR_DONE      indique que c'est fini avec ce buffer.
  66. // 02 WHDR_PREPARED  indique que le buffer a ete prepare (waveInPrepareHeader ou waveOutPrepareHeader)
  67. // 04 WHDR_BEGINLOOP indique que ce buffer est le premier dans une boucle, drapeau utilisé seulement en sortie.
  68. // 08 WHDR_ENDLOOP   indique que ce buffer est le dernier dans une boucle. Ce drapeau est utilisé seulement en sortie.
  69. // 10 WHDR_INQUEUE   indique que le buffer est mis en queue pour la sortie.
  70. //****************************************************************************
  71. DWORD WINAPI InThreadProc(LPVOID lpParam)
  72. {   
  73.   int i=0;
  74.   for(;;)
  75.    {
  76.     WaitForSingleObject(recordDone, INFINITE);
  77.     if (!(pWaveHeaderIn[i]->dwFlags & WHDR_DONE)) continue;
  78.      
  79.     EnterCriticalSection(&CriticalSection );
  80.      
  81.     copier_buffer(Buffer, pWaveHeaderIn[i]->lpData, BUFFER_SIZE); // sauvegarder bloc recu
  82.      
  83.     LeaveCriticalSection(&CriticalSection );
  84.     waveInUnprepareHeader(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR));
  85.     pWaveHeaderIn[i]->dwFlags = 0;
  86.     waveInPrepareHeader(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR));
  87.     waveInAddBuffer(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR));
  88.     __asm
  89.      {
  90.       mov eax, i
  91.       mov ebx, NB_BUFFER
  92.       inc eax            // i++
  93.       cmp eax, ebx       // compare i et NB_BUFFER
  94.       jb  fin1           // si i < NB_BUFFER goto fin1
  95.       xor eax, eax       // si i = NB_BUFFER i=0
  96. fin1: mov i,   eax
  97.      }
  98.    }
  99.   waveInReset(hWaveIn);
  100.   waveInClose(hWaveIn);
  101.   MessageBox(DlgMain,"FIN","RTA",MB_OK);
  102.   OpenedIn = FALSE;
  103.   return 0;
  104. }
  105. //****************************************************************************
  106. void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
  107. {
  108.   if (uMsg == WOM_OPEN)
  109.    {
  110.     MessageBox(DlgMain,"WOM_OPEN","RTA",MB_OK);
  111.     OpenedOut = TRUE;
  112.    }
  113.   if (uMsg == WOM_CLOSE)
  114.    {
  115.     MessageBox(DlgMain,"WOM_CLOSE","RTA",MB_OK);
  116.    }
  117.   if (uMsg == WOM_DONE)  
  118.    {
  119.     SetEvent(playDone);     
  120.    }
  121. }
  122. //****************************************************************************
  123. DWORD WINAPI OutThreadProc(LPVOID lpParam)
  124. {   
  125.   int i=0;
  126.   for(;;)
  127.    {
  128.     WaitForSingleObject(playDone, INFINITE);     
  129.     if (!(pWaveHeaderOut[i]->dwFlags & WHDR_DONE)) continue;
  130.      
  131.     copier_buffer(pWaveHeaderOut[i]->lpData, Buffer, BUFFER_SIZE); // reprendre bloc recu
  132.     waveOutUnprepareHeader(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR));
  133.     pWaveHeaderOut[i]->dwFlags = 0;
  134.     waveOutPrepareHeader(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR));
  135.     waveOutWrite(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR));
  136.     __asm
  137.      {
  138.       mov eax, i
  139.       mov ebx, NB_BUFFER
  140.       inc eax            // i++
  141.       cmp eax, ebx       // compare i et NB_BUFFER
  142.       jb  fin1           // si i < NB_BUFFER goto fin1
  143.       xor eax, eax       // si i = NB_BUFFER i=0
  144. fin1: mov i,   eax
  145.      }
  146.    }
  147.   return 0;
  148. }
  149. //****************************************************************************
  150. int openWaveDev()
  151. {
  152.   int i;
  153.   WAVEFORMATEX WaveFormat;
  154.    
  155.   WaveFormat.nChannels = CANAUX; // 1 pour mono 2 pour stereo
  156.   WaveFormat.wBitsPerSample = 8 * OCTETS; // 8 ou 16 bit
  157.   WaveFormat.nAvgBytesPerSec = SAMPLERATE * WaveFormat.nChannels * WaveFormat.wBitsPerSample/8; // nombre d'octets par seconde
  158.   WaveFormat.wFormatTag = 1; // 1 pour PCM
  159.   WaveFormat.nSamplesPerSec = SAMPLERATE; // frequence d'echantillonnage
  160.   WaveFormat.nBlockAlign = 1;
  161.   WaveFormat.cbSize = 0;
  162.   for(i=0; i<NB_BUFFER; i++)
  163.    {
  164.     pWaveHeaderIn[i] = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  165.     pBufferIn[i] = (PBYTE)malloc(BUFFER_SIZE);
  166.    }
  167.    
  168.   InitializeCriticalSection(&CriticalSection);
  169.   if (waveInOpen(&hWaveIn, WAVE_MAPPER, &WaveFormat, (DWORD)waveInProc, (DWORD)&CriticalSection, CALLBACK_FUNCTION))
  170.    {
  171.     MessageBox(DlgMain,"Ouverture périphérique d'entrée impossible","RTA",MB_OK);
  172.     return 0;
  173.    }
  174.   for(i=0; i<NB_BUFFER; i++)
  175.    {
  176.     pWaveHeaderIn[i]->lpData          = (LPSTR)pBufferIn[i];
  177.     pWaveHeaderIn[i]->dwBufferLength  = BUFFER_SIZE;
  178.     pWaveHeaderIn[i]->dwBytesRecorded = 0;
  179.     pWaveHeaderIn[i]->dwUser          = 0;
  180.     pWaveHeaderIn[i]->dwFlags         = 0;
  181.     pWaveHeaderIn[i]->dwLoops         = 0;
  182.     pWaveHeaderIn[i]->lpNext          = NULL;
  183.     pWaveHeaderIn[i]->reserved        = 0;
  184.    }
  185.   for(i=0; i<NB_BUFFER; i++)
  186.    {
  187.     if (waveInPrepareHeader(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR)))
  188.      {
  189.       MessageBox(DlgMain,"Erreur PrepareHeader","RTA",MB_OK);
  190.       return 0;
  191.      }
  192.    }
  193.   for(i=0; i<NB_BUFFER; i++)
  194.    {
  195.     if (waveInAddBuffer(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR)))
  196.      {
  197.       MessageBox(DlgMain,"Erreur AddBuffer","RTA",MB_OK);
  198.       return 0;
  199.      }
  200.    }
  201.   ResetEvent(recordDone);
  202.   if (waveInStart(hWaveIn))
  203.    {
  204.     waveInClose(hWaveIn);
  205.    }
  206. //****
  207.   for(i=0; i<NB_BUFFER; i++)
  208.    {
  209.     pWaveHeaderOut[i] = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  210.     pBufferOut[i] = (PBYTE)malloc(BUFFER_SIZE);
  211.    }
  212.   if (waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFormat, (DWORD)waveOutProc, 0L, CALLBACK_FUNCTION))
  213.    {
  214.     MessageBox(DlgMain,"Ouverture périphérique de sortie impossible","RTA",MB_OK);
  215.     return 0;
  216.    }
  217.   for(i=0; i<NB_BUFFER; i++)
  218.    {
  219.     pWaveHeaderOut[i]->lpData          = (LPSTR)pBufferOut[i];
  220.     pWaveHeaderOut[i]->dwBufferLength  = BUFFER_SIZE;
  221.     pWaveHeaderOut[i]->dwBytesRecorded = 0;
  222.     pWaveHeaderOut[i]->dwUser          = 0;
  223.     pWaveHeaderOut[i]->dwFlags         = 0;
  224.     pWaveHeaderOut[i]->dwLoops         = 0;
  225.     pWaveHeaderOut[i]->lpNext          = NULL;
  226.     pWaveHeaderOut[i]->reserved        = 0;
  227.    }
  228.   for(i=0; i<NB_BUFFER; i++)
  229.    {
  230.     if (waveOutPrepareHeader(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR)))
  231.      {
  232.       MessageBox(DlgMain,"Erreur PrepareHeader","RTA",MB_OK);
  233.       return 0;
  234.      }
  235.    }
  236.   for(i=0; i<NB_BUFFER; i++)
  237.    {
  238.     if (waveOutWrite(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR)))
  239.      {
  240.       MessageBox(DlgMain,"Erreur OutWrite","RTA",MB_OK);
  241.       return 0;
  242.      }
  243.    }
  244.   ResetEvent(playDone);
  245. //*******
  246.   return 0;
  247. }
  248. //****************************************************************************
  249. BOOL CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  250. {
  251.   if (msg == WM_INITDIALOG)
  252.    {
  253.     DlgMain = hWnd;
  254.     return 0;
  255.    }
  256.    
  257.    
  258.    
  259.    
  260.   if (msg == WM_COMMAND)
  261.    {
  262.     if (wParam == IDC_START)
  263.      {
  264.       if(OpenedIn == TRUE)
  265.        {       
  266.         MessageBox(DlgMain,"Déjà ouvert","RTA",MB_OK);
  267.         return 0;
  268.        }       
  269.       SetDlgItemText(DlgMain, IDC_STATIC1, "" );
  270.       recordDone = CreateEvent(0, FALSE, FALSE, 0);
  271.       ResetEvent(recordDone);
  272.       RecordHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InThreadProc, NULL, 0, &threadidIn);
  273.       playDone = CreateEvent(0, FALSE, FALSE, 0);
  274.       ResetEvent(playDone);
  275.       PlayHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OutThreadProc, NULL, 0, &threadidOut);
  276.       openWaveDev();       
  277.       return 0;
  278.      }
  279.    
  280.   if (wParam == IDCANCEL)
  281.      {
  282.       EndDialog(hWnd, 0);
  283.       return 0;
  284.      }
  285.    }
  286.   return 0;
  287. }
  288. //****************************************************************************
  289.  
  290. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  291. {
  292.   HANDLE hMutex;
  293.   hMutex = CreateMutex (NULL,FALSE, "RTA" );
  294.   if (GetLastError() == ERROR_ALREADY_EXISTS)
  295.    {
  296.     MessageBox(NULL,"Ce programme est déjà en service !","WARNING",MB_OK|MB_ICONEXCLAMATION);
  297.     return 0;
  298.    }
  299.   DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),HWND_DESKTOP,DlgProc);
  300.   return 0;
  301. }
  302. //****************************************************************************

n°1533395
Ace17
Posté le 25-03-2007 à 17:59:14  profilanswer
 

Pourquoi diable avoir mis de l'assembleur la dedans? Ensuite cherche du cote de l'instruction "movsb" et meme "rep movsb", ce que tu implementes via une boucle, le processeur sait deja le faire :-)
Et pour finir, un simple memcpy aurait fait l'affaire non?

n°1533439
karlkox
Posté le 25-03-2007 à 21:05:02  profilanswer
 

Ca me parait déjà plus clean et efficient, bon pour la boucle asm, en effet, un memcpy est aussi rapide donc pas besoin de passer par la, à la limite en simd (sse/sse2), histoire de copier plus de bloc par cycle.

n°1533451
gabuzomeuh​2
Posté le 25-03-2007 à 21:59:59  profilanswer
 

En effet ca a l'air plus efficient et il n'y a plus d'interruption de processus quand la Fenetre est reduite ou restaurée.  
Malgré tout, on dirait que le InThreadPRoc et OutThreadProc finissent par se marcher dessus au bout d'un cerain nombre de tours. Qqn a une solution ?

n°1533452
gabuzomeuh​2
Posté le 25-03-2007 à 22:01:35  profilanswer
 

J'aimerai mettre le traitement de WIM_DATA et WOM_DONE dans le mm thread.

mood
Publicité
Posté le   profilanswer
 


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

  moteur audio

 

Sujets relatifs
[Audio][C++] Quelle librairie utiliser pour générer des sons ?Booleen sur Moteur de Recherche ... c'est du SQL ?
moteur de recherche et Flash (UTF8)Choix d'un moteur 3D
Moteur de recherche de bureau (Desktop Search Engine)liens audio dans un texte
[PHP/MySQL] Je sers la Science (moteur cataloguage recherche pdf)synchronisation de la capture audio sur une source de temps externe
Moteur de recherche internemoteur de recherche sans pub
Plus de sujets relatifs à : moteur audio


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