begin process at 2010 02 10 03:18:16
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Multimédia

 > MOTEUR AUDIO TEMPS REEL AVEC GESTION DU VOLUME

MOTEUR AUDIO TEMPS REEL AVEC GESTION DU VOLUME


 Information sur la source

Note :
Aucune note
Catégorie :Multimédia Classé sous :moteur, audio, volume Niveau :Initié Date de création :27/03/2007 Vu / téléchargé :5 788 / 524

Auteur : gabuzomeuh

Ecrire un message privé
Commentaire sur cette source (15)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Permet de faire passer par un buffer l'entrée ligne et l'envoyer à la sortie carte son en réglant le volume.
Suite du développement: equalizer, analyse de spectre

Source

  • // base.cpp
  • #include "stdafx.h"
  • #include "base.h"
  • BOOL OpenedIn = FALSE;
  • HANDLE recordDone;
  • HWAVEIN hWaveIn;
  • DWORD threadidIn;
  • HANDLE RecordHandle;
  • PWAVEHDR pWaveHeaderIn[NB_BUFFER];
  • BOOL OpenedOut = FALSE;
  • HANDLE playDone;
  • HWAVEOUT hWaveOut;
  • DWORD threadidOut;
  • HANDLE PlayHandle;
  • PWAVEHDR pWaveHeaderOut[NB_BUFFER];
  • short Buffer[TAILLE_BLOC * CANAUX];
  • HWND DlgMain;
  • CRITICAL_SECTION CriticalSection;
  • int volume_general; // 0 a 1000
  • //****************************************************************************
  • void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
  • {
  • if (uMsg == WIM_OPEN)
  • {
  • MessageBox(DlgMain,"WIM_OPEN","RTA",MB_OK);
  • OpenedIn = TRUE;
  • }
  • if (uMsg == WIM_CLOSE)
  • {
  • MessageBox(DlgMain,"WIM_CLOSE","RTA",MB_OK);
  • }
  • if (uMsg == WIM_DATA)
  • {
  • SetEvent(recordDone);
  • }
  • }
  • //****************************************************************************
  • // 01 WHDR_DONE indique que c'est fini avec ce buffer.
  • // 02 WHDR_PREPARED indique que le buffer a ete prepare (waveInPrepareHeader ou waveOutPrepareHeader)
  • // 04 WHDR_BEGINLOOP indique que ce buffer est le premier dans une boucle, drapeau utilisé seulement en sortie.
  • // 08 WHDR_ENDLOOP indique que ce buffer est le dernier dans une boucle. Ce drapeau est utilisé seulement en sortie.
  • // 10 WHDR_INQUEUE indique que le buffer est mis en queue pour la sortie.
  • //****************************************************************************
  • DWORD WINAPI InThreadProc(LPVOID lpParam)
  • {
  • int wbi=0;
  • __1: WaitForSingleObject(recordDone, INFINITE);
  • if (pWaveHeaderIn[wbi]->dwFlags & WHDR_DONE)
  • {
  • EnterCriticalSection(&CriticalSection);
  • copier_buffer(Buffer, (short *)pWaveHeaderIn[wbi]->lpData, TAILLE_BLOC * CANAUX); // sauvegarder bloc recu
  • waveInUnprepareHeader(hWaveIn, pWaveHeaderIn[wbi], sizeof(WAVEHDR));
  • pWaveHeaderIn[wbi]->dwFlags = 0;
  • waveInPrepareHeader(hWaveIn, pWaveHeaderIn[wbi], sizeof(WAVEHDR));
  • waveInAddBuffer(hWaveIn, pWaveHeaderIn[wbi], sizeof(WAVEHDR));
  • __asm // modulo
  • {
  • mov eax, wbi
  • mov ebx, NB_BUFFER
  • inc eax
  • cmp eax, ebx
  • jb fin1
  • xor eax, eax
  • fin1: mov wbi, eax
  • }
  • LeaveCriticalSection(&CriticalSection );
  • }
  • __asm
  • {
  • jmp __1
  • }
  • waveInReset(hWaveIn);
  • waveInClose(hWaveIn);
  • MessageBox(DlgMain,"FIN","RTA",MB_OK);
  • OpenedIn = FALSE;
  • return 0;
  • }
  • //****************************************************************************
  • void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
  • {
  • if (uMsg == WOM_OPEN)
  • {
  • MessageBox(DlgMain,"WOM_OPEN","RTA",MB_OK);
  • OpenedOut = TRUE;
  • }
  • if (uMsg == WOM_CLOSE)
  • {
  • MessageBox(DlgMain,"WOM_CLOSE","RTA",MB_OK);
  • }
  • if (uMsg == WOM_DONE)
  • {
  • SetEvent(playDone);
  • }
  • }
  • //****************************************************************************
  • DWORD WINAPI OutThreadProc(LPVOID lpParam)
  • {
  • int wbo=0;
  • __1:WaitForSingleObject(playDone, INFINITE);
  • if (pWaveHeaderOut[wbo]->dwFlags & WHDR_DONE)
  • {
  • waveOutUnprepareHeader(hWaveOut, pWaveHeaderOut[wbo], sizeof(WAVEHDR));
  • pWaveHeaderOut[wbo]->dwFlags = 0;
  • regler_volume(Buffer, volume_general, 1000.0, TAILLE_BLOC * CANAUX); // appliquer le volume avant de l'envoyer
  • copier_buffer((short *)pWaveHeaderOut[wbo]->lpData, Buffer, TAILLE_BLOC * CANAUX); // reprendre bloc recu
  • waveOutPrepareHeader(hWaveOut, pWaveHeaderOut[wbo], sizeof(WAVEHDR));
  • waveOutWrite(hWaveOut, pWaveHeaderOut[wbo], sizeof(WAVEHDR));
  • __asm
  • {
  • mov eax, wbo
  • mov ebx, NB_BUFFER
  • inc eax
  • cmp eax, ebx
  • jb fin1
  • xor eax, eax
  • fin1: mov wbo, eax
  • }
  • }
  • __asm
  • {
  • jmp __1
  • }
  • return 0;
  • }
  • //****************************************************************************
  • int OuvrirPeripheriques()
  • {
  • int i;
  • WAVEFORMATEX WaveFormat;
  • WaveFormat.nChannels = CANAUX; // 1 pour mono 2 pour stereo
  • WaveFormat.wBitsPerSample = 16; // 16 bit
  • WaveFormat.nAvgBytesPerSec = SAMPLERATE * WaveFormat.nChannels * WaveFormat.wBitsPerSample/8; // nombre d'octets par seconde
  • WaveFormat.wFormatTag = 1; // 1 pour PCM
  • WaveFormat.nSamplesPerSec = SAMPLERATE; // frequence d'echantillonnage
  • WaveFormat.nBlockAlign = 1;
  • WaveFormat.cbSize = 0;
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • pWaveHeaderIn[i] = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  • }
  • InitializeCriticalSection(&CriticalSection);
  • if (waveInOpen(&hWaveIn, WAVE_MAPPER, &WaveFormat, (DWORD)waveInProc, (DWORD)&CriticalSection, CALLBACK_FUNCTION))
  • {
  • MessageBox(DlgMain,"Ouverture périphérique d'entrée impossible","RTA",MB_OK);
  • return 0;
  • }
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • pWaveHeaderIn[i]->lpData = (LPSTR) malloc(BUFFER_SIZE); // reserve des octets et non des short
  • pWaveHeaderIn[i]->dwBufferLength = BUFFER_SIZE;
  • pWaveHeaderIn[i]->dwBytesRecorded = 0;
  • pWaveHeaderIn[i]->dwUser = 0;
  • pWaveHeaderIn[i]->dwFlags = 0;
  • pWaveHeaderIn[i]->dwLoops = 0;
  • pWaveHeaderIn[i]->lpNext = NULL;
  • pWaveHeaderIn[i]->reserved = 0;
  • }
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • if (waveInPrepareHeader(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR)))
  • {
  • MessageBox(DlgMain,"Erreur waveInPrepareHeader","RTA",MB_OK);
  • return 0;
  • }
  • }
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • if (waveInAddBuffer(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR)))
  • {
  • MessageBox(DlgMain,"Erreur AddBuffer","RTA",MB_OK);
  • return 0;
  • }
  • }
  • ResetEvent(recordDone);
  • if (waveInStart(hWaveIn))
  • {
  • waveInClose(hWaveIn);
  • }
  • //****
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • pWaveHeaderOut[i] = (PWAVEHDR) malloc(sizeof(WAVEHDR));
  • }
  • if (waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFormat, (DWORD)waveOutProc, 0L, CALLBACK_FUNCTION))
  • {
  • MessageBox(DlgMain,"Ouverture périphérique de sortie impossible","RTA",MB_OK);
  • return 0;
  • }
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • pWaveHeaderOut[i]->lpData = (LPSTR) malloc(BUFFER_SIZE); // reserve des octets et non des short
  • pWaveHeaderOut[i]->dwBufferLength = BUFFER_SIZE;
  • pWaveHeaderOut[i]->dwBytesRecorded = 0;
  • pWaveHeaderOut[i]->dwUser = 0;
  • pWaveHeaderOut[i]->dwFlags = 0;
  • pWaveHeaderOut[i]->dwLoops = 0;
  • pWaveHeaderOut[i]->lpNext = NULL;
  • pWaveHeaderOut[i]->reserved = 0;
  • }
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • if (waveOutPrepareHeader(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR)))
  • {
  • MessageBox(DlgMain,"Erreur PrepareHeader","RTA",MB_OK);
  • return 0;
  • }
  • }
  • for(i=0; i<NB_BUFFER; i++)
  • {
  • if (waveOutWrite(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR)))
  • {
  • MessageBox(DlgMain,"Erreur OutWrite","RTA",MB_OK);
  • return 0;
  • }
  • }
  • ResetEvent(playDone);
  • //*******
  • return 0;
  • }
  • //****************************************************************************
  • BOOL CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  • {
  • if (msg == WM_INITDIALOG)
  • {
  • DlgMain = hWnd;
  • char str[128];
  • SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_SETRANGEMAX,0,1000);
  • SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_SETRANGEMIN,0,0);
  • SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_SETPOS,1,0); // volume general a fond
  • volume_general = 1000-SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_GETPOS,0,0);
  • sprintf(str,"volume: %1.1f dB",20*log10(volume_general/1000));
  • SetDlgItemText(hWnd,IDC_STATIC_VOLUME,str);
  • return 0;
  • }
  • if (msg == WM_VSCROLL)
  • {
  • char str[128];
  • volume_general = 1000-SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_GETPOS,0,0);
  • if (volume_general == 0)
  • {
  • sprintf(str,"volume: -oo");
  • SetDlgItemText(hWnd,IDC_STATIC_VOLUME,str);
  • return 0;
  • }
  • sprintf(str,"volume: %1.1f dB", 20*log10(volume_general/1000.0));
  • SetDlgItemText(hWnd,IDC_STATIC_VOLUME,str);
  • return 0;
  • }
  • if (msg == WM_COMMAND)
  • {
  • if (wParam == IDC_START)
  • {
  • if(OpenedIn == TRUE)
  • {
  • MessageBox(DlgMain,"Déjà ouvert","RTA",MB_OK);
  • return 0;
  • }
  • recordDone = CreateEvent(0, FALSE, FALSE, 0);
  • ResetEvent(recordDone);
  • RecordHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InThreadProc, NULL, 0, &threadidIn);
  • playDone = CreateEvent(0, FALSE, FALSE, 0);
  • ResetEvent(playDone);
  • PlayHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OutThreadProc, NULL, 0, &threadidOut);
  • OuvrirPeripheriques();
  • return 0;
  • }
  • if (wParam == IDCANCEL)
  • {
  • EndDialog(hWnd, 0);
  • return 0;
  • }
  • }
  • return 0;
  • }
  • //****************************************************************************
  • int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  • {
  • HANDLE hMutex;
  • hMutex = CreateMutex (NULL,FALSE, "RTA");
  • if (GetLastError() == ERROR_ALREADY_EXISTS)
  • {
  • MessageBox(NULL,"Cette application est déjà présente en mémoire !","WARNING",MB_OK|MB_ICONEXCLAMATION);
  • return 0;
  • }
  • InitCommonControls();
  • DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),HWND_DESKTOP,DlgProc);
  • return 0;
  • }
  • //*******************************************************
// base.cpp

#include "stdafx.h"
#include "base.h"

BOOL OpenedIn = FALSE;
HANDLE recordDone;
HWAVEIN hWaveIn;
DWORD threadidIn;
HANDLE RecordHandle;
PWAVEHDR pWaveHeaderIn[NB_BUFFER];

BOOL OpenedOut = FALSE;
HANDLE playDone;
HWAVEOUT hWaveOut;
DWORD threadidOut;
HANDLE PlayHandle;
PWAVEHDR pWaveHeaderOut[NB_BUFFER];

short Buffer[TAILLE_BLOC * CANAUX];

HWND DlgMain;

CRITICAL_SECTION CriticalSection;
int volume_general;        // 0 a 1000

//****************************************************************************

void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
  if (uMsg == WIM_OPEN)
   {
    MessageBox(DlgMain,"WIM_OPEN","RTA",MB_OK);
    OpenedIn = TRUE;
   }

  if (uMsg == WIM_CLOSE)
   {
    MessageBox(DlgMain,"WIM_CLOSE","RTA",MB_OK);
   }

  if (uMsg == WIM_DATA) 
   {    
    SetEvent(recordDone);    
   }
}

//****************************************************************************
// 01 WHDR_DONE      indique que c'est fini avec ce buffer.
// 02 WHDR_PREPARED  indique que le buffer a ete prepare (waveInPrepareHeader ou waveOutPrepareHeader)
// 04 WHDR_BEGINLOOP indique que ce buffer est le premier dans une boucle, drapeau utilisé seulement en sortie.
// 08 WHDR_ENDLOOP   indique que ce buffer est le dernier dans une boucle. Ce drapeau est utilisé seulement en sortie.
// 10 WHDR_INQUEUE   indique que le buffer est mis en queue pour la sortie.
//****************************************************************************

DWORD WINAPI InThreadProc(LPVOID lpParam)
{  
  int wbi=0;

__1: WaitForSingleObject(recordDone, INFINITE);  
     if (pWaveHeaderIn[wbi]->dwFlags & WHDR_DONE)
      {
       EnterCriticalSection(&CriticalSection);    
       copier_buffer(Buffer, (short *)pWaveHeaderIn[wbi]->lpData, TAILLE_BLOC * CANAUX); // sauvegarder bloc recu
       waveInUnprepareHeader(hWaveIn, pWaveHeaderIn[wbi], sizeof(WAVEHDR));
       pWaveHeaderIn[wbi]->dwFlags = 0;
       waveInPrepareHeader(hWaveIn, pWaveHeaderIn[wbi], sizeof(WAVEHDR));
       waveInAddBuffer(hWaveIn, pWaveHeaderIn[wbi], sizeof(WAVEHDR));

       __asm // modulo
        {
         mov eax, wbi
         mov ebx, NB_BUFFER
         inc eax
         cmp eax, ebx
         jb fin1
         xor eax, eax
   fin1: mov wbi, eax
        }      
       LeaveCriticalSection(&CriticalSection );
      }

     __asm
      {
       jmp __1
      }

  waveInReset(hWaveIn);
  waveInClose(hWaveIn);
  MessageBox(DlgMain,"FIN","RTA",MB_OK);
  OpenedIn = FALSE;
  return 0;
}

