static int RawWrite(void *data, uint32_t len) { // uint32_t cw; //printf("Pre: %d\n",SexyALI_DSound_RawCanWrite(device)); //fflush(stdout); CheckDStatus(); /* In this block, we write as much data as we can, then we write the rest of it in >=1ms chunks. */ while(len) { VOID *LockPtr[2]={0,0}; DWORD LockLen[2]={0,0}; int32_t curlen; while(!(curlen=RawCanWrite())) { Sleep(1); } if(curlen>len) curlen=len; if(DS_OK == IDirectSoundBuffer_Lock(ppbufw,ToWritePos,curlen,&LockPtr[0],&LockLen[0],&LockPtr[1],&LockLen[1],0)) { } if(LockPtr[1] != 0 && LockPtr[1] != LockPtr[0]) { memcpy(LockPtr[0],data,LockLen[0]); memcpy(LockPtr[1],data+LockLen[0],len-LockLen[0]); } else if(LockPtr[0]) { memcpy(LockPtr[0],data,curlen); } IDirectSoundBuffer_Unlock(ppbufw,LockPtr[0],LockLen[0],LockPtr[1],LockLen[1]); ToWritePos=(ToWritePos+curlen)%DSBufferSize; len-=curlen; data = (void *)((uint8_t *)data + curlen); if(len) Sleep(1); } // end while(len) loop return(1); }
static int RawWrite(SexyAL_device *device, const void *data, uint32_t len) { CMI8738_Driver_t *ds = (CMI8738_Driver_t *)device->private_data; uint32_t pl_0, pl_1; const uint8_t* data_d8 = (uint8_t*)data; do { uint32_t cw; uint32_t i_len; uint32_t writepos; if(!RawCanWrite(device, &cw)) // Caution: RawCanWrite() will modify ds->write_counter on underflow. return(0); writepos = (ds->write_counter << 2) % (ds->dmabuf.size << 4); i_len = std::min<uint32>(cw, len); pl_0 = std::min<uint32>(i_len, (ds->dmabuf.size << 4) - writepos); pl_1 = i_len - pl_0; if(pl_0) _dosmemputb(data_d8, pl_0, (ds->dmabuf.rm_segment << 4) + writepos); if(pl_1) _dosmemputb(data_d8 + pl_0, pl_1, (ds->dmabuf.rm_segment << 4)); ds->write_counter += i_len >> 2; data_d8 += i_len; len -= i_len; if(ds->paused) Pause(device, false); } while(len > 0); return(1); }
int32 GetWriteSound(void) { return(RawCanWrite() >> bittage); }