Waitforsingleobject()

Тема в разделе "MS Visual C++", создана пользователем Firefox, 25 фев 2011.

Статус темы:
Закрыта.
  1. Firefox

    Firefox Гость

    всем привет. у меня такой вопрос. по функции WaitForSingleObject(). использую её в проге про записи звука. пока использую 1 раз. то есть длинна буфера записи скажем 5 секунд. ожидаю пока они пройдут(WaitForSingleObject()), то есть заполняю буфер полностью. но если хочу сделать в цикле, скажем чтоб запись шла по 5 секунд но до тех пор пока не нажата кнопка стоп, то приложение виснет. помогите правильно цикл организовать.
    Код (C++):
    #include "new_rec.h"
    #include <windows.h>
    #include <dsound.h>
    #include <math.h>

    HWND                            g_hWnd;
    LPDIRECTSOUNDCAPTURE8           g_pDSCapture        = NULL;
    LPDIRECTSOUNDCAPTUREBUFFER8     g_pDSCaptureBuffer  = NULL;
    BITMAPINFO                      g_BI;
    long *                          g_pDIB;
    HANDLE                          g_hThread;
    BOOL                            g_bThreadExit;
    PCMWAVEFORMAT pcmWaveFormat;
    HMMIO       hmmioOut; // handle to open output WAVE file
    MMCKINFO      ckOutRIFF;
    MMCKINFO      ckOut;     
    MMIOINFO      mmioinfoOut;  
    HANDLE hEvent;
    char *DataS;
    int writtenByte=0;
    bool PR_STOP=0;
    NEW_REC::NEW_REC(QWidget *parent, Qt::WFlags flags)
    : QWidget(parent, flags)
    {
    ui.setupUi(this);
    t_time=new QTimer(this);
    //connect(t_time,SIGNAL(timeout()),SLOT(rec_thread()));

    pcmWaveFormat.wf.wFormatTag=WAVE_FORMAT_PCM;
    pcmWaveFormat.wf.nChannels=1;
    pcmWaveFormat.wf.nSamplesPerSec=8000;
    pcmWaveFormat.wBitsPerSample=8;
    pcmWaveFormat.wf.nBlockAlign=pcmWaveFormat.wf.nChannels * (pcmWaveFormat.wBitsPerSample / 8);
    pcmWaveFormat.wf.nAvgBytesPerSec=pcmWaveFormat.wf.nSamplesPerSec * pcmWaveFormat.wf.nBlockAlign;
    char *pDataEcho = new char[pcmWaveFormat.wf.nAvgBytesPerSec];
    }

    NEW_REC::~NEW_REC()
    {

    }

    bool NEW_REC::createFileWav()
    {

    //----------------------------------------------

    LPTSTR m_FileName=L"Sound_out.wav";

    hmmioOut = mmioOpen(L"Sound_out.wav", NULL,
    MMIO_ALLOCBUF | MMIO_WRITE | MMIO_CREATE );
    if (hmmioOut == NULL)
    {
    ::MessageBox(NULL,L"Ошибка при открытии файла wave", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    return false;
    }

    // Write the PCMWAVEFORMAT structure
    ckOutRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
    if (mmioCreateChunk(hmmioOut, &ckOutRIFF, MMIO_CREATERIFF) != 0)
    {
    ::MessageBox(NULL,L"Ошибка при создании сегмента wave", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    return false;
    }

    ckOut.ckid = mmioFOURCC('f', 'm', 't', ' ');
    if (mmioCreateChunk(hmmioOut, &ckOut, 0) != 0)
    {
    ::MessageBox(NULL,L"Ошибка при создании сегмента fmt", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    return false;
    }


    if (mmioWrite(hmmioOut, (HPSTR) &pcmWaveFormat, sizeof(pcmWaveFormat))
    != sizeof(pcmWaveFormat))
    {
    ::MessageBox(NULL,L"Ошибка при создании сегмента fmt и записи его содержмого", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    return false;
    }

    if (mmioAscend(hmmioOut, &ckOut, 0) != 0)
    {
    ::MessageBox(NULL,L"Ошибка при зактытии сегмента fmt", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    return false;
    }

    ckOut.ckid = mmioFOURCC('d', 'a', 't', 'a');
    if (mmioCreateChunk(hmmioOut, &ckOut, 0) != 0)
    {
    ::MessageBox(NULL,L"Ошибка при создании сегмента data", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    return false;
    }
    return true;
    }
    HRESULT NEW_REC::ds_init()
    {
    WAVEFORMATEX    wfx;
    wfx.wFormatTag      = WAVE_FORMAT_PCM;
    wfx.nChannels       = 1;
    wfx.nSamplesPerSec  = 8000;
    wfx.wBitsPerSample  = 8;
    wfx.nBlockAlign     = wfx.nChannels * (wfx.wBitsPerSample / 8);
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
    wfx.cbSize          = 0;
    HRESULT hRes;
    //Создаемустройствоаудиозахвата
    LPDIRECTSOUNDCAPTURE pDSoundCapture;

    if ( FAILED (hRes =
    DirectSoundCaptureCreate(NULL, &pDSoundCapture, NULL)
    ) ) return hRes;

    DSCBUFFERDESC dscBufDesc;
    ZeroMemory(&dscBufDesc, sizeof(dscBufDesc) );
    dscBufDesc.dwSize = sizeof(dscBufDesc);
    dscBufDesc.dwFlags = 0;
    dscBufDesc.dwBufferBytes = wfx.nAvgBytesPerSec * 0.5;
    dscBufDesc.dwReserved = 0;
    dscBufDesc.lpwfxFormat = &wfx;

    createFileWav();
    LPDIRECTSOUNDCAPTUREBUFFER g_pDSCapture;
    if ( FAILED (hRes =
    pDSoundCapture->CreateCaptureBuffer(&dscBufDesc, &g_pDSCapture,
    NULL ) ) ) return hRes;

    //Устанавливаем извещение на конец буфера
    LPDIRECTSOUNDNOTIFY lpDsNotify;
    if (FAILED(
    hRes = g_pDSCapture->QueryInterface(IID_IDirectSoundNotify,
    (LPVOID*)&lpDsNotify))) return hRes;

    DSBPOSITIONNOTIFY PositionNotify;
    PositionNotify.dwOffset = DSBPN_OFFSETSTOP;
    PositionNotify.hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
    hRes = lpDsNotify->SetNotificationPositions(1, &PositionNotify);
    lpDsNotify->Release();
    g_pDSCapture->Start(DSCBSTART_LOOPING);/*DSCBSTART_LOOPING*/
    //Ждем окончания аудиозахвата
    while(FALSE)
    {
    qApp->processEvents();
    WaitForSingleObject(PositionNotify.hEventNotify, INFINITE);
    CloseHandle(PositionNotify.hEventNotify);


    /////////////////////////////
    char *p = NULL;
    DWORD   s = W;
    char *p2 = NULL;
    DWORD   s2 = W;
    g_pDSCapture->Lock( 0, 0, (LPVOID *)&p, &s, (LPVOID *)&p2,&s2, DSCBLOCK_ENTIREBUFFER );// блокировка буфера для чтения инфы из него
    int k=strlen(p);
    if (mmioGetInfo(hmmioOut, &mmioinfoOut, 0) != 0)
    ::MessageBox(NULL,L"Ошибка при записи данных2", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ckOut.cksize = sizeof(pcmWaveFormat)/**10*/;
    // запись данных из буфера в файл
    for (int lSamples =1; lSamples<s; lSamples++)
    {
    if (mmioinfoOut.pchNext == mmioinfoOut.pchEndWrite)
    {
    mmioinfoOut.dwFlags |= MMIO_DIRTY;
    if (mmioAdvance(hmmioOut, &mmioinfoOut, MMIO_WRITE) != 0)
    ::MessageBox(NULL,L"Ошибка при записи данных1", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    }
    *(mmioinfoOut.pchNext)++ =p[lSamples];
    }  

    mmioinfoOut.dwFlags |= MMIO_DIRTY;
    if (mmioAdvance(hmmioOut, &mmioinfoOut, MMIO_WRITE) != 0)
    {
    ::MessageBox(NULL,L"Ошибка при считывании данных data", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    //return false;
    }

    if (mmioSetInfo(hmmioOut, &mmioinfoOut, 0) != 0)
    ::MessageBox(NULL,L"Ошибка при записи данных3", L"Ошибка",MB_OK|MB_SYSTEMMODAL);

    g_pDSCapture->Unlock( p, s, NULL, NULL );// разблокирование буфера для продолжения процесса записи
    }

    if (mmioAscend(hmmioOut, &ckOut, 0) != 0)
    {
    ::MessageBox(NULL,L"Ошибка при закрытии блока данных data", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    return false;
    }
    if (mmioAscend(hmmioOut, &ckOutRIFF, 0) != 0)
    {
    ::MessageBox(NULL,L"Ошибка при закрытии блока RIFF", L"Ошибка",MB_OK|MB_SYSTEMMODAL);
    ::mmioClose(hmmioOut,NULL);
    return false;
    }

    if (hmmioOut != NULL)
    mmioClose(hmmioOut, 0);
    //И в заключении освобождаем объекты
    g_pDSCapture->Release();   
    pDSoundCapture->Release();

    return true;
    }


    void NEW_REC::on_pushButton_clicked()
    {
    ds_init();


    void NEW_REC::on_pushButton_2_clicked()
    {

    //ds_close();
    PR_STOP=1;
    SetEvent(hEvent);
    }

    void NEW_REC::on_play_clicked()
    {
    ::IDirectSound8 *pDirectSound; // определим интерфес
    ::IDirectSoundBuffer *pSoundBuffer; //Определим указатель на звуковой буфер DX-а
    ::DSBUFFERDESC dsBuffer = DSBUFFERDESC(); //Структура формата буфера
    //Заполни ее
    DWORD sizeData=8000;
    dsBuffer.dwBufferBytes =sizeData; //Сколько инфы (в байтах)
    dsBuffer.dwFlags = DSBCAPS_STATIC; //Флаг буфера, у нас буфер как статичный (может быть поточным)
    dsBuffer.dwSize = sizeof(DSBUFFERDESC); //Размер структуры, как любят ребята из Microsoft
    dsBuffer.lpwfxFormat = &WaveFormat; //Формат буфера, мы как раз запишим туда сведения из Wav-Format

    pDirectSound->CreateSoundBuffer(&dsBuffer,&pSoundBuffer,NULL); //Создадим буфер
    void *pDst = 0;
    DWORD dwSize = 0;
    pSoundBuffer->Lock(0,0,&pDst,&dwSize,0,0,DSBLOCK_ENTIREBUFFER);//Заблокируем буфер
    memcpy(pDst,DataS,dwSize); //Запишим нашу pData в него
    pSoundBuffer->Unlock(pDst,dwSize,0,0); //Разблокируем
    pSoundBuffer->Play(0,0,0); //Начнем грать
    DWORD hrStatus = 0;
    do
    {
    pSoundBuffer->GetStatus(&hrStatus); //В цикле получаем статус
    }
    while (hrStatus == DSBSTATUS_PLAYING); //выполнять : Пока статус "Грает"

    pDirectSound->Release(); //Освободим интерфейс
    pDirectSound = NULL;

    }
     
Статус темы:
Закрыта.

Поделиться этой страницей