Здравствуйте, whitebrain, Вы писали:
W>Как записать звук с функцией паузы??
Когда-то делал dll'ину, которая умела записывать звук, передавать его по сети и воспроизводить на другой стороне.
Вот sounds.cpp:
#include "sound.h"
#include <mmsystem.h>
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "winmm.lib")
#define EXPORT extern "C" __declspec (dllexport)
// и переменные
HWAVEIN hWaveIn;HWAVEOUT hWaveOut;
WAVEHDR hdrSndIn[NEC_MAX_BUF_NUM+1]; int curBusyIn;
WAVEHDR hdrSndOut[NEC_MAX_BUF_NUM+1]; int curBusyOut;
int bufSize;
HANDLE hWorkThread;DWORD idWorkThread;
// утилиты ---------------------------------------
void PrepareFormat(WAVEFORMATEX*refFormat,int Freq, int Bit);
int PrepareHeadersIn();
void FreeHeadersIn();
int PrepareHeadersOut();
void FreeHeadersOut();
// ===============================================
#ifdef NEC_USE_CPP_Threads
unsigned int __stdcall WorkThread(void *Arg);
#else
DWORD WINAPI WorkThread(void *Arg);
#endif
int sndInitSound(int SizeOfBuffer,int SoundFrequency,int SoundBit)
{ // функция открывает устройства ввода и вывода. Успех=0.
int rez=0;
WAVEFORMATEX SndFormat;
bufSize=SizeOfBuffer;
rez= PrepareHeadersIn();
rez=rez + PrepareHeadersOut();
if (rez==0) {
PrepareFormat(&SndFormat, SoundFrequency,SoundBit);
#ifdef NEC_USE_CPP_Threads
hWorkThread=(void*)_beginthreadex(NULL,NULL,WorkThread,NULL,NULL,(unsigned int*) &idWorkThread);
#else
hWorkThread=CreateThread(NULL,NULL,WorkThread,NULL,NULL,&idWorkThread);
#endif
if (hWorkThread>0){
rez=rez+waveInOpen(&hWaveIn,WAVE_MAPPER,&SndFormat,idWorkThread,NULL,CALLBACK_THREAD);
rez=rez+waveOutOpen(&hWaveOut,WAVE_MAPPER,&SndFormat,idWorkThread,NULL,CALLBACK_THREAD);
}
}
if (rez>0) {
FreeHeadersIn();
FreeHeadersOut();
}
return rez;
}
void sndDeInitSound()
{
sndStopRecord();
sndStopPlay();
PostThreadMessage(idWorkThread,WM_QUIT,NULL,NULL);
Sleep(200); WaitForSingleObject(hWorkThread,200);
TerminateThread(hWorkThread,0);Sleep(200);
//CloseHandle(hWorkThread);
FreeHeadersIn();
FreeHeadersOut();
waveInClose(hWaveIn);
waveOutClose(hWaveOut);
hWaveIn=0;
hWaveOut=0;
}
// ********************************************
// ****************** Запись ******************
// ********************************************
int sndStartRecord()
{ // начинает запись и вталкивает первый буфер. Успех=0.
curBusyIn=0;DWORD addr=0;
int rez=waveInStart(hWaveIn);
if (rez==0) {
rez=waveInPrepareHeader(hWaveIn,&hdrSndIn[curBusyIn],sizeof(WAVEHDR));
if (rez==0) {
rez=waveInAddBuffer(hWaveIn,&hdrSndIn[curBusyIn],sizeof(WAVEHDR));
}
}
return rez;
}
void sndStopRecord()
{
waveInStop(hWaveIn);
waveInReset(hWaveIn);
}
// ********************************************
// ************** Воспроизведение ************
// ********************************************
int sndPlayThis(char *refArr, int arrSz)
{
int rez=0;
curBusyOut++;
if (curBusyOut>NEC_MAX_BUF_NUM) curBusyOut=0;
//char* arr = (char *)GlobalAlloc (GMEM_FIXED, arrSz);
//char* arr = (char *)mall1oc(arrSz);
if (hdrSndOut[curBusyOut].lpData) {
//if (refArr) {
//strncpy(arr,refArr,arrSz);
//hdrSndOut[curBusyOut].lpData = arr;
memcpy(hdrSndOut[curBusyOut].lpData,refArr,arrSz);
hdrSndOut[curBusyOut].dwBufferLength = arrSz;
hdrSndOut[curBusyOut].dwFlags = 0;
waveOutUnprepareHeader(hWaveOut,&hdrSndOut[curBusyOut],sizeof(WAVEHDR));
rez=waveOutPrepareHeader(hWaveOut,&hdrSndOut[curBusyOut],sizeof(WAVEHDR));
if (rez==0) {
rez=waveOutWrite(hWaveOut,&hdrSndOut[curBusyOut],sizeof(WAVEHDR));
}
}else{
rez=11;
}
//free(arr);
return rez;
}
void sndStopPlay()
{
waveOutReset(hWaveOut);
}
// **********************************************************
// **********************************************************
// **********************************************************
#ifdef NEC_USE_CPP_Threads
unsigned int __stdcall WorkThread(void *Arg)
#else
DWORD WINAPI WorkThread(void *Arg)
#endif
{
int rez=0;
MSG msg;
//SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
while (GetMessage (&msg, NULL, 0, 0) == TRUE){
//MessageBeep(0);
switch (msg.message){
case MM_WIM_DATA:
{ // окончена запись в буфер - надо перезарядить
rez=waveInUnprepareHeader(hWaveIn,&hdrSndIn[curBusyIn],sizeof(WAVEHDR));
//DebugFull((unsigned char*)hdrSndIn[curBusyIn].lpData);
RecordOver(hdrSndIn[curBusyIn].lpData,bufSize);
//sndPlayThis(hdrSndIn[curBusyIn].lpData,bufSize);
curBusyIn++;
if (curBusyIn>NEC_MAX_BUF_NUM) curBusyIn=0;
rez=waveInPrepareHeader(hWaveIn,&hdrSndIn[curBusyIn],sizeof(WAVEHDR));
if (rez==0) {
rez=waveInAddBuffer(hWaveIn,&hdrSndIn[curBusyIn],sizeof(WAVEHDR));
}
break;
}
case MM_WOM_DONE:
{
//PostMessage (WndOut,514,NULL,NULL);
break;
}
}
}
MessageBeep(MB_ICONASTERISK);
return rez;
}
// **********************************************************
// **********************************************************
// **********************************************************
// Утилитный раздел -----------------------------------------
// Функция инициализирует SndFormatIn
void PrepareFormat(WAVEFORMATEX*refFormat,int Freq, int Bit)
{
refFormat->cbSize = sizeof(refFormat);
refFormat->wFormatTag = WAVE_FORMAT_PCM;
refFormat->nChannels = 1;
refFormat->nBlockAlign = 1;
refFormat->nSamplesPerSec = Freq;
refFormat->wBitsPerSample = Bit;
refFormat->nAvgBytesPerSec = (refFormat->nSamplesPerSec * refFormat->nBlockAlign) / Bit; // было /8
}
// Функция подготавливает заголовки для передачи их звуковому драйверу
int PrepareHeadersIn()
{
int i=0,rez=0;
for (i=0;i<=NEC_MAX_BUF_NUM;i++) {
memset(&hdrSndIn[i],0,sizeof(hdrSndIn[i]));
//if (hdrSndIn[i].lpData)
free(hdrSndIn[i].lpData);
hdrSndIn[i].lpData =(char*) malloc(bufSize);
if (!hdrSndIn[i].lpData) rez=GetLastError();
hdrSndIn[i].dwBufferLength = bufSize;
}
return rez;
}
void FreeHeadersIn()
{
int i=0,rez=1;
for (i=0;i<=NEC_MAX_BUF_NUM;i++) {
waveInUnprepareHeader(hWaveIn,&hdrSndIn[i],sizeof(hdrSndIn[i]));
}
}
int PrepareHeadersOut()
{
int i=0,rez=0;
for (i=0;i<=NEC_MAX_BUF_NUM;i++) {
memset(&hdrSndOut[i],0,sizeof(hdrSndOut[i]));
//if (hdrSndOut[i].lpData)
free(hdrSndOut[i].lpData);
hdrSndOut[i].lpData =(char*) malloc(bufSize);
if (!hdrSndOut[i].lpData) rez=GetLastError();
hdrSndOut[i].dwBufferLength = bufSize;
}
return rez;
}
void FreeHeadersOut()
{
int i=0,rez=1;
for (i=0;i<=NEC_MAX_BUF_NUM;i++) {
waveOutUnprepareHeader(hWaveOut,&hdrSndOut[i],sizeof(hdrSndOut[i]));
//GlobalFree ((HGLOBAL)&hdrSndOut[i].lpData);
}
}
на удивление работало. Минут пять, прежде чем падало.
Но если по-уму переделать, то мне кажется можно воспользоваться.