//****************************************************************************

void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
  if (uMsg == WOM_OPEN)
   {
    MessageBox(DlgMain,"WOM_OPEN","RTA",MB_OK);
    OpenedOut = TRUE;
   }

  if (uMsg == WOM_CLOSE)
   {
    MessageBox(DlgMain,"WOM_CLOSE","RTA",MB_OK);
   }

  if (uMsg == WOM_DONE) 
   {
    SetEvent(playDone);    
   }
}

//****************************************************************************

DWORD WINAPI OutThreadProc(LPVOID lpParam)
{  
  int wbo=0;

__1:WaitForSingleObject(playDone, INFINITE);    

    if (pWaveHeaderOut[wbo]->dwFlags & WHDR_DONE)
     {      
      waveOutUnprepareHeader(hWaveOut, pWaveHeaderOut[wbo], sizeof(WAVEHDR));
      pWaveHeaderOut[wbo]->dwFlags = 0;
      
      regler_volume(Buffer, volume_general, 1000.0, TAILLE_BLOC * CANAUX); // appliquer le volume avant de l'envoyer
      copier_buffer((short *)pWaveHeaderOut[wbo]->lpData, Buffer, TAILLE_BLOC * CANAUX); // reprendre bloc recu
      waveOutPrepareHeader(hWaveOut, pWaveHeaderOut[wbo], sizeof(WAVEHDR));
      waveOutWrite(hWaveOut, pWaveHeaderOut[wbo], sizeof(WAVEHDR));

      __asm
       {
        mov eax, wbo
        mov ebx, NB_BUFFER
        inc eax
        cmp eax, ebx
        jb  fin1
        xor eax, eax
  fin1: mov wbo, eax
       }

     }

__asm
    {
     jmp __1
    }





  return 0;
}

//****************************************************************************

