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 / Exemple :
// 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;
}
//*******************************************************
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.