Générateur de signal basse fréquence temps réel

Soyez le premier à donner votre avis sur cette source.

Vue 18 589 fois - Téléchargée 1 045 fois

Description

Ce programme permet la fabrication en continu et en temps réel d'un signal sinusoîdal, 20 Hz à 20kHz. Changement de fréquence appliqué instantanément.

Source / Exemple :


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

#define BUFFER_SIZE 4096
#define SAMPLERATE 44100 
#define CANAUX 1 // mono
#define OCTETS 2 // 16 bit

double pi = 3.1415926535897932;

PBYTE Buffer;
BOOL flag_out_open = FALSE;

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

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

  static HWAVEOUT hWaveOut;
  static PBYTE pBufferOut1, pBufferOut2, pBufferOut3;
  static PWAVEHDR pWaveHdrOut1, pWaveHdrOut2, pWaveHdrOut3;
  static WAVEFORMATEX waveform;
  static long int i;
  static double j = 0;
  static float angle;
  static unsigned char val;
  static double frequence[19981];
  static char txt[128];

  if (msg == WM_INITDIALOG)
   {
    for(i=0; i<19981; i++)
     {
      sprintf(txt,"%1.1f Hz", 20000.0 - i);
      frequence[i] = 20000.0 - i;
      SendDlgItemMessage(hWnd, IDC_COMBO_frequence , CB_ADDSTRING , 0 , (LPARAM)txt);
     }
    SendDlgItemMessage(hWnd, IDC_COMBO_frequence, CB_SETCURSEL, 19560, 0);
    return 0;
   }

    

  if (msg == MM_WOM_OPEN)
   {
    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));
    return 0;
   }

  if (msg == MM_WOM_DONE)
   {
    if (OCTETS == 1)
     {
      for(i=0; i<BUFFER_SIZE; i++)
       {
        angle = 2 * pi * j * frequence[SendDlgItemMessage(hWnd, IDC_COMBO_frequence, CB_GETCURSEL , 0 , 0)] / SAMPLERATE;
        if (angle > 2 * pi) angle = angle - 2 * pi;
        val = 127 + 127 * sin(angle);
        Buffer[i] = (val & 255);
        j = j + 1;
       }
     }
    if (OCTETS == 2)
     {
      for(i=0; i<(BUFFER_SIZE>>1); i++)
       {
        angle = 2 * pi * j * frequence[SendDlgItemMessage(hWnd, IDC_COMBO_frequence, CB_GETCURSEL , 0 , 0)] / SAMPLERATE;
        if (angle > 2 * pi) angle = angle - 2 * pi;
        val = 32767 * sin(angle);
        Buffer[  2*i] = (char)(val & 255);
        Buffer[1+2*i] = (char)(val >> 8);
        j = j + 1;
       }
     }
    CopyMemory(((PWAVEHDR)lParam)->lpData, Buffer, BUFFER_SIZE);
    waveOutPrepareHeader(hWaveOut, ((PWAVEHDR)lParam), sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, ((PWAVEHDR)lParam), sizeof(WAVEHDR));
    return 0;
   }

  if (msg == WM_COMMAND)
   {
    if (wParam == ID_START)
     {
      if(flag_out_open == TRUE)
       {
        MessageBox(hWnd,"périphérique déjà ouvert","Erreur",0);
        return 0;
       }     

      pWaveHdrOut1 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      pWaveHdrOut2 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      pWaveHdrOut3 = (PWAVEHDR) malloc(sizeof(WAVEHDR));
      
      Buffer      = (PBYTE)malloc(BUFFER_SIZE);
      pBufferOut1 = (PBYTE)malloc(BUFFER_SIZE);
      pBufferOut2 = (PBYTE)malloc(BUFFER_SIZE);
      pBufferOut3 = (PBYTE)malloc(BUFFER_SIZE);
    
      if(!pBufferOut1 || !pBufferOut2 || !pBufferOut3)
       {
        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(waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)hWnd,0,CALLBACK_WINDOW))
       {
        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)
{
  DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),HWND_DESKTOP,DlgProc);
  return 0;
}

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

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
mardi 25 mars 2008
Statut
Membre
Dernière intervention
25 mars 2008

je présume que tu veux dire:

int i;
d[0] = 0; // et pas tab
for (i=0; i < 2*n-1; i++) {
c = a*c-b*d[i];
d[i+1] = a*d[i]+b*c;
}
Messages postés
40
Date d'inscription
lundi 18 février 2002
Statut
Membre
Dernière intervention
5 novembre 2012
3
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.
Messages postés
1491
Date d'inscription
dimanche 19 novembre 2000
Statut
Modérateur
Dernière intervention
7 juillet 2014

EnterCriticalSection sert à faire de la synchronisation de thread donc à bloquer ceux-ci tant que la section n'est pas libéré donc sa n'a rien à voir :P Il faut utiliser SetThreadPriority dans ce cas :)
Messages postés
199
Date d'inscription
vendredi 16 avril 2004
Statut
Membre
Dernière intervention
28 février 2008

si tu veux être encore plus performant, tu peux coder en asm inline avec la FPU les calculs des flottants...
Messages postés
53
Date d'inscription
jeudi 31 juillet 2003
Statut
Membre
Dernière intervention
28 mars 2007

Quand la fenêtre est réduite ou restaurée, il y a une courte interruption du processus.
Doit-on utiliser un thread ou un SetPriorityClass ou un EnterCriticalSection ?
Afficher les 8 commentaires

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.