device_mm.cpp

Go to the documentation of this file.
00001 #include <windows.h>
00002 #include <mmsystem.h>
00003 #include "device_mm.h"
00004 #include "utility.h"
00005 
00006 
00007 namespace audiere {
00008 
00009   static const int RATE = 44100;
00010 
00011 
00012   MMAudioDevice*
00013   MMAudioDevice::create(const ParameterList& parameters) {
00014     WAVEFORMATEX wfx;
00015     memset(&wfx, 0, sizeof(wfx));
00016     wfx.wFormatTag      = WAVE_FORMAT_PCM;
00017     wfx.nChannels       = 2;
00018     wfx.nSamplesPerSec  = RATE;
00019     wfx.nAvgBytesPerSec = RATE * 4;
00020     wfx.nBlockAlign     = 4;
00021     wfx.wBitsPerSample  = 16;
00022     wfx.cbSize          = sizeof(WAVEFORMATEX);
00023 
00024     HWAVEOUT handle;
00025     MMRESULT result = waveOutOpen(&handle, WAVE_MAPPER, &wfx, 0, 0, 0);
00026     if (result != MMSYSERR_NOERROR) {
00027       return 0;
00028     }
00029 
00030     return new MMAudioDevice(handle, RATE);
00031   }
00032 
00033 
00034   MMAudioDevice::MMAudioDevice(HWAVEOUT device, int rate)
00035     : MixerDevice(rate)
00036   {
00037     ADR_GUARD("MMAudioDevice::MMAudioDevice");
00038 
00039     m_device = device;
00040     m_current_buffer = 0;
00041 
00042     // fill each buffer with samples and prepare it for output
00043     for (int i = 0; i < BUFFER_COUNT; ++i) {
00044       WAVEHDR& wh = m_buffers[i];
00045       memset(&wh, 0, sizeof(wh));
00046       wh.lpData         = (char*)m_samples + i * BUFFER_LENGTH;
00047       wh.dwBufferLength = BUFFER_LENGTH;
00048 
00049       read(BUFFER_LENGTH / 4, wh.lpData);
00050 
00051       MMRESULT result = waveOutPrepareHeader(m_device, &wh, sizeof(wh));
00052       if (result != MMSYSERR_NOERROR) {
00053         ADR_LOG("waveOutPrepareHeader failed");
00054       }
00055 
00056       result = waveOutWrite(m_device, &wh, sizeof(wh));
00057       if (result != MMSYSERR_NOERROR) {
00058         ADR_LOG("waveOutWrite failed");
00059       }
00060     }
00061   }
00062 
00063 
00064   MMAudioDevice::~MMAudioDevice() {
00065     waveOutReset(m_device);
00066 
00067     for (int i = 0; i < BUFFER_COUNT; ++i) {
00068       WAVEHDR& wh = m_buffers[i];
00069       if (wh.dwFlags & WHDR_PREPARED || wh.dwFlags & WHDR_DONE) {
00070         waveOutUnprepareHeader(m_device, &wh, sizeof(wh));
00071       }
00072     }
00073 
00074     waveOutClose(m_device);
00075   }
00076 
00077 
00078   void
00079   MMAudioDevice::update() {
00080     ADR_GUARD("MMAudioDevice::update");
00081 
00082     // if a buffer is done playing, add it to the queue again
00083     for (int i = 0; i < BUFFER_COUNT; ++i) {
00084       WAVEHDR& wh = m_buffers[i];
00085       if (wh.dwFlags & WHDR_DONE) {
00086 
00087         // unprepare
00088         MMRESULT result = waveOutUnprepareHeader(m_device, &wh, sizeof(wh));
00089         if (result != MMSYSERR_NOERROR) {
00090           ADR_LOG("waveOutUnprepareHeader failed");
00091         }
00092 
00093         // fill with new samples
00094         read(BUFFER_LENGTH / 4, wh.lpData);
00095         wh.dwFlags = 0;
00096 
00097         // prepare
00098         result = waveOutPrepareHeader(m_device, &wh, sizeof(wh));
00099         if (result != MMSYSERR_NOERROR) {
00100           ADR_LOG("waveOutPrepareHeader failed");
00101         }
00102 
00103         // write
00104         result = waveOutWrite(m_device, &wh, sizeof(wh));
00105         if (result != MMSYSERR_NOERROR) {
00106           ADR_LOG("waveOutWrite failed");
00107         }
00108       }
00109     }
00110     Sleep(10);
00111   }
00112 
00113 
00114   const char*
00115   MMAudioDevice::getName() {
00116     return "winmm";
00117   }
00118 
00119 }

Generated on Mon Feb 13 23:07:46 2006 for audiere by  doxygen 1.4.6