int OuvrirPeripheriques()
{
  int i;
  WAVEFORMATEX WaveFormat;
  
  WaveFormat.nChannels = CANAUX; // 1 pour mono 2 pour stereo
  WaveFormat.wBitsPerSample = 16; // 16 bit
  WaveFormat.nAvgBytesPerSec = SAMPLERATE * WaveFormat.nChannels * WaveFormat.wBitsPerSample/8; // nombre d'octets par seconde
  WaveFormat.wFormatTag = 1; // 1 pour PCM
  WaveFormat.nSamplesPerSec = SAMPLERATE; // frequence d'echantillonnage
  WaveFormat.nBlockAlign = 1;
  WaveFormat.cbSize = 0;

  for(i=0; i<NB_BUFFER; i++)
   {
    pWaveHeaderIn[i] = (PWAVEHDR) malloc(sizeof(WAVEHDR));
   }
  
  InitializeCriticalSection(&CriticalSection);

  if (waveInOpen(&hWaveIn, WAVE_MAPPER, &WaveFormat, (DWORD)waveInProc, (DWORD)&CriticalSection, CALLBACK_FUNCTION))
   {
    MessageBox(DlgMain,"Ouverture périphérique d'entrée impossible","RTA",MB_OK);
    return 0;
   }

  for(i=0; i<NB_BUFFER; i++)
   {
    pWaveHeaderIn[i]->lpData          = (LPSTR) malloc(BUFFER_SIZE); // reserve des octets et non des short
    pWaveHeaderIn[i]->dwBufferLength  = BUFFER_SIZE;
    pWaveHeaderIn[i]->dwBytesRecorded = 0;
    pWaveHeaderIn[i]->dwUser          = 0;
    pWaveHeaderIn[i]->dwFlags         = 0;
    pWaveHeaderIn[i]->dwLoops         = 0;
    pWaveHeaderIn[i]->lpNext          = NULL;
    pWaveHeaderIn[i]->reserved        = 0;
   }

  for(i=0; i<NB_BUFFER; i++)
   {
    if (waveInPrepareHeader(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR)))
     {
      MessageBox(DlgMain,"Erreur waveInPrepareHeader","RTA",MB_OK);
      return 0;
     }
   }

  for(i=0; i<NB_BUFFER; i++)
   {
    if (waveInAddBuffer(hWaveIn, pWaveHeaderIn[i], sizeof(WAVEHDR)))
     {
      MessageBox(DlgMain,"Erreur AddBuffer","RTA",MB_OK);
      return 0;
     }
   }

  ResetEvent(recordDone);

  if (waveInStart(hWaveIn))
   {
    waveInClose(hWaveIn);
   }



//****
  for(i=0; i<NB_BUFFER; i++)
   {
    pWaveHeaderOut[i] = (PWAVEHDR) malloc(sizeof(WAVEHDR));
   }

  if (waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFormat, (DWORD)waveOutProc, 0L, CALLBACK_FUNCTION))
   {
    MessageBox(DlgMain,"Ouverture périphérique de sortie impossible","RTA",MB_OK);
    return 0;
   }

  for(i=0; i<NB_BUFFER; i++)
   {
    pWaveHeaderOut[i]->lpData          = (LPSTR) malloc(BUFFER_SIZE); // reserve des octets et non des short
    pWaveHeaderOut[i]->dwBufferLength  = BUFFER_SIZE;
    pWaveHeaderOut[i]->dwBytesRecorded = 0;
    pWaveHeaderOut[i]->dwUser          = 0;
    pWaveHeaderOut[i]->dwFlags         = 0;
    pWaveHeaderOut[i]->dwLoops         = 0;
    pWaveHeaderOut[i]->lpNext          = NULL;
    pWaveHeaderOut[i]->reserved        = 0;
   }

  for(i=0; i<NB_BUFFER; i++)
   {
    if (waveOutPrepareHeader(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR)))
     {
      MessageBox(DlgMain,"Erreur PrepareHeader","RTA",MB_OK);
      return 0;
     }
   }

  for(i=0; i<NB_BUFFER; i++)
   {
    if (waveOutWrite(hWaveOut, pWaveHeaderOut[i], sizeof(WAVEHDR)))
     {
      MessageBox(DlgMain,"Erreur OutWrite","RTA",MB_OK);
      return 0;
     }
   }
  ResetEvent(playDone);
//*******


  return 0;
}

//****************************************************************************

