ЗАпись звука в c#
От: whitebrain  
Дата: 04.04.10 20:37
Оценка:
Как записать звук с функцией паузы??При нажатии клавиши воспроизводится звук,реализована многопоточность,будет ли это влиять как либо на запись?и если делать визуализацию звука,то чем проще??
c# .net
Re: ЗАпись звука в c#
От: Neco  
Дата: 05.04.10 15:47
Оценка:
Здравствуйте, 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);
    }
}

на удивление работало. Минут пять, прежде чем падало.

Но если по-уму переделать, то мне кажется можно воспользоваться.
всю ночь не ем, весь день не сплю — устаю
Re: ЗАпись звука в c#
От: QrystaL Украина  
Дата: 05.04.10 21:03
Оценка:
Здравствуйте, whitebrain, Вы писали:

W>Как записать звук с функцией паузы??При нажатии клавиши воспроизводится звук,реализована многопоточность,будет ли это влиять как либо на запись?и если делать визуализацию звука,то чем проще??


http://www.codeplex.com/naudio
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.