//Return read buffer , 0 if none bool asRingRead(u8* dst,u32 sz) { if (sz==0) sz=BufferSampleCount; if (asRingUsedCount()>=sz) { const u32 ptr=ReadPtr; if ((ReadPtr+sz)<=RingBufferSampleCount) { //R ... W, just copy the sz :) memcpy(dst,&RingBuffer[ptr],sz*sizeof(s16)*2); } else { //...W R...., just copy the sz :) const u32 szhi=RingBufferSampleCount-ptr; const u32 szlow=sz-szhi; memcpy(dst,&RingBuffer[ptr],szhi*sizeof(s16)*2); dst+=szhi*sizeof(s16)*2; memcpy(dst,&RingBuffer[0],szlow*sizeof(s16)*2); } ReadPtr=(ptr+sz)%RingBufferSampleCount; speed_limit.Set(); return true; } else { //printf("ONLY %d used, rd=%d, wt=%d\n",asRingUsedCount(),ReadPtr,WritePtr); return false; } }
void WriteSample(s16 r, s16 l) { #if 0 #if HOST_OS==OS_WINDOWS #ifdef LOG_SOUND rawout.Write(l,r); #endif if (!asRingFreeCount()) { //printf("Buffer overrun\n"); if (settings.aica.LimitFPS) { //speed_limit.Wait(); } else return; } gen_samples++; //while limit on, 128 samples done, there is a buffer ready to be service AND speed is too fast then wait if (settings.aica.LimitFPS==1 && gen_samples>128) { for(;asRingUsedCount()>BufferSampleCount && (os_GetSeconds()-time_last)<=time_diff;) ; gen_samples=0; time_last=os_GetSeconds(); } #else if (!asRingFreeCount()) { if (settings.aica.LimitFPS) { while(!asRingFreeCount()) ; } else return; } #endif #endif const u32 ptr=(WritePtr+1)%RingBufferSampleCount; RingBuffer[ptr].r=r; RingBuffer[ptr].l=l; WritePtr=ptr; if (WritePtr==(SAMPLE_COUNT-1)) { os_Push(RingBuffer,SAMPLE_COUNT,settings.aica.LimitFPS); } }
/* SoundSample DWTTemp[4096]; bool asRingStretchDWT(u8* dst,u32 outcount,u32 usedcount) { u32 strech_count=next_pow2(usedcount); asRingStretchPitchChange((u8*)DWTTemp,strech_count,usedcount); //do DWT //shift the frequencys //do iDWT return true; } */ bool asRingStretchRead(u8* dst,u32 sz) { if (sz==1) return false; //not supported ... if (sz==0) sz=BufferSampleCount; u32 used=asRingUsedCount(); //used=min(used,sz*3/6); if (used==0) return false; if (settings.LimitFPS && used>=sz) { return asRingRead(dst,sz); } else { return asRingStretchPitchChange(dst,sz,used); } }
void WriteSample(s16 r, s16 l) { #ifdef LOG_SOUND rawout.Write(l,r); #endif speed_limit.Reset(); if (!asRingFreeCount()) { if (settings.LimitFPS) { speed_limit.Wait(); } else return; } gen_samples++; //while limit on, 128 samples done, there is a buffer ready to be service AND speed is too fast then wait ;p while (settings.LimitFPS==1 && gen_samples>128 && asRingUsedCount()>BufferSampleCount && QueryPerformanceCounter(&time_now) && (time_now.QuadPart-time_last.QuadPart)<=time_diff.QuadPart ) { __noop; } if (settings.LimitFPS==1 && gen_samples>128) { gen_samples=0; QueryPerformanceCounter(&time_last); } const u32 ptr=(WritePtr+1)%RingBufferSampleCount; RingBuffer[ptr].r=r; RingBuffer[ptr].l=l; WritePtr=ptr; //if (0==(WritePtr&255)) //printf("write done %d %d \n",ReadPtr,WritePtr); }
u32 asRingFreeCount() { return RingBufferSampleCount-asRingUsedCount()-1; }