Moteur audio temps reel

Soyez le premier à donner votre avis sur cette source.

Vue 16 070 fois - Téléchargée 4 403 fois

Description

Fonctionnement: le signal en entrée ligne du PC sort directement à la sortie avec un léger retard du au temps de rotation de tous les buffers.

Ce code permet d'effectuer du traitement de signal en temps réel en modifiant le contenu du buffer (Buffer)

Source / Exemple :


#include <windows.h>
#include "stdafx.h"
#include "resource.h"
#include <mmsystem.h>
#include <malloc.h>
#include <stdio.h>
#include <commctrl.h>

#define BUFFER_SIZE 16384
#define SAMPLERATE 44100
#define CANAUX 2
#define OCTETS 2

HWND DlgMain;
PBYTE Buffer;
HWAVEIN hWaveIn;
HWAVEOUT hWaveOut;
PBYTE pBufferIn1, pBufferIn2, pBufferIn3, pBufferOut1, pBufferOut2, pBufferOut3;
PWAVEHDR pWaveHdrIn1, pWaveHdrIn2, pWaveHdrIn3, pWaveHdrOut1, pWaveHdrOut2, pWaveHdrOut3;
WAVEFORMATEX waveform;
BOOL flag_in_open = FALSE;
BOOL flag_out_open = FALSE;

HANDLE WorkerThreadHandleIn;
DWORD WorkerThreadIdIn;
HANDLE WorkerThreadHandleOut;
DWORD WorkerThreadIdOut;

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

DWORD WINAPI WorkerThreadProcIn (void *Arg)
{
  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
  MSG Msg;

  while (GetMessage (&Msg, NULL, 0, 0) == TRUE)
   {
    switch (Msg.message)
     {
      case MM_WIM_OPEN:
       {
        MessageBox(DlgMain,"In open","RTA",MB_OK);
        flag_in_open = TRUE;
        waveInAddBuffer(hWaveIn,pWaveHdrIn1,sizeof(WAVEHDR));
        waveInAddBuffer(hWaveIn,pWaveHdrIn2,sizeof(WAVEHDR));
        waveInAddBuffer(hWaveIn,pWaveHdrIn3,sizeof(WAVEHDR));
        waveInStart(hWaveIn);  
        break;
       }

      case MM_WIM_DATA:
       {
        WAVEHDR *Hdr = (WAVEHDR *)Msg.lParam;
        CopyMemory(Buffer,Hdr->lpData,BUFFER_SIZE);
        waveInAddBuffer (hWaveIn, Hdr, sizeof (*Hdr));
        break;
       }
     }
   }
  return 0; 
}

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

DWORD WINAPI WorkerThreadProcOut (void *Arg)
{
  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
  MSG Msg;

  while (GetMessage (&Msg, NULL, 0, 0) == TRUE)
   {
    switch (Msg.message)
     {
      case MM_WOM_OPEN:
       {
        MessageBox(DlgMain,"Out open","RTA",MB_OK);
        flag_out_open = TRUE;
        waveOutPrepareHeader(hWaveOut,pWaveHdrOut1,sizeof(WAVEHDR));
        waveOutWrite(hWaveOut,pWaveHdrOut1,sizeof(WAVEHDR));
        waveOutPrepareHeader(hWaveOut,pWaveHdrOut2,sizeof(WAVEHDR));
        waveOutWrite(hWaveOut,pWaveHdrOut2,sizeof(WAVEHDR));
        waveOutPrepareHeader(hWaveOut,pWaveHdrOut3,sizeof(WAVEHDR));
        waveOutWrite(hWaveOut,pWaveHdrOut3,sizeof(WAVEHDR));
        break;
       }

      case MM_WOM_DONE:
       {
        WAVEHDR *Hdr = (WAVEHDR *)Msg.lParam;
        waveOutPrepareHeader (hWaveOut, Hdr, sizeof (*Hdr));
        waveOutWrite (hWaveOut, Hdr, sizeof (*Hdr));
        CopyMemory(Hdr->lpData,Buffer,BUFFER_SIZE);
        break;
       }
     }
   }
  return 0; 
}

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

BOOL CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{  

  static int volume_general;

  if (msg == WM_INITDIALOG)
   {
    DlgMain = hWnd;
    return 0;
   }

  if (msg == WM_COMMAND)
   {
    if (wParam == ID_START)
     {
      if(flag_in_open == TRUE)
       {
        MessageBox(hWnd,"périphérique déjà ouvert","Erreur",0);
        return 0;
       }
       
      WorkerThreadHandleIn = CreateThread (NULL, 0, WorkerThreadProcIn, NULL, 0, &WorkerThreadIdIn );
      WorkerThreadHandleOut = CreateThread (NULL, 0, WorkerThreadProcOut, NULL, 0, &WorkerThreadIdOut );
      pWaveHdrIn1 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      pWaveHdrIn2 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      pWaveHdrIn3 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      pWaveHdrOut1 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      pWaveHdrOut2 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      pWaveHdrOut3 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      
      Buffer   = (PBYTE)malloc(BUFFER_SIZE);
      pBufferIn1 = (PBYTE)malloc(BUFFER_SIZE);
      pBufferIn2 = (PBYTE)malloc(BUFFER_SIZE);
      pBufferIn3 = (PBYTE)malloc(BUFFER_SIZE);
      pBufferOut1 = (PBYTE)malloc(BUFFER_SIZE);
      pBufferOut2 = (PBYTE)malloc(BUFFER_SIZE);
      pBufferOut3 = (PBYTE)malloc(BUFFER_SIZE);
    
      if(!pBufferIn1 || !pBufferIn2 || !pBufferIn3 || !pBufferOut1 || !pBufferOut2 || !pBufferOut3)
       {
        if(pBufferIn1) free (pBufferIn1);
        if(pBufferIn2) free (pBufferIn2);
        if(pBufferIn3) free (pBufferIn3);
        if(pBufferOut1) free (pBufferOut1);
        if(pBufferOut2) free (pBufferOut2);
        if(pBufferOut3) free (pBufferOut3);
        MessageBox(hWnd,"Erreur d'allocation de mémoire","Erreur",0);
        return TRUE;
       }     
    
      waveform.nChannels = CANAUX; // 1 pour mono 2 pour stereo
      waveform.wBitsPerSample = 8 * OCTETS; // 8 ou 16 bit
      waveform.nAvgBytesPerSec = SAMPLERATE * waveform.nChannels * waveform.wBitsPerSample/8; // nombre d'octets par seconde
      waveform.wFormatTag = 1; // 1 pour PCM
      waveform.nSamplesPerSec = SAMPLERATE; // frequence d'echantillonnage
      waveform.nBlockAlign = 1;
      waveform.cbSize = 0;

      if(waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)WorkerThreadIdIn,0,CALLBACK_THREAD))
       {
        free(pBufferIn1);
        free(pBufferIn2);
        free(pBufferIn3);
        MessageBox(hWnd,"ouverture du périphérique d'entrée impossible","WARNING",MB_OK);
        return 0;
       }

      pWaveHdrIn1->lpData          = (LPSTR)pBufferIn1;
      pWaveHdrIn1->dwBufferLength  = BUFFER_SIZE;
      pWaveHdrIn1->dwBytesRecorded = 0;
      pWaveHdrIn1->dwUser          = 0;
      pWaveHdrIn1->dwFlags         = 0;
      pWaveHdrIn1->dwLoops         = 0;
      pWaveHdrIn1->lpNext          = NULL;
      pWaveHdrIn1->reserved        = 0;    
      waveInPrepareHeader(hWaveIn,pWaveHdrIn1,sizeof(WAVEHDR));
    
      pWaveHdrIn2->lpData          = (LPSTR)pBufferIn2;
      pWaveHdrIn2->dwBufferLength  = BUFFER_SIZE;
      pWaveHdrIn2->dwBytesRecorded = 0;
      pWaveHdrIn2->dwUser          = 0;
      pWaveHdrIn2->dwFlags         = 0;
      pWaveHdrIn2->dwLoops         = 0;
      pWaveHdrIn2->lpNext          = NULL;
      pWaveHdrIn2->reserved        = 0;    
      waveInPrepareHeader(hWaveIn,pWaveHdrIn2,sizeof(WAVEHDR));

      pWaveHdrIn3->lpData          = (LPSTR)pBufferIn3;
      pWaveHdrIn3->dwBufferLength  = BUFFER_SIZE;
      pWaveHdrIn3->dwBytesRecorded = 0;
      pWaveHdrIn3->dwUser          = 0;
      pWaveHdrIn3->dwFlags         = 0;
      pWaveHdrIn3->dwLoops         = 0;
      pWaveHdrIn3->lpNext          = NULL;
      pWaveHdrIn3->reserved        = 0;    
      waveInPrepareHeader(hWaveIn,pWaveHdrIn3,sizeof(WAVEHDR));      

      if(waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)WorkerThreadIdOut,0,CALLBACK_THREAD))
       {
        free(pBufferOut1);
        free(pBufferOut2);
        free(pBufferOut3);
        MessageBox(hWnd,"ouverture du périphérique de sortie impossible","WARNING",MB_OK);
        return 0;
       }    

      pWaveHdrOut1->lpData = (LPSTR)pBufferOut1;
      pWaveHdrOut1->dwBufferLength = BUFFER_SIZE;
      pWaveHdrOut1->dwBytesRecorded = 0;
      pWaveHdrOut1->dwUser = 0;
      pWaveHdrOut1->dwFlags = 0;
      pWaveHdrOut1->dwLoops = 0;
      pWaveHdrOut1->lpNext = NULL;
      pWaveHdrOut1->reserved = 0;    
      waveOutPrepareHeader(hWaveOut,pWaveHdrOut1,sizeof(WAVEHDR));
    
      pWaveHdrOut2->lpData = (LPSTR)pBufferOut2;
      pWaveHdrOut2->dwBufferLength = BUFFER_SIZE;
      pWaveHdrOut2->dwBytesRecorded = 0;
      pWaveHdrOut2->dwUser = 0;
      pWaveHdrOut2->dwFlags = 0;
      pWaveHdrOut2->dwLoops = 0;
      pWaveHdrOut2->lpNext = NULL;
      pWaveHdrOut2->reserved = 0;    
      waveOutPrepareHeader(hWaveOut,pWaveHdrOut2,sizeof(WAVEHDR));
    
      pWaveHdrOut3->lpData =(LPSTR)pBufferOut3;
      pWaveHdrOut3->dwBufferLength =BUFFER_SIZE;
      pWaveHdrOut3->dwBytesRecorded =0;
      pWaveHdrOut3->dwUser =0;
      pWaveHdrOut3->dwFlags =0;
      pWaveHdrOut3->dwLoops =0;
      pWaveHdrOut3->lpNext =NULL;
      pWaveHdrOut3->reserved =0;    
      waveOutPrepareHeader(hWaveOut,pWaveHdrOut3,sizeof(WAVEHDR));      

      return 0;
     }

    if (wParam == IDCANCEL)
     {
      if(MessageBox(hWnd, "Voulez-vous vraiment arrêter l'application en cours ?", "Real Time Audio",MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2) == IDNO)
       {
        return TRUE;
       }
      EndDialog(hWnd, 0);
      return 0;
     }
   }

  return 0;
}