BOOL CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (msg == WM_INITDIALOG)
   {
    DlgMain = hWnd;
    
    char str[128];

    SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_SETRANGEMAX,0,1000);
    SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_SETRANGEMIN,0,0);
    SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_SETPOS,1,0); // volume general a fond
    volume_general = 1000-SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_GETPOS,0,0);
    sprintf(str,"volume: %1.1f dB",20*log10(volume_general/1000));
    SetDlgItemText(hWnd,IDC_STATIC_VOLUME,str);

    return 0;
   }




  if (msg == WM_VSCROLL)
   {
    char str[128];

    volume_general = 1000-SendDlgItemMessage(hWnd,IDC_SLIDER_VOLUME,TBM_GETPOS,0,0);    
    if (volume_general == 0)
     {
      sprintf(str,"volume: -oo");
      SetDlgItemText(hWnd,IDC_STATIC_VOLUME,str);
      return 0;
     }
    sprintf(str,"volume: %1.1f dB", 20*log10(volume_general/1000.0));
    SetDlgItemText(hWnd,IDC_STATIC_VOLUME,str);
    return 0;
   }
   
   
   
     
  if (msg == WM_COMMAND)
   {
    if (wParam == IDC_START)
     {
      if(OpenedIn == TRUE)
       {      
        MessageBox(DlgMain,"Déjà ouvert","RTA",MB_OK);
        return 0;
       }
      recordDone = CreateEvent(0, FALSE, FALSE, 0);
      ResetEvent(recordDone);
      RecordHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InThreadProc, NULL, 0, &threadidIn);

      playDone = CreateEvent(0, FALSE, FALSE, 0);
      ResetEvent(playDone);
      PlayHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OutThreadProc, NULL, 0, &threadidOut);

      OuvrirPeripheriques();      
      return 0;
     }
  
    if (wParam == IDCANCEL)
     {
      EndDialog(hWnd, 0);
      return 0;
     }
   }




  return 0;
}

//****************************************************************************

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  HANDLE hMutex;
  hMutex = CreateMutex (NULL,FALSE, "RTA");
  if (GetLastError() == ERROR_ALREADY_EXISTS)
   {
    MessageBox(NULL,"Cette application est déjà présente en mémoire !","WARNING",MB_OK|MB_ICONEXCLAMATION);
    return 0;
   }

  InitCommonControls();
  DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),HWND_DESKTOP,DlgProc);
  return 0;
}

//*******************************************************


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture GÉNÉRATEUR DE SIGNAL BASSE FRÉQUENCE TEMPS RÉEL
Source avec Zip Source avec une capture PLUGIN ECHO POUR WINAMP
MODIFIER LA HAUTEUR DE LA BARRE DE TACHES
Source avec Zip Source avec une capture GÉNÉRATEUR DE FICHIER WAV DE RÉFÉRENCE POUR CD DE TEST
Source avec Zip ICONE DANS BARRE DE TACHES AVEC GESTION DOUBLE CLIC DROIT OU...

 Sources de la même categorie

Source avec Zip Source avec une capture [WIN32] EASY WAVE MIXER par ordiman85
METTRE À JOUR LE TITRE DU MORCEAU EN COURS DANS MSN LIVE par citronz1969
Source avec Zip SUPER MINI MP3 JOUEUR par f_l_a_s_h_b_a_c_k
Source avec Zip MP3 RENAMER par dragonjoker59
Source avec Zip Source avec une capture LECTEUR DE MUSIQUE AVEC SDL ET FMOD par Lemng

 Sources en rapport avec celle ci

Source avec Zip CONVERTIR FLV 2 MP3 par nipepsinicolas
Source avec Zip Source avec une capture LECTEUR DE MUSIQUE AVEC SDL ET FMOD par Lemng
Source avec Zip Source avec une capture CONTROLEUR DE VOLUME SONORE EN C [ API WINDOWS ] par ordiman85
Source avec Zip LINUX MODIFICATION DU VOLUME D'UN MIXER AUDIO par Twinuts
Source avec Zip Source avec une capture CONTROLE DE VOLUME OSD (WIN32) par racpp

Commentaires et avis

Commentaire de BruNews le 27/03/2007 13:13:31 administrateur CS

__asm // modulo
{
  mov eax, wbi
  mov ebx, NB_BUFFER
  inc eax
  cmp eax, ebx
  jb fin1
  xor eax, eax
fin1: mov wbi, eax
}

Explication avec but à obtenir, svp.

Que vient faire ce bout d'asm dans une fonction en C ???
A part empêcher toute optimisation du compilo, je n'en vois pas la raison.
Se souvenir que EBX est à restaurer en sortie de fonction, tu forces donc le "push pop" au compilo.

Commentaire de gabuzomeuh le 27/03/2007 19:06:01


Merci BruNews,

Je suis content que qqn s'intéresse à mon code.
Ce bout d'asm realise un modulo sur un popinteur qui augmente a chaque tout de Thread ça fait la mm chose que:

(wbi++ < NB_BUFFER-1) ? wbi : wbi=0

Ce que je cherche à faire c'est accélerer le traitement des 2 Thread car j'ai l'impression que les 2 Thread se marchent dessus de temps en temps.

Si j'augmente le nombre d'operations dans chaque Thread on finit par perdre des données ou est est-ce plutot à cause d'un mauvais verouillage des données ?

Commentaire de gabuzomeuh le 27/03/2007 19:08:38


Quand tu dis que ce bout d'asm empeche le compilo toute optimisation tu parles du code entier ou juste de la fonction dans laquelle est ce bout d'asm ?

Commentaire de BruNews le 27/03/2007 19:32:18 administrateur CS

Un bout d'ASM au milieu du code C gêne toute optimisation de la fonction.
On peut mettre de l'ASM mais alors on fait la fonction complète en ASM et on préfixe de __declspec(naked) indiquant au compilo de ne pas y toucher.
Je ne vois pas de modulo ici:
__asm // modulo
{
  mov eax, wbi  ; EAX = 0 au 1er tour
  mov ebx, NB_BUFFER ; EBX = 3
  inc eax
  cmp eax, ebx ; if(++EAX < 3) goto fin1
  jb fin1
  xor eax, eax ; EAX = 0
fin1: mov wbi, eax

Tout ceci se réduisait à:
if(++wb1 < 3) goto fin1;
wbi = 0;
le compilo aurait épargné EBX.

copier_buffer() est du même genre, memcpy() direct dans le code gagnerait bien des cycles, pas d'appel de fonction. Ici tu en produis un tout en recopiant le code obsolète de ce bon vieux VC6, à ne jamais refaire.

Commentaire de gabuzomeuh le 27/03/2007 19:44:59


Merci BruNews,

Tu penses que memcpy() qui travaille avec des char est plus rapide que copier_buffer() avec des short ? Si c'est le cas je remplace la fonction.

Dans le zip il y a une fonction qui s'appelle filtrage.cpp mais qui est désactivée dans le code. Quand je l'inclus juste avant regler_volume() ça ralentit grave le traitement. Dois je ajouter un critical section dans le 2e Thread aussi ? Ai-je le droit d'utiliser la mm section critique pour les 2 Thread ?

Commentaire de BruNews le 27/03/2007 20:09:07 administrateur CS

pas le temps de tout analyser, faudrait deja voir si tes CriticalSection sont utiles.

Pourquoi copier par WORD, en DWORD irait PLUS DE 2 FOIS plus vite.
Me seble que tu copies 4096 octets (meme 3eme param) à chaque appel.
En ce cas:
__decspec(naked) void __fastcall bnCopie4096(void *pdst, void *psrc)
{ // ECX = pdst, EDX = psrc
  __asm { // 1204 tours de 4 octets = 4096
    mov [esp-4], ebx
    sub ecx, 4 ;// POUR PARALLELISATION DES INSTRUCTIONS
    mov ebx, 1024
  lCPY:
    mov eax, [edx]
    add ecx, 4
    add edx, 4
    sub ebx, 1
    mov [ecx], eax
    jnz short lCPY
    mov ebx, [esp-4]
    ret 0 ;// RIEN A DEPILER
  }
}
ainsi aucun empilage de param.

Attention qu'on devrait garantir l'alignement des buffers sur un multiple de 4 sinon il y a une erreur d'alignement envoyée par le CPU.
OK sous Windows, c'est réglé par défaut pour que le système rattrape mais serait inacceptable pour du code haute performance.

Commentaire de gabuzomeuh le 27/03/2007 23:03:21

Merci BruNews,

Apparemment VC6 ne connait pas naked, il dit que c'est "undeclared identifier".

Pour copier des DWORD on peut utiliser rep movsd ?



void copier_buffer(void * dest, void * src, int taille)
{  
  __asm
   {
    mov  ecx, taille
    shr  ecx, 2
    mov  edi, dest
    mov  esi, src
    cld  
    rep  movsd
   }
}

Commentaire de BruNews le 28/03/2007 09:13:27 administrateur CS

Je répète: "rep movsd" et toutes autres formes de ces vieilles instructions de chaine sont totalement obsolètes, une boucle comme celle que je t'ai mise plus haut aura un rendement nettement supérieur, il est d'ailleurs aisé de dérouler la boucle pour minimiser le nbr de sauts de code:
  lCPY:
    mov eax, [edx]
    add ecx, 4
    add edx, 4
    sub ebx, 1
    mov [ecx], eax
    jz  short endCPY
    mov eax, [edx]
    add ecx, 4
    add edx, 4
    sub ebx, 1
    mov [ecx], eax
    jz  short endCPY
    mov eax, [edx]
    add ecx, 4
    add edx, 4
    sub ebx, 1
    mov [ecx], eax
    jnz short lCPY
  endCPY:
    mov ebx, [esp-4]
    ret 0

'naked' non reconnu sous VC6, bah je ne me souviens plus.
Pose donc VC++ 2005, son compilo est incomparablement meilleur:
http://www.cppfrance.com/code.aspx?ID=38359

Commentaire de arb le 28/03/2007 10:15:20

Super et très intéressant : le hic : je n'ai pas VCC. Puis je porter tout ça sous DEVCPP sans trop d'encombre ou un autre?
Merci de votre aide.
PS : je viens aussi de voir que tu as un gene de signal et je suis aussi super intéressé bricolant un peu d'électronique et d'interface PC. Est il aussi en VC?

Commentaire de gabuzomeuh le 28/03/2007 14:53:40

Merci BruNews,

Pourquoi faut-il faire un push et pop de EBX a chaque fois ?

Commentaire de BruNews le 28/03/2007 16:39:13 administrateur CS

Hors EAX, ECX et EDX qui sont considérés comme "écrasés", tous les registres sont à restaurer en sortie de fonction.

Commentaire de gabuzomeuh le 28/03/2007 22:01:40


Merci BruNews,

Petite précision quand même quant à l'utilisation de naked.

dans le fichier .h de déclaration de fonction il faut mettre:

int __fastcall copier_buffer(void *  , void * , int);

et dans le fichier .cpp il faut mettre:

__declspec(naked) int __fastcall copier_buffer(void * dest, void * src, int taille)
{  
  __asm
   {
    ...
    ...
   }
}

Commentaire de BruNews le 28/03/2007 22:13:16 administrateur CS

ah bien entendu, excuse mais c'est l'habitude qui fait croire évidentes des choses qui ne le sont pas forcément.

Commentaire de gabuzomeuh le 28/03/2007 22:17:54


Du coup naked ca marche sans problème aussi bien avec VC6 et Visual express c++ 2005

Commentaire de Phenixar le 27/04/2007 16:46:09

Salut,
je viens de voir ta nouvelle source pour le son.
mais j ai encore un soucis :p ... on ne peux pas choisir l'entrée ni la sortie
dans les 2 cas on se base sur ceux selectionnée par default dans windows
Je ne vois pas comment faire pour choisir une entrée bien precise ainsi qu'une sortie.
Si tu as un conseil n'esite pas.
merci.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

controle du volume audio général [ par roxanic ] BonjourJe cherche a controler les bouton de volume.Pour le bouton Wave c'est OK. Mais je ne trouve pas le solution pour le curseur du volume général.M Quelle librairi audio choisir [ par mmaximum ] Salut à tous,Je cherche à faire un petit moteur de jeu 3D, mais je bloque sur le moteur sonore.Est-ce que quelqu'un connait un petit librairi audio po Sélectionner la source audio... [ par MisteryX ] Bonjour à tous,Si j'ai choisi un thème pour poster ma question c'est vraiment parce qu'il le fallait, donc je ne sais pas si j'ai fait le bon choix ?? Capture audio multiple avec directsound [ par CreugenatCoco ] Bonjour à tous et à toutes, je suis assez nouveau en programmation C++, et je dois réaliser une application qui:- detecte les cartes sons installées e PIC 16F877 ET PWM [ par faaffou ] Bonjour, je veux réaliser un programme sur mplab pour générer un signal PWM en utilisant le PIC 16F877 pour faire la variation de vitesse d'un moteur pilote d'unne carte commande d'un moteur pas à pas [ par slach100 ] command je peus crier un programme pour l'instalation materielle d'une carte commande d'un moteur pas à pas Changer le volume d'un WAV par logarithme [ par carat ] Salut à tous, Je suis en train de développer un lecteur bas-niveau afin de pouvoir intégrer des effets sonores. Je supporte actuellement les pcm, le converteur audio (wav) en binaire [ par polobou ] [b]Bonjour[/b][^^happy10] j'ai besoin d'un logiciel qui peut m'aider a converter un "fichier.wav" au code binaire dans un autre "fichier.bin". [b]Merc Besoin d'aide sur developpement de jeu 3D [ par Niggaz ] Bonjour, PRÉSENTATION J'ai 27 ans et cela fait déjà un bon moment que je bosse seul sur la partie programmation d'un jeu. Je n'ai pas les compétenc Séparer les 2 pistes audio d'un fichier mp3 [ par Rogue2575 ] Bonjour, Quelqu'un saurait il séparer les deux pistes mono d'un fichier mp3 stéréo. Je ne peux pas utiliser audacity car il faudrait que cette séparat


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,170 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales