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

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

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.