//****************************************************************************
 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  InitCommonControls();
  DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),HWND_DESKTOP,DlgProc);
  return 0;
}

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

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

cs_Arnotic
Messages postés
936
Date d'inscription
dimanche 1 avril 2001
Statut
Modérateur
Dernière intervention
9 janvier 2012
-
Salut,
Ton programme semble super bien, mais j'ai quelques petit problème. Lorsque je l'execute je clique sur start et là j'ai un msg de windows m'informant que l'insttruction 0x0040108E emploie l'adresse 0x0042301c et que la mémoire ne peut être "written".
Des explications ?

@+
gabuzomeuh
Messages postés
53
Date d'inscription
jeudi 31 juillet 2003
Statut
Membre
Dernière intervention
28 mars 2007
-
Non je ne vois pas d'explication je n'ai jamais eu ce message d'erreur le mieux est de le faire tourner en pas a pas pour voir quelle fonction genere l'erreur

A+
cs_Arnotic
Messages postés
936
Date d'inscription
dimanche 1 avril 2001
Statut
Modérateur
Dernière intervention
9 janvier 2012
-
c'est sur cette ligne : dst[i]=0x30+((((0x0f0000000)>>(i*4))&valeur)>>(28-i*4));

@+
gabuzomeuh
Messages postés
53
Date d'inscription
jeudi 31 juillet 2003
Statut
Membre
Dernière intervention
28 mars 2007
-
Le mieux est de remplacer la boucle

for (i=0; i<8; i++)
{
dst[i]=0x30+((((0x0f0000000)>>(i*4))&valeur)>>(28-i*4));
if (dst[i]>0x39) dst[i]=0x37+((((0x0f0000000)>>(i*4))&valeur)>>(28-i*4));
}

par:

dst[0]=0x30+((0x0f0000000 & valeur)>>28);
dst[1]=0x30+((0x00f000000 & valeur)>>24);
dst[2]=0x30+((0x000f00000 & valeur)>>20);
dst[3]=0x30+((0x0000f0000 & valeur)>>16);
dst[4]=0x30+((0x00000f000 & valeur)>>12);
dst[5]=0x30+((0x000000f00 & valeur)>>8);
dst[6]=0x30+((0x0000000f0 & valeur)>>4);
dst[7]=0x30+((0x00000000f & valeur));
if (dst[0]>0x39) dst[0]=0x37+((0x0f0000000 & valeur)>>28);
if (dst[1]>0x39) dst[1]=0x37+((0x00f000000 & valeur)>>24) ;
if (dst[2]>0x39) dst[2]=0x37+((0x000f00000 & valeur)>>20) ;
if (dst[3]>0x39) dst[3]=0x37+((0x0000f0000 & valeur)>>16);
if (dst[4]>0x39) dst[4]=0x37+((0x00000f000 & valeur)>>12) ;
if (dst[5]>0x39) dst[5]=0x37+((0x000000f00 & valeur)>>8) ;
if (dst[6]>0x39) dst[6]=0x37+((0x0000000f0 & valeur)>>4) ;
if (dst[7]>0x39) dst[7]=0x37+((0x00000000f & valeur)) ;
cs_Arnotic
Messages postés
936
Date d'inscription
dimanche 1 avril 2001
Statut
Modérateur
Dernière intervention
9 janvier 2012
-
merci, mais ca plante toujours sur la ligne : dst[0]=0x30+((0x0f0000000 & valeur)>>28);

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.