Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Программирование звука > Проигрыватель.


Автор: WizzzI 10.07.12, 08:32
Прога проигрывает WAV файлы, все в принципе устраивает, кроме того, что
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream.h>
    #include <windows.h>
    #include <mmsystem.h>
    #include <stdio.h>
     
    #define BLOCK_SIZE 1024*4
    #define BLOCK_COUNT 6
     
    WAVEHDR* waveBlocks;
    int waveFreeBlockCount;
    int waveCurrentBlock;
     
    void CALLBACK waveOutProc(HWAVEOUT hWaveOut,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2){
     
          int *freeBlockCounter = (int*)dwInstance;
     
          if(uMsg!=WOM_DONE) return;
          (*freeBlockCounter)++;
          return;
    }
     
    WAVEHDR* allocateBlocks(int size,int count){
          char* buffer;
          int i;
          WAVEHDR* blocks;
          DWORD totalBufferSize = size*count;
     
          if((buffer = (unsigned char*) HeapAlloc(GetProcessHeap(),
          HEAP_ZERO_MEMORY, totalBufferSize)) == NULL)
          {
                printf("Ошибка при выделение памяти\n");
                getchar();
                ExitProcess(1);
          }
     
          blocks = (WAVEHDR*)buffer;
          buffer += sizeof(WAVEHDR)*count;
          for(i=0; i < count; i++)
          {
                blocks[i].dwBufferLength = size;
                blocks[i].lpData = buffer;
                buffer += size;
          }
          return blocks;
    }
    void freeBlocks(WAVEHDR* blockArray){
          HeapFree(GetProcessHeap(),0,blockArray);
          return;
    }
    void writeAudio(HWAVEOUT hWaveOut,char *data,int size){
          WAVEHDR* current;
          int remain;
          current = &waveBlocks[waveCurrentBlock];
          while(size>0){
                if(size < (int)(BLOCK_SIZE - current->dwUser)){
     
                      memcpy(current->lpData + current->dwUser,data,size);
                      current->dwUser += size;
                      break;
                }
     
                remain = BLOCK_SIZE-current->dwUser;
                memcpy(current->lpData+current->dwUser,data,remain);
                size -= remain;
                data += remain;
                current->dwBufferLength = BLOCK_SIZE;
                waveOutPrepareHeader(hWaveOut,current,sizeof(WAVEHDR));
                waveOutWrite(hWaveOut,current,sizeof(WAVEHDR));
     
                waveFreeBlockCount--;
     
                while(!waveFreeBlockCount) Sleep(5);
     
                waveCurrentBlock++;
                waveCurrentBlock %= BLOCK_COUNT;
                cout << "" << waveCurrentBlock;
                current = &waveBlocks[waveCurrentBlock];
                current->dwUser = 0;
          }
          return;
    }
    int main()
    {
    HWAVEOUT hWaveOut;
    HANDLE hFile;
    WAVEFORMATEX wfx;
    char buffer[1024]; /* промежуточный буфер чтения */
    int i;
     
    waveBlocks = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
    waveFreeBlockCount = BLOCK_COUNT;
    waveCurrentBlock= 0;
     
    if((hFile = CreateFile(
    "D:\\b.wav",
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    0,
    NULL
    )) == INVALID_HANDLE_VALUE) {
    printf("неудается открыть файл\n");
    getchar();
    }
     
    wfx.nSamplesPerSec = 44100;
    wfx.wBitsPerSample = 16;
    wfx.nChannels= 2; wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) / 8 ;
    wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
     
    if(waveOutOpen(
    &hWaveOut,
    WAVE_MAPPER,
    &wfx,
    (DWORD_PTR)waveOutProc,
    (DWORD_PTR)&waveFreeBlockCount,
    CALLBACK_FUNCTION
    ) != MMSYSERR_NOERROR) {
    printf("не удалось открыть устройство");
    getchar();
    ExitProcess(1);
    }
     
    while(1) {
    DWORD readBytes;
    if(!ReadFile(hFile, buffer, sizeof(buffer), &readBytes, NULL))
    break;
    writeAudio(hWaveOut, buffer, sizeof(buffer));
    }
     
    waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
    freeBlocks(waveBlocks);
    waveOutClose(hWaveOut);
    CloseHandle(hFile);
    return 0;
    }

вот этот цикл выполняется бесконечно(после того как файл уже проигрался):
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    while(1) {
    DWORD readBytes;
    if(!ReadFile(hFile, buffer, sizeof(buffer), &readBytes, NULL))
    break;
    writeAudio(hWaveOut, buffer, sizeof(buffer));
    }

т.е. он не дает выполниться вот этому фрагменту,
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
    freeBlocks(waveBlocks);
    waveOutClose(hWaveOut);
    CloseHandle(hFile);
    return 0;

подскажите путь решения проблемки.

Автор: B.V. 11.07.12, 12:29
Цитата MSDN
The ReadFile function checks for the end-of-file condition (EOF) differently for synchronous and asynchronous read operations. When a synchronous read operation gets to the end of a file, ReadFile returns TRUE and sets the variable pointed to by the lpNumberOfBytesRead parameter to zero.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)