double VDAudioOutputWaveOutW32::GetPositionTime() { MMTIME mmtime; if (mCurState != kStatePlaying) return -1; mmtime.wType = TIME_MS; MMRESULT res; vdsynchronized(mcsWaveDevice) { res = waveOutGetPosition(mhWaveOut, &mmtime, sizeof mmtime); } if (MMSYSERR_NOERROR != res) return -1; switch(mmtime.wType) { case TIME_BYTES: return (double)mmtime.u.cb / (double)mAvgBytesPerSec; case TIME_MS: return (double)mmtime.u.ms / 1000.0; case TIME_SAMPLES: return (double)mmtime.u.sample / (double)mSamplesPerSec; } return -1; }
_int64 pcm_get_buffering_time() { if (!wout) return 1; MMTIME mmt; mmt.wType = TIME_BYTES; waveOutGetPosition(wout, &mmt, sizeof(mmt)); return (_int64)(total_bytes - mmt.u.cb) * 1000000 / cb_per_sec; }
ULONG GetPos(MADDriverRec *WinMADDriver) { MMTIME mmt; mmt.wType = TIME_BYTES; waveOutGetPosition(WinMADDriver->hWaveOut, &mmt,sizeof(MMTIME)); return(mmt.u.cb & 0xfffffff0); // A cause du 16 bits?? }
long msys_soundGetPosInSamples( void ) { MMTIME mmt; mmt.wType = TIME_SAMPLES; waveOutGetPosition( h, &mmt, sizeof(MMTIME) ); return mmt.u.cb; }
long getPosition(Audio *audio) { MMTIME mmtime; MMRESULT rc; mmtime.wType = TIME_MS; if (audio->whdr != NULL) { rc = waveOutGetPosition(audio->hwo, &mmtime, sizeof(mmtime)); return mmtime.u.ms; } else { return 0; } }
uint32_t AudioPlayback::QueryStreamPosition() { uint32_t pos = 0; if (hWaveOut && _sound) { MMTIME mmTime = {}; mmTime.wType = TIME_BYTES; if (MMSYSERR_NOERROR == waveOutGetPosition(hWaveOut, &mmTime, sizeof(mmTime))) { pos = mmTime.u.cb; } } return pos; }
DWORD AudioPlayback::QueryPosition(DWORD scope) { DWORD pos = 0; if (hWaveOut && _sound) { MMTIME mmTime = {}; mmTime.wType = TIME_BYTES; if (MMSYSERR_NOERROR == waveOutGetPosition(hWaveOut, &mmTime, sizeof(mmTime))) { pos = (scope * mmTime.u.cb / _sound->DigitalSamplePCM.size()); } } return pos; }
static void DrawWave(struct client *pc, HDC hdc, WPARAM wParam){ #if 0 int k; MMTIME mmtime; RECT rr = {320, 320, 320 + 32, 320 + 32}; mmtime.wType = TIME_SAMPLES; waveOutGetPosition(pc->hwo, &mmtime, sizeof mmtime); SetBkColor(hdc, !mmtime.u.sample ? RGB(255,0,0) : RGB(0,255,0)); ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rr, NULL, 0, NULL); rr.left += 32; rr.right += 32; for(k = 0; k < 2; k++){ SetBkColor(hdc, (~(whs[k].dwFlags | ~(/*WHDR_PREPARED |*/ WHDR_DONE))) | (whs[k].dwFlags & WHDR_INQUEUE) ? RGB(255,0,0) : RGB(0,255,0)); rr.left += k * 32; rr.right += k * 32; ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rr, NULL, 0, NULL); } #endif #if 1 int i, t; { MMTIME mmt; mmt.wType = TIME_SAMPLES; waveOutGetPosition(pc->hwo, &mmt, sizeof mmt); t = mmt.u.sample % numof(soundbuf[0]); } SetBkColor(hdc, RGB(127, 127, 127)); RECT rr = {320, 320, 320 + 256, 320 + 256}; ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rr, NULL, 0, NULL); for(i = 0; i < 256; i++){ if(i == t * numof(soundbuf[0]) / 256) SelectObject(hdc, GetStockObject(WHITE_PEN)); MoveToEx(hdc, 320 + i, 320 + 128, NULL); LineTo(hdc, 320 + i, 320 + ((BYTE*)((WAVEHDR*)wParam)->lpData)[i * numof(soundbuf[0]) / 256]); } #endif }
float WaveLib_PlaybackTime(HWAVEOUT hWaveOut) { //PWAVELIB pWaveLib = NULL; FLOAT time; //int total_playtime = WaveFileHeader. playbacktime.wType = TIME_MS; //Make sure time is in the smpte section of the mmtime struct playbacktime_size = sizeof(playbacktime); waveOutGetPosition(hWaveOut, &playbacktime, playbacktime_size); time = (float)playbacktime.u.ms / 100000; //printf("Elapsed Time: %0.4f",time); return time; //printf("Elapsed Time: %d:%",playbacktime.u.smpte.min, playbacktime.u.smpte.sec); }
DWORD COutput::GetCurrent() { CAutoLock lock(&m_csecDevice); if (!m_hwo) return 0; if (m_fDoubleBuf) return m_dwTotalSamples; MMTIME time; memset(&time, 0, sizeof(MMTIME)); time.wType = TIME_SAMPLES; waveOutGetPosition(m_hwo, &time, sizeof(MMTIME)); return time.u.sample; }
int cubeb_stream_get_position(cubeb_stream * stm, uint64_t * position) { MMRESULT r; MMTIME time; time.wType = TIME_SAMPLES; r = waveOutGetPosition(stm->waveout, &time, sizeof(time)); assert(r == MMSYSERR_NOERROR); assert(time.wType == TIME_SAMPLES); *position = time.u.sample; return CUBEB_OK; }
/** sync/timing */ int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) { int status; MMTIME mm; ERROR_IF_NO_INIT(s); if (position != SA_POSITION_WRITE_HARDWARE) { return SA_ERROR_NOT_SUPPORTED; } // request playback progress in bytes mm.wType = TIME_BYTES; status = waveOutGetPosition(s->hWaveOut, &mm, sizeof(MMTIME)); HANDLE_WAVE_ERROR(status, "reading audio buffer position"); *pos = (int64_t)mm.u.cb; return SA_SUCCESS; }
static int winmm_stream_get_latency(cubeb_stream * stm, uint32_t * latency) { MMRESULT r; MMTIME time; uint64_t written; EnterCriticalSection(&stm->lock); time.wType = TIME_SAMPLES; r = waveOutGetPosition(stm->waveout, &time, sizeof(time)); written = stm->written; LeaveCriticalSection(&stm->lock); *latency = written - time.u.sample; return CUBEB_OK; }
/* [DESCRIPTION] [PARAMETERS] [RETURN_VALUE] [REMARKS] [SEE_ALSO] */ DWORD FSOUND_Software_DoubleBufferThread(LPDWORD lpdwParam) { int totalblocks; FSOUND_Software_ThreadFinished = FALSE; totalblocks = FSOUND_BufferSize / FSOUND_BlockSize; while (!FSOUND_Software_Exit) { int cursorpos,cursorblock,prevblock; MMTIME mmt; mmt.wType = TIME_BYTES; waveOutGetPosition(FSOUND_WaveOutHandle, &mmt, sizeof(MMTIME)); mmt.u.cb >>= 2; cursorpos = mmt.u.cb; cursorpos %= FSOUND_BufferSize; cursorblock = cursorpos / FSOUND_BlockSize; prevblock = cursorblock - 1; if (prevblock < 0) prevblock = totalblocks - 1; while (FSOUND_Software_FillBlock != cursorblock) { FSOUND_Software_UpdateMutex = TRUE; FSOUND_Software_Fill(); FSOUND_Software_RealBlock++; if (FSOUND_Software_RealBlock >= totalblocks) FSOUND_Software_RealBlock = 0; FSOUND_Software_UpdateMutex = FALSE; } Sleep(5); }; FSOUND_Software_ThreadFinished = TRUE; return 0; }
static pa_usec_t sink_get_latency(struct userdata *u) { uint32_t free_frags; MMTIME mmt; pa_assert(u); pa_assert(u->sink); memset(&mmt, 0, sizeof(mmt)); mmt.wType = TIME_BYTES; if (waveOutGetPosition(u->hwo, &mmt, sizeof(mmt)) == MMSYSERR_NOERROR) return pa_bytes_to_usec(u->written_bytes - mmt.u.cb, &u->sink->sample_spec); else { EnterCriticalSection(&u->crit); free_frags = u->free_ofrags; LeaveCriticalSection(&u->crit); return pa_bytes_to_usec((u->fragments - free_frags) * u->fragment_size, &u->sink->sample_spec); } }
UINT64 GetPos() { static const DWORD WRAP_BITS = 27; static const UINT64 WRAP_MASK = (1 << 27) - 1; static const int WRAP_THRESHOLD = 1 << (WRAP_BITS - 1); // Taking a snapshot to avoid possible thread interference UINT64 playPositionSnapshot = prevPlayPosition; DWORD wrapCount = DWORD(playPositionSnapshot >> WRAP_BITS); DWORD wrappedPosition = DWORD(playPositionSnapshot & WRAP_MASK); MMTIME mmTime; mmTime.wType = TIME_SAMPLES; if (waveOutGetPosition(hWaveOut, &mmTime, sizeof(MMTIME)) != MMSYSERR_NOERROR) { MessageBox(NULL, L"Failed to get current playback position", L"MT32", MB_OK | MB_ICONEXCLAMATION); return 10; } if (mmTime.wType != TIME_SAMPLES) { MessageBox(NULL, L"Failed to get # of samples played", L"MT32", MB_OK | MB_ICONEXCLAMATION); return 10; } mmTime.u.sample &= WRAP_MASK; // Deal with waveOutGetPosition() wraparound. For 16-bit stereo output, it equals 2^27, // presumably caused by the internal 32-bit counter of bits played. // The output of that nasty waveOutGetPosition() isn't monotonically increasing // even during 2^27 samples playback, so we have to ensure the difference is big enough... int delta = mmTime.u.sample - wrappedPosition; if (delta < -WRAP_THRESHOLD) { #ifdef ENABLE_DEBUG_OUTPUT std::cout << "MT32: GetPos() wrap: " << delta << "\n"; #endif ++wrapCount; } else if (delta < 0) { // This ensures the return is monotonically increased #ifdef ENABLE_DEBUG_OUTPUT std::cout << "MT32: GetPos() went back by " << delta << " samples\n"; #endif return playPositionSnapshot; } prevPlayPosition = playPositionSnapshot = mmTime.u.sample + (wrapCount << WRAP_BITS); return playPositionSnapshot; }
int cubeb_stream_get_position(cubeb_stream * stm, uint64_t * position) { MMRESULT r; MMTIME time; EnterCriticalSection(&stm->lock); time.wType = TIME_SAMPLES; r = waveOutGetPosition(stm->waveout, &time, sizeof(time)); LeaveCriticalSection(&stm->lock); if (r != MMSYSERR_NOERROR || time.wType != TIME_SAMPLES) { return CUBEB_ERROR; } *position = time.u.sample; return CUBEB_OK; }
BOOL COXSound::GetCurrentPosition(MMTIME* pMMTime) const { if(!m_hWaveOut) { return FALSE; } if(!IsPlaying()) { return FALSE; } ASSERT(pMMTime != NULL); // Return time in milliseconds pMMTime->wType=TIME_MS; MMRESULT hResult; hResult=waveOutGetPosition(m_hWaveOut,pMMTime,sizeof(MMTIME)); return (hResult==MMSYSERR_NOERROR); }
static int winmm_stream_get_latency(cubeb_stream * stm, uint32_t * latency) { MMRESULT r; MMTIME time; uint64_t written; EnterCriticalSection(&stm->lock); time.wType = TIME_SAMPLES; r = waveOutGetPosition(stm->waveout, &time, sizeof(time)); written = stm->written; LeaveCriticalSection(&stm->lock); if (r != MMSYSERR_NOERROR || time.wType != TIME_SAMPLES) { return CUBEB_ERROR; } XASSERT(written - time.u.sample <= UINT32_MAX); *latency = (uint32_t) (written - time.u.sample); return CUBEB_OK; }
CADENCII_MEDIA_HELPER_API(double, SoundGetPosition)() { if ( NULL == wave_out ) { return 0.0; } MMTIME mmt; mmt.wType = TIME_MS; EnterCriticalSection( &locker ); waveOutGetPosition( wave_out, &mmt, sizeof( MMTIME ) ); LeaveCriticalSection( &locker ); float ms = 0.0f; switch ( mmt.wType ) { case TIME_MS: return mmt.u.ms * 0.001; case TIME_SAMPLES: return (double)mmt.u.sample / (double)wave_format.nSamplesPerSec; case TIME_BYTES: return (double)mmt.u.cb / (double)wave_format.nAvgBytesPerSec; default: return 0.0; } return 0.0; }
void SoundCardPMO::HandleTimeInfoEvent(PMOTimeInfoEvent *pEvent) { MediaTimeInfoEvent *pmtpi; int32 hours, minutes, seconds; int iTotalTime = 0; MMTIME sTime; if (m_iBaseTime == MAXINT32) { if (!pEvent) return; m_iBaseTime = (pEvent->GetFrameNumber() * m_samples_per_frame) / m_samples_per_second; sTime.wType = TIME_BYTES; if (waveOutGetPosition(m_hwo, &sTime, sizeof(sTime)) != MMSYSERR_NOERROR) return; m_iBaseTime -= (sTime.u.cb / (m_samples_per_second * m_iBytesPerSample)); m_iLastTime = 0; } if (m_samples_per_second <= 0) return; sTime.wType = TIME_BYTES; if (waveOutGetPosition(m_hwo, &sTime, sizeof(sTime)) != MMSYSERR_NOERROR) return; iTotalTime = (sTime.u.cb / (m_samples_per_second * m_iBytesPerSample)) + m_iBaseTime; // Time needs to be greater or equal to the last time for each pass, // otherwise we have a break in playback, in which case we need to // reset the base time. After a break in playback the waveOutGetPosition() // function will reset back to 0. // Alternatively, if m_iBaseTime gets messed up (i.e. its more than 24 hours!) // force a reset as well. if (iTotalTime < m_iLastTime || (m_iBaseTime > 86400 && m_iBaseTime < MAXINT32)) { Debug_v("Reset: %d %d %d", iTotalTime, m_iLastTime, m_iBaseTime); m_iBaseTime = MAXINT32; return; } hours = iTotalTime / 3600; minutes = (iTotalTime - (hours * 3600)) / 60; seconds = iTotalTime - (hours * 3600) - (minutes * 60); // If something became wonky, reset. if (minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59 || hours < 0 || hours > 24) { m_iBaseTime = MAXINT32; return; } pmtpi = new MediaTimeInfoEvent(hours, minutes, seconds, 0, (float)iTotalTime, 0); m_pTarget->AcceptEvent(pmtpi); m_iLastTime = iTotalTime; }
void entrypoint( void ) { // full screen #ifdef SETRESOLUTION if( ChangeDisplaySettings(&screenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) return; #endif // create window HWND hWnd = CreateWindow( "static",0,WS_POPUP|WS_VISIBLE|WS_MAXIMIZE,0,0,0,0,0,0,0,0); HDC hDC = GetDC(hWnd); // initalize opengl if( !SetPixelFormat(hDC,ChoosePixelFormat(hDC,&pfd),&pfd) ) return; HGLRC tempOpenGLContext; tempOpenGLContext = wglCreateContext(hDC); wglMakeCurrent(hDC, tempOpenGLContext); // create openGL functions for (int i=0; i<NUM_GL_NAMES; i++) glFP[i] = (GenFP)wglGetProcAddress(glnames[i]); HGLRC hRC = wglCreateContextAttribsARB(hDC, NULL, glAttribs); // Remove temporary context and set new one wglMakeCurrent(NULL, NULL); wglDeleteContext(tempOpenGLContext); wglMakeCurrent(hDC, hRC); // init intro intro_init(); // open audio device waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL); // create music block mzk_init(); // prepare and play music block header[0].lpData = (char *)myMuzikBlock[0]; header[1].lpData = (char *)myMuzikBlock[1]; header[0].dwBufferLength = AUDIO_BUFFER_SIZE * MZK_NUMCHANNELS * 2; header[1].dwBufferLength = AUDIO_BUFFER_SIZE * MZK_NUMCHANNELS * 2; waveOutPrepareHeader(hWaveOut, &(header[0]), sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &(header[0]), sizeof(WAVEHDR)); waveOutPrepareHeader(hWaveOut, &(header[1]), sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &(header[1]), sizeof(WAVEHDR)); timer.wType = TIME_SAMPLES; do { MSG msg; PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); ShowCursor(0); waveOutGetPosition(hWaveOut, &timer, sizeof(timer)); DWORD t = timer.u.sample; intro_do(t); //SwapBuffers ( hDC ); wglSwapLayerBuffers( hDC, WGL_SWAP_MAIN_PLANE ); // Try to unprepare header if (waveOutUnprepareHeader(hWaveOut, &(header[nextPlayBlock]), sizeof(WAVEHDR)) != WAVERR_STILLPLAYING) { mzk_prepare_block(myMuzikBlock[nextPlayBlock]); waveOutPrepareHeader(hWaveOut, &(header[nextPlayBlock]), sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &(header[nextPlayBlock]), sizeof(WAVEHDR)); nextPlayBlock = 1 - nextPlayBlock; } } while ( !(GetAsyncKeyState(VK_ESCAPE) || GetAsyncKeyState(VK_F4))); sndPlaySound(0,0); ExitProcess(0); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; char file[512]; WAVEHDR * pwhOut; MMTIME mmt; unsigned long * framebuf; switch (message) // switch selon le message { case WM_CREATE: SetTimer(hWnd,0,10,NULL); break; case WM_DROPFILES: file[0] = 0; DragQueryFile((HDROP)wParam, 0, (char*)file, sizeof(file)); loadmod(file); break; case WM_TIMER: mmt.wType = TIME_SAMPLES; if(waveOutGetPosition(wout,&mmt,sizeof(MMTIME)) == MMSYSERR_NOERROR) { file[0] = 0; if(IsWindowVisible(hWnd) && fg) { if(mmt.u.sample&NBSTEREO16BITSAMPLES) { framebuf = fg_generateFrame(fg,&trackbuf_state2,mmt.u.sample&(NBSTEREO16BITSAMPLES-1)); } else { framebuf = fg_generateFrame(fg,&trackbuf_state1,mmt.u.sample&(NBSTEREO16BITSAMPLES-1)); } updateScreen(hWnd, framebuf, fg->xres,fg->yres); } } break; case WM_COMMAND: //Action sur un menu wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch(wmId) { case IDI_PLAY: waveOutRestart(wout); break; case IDI_PAUSE: waveOutPause(wout); break; case IDI_EJECT: file[0] = 0; if(fileselector(hWnd,file,"Load mod file","*.mod","*.mod",0,0)) { loadmod(file); } break; case IDI_INFO: break; case IDI_FILTER: break; case IDI_STEREO: break; case IDI_QUIT: PostQuitMessage(0); break; } break; case WM_DESTROY: break; case WM_USER: //Message venant de l'icone de la barre des taches switch(lParam) { case WM_LBUTTONDOWN: if(GetFocus() == hWnd) { ShowWindow(hWnd,SW_HIDE); } else { ShowWindow(hWnd,SW_SHOWNORMAL); SetFocus(hWnd); } break; case WM_RBUTTONDOWN: ListPopup(hWnd); break; } break; case WM_USER+1: break; case WM_CLOSE: //message de fermeture ShowWindow(hWnd,SW_HIDE); break; case WM_MOUSEMOVE: break; case MM_WOM_OPEN: break; case MM_WOM_CLOSE: break; case MM_WOM_DONE: pwhOut = (struct wavehdr_tag *)lParam; if(pwhOut->lpData == (char*)&sndbuffer1) { trackbuf_state1.nb_of_state = 0; hxcmod_fillbuffer(&modloaded,(unsigned short*)pwhOut->lpData, pwhOut->dwBufferLength /4,&trackbuf_state1); } else { trackbuf_state2.nb_of_state = 0; hxcmod_fillbuffer(&modloaded,(unsigned short*)pwhOut->lpData, pwhOut->dwBufferLength /4,&trackbuf_state2); } waveOutWrite((HWAVEOUT)wParam,pwhOut,sizeof(WAVEHDR)); nb_wr_block++; break; case WM_KEYDOWN: break; default: // traitement par defaut de l'evenement (gerer par windows) return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
int GetCurrentSample() { waveOutGetPosition(hWaveOut, &MMTime, sizeof(MMTIME)); return MMTime.u.sample; }
DWORD PlayWavStream::GetCurrentTime() { DWORD dwResult = 0; m_mtWavOut.Lock(); if ( m_pWavOut && NULL != m_pWavOut->GetHwave() ) { MMTIME mmt; MMRESULT mmr; mmt.wType = TIME_BYTES; mmr = waveOutGetPosition( m_pWavOut->GetHwave(), &mmt, sizeof( mmt ) ); if ( m_WavFormat.nAvgBytesPerSec ) { dwResult = (DWORD)( mmt.u.cb * 1000.0 / m_WavFormat.nAvgBytesPerSec ); } } m_mtWavOut.Unlock(); return dwResult; }
// Return the time in milliseconds corresponding to the currently playing audio sample, or -1 if no audio is playing. LONG CALLBACK aviaudioTime(void) { MMTIME mmtime; if (audioPlayable <= 0) return -1; if (!sfPlaying) return -1; //not sure if (recalc) { streamEnd = AVIStreamEnd(spavi); streamStart = AVIStreamStart(spavi); recalc = 0; //ErrMsg("recalc"); } if ((streamEnd<=streamStart) || (streamEnd<=0)) return -1; mmtime.wType = TIME_SAMPLES; waveOutGetPosition(shWaveOut, &mmtime, sizeof(mmtime)); if (mmtime.wType == TIME_SAMPLES) return AVIStreamSampleToTime(spavi, slBegin) + muldiv32(mmtime.u.sample, 1000, sdwSamplesPerSec); else if (mmtime.wType == TIME_BYTES) return AVIStreamSampleToTime(spavi, slBegin) + muldiv32(mmtime.u.cb, 1000, sdwBytesPerSec); else return -1; }
sint32 VDAudioOutputWaveOutW32::GetPositionBytes() { MMTIME mmtime; if (mCurState != kStatePlaying) return -1; mmtime.wType = TIME_BYTES; MMRESULT res; vdsynchronized(mcsWaveDevice) { res = waveOutGetPosition(mhWaveOut, &mmtime, sizeof mmtime); } if (MMSYSERR_NOERROR != res) return -1; switch(mmtime.wType) { case TIME_BYTES: return mmtime.u.cb; case TIME_MS: return MulDiv(mmtime.u.ms, mAvgBytesPerSec, 1000); case TIME_SAMPLES: return MulDiv(mmtime.u.sample, mAvgBytesPerSec, mSamplesPerSec); } return -1; }
int64_t RageSoundDriver_WaveOut::GetPosition() const { MMTIME tm; tm.wType = TIME_SAMPLES; MMRESULT ret = waveOutGetPosition( m_hWaveOut, &tm, sizeof(tm) ); if( ret != MMSYSERR_NOERROR ) FAIL_M( wo_ssprintf(ret, "waveOutGetPosition failed") ); return tm.u.sample; }
MMRESULT TinyWaveOut::GetPosition(LPMMTIME pmmt) { if (hWaveOut == NULL || pmmt == NULL) return S_FALSE; MMRESULT hRes = waveOutGetPosition(hWaveOut, pmmt, sizeof(WAVEOUTCAPS)); if (hRes != MMSYSERR_NOERROR) { waveOutClose(hWaveOut); hWaveOut = NULL; } return hRes; }
void flip() { MMTIME time; int err; if (playing==0) return; if (timeout) { if (--timeout) return; buffer.play(device); } memset(&time,0,sizeof(MMTIME)); time.wType=TIME_BYTES; err=waveOutGetPosition(device,&time,sizeof(MMTIME)); if (time.wType!=TIME_BYTES) err=-666;else if (time.u.cb>0x10000000) err=-6667; if (err) { // printf("waveOutGetPosition failed err=%d\n",err);fflush(stdout); waveOutReset(device); mixpos=0; memset(buffer.data,0,buffersize*samplesize*32); buffer.play(device); return; } int wavepos=time.u.cb/samplesize; int writeahead=buffersize*lagbuffers; if (wavepos && wavepos+buffersize*2>mixpos) { timeout=250; memset(buffer.data,0,buffersize*samplesize*32); waveOutReset(device); if (lagbuffers<10) lagbuffers+=2; mixpos=buffersize*lagbuffers*2; // printf("collision");fflush(stdout); return; } int seek=wavepos+writeahead; while (mixpos<seek) { int f=(mixpos/buffersize)&31; if (mode==0) { mix->mix8(buffer.data+f*buffersize); } else { mix->mix16((short *)buffer.data+f*buffersize); } mixpos+=buffersize; } }