📄 snd_wave.c
字号:
/*@@ Wedit generated application. Written Mon Jun 03 15:53:20 2002
@@header: d:\my\prog\wav\lcc\snd_wavewiz.h
@@resources: d:\my\prog\wav\lcc\snd_wave.rc
Do not edit outside the indicated areas */
/*<---------------------------------------------------------------------->*/
/*<---------------------------------------------------------------------->*/
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <mmsystem.h>
#include <math.h>
#include <winsock2.h>
#include "snd_wavewiz.h"
/*<---------------------------------------------------------------------->*/
#define MAX_INQUEU 8
#define BUFSIZE 1024
#define SAMPLES 8000
#define IN_PORT 6000
#define WM_SOCKET WM_USER+1024
typedef void (__stdcall *PFNFFT)(double InReal[],double InImag[],double OutReal[],double OutImag[],int n,int k);
/* FFT function from DEMO.DLL */
/* n=2^k */
PFNFFT pfnFft;
static HINSTANCE hInst; // Instance handle
static HWND hwndMain; //Main window handle
static HDC whdc;
static HMODULE hMod;
static HPEN hpenB,hpenG,hpenOld;
static HWAVEIN hwi;
static WAVEHDR *pwhi,whis[MAX_INQUEU];
static char waveBufferRecord[MAX_INQUEU][BUFSIZE];
static DWORD currWavInHdr=0,nextWavInHdr;
static BOOL b_recording;
static HWAVEOUT hwo;
static WAVEHDR *pwho,whos[MAX_INQUEU];
static char waveBufferPlayback[MAX_INQUEU][BUFSIZE];
static DWORD currWavOutHdr=0;
static SOCKET sock;
static SOCKADDR_IN sao;
static LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
static SOCKET sockInit(HWND hwnd)
{
WSADATA wd;
SOCKADDR_IN sai;
SOCKET ssin;
BOOL bc=TRUE;
WSAStartup(0x0101,&wd);
ssin=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
sai.sin_family = AF_INET;
sai.sin_port=htons(IN_PORT);
sai.sin_addr.s_addr=htonl(ADDR_ANY);
sao.sin_family=AF_INET;
sao.sin_port=htons(IN_PORT);
sao.sin_addr.s_addr=htonl(INADDR_BROADCAST);
bind(ssin,(SOCKADDR *)&sai,sizeof(SOCKADDR_IN));
setsockopt(ssin,SOL_SOCKET,SO_BROADCAST,(char *)&bc,sizeof(bc));
WSAAsyncSelect(ssin,hwnd,WM_SOCKET,FD_READ|FD_WRITE|FD_CONNECT|FD_ACCEPT|FD_CLOSE);
return ssin;
}
static void sockDeinit(SOCKET s)
{
closesocket(s);
WSACleanup();
}
static void waveInit(HWND hWnd,WORD FormatTag,WORD Channel,DWORD Samples,WORD Bits)
{
WAVEFORMATEX wfx;
long k;
memset(&wfx,0,sizeof(WAVEFORMATEX));
wfx.wFormatTag=WAVE_FORMAT_PCM;
wfx.nChannels=Channel;
wfx.wBitsPerSample=Bits;
wfx.nSamplesPerSec=Samples;
wfx.nBlockAlign=Bits*Channel/8;
wfx.nAvgBytesPerSec=Samples*Bits*Channel/8;
wfx.cbSize=0;
waveInOpen(&hwi,0,&wfx,(DWORD)hWnd,0,CALLBACK_WINDOW|WAVE_MAPPED);
waveOutOpen(&hwo,0,&wfx,(DWORD)hWnd,0,CALLBACK_WINDOW|WAVE_MAPPED);
for(k=0;k<MAX_INQUEU;k++)
{
pwhi=&whis[k];
pwhi->dwFlags=0;
pwhi->dwLoops=0;
pwhi->dwBytesRecorded=0;
pwhi->dwBufferLength=BUFSIZE;
pwhi->lpData=waveBufferRecord[k];
pwho=&whos[k];
pwho->dwFlags=0;
pwho->dwLoops=0;
pwho->dwBytesRecorded=0;
pwho->dwBufferLength=BUFSIZE;
pwho->lpData=waveBufferPlayback[k];
}
for(k=0;k<MAX_INQUEU-1;k++)
{
pwhi=&whis[k];
waveInPrepareHeader(hwi,pwhi,sizeof(WAVEHDR));
waveInAddBuffer(hwi,pwhi,sizeof(WAVEHDR));
}
currWavInHdr=0;
currWavOutHdr=0;
pwhi=&whis[currWavInHdr];
pwho=&whos[currWavOutHdr];
b_recording=TRUE;
waveInStart(hwi);
}
static void DrawWave(WAVEHDR *whdr,HDC hdc)
{
static unsigned char prevBuf[BUFSIZE];
static DWORD prevBytes=0;
DWORD i;
hpenOld = SelectObject(hdc, hpenB);
MoveToEx(hdc,0,prevBuf[0],NULL);
for(i=1;i<512;i++)
{
LineTo(hdc,i,prevBuf[i]);
}
SelectObject(hdc, hpenG);
MoveToEx(hdc,0,(unsigned char)(whdr->lpData[0]),NULL);
for(i=1;i<512;i++)
{
LineTo(hdc,i,(unsigned char)(whdr->lpData[i]));
}
SelectObject(hdc, hpenOld);
memcpy(prevBuf,whdr->lpData,whdr->dwBytesRecorded);
prevBytes=whdr->dwBytesRecorded;
}
static void DrawFreq(WAVEHDR *whdr,HDC hdc)
{
static double prevFreqI[BUFSIZE];
static double currFreqI[BUFSIZE];
static double prevFreqR[BUFSIZE];
static double currFreqR[BUFSIZE];
double WaveR[BUFSIZE];
double WaveI[BUFSIZE];
DWORD i;
memset(WaveR,0,BUFSIZE*sizeof(double));
memset(WaveI,0,BUFSIZE*sizeof(double));
for(i=0;i<whdr->dwBytesRecorded;i++)
{
WaveR[i]=(unsigned char)whdr->lpData[i]-128;
}
pfnFft(WaveR,WaveI,currFreqR,currFreqI,1024,10);
hpenOld = SelectObject(hdc, hpenB);
MoveToEx(hdc,0,380,NULL);
for(i=0;i<BUFSIZE/2;i++)
{
LineTo(hdc,i,380-sqrt((prevFreqR[i]*prevFreqR[i]+prevFreqI[i]*prevFreqI[i])/BUFSIZE));
}
SelectObject(hdc, hpenG);
MoveToEx(hdc,0,380,NULL);
for(i=0;i<BUFSIZE/2;i++)
{
LineTo(hdc,i,380-sqrt((currFreqR[i]*currFreqR[i]+currFreqI[i]*currFreqI[i])/BUFSIZE));
}
SelectObject(hdc, hpenOld);
memcpy(prevFreqR,currFreqR,BUFSIZE*sizeof(double));
memcpy(prevFreqI,currFreqI,BUFSIZE*sizeof(double));
}
/*<---------------------------------------------------------------------->*/
/*@@0->@@*/
static BOOL InitApplication(void)
{
WNDCLASS wc;
memset(&wc,0,sizeof(WNDCLASS));
wc.style = CS_HREDRAW|CS_VREDRAW |CS_DBLCLKS ;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.hInstance = hInst;
wc.hbrBackground = CreateSolidBrush(0);//(HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "snd_waveWndClass";
wc.lpszMenuName = MAKEINTRESOURCE(IDMAINMENU);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
if (!RegisterClass(&wc))
return 0;
/*@@0<-@@*/
// ---TODO--- Call module specific initialization routines here
return 1;
}
/*<---------------------------------------------------------------------->*/
/*@@1->@@*/
static HWND Createsnd_waveWndClassWnd(void)
{
return CreateWindow("snd_waveWndClass","Sound Wave Display",
WS_MINIMIZEBOX|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CAPTION|WS_BORDER|WS_SYSMENU,
100,100,530,450,
NULL,
NULL,
hInst,
NULL);
}
/*@@1<-@@*/
/*<---------------------------------------------------------------------->*/
/* --- The following code comes from D:\MY\PROG\EXAM\lcc\lib\wizard\defOnCmd.tpl. */
static void MainWndProc_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id) {
// ---TODO--- Add new menu commands here
/*@@NEWCOMMANDS@@*/
case IDM_EXIT:
PostMessage(hwnd,WM_CLOSE,0,0);
break;
case IDM_ABOUT:
MessageBox(hwnd,"Author:NowCan\nhttp://nowcan.yeah.net","About Sound Wave Display",MB_OK|MB_ICONINFORMATION);
break;
}
}
/*<---------------------------------------------------------------------->*/
/*@@2->@@*/
static LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
int i;
int dwRead;
switch (msg) {
/*@@3->@@*/
case WM_COMMAND:
HANDLE_WM_COMMAND(hwnd,wParam,lParam,MainWndProc_OnCommand);
break;
case WM_DESTROY:
b_recording=FALSE;
waveInReset(hwi);
waveOutReset(hwo);
for(i=0;i<MAX_INQUEU;i++)
{
waveInUnprepareHeader(hwi,pwhi,sizeof(WAVEHDR));
waveOutUnprepareHeader(hwo,pwho,sizeof(WAVEHDR));
}
waveInClose(hwi);
waveOutClose(hwo);
sockDeinit(sock);
DeleteObject(hpenG);
DeleteObject(hpenB);
FreeLibrary(hMod);
PostQuitMessage(0);
break;
case WM_CREATE:
hpenG = CreatePen(PS_SOLID, 0, RGB(0, 255, 0));
hpenB = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
hMod=LoadLibrary("demo.dll");
if(!hMod)
{
MessageBox(hwnd,"LoadLibrary() failed.","Warning",MB_OK|MB_ICONWARNING);
}
else
{
pfnFft=(PFNFFT)GetProcAddress(hMod,"Fft");
if(!pfnFft)
MessageBox(hwnd,"GetProcAddress() failed.","Warning",MB_OK|MB_ICONWARNING);
}
sock=sockInit(hwnd);
waveInit(hwnd,WAVE_FORMAT_PCM,1,SAMPLES,8);
break;
case WIM_DATA:
waveInUnprepareHeader(hwi,pwhi,sizeof(WAVEHDR));
sendto(sock,pwhi->lpData,pwhi->dwBytesRecorded,0,(SOCKADDR *)&sao,sizeof(SOCKADDR_IN));
nextWavInHdr=(currWavInHdr-1+MAX_INQUEU)%MAX_INQUEU;
currWavInHdr=(currWavInHdr+1)%MAX_INQUEU;
if(b_recording)
{
pwhi=&whis[nextWavInHdr];
pwhi->dwFlags=0;
pwhi->dwLoops=0;
waveInPrepareHeader(hwi,pwhi,sizeof(WAVEHDR));
waveInAddBuffer(hwi,pwhi,sizeof(WAVEHDR));
}
whdc=GetDC(hwnd);
if(pfnFft)
DrawFreq((WAVEHDR *)lParam,whdc);
DrawWave((WAVEHDR *)lParam,whdc);
ReleaseDC(hwnd,whdc);
break;
case WOM_DONE:
waveOutUnprepareHeader(hwo,(WAVEHDR *)lParam,sizeof(WAVEHDR));
break;
case WM_SOCKET:
currWavOutHdr=(currWavOutHdr+1)%MAX_INQUEU;
pwho=&whos[currWavOutHdr];
dwRead=recv(sock,waveBufferPlayback[currWavOutHdr],BUFSIZE,0);
pwho->dwBufferLength=dwRead;
waveOutPrepareHeader(hwo,pwho,sizeof(WAVEHDR));
waveOutWrite(hwo,pwho,sizeof(WAVEHDR));
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
/*@@3<-@@*/
return 0;
}
/*@@2<-@@*/
/*<---------------------------------------------------------------------->*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
MSG msg;
HANDLE hAccelTable;
hInst = hInstance;
if (!InitApplication())
return 0;
hAccelTable = LoadAccelerators(hInst,MAKEINTRESOURCE(IDACCEL));
if ((hwndMain = Createsnd_waveWndClassWnd()) == (HWND)0)
return 0;
ShowWindow(hwndMain,SW_SHOW);
while (GetMessage(&msg,NULL,0,0)) {
if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -