From c83ecfe99390a8a3192e55bad94dcf593348deb7 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 26 Feb 2025 20:29:13 -0500 Subject: [PATCH 01/11] prepare new chan osc code chan osc output will be 65536Hz - always new functions for initializing the osc buffer and all --- src/engine/dispatch.h | 15 +++++++++++++++ src/engine/platform/abstract.cpp | 4 ++++ src/engine/platform/pcspkr.cpp | 10 ++++++++++ src/engine/platform/pcspkr.h | 1 + 4 files changed, 30 insertions(+) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 6c30c6656..ba083ae94 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -424,6 +424,7 @@ struct DivSamplePos { freq(0) {} }; +// the actual output of all DivDispatchOscBuffer instanced runs at 65536Hz. struct DivDispatchOscBuffer { bool follow; unsigned int rate; @@ -432,6 +433,20 @@ struct DivDispatchOscBuffer { unsigned short followNeedle; short data[65536]; + // TODO: all of this + inline void putSample(unsigned short pos, short val) { + unsigned short realPos=needle+pos; + if (val==0xffff) { + data[needle+pos]=0xfffe; + return; + } + data[needle+pos]=val; + } + inline void begin(unsigned short len) { + } + inline void end(unsigned short len) { + needle+=len; + } DivDispatchOscBuffer(): follow(true), rate(65536), diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 73abebc30..41662176b 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -134,6 +134,10 @@ bool DivDispatch::hasAcquireDirect() { return false; } +bool DivDispatch::isOscBufPositional() { + return false; +} + bool DivDispatch::getWantPreNote() { return false; } diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index bc55ae402..75f38d312 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -210,6 +210,8 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t } out=(posToggle && !isMuted[0])?32767:0; blip_add_delta(bb[0],off,out-oldOut); + oscBuf->data[oscBuf->needle++]=oscBufPos; + oscBuf->data[oscBuf->needle++]=out; oldOut=out; if (freq>=1) { size_t boff=off; @@ -222,6 +224,7 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t i-=timeToNextToggle; boff+=timeToNextToggle; pos-=timeToNextToggle; + oscBufPos+=timeToNextToggle; if (pos<=0) { pos=freq1; } @@ -234,6 +237,8 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t } out=(posToggle && !isMuted[0])?32767:0; blip_add_delta(bb[0],boff,out-oldOut); + oscBuf->data[oscBuf->needle++]=oscBufPos; + oscBuf->data[oscBuf->needle++]=out; oldOut=out; } } @@ -641,6 +646,10 @@ bool DivPlatformPCSpeaker::hasAcquireDirect() { return (speakerType==0 || speakerType==3); } +bool DivPlatformPCSpeaker::isOscBufPositional() { + return (speakerType==0 || speakerType==3); +} + void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) { switch (flags.getInt("clockSel",0)) { case 1: // PC-98 @@ -705,6 +714,7 @@ int DivPlatformPCSpeaker::init(DivEngine* p, int channels, int sugRate, const Di for (int i=0; i<1; i++) { isMuted[i]=false; } + oscBufPos=0; oscBuf=new DivDispatchOscBuffer; setFlags(flags); diff --git a/src/engine/platform/pcspkr.h b/src/engine/platform/pcspkr.h index 8d7b1c546..65300e75f 100644 --- a/src/engine/platform/pcspkr.h +++ b/src/engine/platform/pcspkr.h @@ -88,6 +88,7 @@ class DivPlatformPCSpeaker: public DivDispatch { void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); bool hasAcquireDirect(); + bool isOscBufPositional(); void setFlags(const DivConfig& flags); void notifyInsDeletion(void* ins); void notifyPlaybackStop(); From 0eea0ec139117ab36acf2548854ba06c96279ad5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 1 Mar 2025 00:33:15 -0500 Subject: [PATCH 02/11] a new method for setting chan osc rate... --- src/engine/dispatch.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index ba083ae94..5a4940019 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -428,6 +428,7 @@ struct DivSamplePos { struct DivDispatchOscBuffer { bool follow; unsigned int rate; + size_t rateMul; unsigned short needle; unsigned short readNeedle; unsigned short followNeedle; @@ -446,6 +447,9 @@ struct DivDispatchOscBuffer { } inline void end(unsigned short len) { needle+=len; + } + void setRate(unsigned int r) { + } DivDispatchOscBuffer(): follow(true), From dd7e1def3d2630e6b272ca97baad2bccdc0bae75 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 1 Mar 2025 05:05:50 -0500 Subject: [PATCH 03/11] new chan osc work in progress --- src/engine/dispatch.h | 65 ++++++++++++++++----- src/engine/engine.cpp | 4 +- src/engine/platform/abstract.cpp | 4 -- src/engine/platform/amiga.cpp | 15 ++++- src/engine/platform/ga20.cpp | 12 +++- src/engine/platform/pcspkr.cpp | 25 ++++---- src/engine/platform/snes.cpp | 10 +++- src/engine/playback.cpp | 4 +- src/gui/chanOsc.cpp | 99 ++++++++++++++++++++++---------- src/gui/debugWindow.cpp | 2 +- src/gui/gui.cpp | 5 +- 11 files changed, 171 insertions(+), 74 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 5a4940019..91f430b4b 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -424,40 +424,79 @@ struct DivSamplePos { freq(0) {} }; +constexpr uintmax_t OSCBUF_PREC=(sizeof(uintmax_t)>=8)?32:16; +constexpr uintmax_t OSCBUF_MASK=(1UL<>OSCBUF_PREC); + if (val==-1) { + data[realPos]=0xfffe; return; } - data[needle+pos]=val; + lastSample=val; + data[realPos]=val; } inline void begin(unsigned short len) { + uintmax_t calc=(needleSub+len*rateMul)>>OSCBUF_PREC; + unsigned short start=needle; + unsigned short end=needle+calc; + + if (end=(OSCBUF_MASK+1UL)) { + needle++; + } + needleSub=(needleSub+calc)&OSCBUF_MASK; + needle+=calc>>OSCBUF_PREC; + data[needle]=lastSample; + } + void reset() { + memset(data,-1,65536*sizeof(short)); + needle=0; + readNeedle=0; + followNeedle=0; + needleSub=0; + lastSample=0; } void setRate(unsigned int r) { - + double rateMulD=65536.0/(double)r; + rateMulD*=(double)(1UL<getOscBuffer(dispatchChanOfChan[i]); if (buf!=NULL) { - memset(buf->data,0,65536*sizeof(short)); - buf->needle=0; - buf->readNeedle=0; + buf->reset(); } } BUSY_END; diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 41662176b..73abebc30 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -134,10 +134,6 @@ bool DivDispatch::hasAcquireDirect() { return false; } -bool DivDispatch::isOscBufPositional() { - return false; -} - bool DivDispatch::getWantPreNote() { return false; } diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 0c4022021..71f39b420 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -82,6 +82,10 @@ const char** DivPlatformAmiga::getRegisterSheet() { void DivPlatformAmiga::acquire(short** buf, size_t len) { thread_local int outL, outR, output; + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h>7; outR+=(output*sep1)>>7; } - oscBuf[i]->data[oscBuf[i]->needle++]=(amiga.nextOut[i]*MIN(64,amiga.audVol[i]&127))<<1; + oscBuf[i]->putSample(h,(amiga.nextOut[i]*MIN(64,amiga.audVol[i]&127))<<1); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=0; + // TODO: we can remove this! + oscBuf[i]->putSample(h,0); } } @@ -195,6 +200,10 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) { buf[0][h]=filter[0][1]; buf[1][h]=filter[1][1]; } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformAmiga::irq(int ch) { @@ -826,7 +835,7 @@ void DivPlatformAmiga::setFlags(const DivConfig& flags) { rate=chipClock/AMIGA_DIVIDER; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } int sep=flags.getInt("stereoSep",0)&127; sep1=sep+127; diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index e5e3894da..94306cd98 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -60,6 +60,10 @@ void DivPlatformGA20::acquire(short** buf, size_t len) { } } + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h>2; for (int i=0; i<4; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=ga20Buf[i][h]>>1; + oscBuf[i]->putSample(h,ga20Buf[i][h]>>1); } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } u8 DivPlatformGA20::read_byte(u32 address) { @@ -403,7 +411,7 @@ void DivPlatformGA20::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index 75f38d312..a41a18ead 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -196,6 +196,7 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t int out=0; int freq1=freq+1; int timeToNextToggle=0; + oscBuf->begin(len); if (on) { // just in case if (pos>freq1) { @@ -210,11 +211,11 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t } out=(posToggle && !isMuted[0])?32767:0; blip_add_delta(bb[0],off,out-oldOut); - oscBuf->data[oscBuf->needle++]=oscBufPos; oscBuf->data[oscBuf->needle++]=out; oldOut=out; if (freq>=1) { size_t boff=off; + size_t oscOff=0; size_t i=len; while (true) { if ((int)idata[oscBuf->needle++]=oscBufPos; - oscBuf->data[oscBuf->needle++]=out; + oscBuf->putSample(oscOff,out); oldOut=out; } } } else { out=0; blip_add_delta(bb[0],off,out-oldOut); + oscBuf->putSample(0,out); oldOut=out; } + oscBuf->end(len); } void DivPlatformPCSpeaker::acquire_cone(short** buf, size_t len) { + oscBuf->begin(len); for (size_t i=0; i1.0) out=1.0; if (out<-1.0) out=-1.0; buf[0][i]=out*32767; - oscBuf->data[oscBuf->needle++]=out*32767; + oscBuf->putSample(i,out*32767); } else { buf[0][i]=0; - oscBuf->data[oscBuf->needle++]=0; + oscBuf->putSample(i,0); } } + oscBuf->end(len); } void DivPlatformPCSpeaker::acquire_piezo(short** buf, size_t len) { + oscBuf->begin(len); for (size_t i=0; i1.0) out=1.0; if (out<-1.0) out=-1.0; buf[0][i]=out*32767; - oscBuf->data[oscBuf->needle++]=out*32767; + oscBuf->putSample(i,out*32767); } else { buf[0][i]=0; - oscBuf->data[oscBuf->needle++]=0; + oscBuf->putSample(i,0); } } + oscBuf->end(len); } void DivPlatformPCSpeaker::beepFreq(int freq, int delay) { @@ -670,7 +676,7 @@ void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) { } else { rate=chipClock/PCSPKR_DIVIDER; } - oscBuf->rate=rate; + oscBuf->setRate(rate); switch (speakerType) { case 1: @@ -714,7 +720,6 @@ int DivPlatformPCSpeaker::init(DivEngine* p, int channels, int sugRate, const Di for (int i=0; i<1; i++) { isMuted[i]=false; } - oscBufPos=0; oscBuf=new DivDispatchOscBuffer; setFlags(flags); diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index ee8ef975f..1c4136f4d 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -71,6 +71,9 @@ const char** DivPlatformSNES::getRegisterSheet() { void DivPlatformSNES::acquire(short** buf, size_t len) { short out[2]; short chOut[16]; + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } for (size_t h=0; h32767) next=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=next>>1; + oscBuf[i]->putSample(h,next>>1); } } + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSNES::tick(bool sysTick) { @@ -1058,7 +1064,7 @@ int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, const DivConf rate=chipClock/32; for (int i=0; i<8; i++) { oscBuf[i]=new DivDispatchOscBuffer; - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); isMuted[i]=false; } setFlags(flags); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index dcdfcbf57..5a7461a74 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1986,9 +1986,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { for (int i=0; igetOscBuffer(dispatchChanOfChan[i]); if (buf!=NULL) { - memset(buf->data,0,65536*sizeof(short)); - buf->needle=0; - buf->readNeedle=0; + buf->reset(); } } return ret; diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index 074ff9b1e..ededa8646 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -102,14 +102,14 @@ void FurnaceGUI::calcChanOsc() { } if (buf!=NULL && e->curSubSong->chanShowChanOsc[i]) { // 30ms should be enough - int displaySize=(float)(buf->rate)*0.03f; + int displaySize=65536.0f*0.03f; if (e->isRunning()) { short minLevel=32767; short maxLevel=-32768; unsigned short needlePos=buf->needle; - needlePos-=displaySize; - for (unsigned short i=0; i<512; i++) { - short y=buf->data[(unsigned short)(needlePos+(i*displaySize/512))]; + for (unsigned short i=needlePos-displaySize; i!=needlePos; i++) { + short y=buf->data[i]; + if (y==-1) continue; if (minLevel>y) minLevel=y; if (maxLevelrate)*(fft->windowSize/1000.0f); + int displaySize=65536.0f*(fft->windowSize/1000.0f); + int displaySize2=65536.0f*(fft->windowSize/500.0f); fft->loudEnough=false; fft->needle=buf->needle; // first FFT - for (int j=0; jinBuf[j]=(double)buf->data[(unsigned short)(fft->needle-displaySize*2+((j*displaySize*2)/(FURNACE_FFT_SIZE)))]/32768.0; - if (fft->inBuf[j]>0.001 || fft->inBuf[j]<-0.001) fft->loudEnough=true; - fft->inBuf[j]*=0.55-0.45*cos(M_PI*(double)j/(double)(FURNACE_FFT_SIZE>>1)); + int k=0; + short lastSample=0; + memset(fft->inBuf,0,FURNACE_FFT_SIZE*sizeof(double)); + if (displaySize2data[(unsigned short)(fft->needle-displaySize2+((j*displaySize2)/(FURNACE_FFT_SIZE)))]; + if (newData!=-1) lastSample=newData; + fft->inBuf[j]=(double)lastSample/32768.0; + if (fft->inBuf[j]>0.001 || fft->inBuf[j]<-0.001) fft->loudEnough=true; + fft->inBuf[j]*=0.55-0.45*cos(M_PI*(double)j/(double)(FURNACE_FFT_SIZE>>1)); + } + } else { + for (unsigned short j=fft->needle-displaySize2; j!=fft->needle; j++, k++) { + const int kIn=(k*FURNACE_FFT_SIZE)/displaySize2; + if (kIn>=FURNACE_FFT_SIZE) break; + if (buf->data[j]!=-1) lastSample=buf->data[j]; + fft->inBuf[kIn]=(double)lastSample/32768.0; + if (fft->inBuf[kIn]>0.001 || fft->inBuf[kIn]<-0.001) fft->loudEnough=true; + fft->inBuf[kIn]*=0.55-0.45*cos(M_PI*(double)kIn/(double)(FURNACE_FFT_SIZE>>1)); + } } // only proceed if not quiet @@ -615,7 +634,8 @@ void FurnaceGUI::drawChanOsc() { } } } else { - int displaySize=(float)(buf->rate)*(chanOscWindowSize/1000.0f); + int displaySize=65536.0f*(chanOscWindowSize/1000.0f); + int displaySize2=65536.0f*(chanOscWindowSize/500.0f); float minLevel=1.0f; float maxLevel=-1.0f; @@ -654,7 +674,7 @@ void FurnaceGUI::drawChanOsc() { } } if (fft->loudEnough) { - String cPhase=fmt::sprintf("\n%.1f (b: %d t: %d)",fft->waveLen,fft->waveLenBottom,fft->waveLenTop); + String cPhase=fmt::sprintf("\n%.1f (b: %d t: %d)\nSIZES: %d, %d, %d",fft->waveLen,fft->waveLenBottom,fft->waveLenTop,displaySize,displaySize2,FURNACE_FFT_SIZE); dl->AddText(inRect.Min,0xffffffff,cPhase.c_str()); dl->AddLine( @@ -673,31 +693,48 @@ void FurnaceGUI::drawChanOsc() { } } } else { - for (unsigned short j=0; jdata[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f; - if (minLevel>y) minLevel=y; - if (maxLevelAddText(inRect.Min,0xffffffff,dStr.c_str()); + if (displaySizedata[(unsigned short)(fft->needle+(j*displaySize/precision))]; + if (y_s!=-1) { + y=(float)y_s/32768.0f; + if (minLevel>y) minLevel=y; + if (maxLevel0.5f) yOut=0.5f; + yOut*=chanOscAmplify*2.0f; + fft->oscTex[j]=yOut; + } + } else { + float y=0; + int k=0; + for (unsigned short j=fft->needle; j!=fft->needle+displaySize; j++, k++) { + const short y_s=buf->data[j]; + const int kTex=(k*precision)/displaySize; + if (kTex>=precision) break; + if (y_s!=-1) { + y=(float)y_s/32768.0f; + if (minLevel>y) minLevel=y; + if (maxLevel0.5f) yOut=0.5f; + yOut*=chanOscAmplify*2.0f; + fft->oscTex[kTex]=yOut; + } } dcOff=(minLevel+maxLevel)*0.5f; - if (rend->supportsDrawOsc() && settings.shaderOsc) { - for (unsigned short j=0; jdata[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f; - y-=dcOff; - if (y<-0.5f) y=-0.5f; - if (y>0.5f) y=0.5f; - y*=chanOscAmplify*2.0f; - fft->oscTex[j]=y; - } - } else { + if (!(rend->supportsDrawOsc() && settings.shaderOsc)) { for (unsigned short j=0; jdata[(unsigned short)(fft->needle+(j*displaySize/precision))]/32768.0f; - y-=dcOff; - if (y<-0.5f) y=-0.5f; - if (y>0.5f) y=0.5f; - y*=chanOscAmplify; - waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y)); + waveform[j]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-fft->oscTex[j]*0.5f)); } } } diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index 89515ebfc..15f17f851 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -252,7 +252,7 @@ void FurnaceGUI::drawDebug() { ImGui::TableNextColumn(); ImGui::Text("Follow"); ImGui::TableNextColumn(); - ImGui::Text("Address"); + ImGui::Text("Needle"); ImGui::TableNextColumn(); ImGui::Text("Data"); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index a2402e553..60c245b86 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4181,8 +4181,9 @@ bool FurnaceGUI::loop() { for (int i=0; igetTotalChannelCount(); i++) { DivDispatchOscBuffer* buf=e->getOscBuffer(i); if (buf!=NULL) { - buf->needle=0; - buf->readNeedle=0; + //buf->needle=0; + //buf->readNeedle=0; + // TODO: should we reset here? } } }); From 6dc4f166896269279931661061b1731d3f1332aa Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 1 Mar 2025 06:10:59 -0500 Subject: [PATCH 04/11] GUI: add an audio load chart --- src/gui/gui.cpp | 3 +++ src/gui/gui.h | 3 +++ src/gui/stats.cpp | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 60c245b86..c85504773 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -8569,6 +8569,7 @@ FurnaceGUI::FurnaceGUI(): lastPatternWidth(0.0f), longThreshold(0.48f), buttonLongThreshold(0.20f), + lastAudioLoadsPos(0), latchNote(-1), latchIns(-2), latchVol(-1), @@ -8937,6 +8938,8 @@ FurnaceGUI::FurnaceGUI(): memset(keyHit,0,sizeof(float)*DIV_MAX_CHANS); memset(keyHit1,0,sizeof(float)*DIV_MAX_CHANS); + memset(lastAudioLoads,0,sizeof(float)*120); + memset(pianoKeyHit,0,sizeof(float)*180); memset(pianoKeyPressed,0,sizeof(bool)*180); diff --git a/src/gui/gui.h b/src/gui/gui.h index c82ebc799..8d252d3e6 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2379,6 +2379,9 @@ class FurnaceGUI { String nextDesc; String nextDescName; + float lastAudioLoads[120]; + int lastAudioLoadsPos; + OperationMask opMaskDelete, opMaskPullDelete, opMaskInsert, opMaskPaste, opMaskTransposeNote, opMaskTransposeValue; OperationMask opMaskInterpolate, opMaskFade, opMaskInvertVal, opMaskScale; OperationMask opMaskRandomize, opMaskFlip, opMaskCollapseExpand; diff --git a/src/gui/stats.cpp b/src/gui/stats.cpp index 0929cfd74..f9f27fa6d 100644 --- a/src/gui/stats.cpp +++ b/src/gui/stats.cpp @@ -31,11 +31,21 @@ void FurnaceGUI::drawStats() { if (ImGui::Begin("Statistics",&statsOpen,globalWinFlags,_("Statistics"))) { size_t lastProcTime=e->processTime; double maxGot=1000000000.0*(double)e->getAudioDescGot().bufsize/(double)e->getAudioDescGot().rate; - String procStr=fmt::sprintf("%.1f%%",100.0*((double)lastProcTime/(double)maxGot)); ImGui::AlignTextToFramePadding(); ImGui::Text(_("Audio load")); ImGui::SameLine(); - ImGui::ProgressBar((double)lastProcTime/maxGot,ImVec2(-FLT_MIN,0),procStr.c_str()); + ImGui::ProgressBar((double)lastProcTime/maxGot,ImVec2(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize("100.0%").x,0),""); + ImGui::SameLine(); + ImGui::Text("%.1f%%",100.0*((double)lastProcTime/(double)maxGot)); + if (ImGui::GetContentRegionAvail().y>8.0f*dpiScale) { + // draw a chart + lastAudioLoads[lastAudioLoadsPos]=(double)lastProcTime/maxGot; + if (++lastAudioLoadsPos>=120) lastAudioLoadsPos=0; + + ImGui::PushStyleColor(ImGuiCol_FrameBg,ImVec4(0,0,0,0)); + ImGui::PlotLines("##ALChart",lastAudioLoads,120,lastAudioLoadsPos,NULL,0.0f,1.0f,ImGui::GetContentRegionAvail()); + ImGui::PopStyleColor(); + } } if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_STATS; ImGui::End(); From 10e60ec8c1e5b2b435ccdb4b070f88f0374b1978 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 1 Mar 2025 17:22:34 -0500 Subject: [PATCH 05/11] new chan osc, part 2 why is it jerky? --- src/engine/dispatch.h | 9 +++++---- src/engine/platform/pcspkr.cpp | 2 +- src/gui/chanOsc.cpp | 15 ++++++++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 91f430b4b..5c17d5f1b 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -439,7 +439,6 @@ struct DivDispatchOscBuffer { bool follow; short data[65536]; - // TODO: all of this inline void putSample(uintmax_t pos, short val) { unsigned short realPos=needle+((needleSub+pos*rateMul)>>OSCBUF_PREC); if (val==-1) { @@ -454,8 +453,10 @@ struct DivDispatchOscBuffer { unsigned short start=needle; unsigned short end=needle+calc; + //logD("C %d %d %d",len,calc,rate); + if (end=(OSCBUF_MASK+1UL)) { - needle++; + if (((calc&OSCBUF_MASK)+needleSub)>OSCBUF_MASK) { + calc+=1UL<>OSCBUF_PREC; diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index a41a18ead..1dec2dbdd 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -211,7 +211,7 @@ void DivPlatformPCSpeaker::acquire_unfilt(blip_buffer_t** bb, size_t off, size_t } out=(posToggle && !isMuted[0])?32767:0; blip_add_delta(bb[0],off,out-oldOut); - oscBuf->data[oscBuf->needle++]=out; + oscBuf->putSample(0,out); oldOut=out; if (freq>=1) { size_t boff=off; diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index ededa8646..127337d4f 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -474,9 +474,10 @@ void FurnaceGUI::drawChanOsc() { short lastSample=0; memset(fft->inBuf,0,FURNACE_FFT_SIZE*sizeof(double)); if (displaySize2data[(unsigned short)(fft->needle-displaySize2+((j*displaySize2)/(FURNACE_FFT_SIZE)))]; if (newData!=-1) lastSample=newData; + if (j<0) continue; fft->inBuf[j]=(double)lastSample/32768.0; if (fft->inBuf[j]>0.001 || fft->inBuf[j]<-0.001) fft->loudEnough=true; fft->inBuf[j]*=0.55-0.45*cos(M_PI*(double)j/(double)(FURNACE_FFT_SIZE>>1)); @@ -693,17 +694,19 @@ void FurnaceGUI::drawChanOsc() { } } } else { - String dStr=fmt::sprintf("DS: %d P: %d",displaySize,precision); + String dStr=fmt::sprintf("DS: %d P: %d\nMAX: %d",displaySize,precision,(short)((fft->needle+displaySize)-fft->relatedBuf->needle)); dl->AddText(inRect.Min,0xffffffff,dStr.c_str()); if (displaySizedata[(unsigned short)(fft->needle+(j*displaySize/precision))]; if (y_s!=-1) { y=(float)y_s/32768.0f; + if (j<0) continue; if (minLevel>y) minLevel=y; if (maxLevel0.5f) yOut=0.5f; @@ -712,16 +715,18 @@ void FurnaceGUI::drawChanOsc() { } } else { float y=0; - int k=0; - for (unsigned short j=fft->needle; j!=fft->needle+displaySize; j++, k++) { + int k=-2048; + for (unsigned short j=fft->needle-2048; j!=fft->needle+displaySize; j++, k++) { const short y_s=buf->data[j]; const int kTex=(k*precision)/displaySize; if (kTex>=precision) break; if (y_s!=-1) { y=(float)y_s/32768.0f; + if (k<0) continue; if (minLevel>y) minLevel=y; if (maxLevel0.5f) yOut=0.5f; From c0e4552c52f924196d53b5a4c2d5e447127100a2 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 1 Mar 2025 18:46:11 -0500 Subject: [PATCH 06/11] new chan osc, part 3 fix the jerkiness! --- src/gui/chanOsc.cpp | 18 ++++++++++++++---- src/gui/gui.h | 3 ++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index 127337d4f..88086620b 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -550,8 +550,11 @@ void FurnaceGUI::drawChanOsc() { double dft[2]; dft[0]=0.0; dft[1]=0.0; - for (int j=fft->needle-1-(displaySize>>1)-(int)fft->waveLen, k=0; kwaveLen; j++, k++) { - double one=((double)buf->data[j&0xffff]/32768.0); + lastSample=0; + for (int j=fft->needle-1-displaySize-(int)fft->waveLen, k=-(displaySize>>1); kwaveLen; j++, k++) { + if (buf->data[j&0xffff]!=-1) lastSample=buf->data[j&0xffff]; + if (k<0) continue; + double one=((double)lastSample/32768.0); double two=(double)k*(-2.0*M_PI)/fft->waveLen; dft[0]+=one*cos(two); dft[1]+=one*sin(two); @@ -560,6 +563,8 @@ void FurnaceGUI::drawChanOsc() { // calculate and lock into phase phase=(0.5+(atan2(dft[1],dft[0])/(2.0*M_PI))); + fft->debugPhase=phase; + if (fft->waveCorr) { fft->needle-=(phase+(fft->phaseOff*2))*fft->waveLen; } @@ -675,7 +680,7 @@ void FurnaceGUI::drawChanOsc() { } } if (fft->loudEnough) { - String cPhase=fmt::sprintf("\n%.1f (b: %d t: %d)\nSIZES: %d, %d, %d",fft->waveLen,fft->waveLenBottom,fft->waveLenTop,displaySize,displaySize2,FURNACE_FFT_SIZE); + String cPhase=fmt::sprintf("\n%.1f (b: %d t: %d)\nSIZES: %d, %d, %d\nPHASE %f",fft->waveLen,fft->waveLenBottom,fft->waveLenTop,displaySize,displaySize2,FURNACE_FFT_SIZE,fft->debugPhase); dl->AddText(inRect.Min,0xffffffff,cPhase.c_str()); dl->AddLine( @@ -688,13 +693,18 @@ void FurnaceGUI::drawChanOsc() { ImLerp(inRect.Min,inRect.Max,ImVec2((double)fft->waveLenTop/(double)FURNACE_FFT_SIZE,1.0)), 0xff00ff00 ); + dl->AddLine( + ImLerp(inRect.Min,inRect.Max,ImVec2(0.75-(fft->debugPhase*0.25),0.0)), + ImLerp(inRect.Min,inRect.Max,ImVec2(0.75-(fft->debugPhase*0.25),1.0)), + 0xff00ffff + ); } else { if (debugFFT) { dl->AddText(inRect.Min,0xffffffff,"\nquiet"); } } } else { - String dStr=fmt::sprintf("DS: %d P: %d\nMAX: %d",displaySize,precision,(short)((fft->needle+displaySize)-fft->relatedBuf->needle)); + String dStr=fmt::sprintf("DS: %d P: %d\nMAX: %d\nPHASE %f",displaySize,precision,(short)((fft->needle+displaySize)-fft->relatedBuf->needle),fft->debugPhase); dl->AddText(inRect.Min,0xffffffff,dStr.c_str()); if (displaySize Date: Sat, 1 Mar 2025 19:49:56 -0500 Subject: [PATCH 07/11] new chan osc, part 4 adapt dispatch code to it --- src/engine/platform/arcade.cpp | 22 ++++++++++-- src/engine/platform/ay.cpp | 34 ++++++++++++------ src/engine/platform/ay8930.cpp | 16 ++++++--- src/engine/platform/bifurcator.cpp | 10 ++++-- src/engine/platform/bubsyswsg.cpp | 12 +++++-- src/engine/platform/c140.cpp | 20 ++++++++--- src/engine/platform/c64.cpp | 39 +++++++++++--------- src/engine/platform/dave.cpp | 58 +++++++++++++++++------------- src/engine/platform/dummy.cpp | 14 +++++--- src/engine/platform/es5506.cpp | 10 ++++-- src/engine/platform/esfm.cpp | 11 +++++- src/engine/platform/fds.cpp | 10 ++++-- src/engine/platform/gb.cpp | 12 +++++-- src/engine/platform/gbadma.cpp | 10 ++++-- src/engine/platform/gbaminmod.cpp | 12 +++++-- src/engine/platform/genesis.cpp | 2 +- src/engine/platform/su.cpp | 12 +++++-- src/gui/chanOsc.cpp | 2 ++ 18 files changed, 218 insertions(+), 88 deletions(-) diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index f12151011..24ed8a405 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -54,6 +54,10 @@ const char** DivPlatformArcade::getRegisterSheet() { void DivPlatformArcade::acquire_nuked(short** buf, size_t len) { thread_local int o[2]; + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h0) delay--; for (int i=0; i<8; i++) { @@ -81,7 +85,7 @@ void DivPlatformArcade::acquire_nuked(short** buf, size_t len) { for (int i=0; i<8; i++) { int chOut=(int16_t)fm.ch_out[i]; - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767)); } if (o[0]<-32768) o[0]=-32768; @@ -93,6 +97,10 @@ void DivPlatformArcade::acquire_nuked(short** buf, size_t len) { buf[0][h]=o[0]; buf[1][h]=o[1]; } + + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); + } } void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) { @@ -100,6 +108,10 @@ void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) { ymfm::ym2151::fm_engine* fme=fm_ymfm->debug_engine(); + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdebug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1); - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut,-32768,32767)); } os[0]=out_ymfm.data[0]; @@ -135,6 +147,10 @@ void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) { buf[0][h]=os[0]; buf[1][h]=os[1]; } + + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); + } } void DivPlatformArcade::acquire(short** buf, size_t len) { @@ -964,7 +980,7 @@ void DivPlatformArcade::setFlags(const DivConfig& flags) { rate=chipClock/64; for (int i=0; i<8; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 6639296d1..08c310138 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -257,6 +257,10 @@ void DivPlatformAY8910::acquire_mame(short** buf, size_t len) { } } + for (int i=0; i<3; i++) { + oscBuf[i]->begin(len); + } + if (sunsoft) { for (size_t i=0; idata[oscBuf[0]->needle++]=CLAMP(sunsoftVolTable[31-(ay->lastIndx&31)]<<3,-32768,32767); - oscBuf[1]->data[oscBuf[1]->needle++]=CLAMP(sunsoftVolTable[31-((ay->lastIndx>>5)&31)]<<3,-32768,32767); - oscBuf[2]->data[oscBuf[2]->needle++]=CLAMP(sunsoftVolTable[31-((ay->lastIndx>>10)&31)]<<3,-32768,32767); + oscBuf[0]->putSample(i,CLAMP(sunsoftVolTable[31-(ay->lastIndx&31)]<<3,-32768,32767)); + oscBuf[1]->putSample(i,CLAMP(sunsoftVolTable[31-((ay->lastIndx>>5)&31)]<<3,-32768,32767)); + oscBuf[2]->putSample(i,CLAMP(sunsoftVolTable[31-((ay->lastIndx>>10)&31)]<<3,-32768,32767)); } } else { for (size_t i=0; idata[oscBuf[0]->needle++]=ayBuf[0][0]<<2; - oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<2; - oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<2; + oscBuf[0]->putSample(i,ayBuf[0][0]<<2); + oscBuf[1]->putSample(i,ayBuf[1][0]<<2); + oscBuf[2]->putSample(i,ayBuf[2][0]<<2); } } + + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); + } } void DivPlatformAY8910::acquire_atomic(short** buf, size_t len) { + for (int i=0; i<3; i++) { + oscBuf[i]->begin(len); + } for (size_t i=0; idata[oscBuf[0]->needle++]=ay_atomic.o_analog[0]; - oscBuf[1]->data[oscBuf[1]->needle++]=ay_atomic.o_analog[1]; - oscBuf[2]->data[oscBuf[2]->needle++]=ay_atomic.o_analog[2]; + oscBuf[0]->putSample(i,ay_atomic.o_analog[0]); + oscBuf[1]->putSample(i,ay_atomic.o_analog[1]); + oscBuf[2]->putSample(i,ay_atomic.o_analog[2]); + } + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); } } @@ -1154,7 +1168,7 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) { } for (int i=0; i<3; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } stereo=flags.getBool("stereo",false); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index dcf7b30d8..103f9ffd1 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -173,6 +173,10 @@ void DivPlatformAY8930::acquire(short** buf, size_t len) { } } + for (int i=0; i<3; i++) { + oscBuf[i]->begin(len); + } + for (size_t i=0; idata[oscBuf[0]->needle++]=ayBuf[0][0]<<2; - oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<2; - oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<2; + oscBuf[0]->putSample(i,ayBuf[0][0]<<2); + oscBuf[1]->putSample(i,ayBuf[1][0]<<2); + oscBuf[2]->putSample(i,ayBuf[2][0]<<2); + } + + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); } } @@ -923,7 +931,7 @@ void DivPlatformAY8930::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<3; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } stereo=flags.getBool("stereo",false); diff --git a/src/engine/platform/bifurcator.cpp b/src/engine/platform/bifurcator.cpp index 87e042dc7..200a59dec 100644 --- a/src/engine/platform/bifurcator.cpp +++ b/src/engine/platform/bifurcator.cpp @@ -48,6 +48,9 @@ void DivPlatformBifurcator::acquire(short** buf, size_t len) { chan[i].chVolL=regPool[i*8+6]; chan[i].chVolR=regPool[i*8+7]; } + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } for (size_t h=0; hdata[oscBuf[i]->needle++]=(short)((outL+outR)/2); + oscBuf[i]->putSample(h,(short)((outL+outR)/2)); l+=outL/4; r+=outR/4; } buf[0][h]=(short)l; buf[1][h]=(short)r; } + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } for (int i=0; i<4; i++) { regPool[i*8]=chan[i].curx&0xff; regPool[i*8+1]=chan[i].curx>>8; @@ -347,7 +353,7 @@ void DivPlatformBifurcator::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/16; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index b0b470bf2..fa53a40a8 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -41,6 +41,9 @@ const char** DivPlatformBubSysWSG::getRegisterSheet() { void DivPlatformBubSysWSG::acquire(short** buf, size_t len) { int chanOut=0; + for (int i=0; i<2; i++) { + oscBuf[i]->begin(len); + } for (size_t h=0; hdata[oscBuf[i]->needle++]=0; + oscBuf[i]->putSample(h,0); continue; } else { chanOut=chan[i].waveROM[k005289.addr(i)]*(regPool[2+i]&0xf); out+=chanOut; if (writeOscBuf==0) { - oscBuf[i]->data[oscBuf[i]->needle++]=chanOut<<7; + oscBuf[i]->putSample(h,chanOut<<7); } } } @@ -70,6 +73,9 @@ void DivPlatformBubSysWSG::acquire(short** buf, size_t len) { //printf("out: %d\n",out); buf[0][h]=out; } + for (int i=0; i<2; i++) { + oscBuf[i]->end(len); + } } void DivPlatformBubSysWSG::updateWave(int ch) { @@ -334,7 +340,7 @@ void DivPlatformBubSysWSG::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/coreQuality; for (int i=0; i<2; i++) { - oscBuf[i]->rate=rate/8; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index 99d6d6e6c..509532d5f 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -68,6 +68,9 @@ const char** DivPlatformC140::getRegisterSheet() { } void DivPlatformC140::acquire_219(short** buf, size_t len) { + for (int i=0; ibegin(len); + } for (size_t h=0; hdata[oscBuf[i]->needle++]=(c219.voice[i].lout-c219.voice[i].rout)>>10; + oscBuf[i]->putSample(h,(c219.voice[i].lout-c219.voice[i].rout)>>10); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=(c219.voice[i].lout+c219.voice[i].rout)>>10; + oscBuf[i]->putSample(h,(c219.voice[i].lout+c219.voice[i].rout)>>10); } } } + for (int i=0; iend(len); + } } void DivPlatformC140::acquire_140(short** buf, size_t len) { + for (int i=0; ibegin(len); + } for (size_t h=0; hdata[oscBuf[i]->needle++]=(c140.voice[i].lout+c140.voice[i].rout)>>10; + oscBuf[i]->putSample(h,(c140.voice[i].lout+c140.voice[i].rout)>>10); } } + for (int i=0; iend(len); + } } void DivPlatformC140::acquire(short** buf, size_t len) { @@ -752,7 +764,7 @@ void DivPlatformC140::setFlags(const DivConfig& flags) { c140_bank_type(&c140,bankType); } for (int i=0; irate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 44227732e..89d349071 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -139,6 +139,9 @@ void DivPlatformC64::processDAC(int sRate) { void DivPlatformC64::acquire(short** buf, size_t len) { int dcOff=(sidCore)?0:sid->get_dc(0); + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } for (size_t i=0; i=4) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=sid_d->lastOut[0]; - oscBuf[1]->data[oscBuf[1]->needle++]=sid_d->lastOut[1]; - oscBuf[2]->data[oscBuf[2]->needle++]=sid_d->lastOut[2]; - oscBuf[3]->data[oscBuf[3]->needle++]=chan[3].pcmOut<<11; + oscBuf[0]->putSample(i,sid_d->lastOut[0]); + oscBuf[1]->putSample(i,sid_d->lastOut[1]); + oscBuf[2]->putSample(i,sid_d->lastOut[2]); + oscBuf[3]->putSample(i,chan[3].pcmOut<<11); } } else if (sidCore==1) { sid_fp->clock(4,&buf[0][i]); if (++writeOscBuf>=4) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=runFakeFilter(0,(sid_fp->lastChanOut[0]-dcOff)>>5); - oscBuf[1]->data[oscBuf[1]->needle++]=runFakeFilter(1,(sid_fp->lastChanOut[1]-dcOff)>>5); - oscBuf[2]->data[oscBuf[2]->needle++]=runFakeFilter(2,(sid_fp->lastChanOut[2]-dcOff)>>5); - oscBuf[3]->data[oscBuf[3]->needle++]=chan[3].pcmOut<<11; + oscBuf[0]->putSample(i,runFakeFilter(0,(sid_fp->lastChanOut[0]-dcOff)>>5)); + oscBuf[1]->putSample(i,runFakeFilter(1,(sid_fp->lastChanOut[1]-dcOff)>>5)); + oscBuf[2]->putSample(i,runFakeFilter(2,(sid_fp->lastChanOut[2]-dcOff)>>5)); + oscBuf[3]->putSample(i,chan[3].pcmOut<<11); } } else { sid->clock(); buf[0][i]=sid->output(); if (++writeOscBuf>=16) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=runFakeFilter(0,(sid->last_chan_out[0]-dcOff)>>5); - oscBuf[1]->data[oscBuf[1]->needle++]=runFakeFilter(1,(sid->last_chan_out[1]-dcOff)>>5); - oscBuf[2]->data[oscBuf[2]->needle++]=runFakeFilter(2,(sid->last_chan_out[2]-dcOff)>>5); - oscBuf[3]->data[oscBuf[3]->needle++]=chan[3].pcmOut<<11; + oscBuf[0]->putSample(i,runFakeFilter(0,(sid->last_chan_out[0]-dcOff)>>5)); + oscBuf[1]->putSample(i,runFakeFilter(1,(sid->last_chan_out[1]-dcOff)>>5)); + oscBuf[2]->putSample(i,runFakeFilter(2,(sid->last_chan_out[2]-dcOff)>>5)); + oscBuf[3]->putSample(i,chan[3].pcmOut<<11); } } } + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformC64::updateFilter() { @@ -913,7 +919,7 @@ void DivPlatformC64::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate/16; + oscBuf[i]->setRate(rate); } if (sidCore>0) { rate/=(sidCore==2)?coreQuality:4; @@ -930,15 +936,16 @@ void DivPlatformC64::setFlags(const DivConfig& flags) { // init fake filter table // taken from dSID - double cutRatio=-2.0*3.14*(sidIs6581?(((double)oscBuf[0]->rate/44100.0)*(20000.0/256.0)):(12500.0/256.0))/(double)oscBuf[0]->rate; + double oscBufRate=(double)rate/16.0; + double cutRatio=-2.0*3.14*(sidIs6581?((oscBufRate/44100.0)*(20000.0/256.0)):(12500.0/256.0))/oscBufRate; for (int i=0; i<2048; i++) { double c=(double)i/8.0+0.2; if (sidIs6581) { if (c<24) { - c=2.0*sin(771.78/(double)oscBuf[0]->rate); + c=2.0*sin(771.78/oscBufRate); } else { - c=(44100.0/(double)oscBuf[0]->rate)-1.263*(44100.0/(double)oscBuf[0]->rate)*exp(c*cutRatio); + c=(44100.0/oscBufRate)-1.263*(44100.0/oscBufRate)*exp(c*cutRatio); } } else { c=1-exp(c*cutRatio); diff --git a/src/engine/platform/dave.cpp b/src/engine/platform/dave.cpp index c61a51e70..9e12ef095 100644 --- a/src/engine/platform/dave.cpp +++ b/src/engine/platform/dave.cpp @@ -64,6 +64,10 @@ const char** DivPlatformDave::getRegisterSheet() { } void DivPlatformDave::acquire(short** buf, size_t len) { + for (int i=0; i<6; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h>16; if ((regPool[7]&0x18)==0x18) { - oscBuf[0]->data[oscBuf[0]->needle++]=0; - oscBuf[1]->data[oscBuf[1]->needle++]=0; - oscBuf[2]->data[oscBuf[2]->needle++]=0; - oscBuf[3]->data[oscBuf[3]->needle++]=0; - oscBuf[4]->data[oscBuf[4]->needle++]=dave->chn0_left<<9; - oscBuf[5]->data[oscBuf[5]->needle++]=dave->chn0_right<<9; + oscBuf[0]->putSample(h,0); + oscBuf[1]->putSample(h,0); + oscBuf[2]->putSample(h,0); + oscBuf[3]->putSample(h,0); + oscBuf[4]->putSample(h,dave->chn0_left<<9); + oscBuf[5]->putSample(h,dave->chn0_right<<9); } else if (regPool[7]&0x08) { - oscBuf[0]->data[oscBuf[0]->needle++]=dave->chn0_state?(dave->chn0_right<<8):0; - oscBuf[1]->data[oscBuf[1]->needle++]=dave->chn1_state?(dave->chn1_right<<8):0; - oscBuf[2]->data[oscBuf[2]->needle++]=dave->chn2_state?(dave->chn2_right<<8):0; - oscBuf[3]->data[oscBuf[3]->needle++]=dave->chn3_state?(dave->chn3_right<<8):0; - oscBuf[4]->data[oscBuf[4]->needle++]=dave->chn0_left<<9; - oscBuf[5]->data[oscBuf[5]->needle++]=0; + oscBuf[0]->putSample(h,dave->chn0_state?(dave->chn0_right<<8):0); + oscBuf[1]->putSample(h,dave->chn1_state?(dave->chn1_right<<8):0); + oscBuf[2]->putSample(h,dave->chn2_state?(dave->chn2_right<<8):0); + oscBuf[3]->putSample(h,dave->chn3_state?(dave->chn3_right<<8):0); + oscBuf[4]->putSample(h,dave->chn0_left<<9); + oscBuf[5]->putSample(h,0); } else if (regPool[7]&0x10) { - oscBuf[0]->data[oscBuf[0]->needle++]=dave->chn0_state?(dave->chn0_left<<8):0; - oscBuf[1]->data[oscBuf[1]->needle++]=dave->chn1_state?(dave->chn1_left<<8):0; - oscBuf[2]->data[oscBuf[2]->needle++]=dave->chn2_state?(dave->chn2_left<<8):0; - oscBuf[3]->data[oscBuf[3]->needle++]=dave->chn3_state?(dave->chn3_left<<8):0; - oscBuf[4]->data[oscBuf[4]->needle++]=0; - oscBuf[5]->data[oscBuf[5]->needle++]=dave->chn0_right<<9; + oscBuf[0]->putSample(h,dave->chn0_state?(dave->chn0_left<<8):0); + oscBuf[1]->putSample(h,dave->chn1_state?(dave->chn1_left<<8):0); + oscBuf[2]->putSample(h,dave->chn2_state?(dave->chn2_left<<8):0); + oscBuf[3]->putSample(h,dave->chn3_state?(dave->chn3_left<<8):0); + oscBuf[4]->putSample(h,0); + oscBuf[5]->putSample(h,dave->chn0_right<<9); } else { - oscBuf[0]->data[oscBuf[0]->needle++]=dave->chn0_state?((dave->chn0_left+dave->chn0_right)<<8):0; - oscBuf[1]->data[oscBuf[1]->needle++]=dave->chn1_state?((dave->chn1_left+dave->chn1_right)<<8):0; - oscBuf[2]->data[oscBuf[2]->needle++]=dave->chn2_state?((dave->chn2_left+dave->chn2_right)<<8):0; - oscBuf[3]->data[oscBuf[3]->needle++]=dave->chn3_state?((dave->chn3_left+dave->chn3_right)<<8):0; - oscBuf[4]->data[oscBuf[4]->needle++]=0; - oscBuf[5]->data[oscBuf[5]->needle++]=0; + oscBuf[0]->putSample(h,dave->chn0_state?((dave->chn0_left+dave->chn0_right)<<8):0); + oscBuf[1]->putSample(h,dave->chn1_state?((dave->chn1_left+dave->chn1_right)<<8):0); + oscBuf[2]->putSample(h,dave->chn2_state?((dave->chn2_left+dave->chn2_right)<<8):0); + oscBuf[3]->putSample(h,dave->chn3_state?((dave->chn3_left+dave->chn3_right)<<8):0); + oscBuf[4]->putSample(h,0); + oscBuf[5]->putSample(h,0); } buf[0][h]=(short)nextL; buf[1][h]=(short)nextR; } + + for (int i=0; i<6; i++) { + oscBuf[i]->end(len); + } } void DivPlatformDave::tick(bool sysTick) { @@ -596,7 +604,7 @@ void DivPlatformDave::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/16; for (int i=0; i<6; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/dummy.cpp b/src/engine/platform/dummy.cpp index 422397b14..1be4a4962 100644 --- a/src/engine/platform/dummy.cpp +++ b/src/engine/platform/dummy.cpp @@ -26,26 +26,32 @@ void DivPlatformDummy::acquire(short** buf, size_t len) { int chanOut; + for (int i=0; ibegin(len); + } for (size_t i=0; i>12; - oscBuf[j]->data[oscBuf[j]->needle++]=chanOut<<1; + oscBuf[j]->putSample(i,chanOut<<1); out+=chanOut; } else { - oscBuf[j]->data[oscBuf[j]->needle++]=0; + oscBuf[j]->putSample(i,0); } chan[j].pos+=chan[j].freq; } else { - oscBuf[j]->data[oscBuf[j]->needle++]=0; + oscBuf[j]->putSample(i,0); } } if (out<-32768) out=-32768; if (out>32767) out=32767; buf[0][i]=out; } + for (int i=0; iend(len); + } } void DivPlatformDummy::muteChannel(int ch, bool mute) { @@ -150,7 +156,7 @@ int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, const DivCon isMuted[i]=false; if (irate=65536; + oscBuf[i]->setRate(65536); } } rate=65536; diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index a40e7d4d5..2f5f7b3c1 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -111,6 +111,9 @@ const char** DivPlatformES5506::getRegisterSheet() { } void DivPlatformES5506::acquire(short** buf, size_t len) { + for (int i=0; ibegin(len); + } for (size_t h=0; h=0; i--) { - oscBuf[i]->data[oscBuf[i]->needle++]=(es5506.voice_lout(i)+es5506.voice_rout(i))>>5; + oscBuf[i]->putSample(h,(es5506.voice_lout(i)+es5506.voice_rout(i))>>5); } } + for (int i=0; iend(len); + } } void DivPlatformES5506::e_pin(bool state) { @@ -1259,7 +1265,7 @@ void DivPlatformES5506::setFlags(const DivConfig& flags) { rate=chipClock/(16*(initChanMax+1)); // 2 E clock tick (16 CLKIN tick) per voice / 4 for (int i=0; i<32; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index e0f3252a7..bbce9d665 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -40,6 +40,9 @@ void DivPlatformESFM::acquire(short** buf, size_t len) { thread_local short o[2]; + for (int i=0; i<18; i++) { + oscBuf[i]->begin(len); + } for (size_t h=0; hdata[oscBuf[c]->needle++]=ESFM_get_channel_output_native(&chip,c); + oscBuf[c]->putSample(h,ESFM_get_channel_output_native(&chip,c)); } buf[0][h]=o[0]; buf[1][h]=o[1]; } + for (int i=0; i<18; i++) { + oscBuf[i]->end(len); + } } void DivPlatformESFM::tick(bool sysTick) { @@ -1068,6 +1074,9 @@ void DivPlatformESFM::poke(std::vector& wlist) { void DivPlatformESFM::setFlags(const DivConfig& flags) { chipClock=COLOR_NTSC*4.0; rate=chipClock/288.0; + for (int i=0; i<18; i++) { + oscBuf[i]->setRate(rate); + } } void DivPlatformESFM::setFast(bool fast) { diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index 1b3428455..215b640da 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -56,6 +56,7 @@ const char** DivPlatformFDS::getRegisterSheet() { } void DivPlatformFDS::acquire_puNES(short* buf, size_t len) { + oscBuf->begin(len); for (size_t i=0; isnd.main.output; @@ -64,13 +65,15 @@ void DivPlatformFDS::acquire_puNES(short* buf, size_t len) { buf[i]=sample; if (++writeOscBuf>=32) { writeOscBuf=0; - oscBuf->data[oscBuf->needle++]=sample*3; + oscBuf->putSample(i,sample*3); } } + oscBuf->end(len); } void DivPlatformFDS::acquire_NSFPlay(short* buf, size_t len) { int out[2]; + oscBuf->begin(len); for (size_t i=0; iTick(1); fds_NP->Render(out); @@ -80,9 +83,10 @@ void DivPlatformFDS::acquire_NSFPlay(short* buf, size_t len) { buf[i]=sample; if (++writeOscBuf>=32) { writeOscBuf=0; - oscBuf->data[oscBuf->needle++]=sample*3; + oscBuf->putSample(i,sample*3); } } + oscBuf->end(len); } void DivPlatformFDS::doWrite(unsigned short addr, unsigned char data) { @@ -486,7 +490,7 @@ void DivPlatformFDS::setFlags(const DivConfig& flags) { } CHECK_CUSTOM_CLOCK; rate=chipClock; - oscBuf->rate=rate/32; + oscBuf->setRate(rate); if (useNP) { fds_NP->SetClock(rate); fds_NP->SetRate(rate); diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 0cf65722c..819df4c16 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -63,6 +63,9 @@ const char** DivPlatformGB::getRegisterSheet() { } void DivPlatformGB::acquire(short** buf, size_t len) { + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } for (size_t i=0; iapu_output.final_sample.left; buf[1][i]=gb->apu_output.final_sample.right; - for (int i=0; i<4; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=(gb->apu_output.current_sample[i].left+gb->apu_output.current_sample[i].right)<<6; + for (int j=0; j<4; j++) { + oscBuf[j]->putSample(i,(gb->apu_output.current_sample[j].left+gb->apu_output.current_sample[j].right)<<6); } } + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformGB::updateWave() { @@ -724,7 +730,7 @@ void DivPlatformGB::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/coreQuality; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/gbadma.cpp b/src/engine/platform/gbadma.cpp index c180cef1f..84621e079 100644 --- a/src/engine/platform/gbadma.cpp +++ b/src/engine/platform/gbadma.cpp @@ -29,6 +29,9 @@ void DivPlatformGBADMA::acquire(short** buf, size_t len) { // HLE for now int outL[2]={0,0}; int outR[2]={0,0}; + for (int i=0; i<2; i++) { + oscBuf[i]->begin(len); + } for (size_t h=0; hdata[oscBuf[i]->needle++]=(short)((outL[i]+outR[i])<<5); + oscBuf[i]->putSample(h,(short)((outL[i]+outR[i])<<5)); } int l=outL[0]+outL[1]; int r=outR[0]+outR[1]; @@ -100,6 +103,9 @@ void DivPlatformGBADMA::acquire(short** buf, size_t len) { buf[0][h]=(short)l; buf[1][h]=(short)r; } + for (int i=0; i<2; i++) { + oscBuf[i]->end(len); + } } void DivPlatformGBADMA::tick(bool sysTick) { @@ -493,7 +499,7 @@ void DivPlatformGBADMA::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock>>outDepth; for (int i=0; i<2; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/gbaminmod.cpp b/src/engine/platform/gbaminmod.cpp index add60505e..435999cde 100644 --- a/src/engine/platform/gbaminmod.cpp +++ b/src/engine/platform/gbaminmod.cpp @@ -61,6 +61,9 @@ void DivPlatformGBAMinMod::acquire(short** buf, size_t len) { chState[i].volL=(short)chReg[14]; chState[i].volR=(short)chReg[15]; } + for (int i=0; ibegin(len); + } for (size_t h=0; h=sampCycles) { // the driver generates 4 samples at a time and can be start-offset @@ -133,10 +136,10 @@ void DivPlatformGBAMinMod::acquire(short** buf, size_t len) { buf[0][h]=sampL; buf[1][h]=sampR; for (int i=0; idata[oscBuf[i]->needle++]=oscOut[i][sampPos]; + oscBuf[i]->putSample(h,oscOut[i][sampPos]); } for (int i=chanMax; i<16; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=0; + oscBuf[i]->putSample(h,0); } while (updTimer>=updCycles) { // flip buffer @@ -197,6 +200,9 @@ void DivPlatformGBAMinMod::acquire(short** buf, size_t len) { updTimer+=1<end(len); + } // write back changed cached channel registers for (int i=0; i>dacDepth; for (int i=0; i<16; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } sampCycles=16777216/flags.getInt("sampRate",21845); chipClock=16777216/sampCycles; diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index e3455db01..7b2c71b50 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -1840,7 +1840,7 @@ void DivPlatformGenesis::setFlags(const DivConfig& flags) { rate=chipClock/36; } for (int i=0; i<10; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 07802f7a3..79776ce7b 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -41,6 +41,10 @@ double DivPlatformSoundUnit::NOTE_SU(int ch, int note) { } void DivPlatformSoundUnit::acquire(short** buf, size_t len) { + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hNextSample(&buf[0][h],&buf[1][h]); for (int i=0; i<8; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=su->GetSample(i); + oscBuf[i]->putSample(h,su->GetSample(i)); } } + + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSoundUnit::writeControl(int ch) { @@ -646,7 +654,7 @@ void DivPlatformSoundUnit::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<8; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } bool echoOn=flags.getBool("echo",false); initIlCtrl=3|(echoOn?4:0); diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index 88086620b..3bee3dda3 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -704,8 +704,10 @@ void FurnaceGUI::drawChanOsc() { } } } else { + /* String dStr=fmt::sprintf("DS: %d P: %d\nMAX: %d\nPHASE %f",displaySize,precision,(short)((fft->needle+displaySize)-fft->relatedBuf->needle),fft->debugPhase); dl->AddText(inRect.Min,0xffffffff,dStr.c_str()); + */ if (displaySize Date: Sat, 1 Mar 2025 19:57:16 -0500 Subject: [PATCH 08/11] new chan osc, part 5 fix C64 rate --- src/engine/platform/c64.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 89d349071..c0352eeb3 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -918,13 +918,13 @@ void DivPlatformC64::setFlags(const DivConfig& flags) { } CHECK_CUSTOM_CLOCK; rate=chipClock; - for (int i=0; i<4; i++) { - oscBuf[i]->setRate(rate); - } if (sidCore>0) { rate/=(sidCore==2)?coreQuality:4; if (sidCore==1) sid_fp->setSamplingParameters(chipClock,reSIDfp::DECIMATE,rate,0); } + for (int i=0; i<4; i++) { + oscBuf[i]->setRate(rate); + } keyPriority=flags.getBool("keyPriority",true); no1EUpdate=flags.getBool("no1EUpdate",false); multiplyRel=flags.getBool("multiplyRel",false); From 6265d2cd3968233b29f9d018d40553bc53b65247 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 2 Mar 2025 04:11:10 -0500 Subject: [PATCH 09/11] new chan osc, part 6 more adaptations how can I get you out of my head... I want to go back to work! --- extern/SAASound/src/SAADevice.cpp | 14 ++-- extern/SAASound/src/SAADevice.h | 2 +- extern/SAASound/src/SAAImpl.cpp | 3 +- src/engine/platform/genesis.cpp | 97 ++++++++++++++---------- src/engine/platform/genesis.h | 2 +- src/engine/platform/k007232.cpp | 14 +++- src/engine/platform/k053260.cpp | 18 +++-- src/engine/platform/lynx.cpp | 18 ++++- src/engine/platform/mmc5.cpp | 16 +++- src/engine/platform/msm5232.cpp | 14 +++- src/engine/platform/msm6258.cpp | 10 ++- src/engine/platform/msm6295.cpp | 12 ++- src/engine/platform/n163.cpp | 14 +++- src/engine/platform/namcowsg.cpp | 13 +++- src/engine/platform/nds.cpp | 18 +++-- src/engine/platform/nes.cpp | 58 ++++++++++---- src/engine/platform/pcmdac.cpp | 11 ++- src/engine/platform/pet.cpp | 8 +- src/engine/platform/pokemini.cpp | 8 +- src/engine/platform/pong.cpp | 8 +- src/engine/platform/powernoise.cpp | 18 +++-- src/engine/platform/pv1000.cpp | 12 ++- src/engine/platform/qsound.cpp | 12 ++- src/engine/platform/saa.cpp | 6 ++ src/engine/platform/sound/lynx/Mikey.cpp | 6 +- src/engine/platform/sound/lynx/Mikey.hpp | 2 +- src/gui/chanOsc.cpp | 2 - 27 files changed, 293 insertions(+), 123 deletions(-) diff --git a/extern/SAASound/src/SAADevice.cpp b/extern/SAASound/src/SAADevice.cpp index eb88e9ace..7b9ae6c2a 100644 --- a/extern/SAASound/src/SAADevice.cpp +++ b/extern/SAASound/src/SAADevice.cpp @@ -307,7 +307,7 @@ BYTE CSAADevice::_ReadData(void) } #endif -void CSAADevice::_TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf) +void CSAADevice::_TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf, unsigned int where) { unsigned int temp_left, temp_right; unsigned int accum_left = 0, accum_right = 0; @@ -316,27 +316,27 @@ void CSAADevice::_TickAndOutputStereo(unsigned int& left_mixed, unsigned int& ri m_Noise0.Tick(); m_Noise1.Tick(); m_Amp0.TickAndOutputStereo(temp_left, temp_right); - oscBuf[0]->data[oscBuf[0]->needle++]=(temp_left+temp_right)<<5; + oscBuf[0]->putSample(where,(temp_left+temp_right)<<5); accum_left += temp_left; accum_right += temp_right; m_Amp1.TickAndOutputStereo(temp_left, temp_right); - oscBuf[1]->data[oscBuf[1]->needle++]=(temp_left+temp_right)<<5; + oscBuf[1]->putSample(where,(temp_left+temp_right)<<5); accum_left += temp_left; accum_right += temp_right; m_Amp2.TickAndOutputStereo(temp_left, temp_right); - oscBuf[2]->data[oscBuf[2]->needle++]=(temp_left+temp_right)<<5; + oscBuf[2]->putSample(where,(temp_left+temp_right)<<5); accum_left += temp_left; accum_right += temp_right; m_Amp3.TickAndOutputStereo(temp_left, temp_right); - oscBuf[3]->data[oscBuf[3]->needle++]=(temp_left+temp_right)<<5; + oscBuf[3]->putSample(where,(temp_left+temp_right)<<5); accum_left += temp_left; accum_right += temp_right; m_Amp4.TickAndOutputStereo(temp_left, temp_right); - oscBuf[4]->data[oscBuf[4]->needle++]=(temp_left+temp_right)<<5; + oscBuf[4]->putSample(where,(temp_left+temp_right)<<5); accum_left += temp_left; accum_right += temp_right; m_Amp5.TickAndOutputStereo(temp_left, temp_right); - oscBuf[5]->data[oscBuf[5]->needle++]=(temp_left+temp_right)<<5; + oscBuf[5]->putSample(where,(temp_left+temp_right)<<5); accum_left += temp_left; accum_right += temp_right; } diff --git a/extern/SAASound/src/SAADevice.h b/extern/SAASound/src/SAADevice.h index fe4339305..60b934ddf 100644 --- a/extern/SAASound/src/SAADevice.h +++ b/extern/SAASound/src/SAADevice.h @@ -53,7 +53,7 @@ public: void _SetClockRate(unsigned int nClockRate); void _SetSampleRate(unsigned int nSampleRate); void _SetOversample(unsigned int nOversample); - void _TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf); + void _TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed, DivDispatchOscBuffer** oscBuf, unsigned int where); void _TickAndOutputSeparate(unsigned int& left_mixed, unsigned int& right_mixed, unsigned int& left0, unsigned int& right0, unsigned int& left1, unsigned int& right1, diff --git a/extern/SAASound/src/SAAImpl.cpp b/extern/SAASound/src/SAAImpl.cpp index ef1014c01..7efae7f8b 100644 --- a/extern/SAASound/src/SAAImpl.cpp +++ b/extern/SAASound/src/SAAImpl.cpp @@ -373,9 +373,10 @@ void CSAASoundInternal::GenerateMany(BYTE* pBuffer, unsigned int nSamples, DivDi else { #endif + unsigned int where=0; while (nSamples--) { - m_chip._TickAndOutputStereo(left_mixed, right_mixed, oscBuf); + m_chip._TickAndOutputStereo(left_mixed, right_mixed, oscBuf, where++); scale_for_output(left_mixed, right_mixed, oversample, m_bHighpass, nBoost, filterout_z1_left_mixed, filterout_z1_right_mixed, pBuffer); } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 7b2c71b50..be99595cb 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -139,6 +139,10 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) { thread_local short o[2]; thread_local int os[2]; + for (int i=0; i<7; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[5]->needle++]=chan[5].dacOutput<<6; - oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6; + oscBuf[5]->putSample(h,chan[5].dacOutput<<6); + oscBuf[6]->putSample(h,chan[6].dacOutput<<6); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=((fm.dacdata^0x100)-0x100)<<6; - oscBuf[6]->data[oscBuf[6]->needle++]=0; + oscBuf[i]->putSample(h,((fm.dacdata^0x100)-0x100)<<6); + oscBuf[6]->putSample(h,0); } } else { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767); - oscBuf[6]->data[oscBuf[6]->needle++]=0; + oscBuf[i]->putSample(h,CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767)); + oscBuf[6]->putSample(h,0); } } else { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fm.ch_out[i]<<(chipType==2?1:6),-32768,32767)); } } @@ -219,6 +223,10 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) { buf[0][h]=os[0]; buf[1][h]=os[1]; } + + for (int i=0; i<7; i++) { + oscBuf[i]->end(len); + } } void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) { @@ -226,6 +234,10 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) { ymfm::ym2612::fm_engine* fme=fm_ymfm->debug_engine(); + for (int i=0; i<7; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdebug_dac_enable()) { if (softPCM) { - oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<6; - oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6; + oscBuf[5]->putSample(h,chan[5].dacOutput<<6); + oscBuf[6]->putSample(h,chan[6].dacOutput<<6); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=((fm_ymfm->debug_dac_data()^0x100)-0x100)<<6; - oscBuf[6]->data[oscBuf[6]->needle++]=0; + oscBuf[i]->putSample(h,((fm_ymfm->debug_dac_data()^0x100)-0x100)<<6); + oscBuf[6]->putSample(h,0); } } else { - oscBuf[i]->data[oscBuf[i]->needle++]=chOut; - oscBuf[6]->data[oscBuf[6]->needle++]=0; + oscBuf[i]->putSample(h,chOut); + oscBuf[6]->putSample(h,0); } } else { - oscBuf[i]->data[oscBuf[i]->needle++]=chOut; + oscBuf[i]->putSample(h,chOut); } } @@ -302,6 +314,10 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) { buf[0][h]=os[0]; buf[1][h]=os[1]; } + + for (int i=0; i<7; i++) { + oscBuf[i]->end(len); + } } const unsigned char chanMap276[6]={ @@ -309,7 +325,7 @@ const unsigned char chanMap276[6]={ }; // thanks LTVA -void DivPlatformGenesis::acquire276OscSub() { +inline void DivPlatformGenesis::acquire276OscSub(int h) { if (fm_276.fsm_cnt2[1]==0 && llePrevCycle!=0) { lleCycle=0; } @@ -326,22 +342,22 @@ void DivPlatformGenesis::acquire276OscSub() { for (int i=0; i<6; i++) { if ((softPCM && ((chanMap276[i]!=5) || !chan[5].dacMode)) || (!softPCM)) { - oscBuf[chanMap276[i]]->data[oscBuf[chanMap276[i]]->needle++]=lleOscData[i]; + oscBuf[chanMap276[i]]->putSample(h,lleOscData[i]); } lleOscData[i]=0; } if (softPCM && chan[5].dacMode) { - oscBuf[5]->data[oscBuf[5]->needle++]=chan[5].dacOutput<<6; - oscBuf[6]->data[oscBuf[6]->needle++]=chan[6].dacOutput<<6; + oscBuf[5]->putSample(h,chan[5].dacOutput<<6); + oscBuf[6]->putSample(h,chan[6].dacOutput<<6); } else { - oscBuf[6]->data[oscBuf[6]->needle++]=0; + oscBuf[6]->putSample(h,0); } } } else { for (int i=0; i<6; i++) { if (lleCycle==((7+i)*12)) { - oscBuf[i]->data[oscBuf[i]->needle]=(fm_276.osc_out>>1)*8; + oscBuf[i]->putSample(h,(fm_276.osc_out>>1)*4); } } @@ -351,18 +367,15 @@ void DivPlatformGenesis::acquire276OscSub() { lleCycle=0; for (int i=0; i<6; i++) { - oscBuf[i]->data[oscBuf[i]->needle]>>=1; + // we cannot do this anymore + //oscBuf[i]->putSample(h,>>=1); } if (softPCM && chan[5].dacMode) { - oscBuf[5]->data[oscBuf[5]->needle]=chan[5].dacOutput<<6; - oscBuf[6]->data[oscBuf[6]->needle]=chan[6].dacOutput<<6; + oscBuf[5]->putSample(h,chan[5].dacOutput<<6); + oscBuf[6]->putSample(h,chan[6].dacOutput<<6); } else { - oscBuf[6]->data[oscBuf[6]->needle]=0; - } - - for (int i=0; i<7; i++) { - oscBuf[i]->needle++; + oscBuf[6]->putSample(h,0); } } } @@ -370,6 +383,10 @@ void DivPlatformGenesis::acquire276OscSub() { // thanks LTVA void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) { + for (int i=0; i<7; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h>2; } } + + for (int i=0; i<7; i++) { + oscBuf[i]->end(len); + } } void DivPlatformGenesis::acquire(short** buf, size_t len) { diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 9ecc80419..82495bdef 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -94,7 +94,7 @@ class DivPlatformGenesis: public DivPlatformOPN { inline void processDAC(int iRate); inline void commitState(int ch, DivInstrument* ins); - void acquire276OscSub(); + inline void acquire276OscSub(int h); void acquire_nuked(short** buf, size_t len); void acquire_nuked276(short** buf, size_t len); void acquire_ymfm(short** buf, size_t len); diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index 6aaccc908..c03081f7c 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -55,6 +55,10 @@ inline void DivPlatformK007232::chWrite(unsigned char ch, unsigned int addr, uns } void DivPlatformK007232::acquire(short** buf, size_t len) { + for (int i=0; i<2; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=8) { oscDivider=0; for (int i=0; i<2; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=(lout[i]+rout[i])<<3; + oscBuf[i]->putSample(h,(lout[i]+rout[i])<<3); } } } else { @@ -91,11 +95,15 @@ void DivPlatformK007232::acquire(short** buf, size_t len) { if (++oscDivider>=8) { oscDivider=0; for (int i=0; i<2; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=out[i]<<4; + oscBuf[i]->putSample(h,out[i]<<4); } } } } + + for (int i=0; i<2; i++) { + oscBuf[i]->end(len); + } } u8 DivPlatformK007232::read_sample(u8 ne, u32 address) { @@ -490,7 +498,7 @@ void DivPlatformK007232::setFlags(const DivConfig& flags) { stereo=flags.getBool("stereo",false); for (int i=0; i<2; i++) { chan[i].volumeChanged=true; - oscBuf[i]->rate=rate/8; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 1916270c3..85d7ab817 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -69,7 +69,11 @@ u8 DivPlatformK053260::read_sample(u32 address) { } void DivPlatformK053260::acquire(short** buf, size_t len) { - for (size_t i=0; ibegin(len); + } + + for (size_t h=0; h32767) rout=32767; if (rout<-32768) rout=-32768; - buf[0][i]=lout; - buf[1][i]=rout; + buf[0][h]=lout; + buf[1][h]=rout; for (int i=0; i<4; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=(k053260.voice_out(i,0)+k053260.voice_out(i,1))>>1; + oscBuf[i]->putSample(h,(k053260.voice_out(i,0)+k053260.voice_out(i,1))>>1); } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformK053260::tick(bool sysTick) { @@ -427,7 +435,7 @@ void DivPlatformK053260::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/TICK_DIVIDER; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index e044ba5e6..7a2db6025 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -154,6 +154,12 @@ void DivPlatformLynx::processDAC(int sRate) { } void DivPlatformLynx::acquire(short** buf, size_t len) { + thread_local int chanBuf[4]; + + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hsampleAudio(buf[0]+h,buf[1]+h,1,oscBuf); + mikey->sampleAudio(buf[0]+h,buf[1]+h,1,chanBuf); + + for (int i=0; i<4; i++) { + oscBuf[i]->putSample(h,chanBuf[i]); + } + } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); } } @@ -555,7 +569,7 @@ void DivPlatformLynx::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/128; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index da024ecc0..506ba3be4 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -44,6 +44,10 @@ const char** DivPlatformMMC5::getRegisterSheet() { } void DivPlatformMMC5::acquire(short** buf, size_t len) { + for (int i=0; i<3; i++) { + oscBuf[i]->begin(len); + } + for (size_t i=0; i=32) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=isMuted[0]?0:((mmc5->S3.output)<<11); - oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:((mmc5->S4.output)<<11); - oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:((mmc5->pcm.output)<<7); + oscBuf[0]->putSample(i,isMuted[0]?0:((mmc5->S3.output)<<11)); + oscBuf[1]->putSample(i,isMuted[1]?0:((mmc5->S4.output)<<11)); + oscBuf[2]->putSample(i,isMuted[2]?0:((mmc5->pcm.output)<<7)); } } + + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); + } } void DivPlatformMMC5::tick(bool sysTick) { @@ -427,7 +435,7 @@ void DivPlatformMMC5::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock; for (int i=0; i<3; i++) { - oscBuf[i]->rate=rate/32; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/msm5232.cpp b/src/engine/platform/msm5232.cpp index 0e96b8df2..d0325ae60 100644 --- a/src/engine/platform/msm5232.cpp +++ b/src/engine/platform/msm5232.cpp @@ -46,6 +46,10 @@ const char** DivPlatformMSM5232::getRegisterSheet() { } void DivPlatformMSM5232::acquire(short** buf, size_t len) { + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=0; + oscBuf[i]->putSample(h,0); } else { int o=( ((regPool[12+(i>>2)]&1)?((msm->vo16[i]*partVolume[3+(i&4)])>>8):0)+ @@ -64,7 +68,7 @@ void DivPlatformMSM5232::acquire(short** buf, size_t len) { ((regPool[12+(i>>2)]&4)?((msm->vo4[i]*partVolume[1+(i&4)])>>8):0)+ ((regPool[12+(i>>2)]&8)?((msm->vo2[i]*partVolume[i&4])>>8):0) )<<2; - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(o,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(o,-32768,32767)); } } @@ -84,6 +88,10 @@ void DivPlatformMSM5232::acquire(short** buf, size_t len) { buf[0][h]+=(temp[i]*partVolume[i])>>8; } } + + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); + } } const int attackMap[8]={ @@ -400,7 +408,7 @@ void DivPlatformMSM5232::setFlags(const DivConfig& flags) { msm->set_clock(chipClock+detune*1024); rate=msm->get_rate(); for (int i=0; i<8; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } initPartVolume[0]=flags.getInt("partVolume0",255); initPartVolume[1]=flags.getInt("partVolume1",255); diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index 84d529c8f..a6a19f100 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -41,6 +41,8 @@ int DivPlatformMSM6258::calcVGMRate() { } void DivPlatformMSM6258::acquire(short** buf, size_t len) { + oscBuf[0]->begin(len); + for (size_t h=0; hdata[oscBuf[0]->needle++]=0; + oscBuf[0]->putSample(h,0); } else { buf[0][h]=(msmPan&2)?0:msmOut; buf[1][h]=(msmPan&1)?0:msmOut; - oscBuf[0]->data[oscBuf[0]->needle++]=msmPan?(msmOut>>1):0; + oscBuf[0]->putSample(h,msmPan?(msmOut>>1):0); } } + + oscBuf[0]->end(len); } void DivPlatformMSM6258::tick(bool sysTick) { @@ -407,7 +411,7 @@ void DivPlatformMSM6258::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/256; for (int i=0; i<1; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } variableRate=flags.getBool("variableRate",false); } diff --git a/src/engine/platform/msm6295.cpp b/src/engine/platform/msm6295.cpp index bd030b4c5..d70a05b84 100644 --- a/src/engine/platform/msm6295.cpp +++ b/src/engine/platform/msm6295.cpp @@ -63,6 +63,10 @@ u8 DivPlatformMSM6295::read_byte(u32 address) { } void DivPlatformMSM6295::acquire(short** buf, size_t len) { + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=22) { updateOsc=0; for (int i=0; i<4; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=msm.voice_out(i)<<5; + oscBuf[i]->putSample(h,msm.voice_out(i)<<5); } } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformMSM6295::tick(bool sysTick) { @@ -560,7 +568,7 @@ void DivPlatformMSM6295::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/3; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate/22; + oscBuf[i]->setRate(rate);; } if (rateSel!=rateSelInit) { rWrite(12,!rateSelInit); diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index 5ee2519c3..4ac1c2289 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -109,6 +109,10 @@ const char** DivPlatformN163::getRegisterSheet() { } void DivPlatformN163::acquire(short** buf, size_t len) { + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + for (size_t i=0; idata[oscBuf[i]->needle++]=n163.voice_out(i)<<7; + if (n163.voice_cycle()==0x78) for (int j=0; j<8; j++) { + oscBuf[j]->putSample(i,n163.voice_out(j)<<7); } // command queue @@ -128,6 +132,10 @@ void DivPlatformN163::acquire(short** buf, size_t len) { writes.pop(); } } + + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); + } } void DivPlatformN163::updateWave(int ch, int wave, int pos, int len) { @@ -595,7 +603,7 @@ void DivPlatformN163::setFlags(const DivConfig& flags) { n163.set_multiplex(multiplex); rWrite(0x7f,initChanMax<<4); for (int i=0; i<8; i++) { - oscBuf[i]->rate=rate/(initChanMax+1); + oscBuf[i]->setRate(rate);//=rate/(initChanMax+1); } lenCompensate=flags.getBool("lenCompensate",false); diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index 3d26c2aae..bbd470fc4 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -171,15 +171,24 @@ void DivPlatformNamcoWSG::acquire(short** buf, size_t len) { regPool[w.addr&0x3f]=w.val; writes.pop(); } + + for (int i=0; ibegin(len); + } + for (size_t h=0; hsound_stream_update(bufC,1); for (int i=0; idata[oscBuf[i]->needle++]=(namco->m_channel_list[i].last_out*chans)>>1; + oscBuf[i]->putSample(h,(namco->m_channel_list[i].last_out*chans)>>1); } } + + for (int i=0; iend(len); + } } void DivPlatformNamcoWSG::updateWave(int ch) { @@ -579,7 +588,7 @@ void DivPlatformNamcoWSG::setFlags(const DivConfig& flags) { rate=chipClock/32; namco->device_clock_changed(96000); for (int i=0; irate=rate; + oscBuf[i]->setRate(rate); } newNoise=flags.getBool("newNoise",true); romMode=flags.getBool("romMode",false); diff --git a/src/engine/platform/nds.cpp b/src/engine/platform/nds.cpp index 2478989d0..98611ad62 100644 --- a/src/engine/platform/nds.cpp +++ b/src/engine/platform/nds.cpp @@ -69,7 +69,11 @@ const char** DivPlatformNDS::getRegisterSheet() { } void DivPlatformNDS::acquire(short** buf, size_t len) { - for (size_t i=0; ibegin(len); + } + + for (size_t h=0; h32767) rout=32767; if (rout<-32768) rout=-32768; - buf[0][i]=lout; - buf[1][i]=rout; + buf[0][h]=lout; + buf[1][h]=rout; for (int i=0; i<16; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=(nds.chan_lout(i)+nds.chan_rout(i))>>1; + oscBuf[i]->putSample(h,(nds.chan_lout(i)+nds.chan_rout(i))>>1); } } + + for (int i=0; i<16; i++) { + oscBuf[i]->end(len); + } } u8 DivPlatformNDS::read_byte(u32 addr) { @@ -564,7 +572,7 @@ void DivPlatformNDS::setFlags(const DivConfig& flags) { chipClock=33513982; rate=chipClock/2/coreQuality; for (int i=0; i<16; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } memCompo.capacity=(isDSi?16777216:4194304); } diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 22c949f3a..733ba2630 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -106,6 +106,10 @@ void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) { } void DivPlatformNES::acquire_puNES(short** buf, size_t len) { + for (int i=0; i<5; i++) { + oscBuf[i]->begin(len); + } + for (size_t i=0; i=32) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=isMuted[0]?0:(nes->S1.output<<11); - oscBuf[1]->data[oscBuf[1]->needle++]=isMuted[1]?0:(nes->S2.output<<11); - oscBuf[2]->data[oscBuf[2]->needle++]=isMuted[2]?0:(nes->TR.output<<11); - oscBuf[3]->data[oscBuf[3]->needle++]=isMuted[3]?0:(nes->NS.output<<11); - oscBuf[4]->data[oscBuf[4]->needle++]=isMuted[4]?0:(nes->DMC.output<<8); + oscBuf[0]->putSample(i,isMuted[0]?0:(nes->S1.output<<11)); + oscBuf[1]->putSample(i,isMuted[1]?0:(nes->S2.output<<11)); + oscBuf[2]->putSample(i,isMuted[2]?0:(nes->TR.output<<11)); + oscBuf[3]->putSample(i,isMuted[3]?0:(nes->NS.output<<11)); + oscBuf[4]->putSample(i,isMuted[4]?0:(nes->DMC.output<<8)); } } + + for (int i=0; i<5; i++) { + oscBuf[i]->end(len); + } } void DivPlatformNES::acquire_NSFPlay(short** buf, size_t len) { int out1[2]; int out2[2]; + + for (int i=0; i<5; i++) { + oscBuf[i]->begin(len); + } + for (size_t i=0; i=4) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=nes1_NP->out[0]<<11; - oscBuf[1]->data[oscBuf[1]->needle++]=nes1_NP->out[1]<<11; - oscBuf[2]->data[oscBuf[2]->needle++]=nes2_NP->out[0]<<11; - oscBuf[3]->data[oscBuf[3]->needle++]=nes2_NP->out[1]<<11; - oscBuf[4]->data[oscBuf[4]->needle++]=nes2_NP->out[2]<<8; + oscBuf[0]->putSample(i,nes1_NP->out[0]<<11); + oscBuf[1]->putSample(i,nes1_NP->out[1]<<11); + oscBuf[2]->putSample(i,nes2_NP->out[0]<<11); + oscBuf[3]->putSample(i,nes2_NP->out[1]<<11); + oscBuf[4]->putSample(i,nes2_NP->out[2]<<8); } } + + for (int i=0; i<5; i++) { + oscBuf[i]->end(len); + } } void DivPlatformNES::acquire_NSFPlayE(short** buf, size_t len) { int out1[2]; int out2[2]; + + for (int i=0; i<5; i++) { + oscBuf[i]->begin(len); + } + for (size_t i=0; i=4) { writeOscBuf=0; - oscBuf[0]->data[oscBuf[0]->needle++]=e1_NP->out[0]<<11; - oscBuf[1]->data[oscBuf[1]->needle++]=e1_NP->out[1]<<11; - oscBuf[2]->data[oscBuf[2]->needle++]=e2_NP->out[0]<<11; - oscBuf[3]->data[oscBuf[3]->needle++]=e2_NP->out[1]<<11; - oscBuf[4]->data[oscBuf[4]->needle++]=e2_NP->out[2]<<8; + oscBuf[0]->putSample(i,e1_NP->out[0]<<11); + oscBuf[1]->putSample(i,e1_NP->out[1]<<11); + oscBuf[2]->putSample(i,e2_NP->out[0]<<11); + oscBuf[3]->putSample(i,e2_NP->out[1]<<11); + oscBuf[4]->putSample(i,e2_NP->out[2]<<8); } } + + for (int i=0; i<5; i++) { + oscBuf[i]->end(len); + } } void DivPlatformNES::acquire(short** buf, size_t len) { @@ -929,7 +955,7 @@ void DivPlatformNES::setFlags(const DivConfig& flags) { rate/=8; } for (int i=0; i<5; i++) { - oscBuf[i]->rate=rate/(useNP?4:32); + oscBuf[i]->setRate(rate); } dpcmModeDefault=flags.getBool("dpcmMode",true); diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index a9376ebd9..42b9babd9 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -29,11 +29,14 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) { const int depthScale=(15-outDepth); int output=0; + + oscBuf->begin(len); + for (size_t h=0; hdata[oscBuf->needle++]=0; + oscBuf->putSample(h,0); continue; } if (chan[0].useWave || (chan[0].sample>=0 && chan[0].samplesong.sampleLen)) { @@ -229,7 +232,7 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) { } else { output=((output*MIN(volMax,chan[0].vol)*MIN(chan[0].envVol,64))>>6)/volMax; } - oscBuf->data[oscBuf->needle++]=((output>>depthScale)<>1; + oscBuf->putSample(h,((output>>depthScale)<>1); if (outStereo) { buf[0][h]=((output*chan[0].panL)>>(depthScale+8))<>(depthScale+8))<end(len); } void DivPlatformPCMDAC::tick(bool sysTick) { @@ -542,7 +547,7 @@ void DivPlatformPCMDAC::setFlags(const DivConfig& flags) { outDepth=(flags.getInt("outDepth",15))&15; outStereo=flags.getBool("stereo",true); interp=flags.getInt("interpolation",0); - oscBuf->rate=rate; + oscBuf->setRate(rate); volMax=flags.getInt("volMax",255); if (volMax<1) volMax=1; } diff --git a/src/engine/platform/pet.cpp b/src/engine/platform/pet.cpp index ecbee3ff4..fc78165d7 100644 --- a/src/engine/platform/pet.cpp +++ b/src/engine/platform/pet.cpp @@ -57,6 +57,7 @@ void DivPlatformPET::rWrite(unsigned int addr, unsigned char val) { void DivPlatformPET::acquire(short** buf, size_t len) { bool hwSROutput=((regPool[11]>>2)&7)==4; + oscBuf->begin(len); if (chan[0].enable) { int reload=regPool[8]*2+4; if (!hwSROutput) { @@ -71,7 +72,7 @@ void DivPlatformPET::acquire(short** buf, size_t len) { chan[0].cnt-=SAMP_DIVIDER; } buf[0][h]=chan[0].out; - oscBuf->data[oscBuf->needle++]=chan[0].out; + oscBuf->putSample(h,chan[0].out); } // emulate driver writes to PCR if (!hwSROutput) regPool[12]=chan[0].out?0xe0:0xc0; @@ -79,9 +80,10 @@ void DivPlatformPET::acquire(short** buf, size_t len) { chan[0].out=0; for (size_t h=0; hdata[oscBuf->needle++]=0; + oscBuf->putSample(h,0); } } + oscBuf->end(len); } void DivPlatformPET::writeOutVol() { @@ -311,7 +313,7 @@ int DivPlatformPET::init(DivEngine* p, int channels, int sugRate, const DivConfi rate=chipClock/SAMP_DIVIDER; // = 250000kHz isMuted=false; oscBuf=new DivDispatchOscBuffer; - oscBuf->rate=rate; + oscBuf->setRate(rate); reset(); return 1; } diff --git a/src/engine/platform/pokemini.cpp b/src/engine/platform/pokemini.cpp index cdeb69b99..9e29277e4 100644 --- a/src/engine/platform/pokemini.cpp +++ b/src/engine/platform/pokemini.cpp @@ -88,6 +88,7 @@ void DivPlatformPokeMini::rWrite(unsigned char addr, unsigned char val) { void DivPlatformPokeMini::acquire(short** buf, size_t len) { int out=0; + oscBuf->begin(len); for (size_t i=0; i=pivot && !isMuted[0])?volTable[vol&3]:0; buf[0][i]=out; - oscBuf->data[oscBuf->needle++]=out; + oscBuf->putSample(i,out); } else { buf[0][i]=0; - oscBuf->data[oscBuf->needle++]=0; + oscBuf->putSample(i,0); } } + oscBuf->end(len); } void DivPlatformPokeMini::tick(bool sysTick) { @@ -323,7 +325,7 @@ void DivPlatformPokeMini::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/PCSPKR_DIVIDER; - oscBuf->rate=rate; + oscBuf->setRate(rate); } void DivPlatformPokeMini::notifyInsDeletion(void* ins) { diff --git a/src/engine/platform/pong.cpp b/src/engine/platform/pong.cpp index bfb362dc3..19c478711 100644 --- a/src/engine/platform/pong.cpp +++ b/src/engine/platform/pong.cpp @@ -25,6 +25,7 @@ void DivPlatformPong::acquire(short** buf, size_t len) { int out=0; + oscBuf->begin(len); for (size_t i=0; idata[oscBuf->needle++]=out; + oscBuf->putSample(i,out); } else { buf[0][i]=0; - oscBuf->data[oscBuf->needle++]=0; + oscBuf->putSample(i,0); flip=false; } } + oscBuf->end(len); } void DivPlatformPong::tick(bool sysTick) { @@ -237,7 +239,7 @@ void DivPlatformPong::setFlags(const DivConfig& flags) { chipClock=1000000; CHECK_CUSTOM_CLOCK; rate=chipClock/64; - oscBuf->rate=rate; + oscBuf->setRate(rate); } void DivPlatformPong::notifyInsDeletion(void* ins) { diff --git a/src/engine/platform/powernoise.cpp b/src/engine/platform/powernoise.cpp index a5103b8f9..c7870e31e 100644 --- a/src/engine/platform/powernoise.cpp +++ b/src/engine/platform/powernoise.cpp @@ -82,17 +82,25 @@ const char** DivPlatformPowerNoise::getRegisterSheet() { void DivPlatformPowerNoise::acquire(short** buf, size_t len) { short left, right; + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[0]->needle++]=mapAmp((pn.n1.out_latch&0xf)+(pn.n1.out_latch>>4)); - oscBuf[1]->data[oscBuf[1]->needle++]=mapAmp((pn.n2.out_latch&0xf)+(pn.n2.out_latch>>4)); - oscBuf[2]->data[oscBuf[2]->needle++]=mapAmp((pn.n3.out_latch&0xf)+(pn.n3.out_latch>>4)); - oscBuf[3]->data[oscBuf[3]->needle++]=mapAmp((pn.s.out_latch&0xf)+(pn.s.out_latch>>4)); + oscBuf[0]->putSample(h,mapAmp((pn.n1.out_latch&0xf)+(pn.n1.out_latch>>4))); + oscBuf[1]->putSample(h,mapAmp((pn.n2.out_latch&0xf)+(pn.n2.out_latch>>4))); + oscBuf[2]->putSample(h,mapAmp((pn.n3.out_latch&0xf)+(pn.n3.out_latch>>4))); + oscBuf[3]->putSample(h,mapAmp((pn.s.out_latch&0xf)+(pn.s.out_latch>>4))); buf[0][h]=left; buf[1][h]=right; } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } /* macros: @@ -506,7 +514,7 @@ void DivPlatformPowerNoise::setFlags(const DivConfig& flags) { rate=chipClock/coreQuality; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index 3c6212dd3..11cab5457 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -38,13 +38,21 @@ const char** DivPlatformPV1000::getRegisterSheet() { } void DivPlatformPV1000::acquire(short** buf, size_t len) { + for (int i=0; i<3; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=MAX(d65010g031.out[i]<<2,0); + oscBuf[i]->putSample(h,MAX(d65010g031.out[i]<<2,0)); } } + + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); + } } void DivPlatformPV1000::tick(bool sysTick) { @@ -263,7 +271,7 @@ void DivPlatformPV1000::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/1024; for (int i=0; i<3; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index 82dd57b7c..47e67c823 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -265,6 +265,10 @@ const char** DivPlatformQSound::getRegisterSheet() { } void DivPlatformQSound::acquire(short** buf, size_t len) { + for (int i=0; i<19; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h32767) data=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=data; + oscBuf[i]->putSample(h,data); } } + + for (int i=0; i<19; i++) { + oscBuf[i]->end(len); + } } void DivPlatformQSound::tick(bool sysTick) { @@ -861,7 +869,7 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, const DivCo reset(); for (int i=0; i<19; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } return 19; } diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index 9f00be400..a600d12f9 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -71,7 +71,13 @@ void DivPlatformSAA1099::acquire_saaSound(short** buf, size_t len) { regPool[w.addr&0x1f]=w.val; writes.pop(); } + for (int i=0; i<6; i++) { + oscBuf[i]->begin(len); + } saa_saaSound->GenerateMany((unsigned char*)saaBuf[0],len,oscBuf); + for (int i=0; i<6; i++) { + oscBuf[i]->end(len); + } #ifdef TA_BIG_ENDIAN for (size_t i=0; i>8)); diff --git a/src/engine/platform/sound/lynx/Mikey.cpp b/src/engine/platform/sound/lynx/Mikey.cpp index 791336c1b..bac80792c 100644 --- a/src/engine/platform/sound/lynx/Mikey.cpp +++ b/src/engine/platform/sound/lynx/Mikey.cpp @@ -485,7 +485,7 @@ public: return mAudioChannels[timer].fireAction( tick ); } - AudioSample sampleAudio( DivDispatchOscBuffer** oscb ) const + AudioSample sampleAudio( int* oscb ) const { int left{}; int right{}; @@ -509,7 +509,7 @@ public: } if (oscb!=NULL) { - oscb[i]->data[oscb[i]->needle++]=oscbWrite; + oscb[i]=oscbWrite; } } @@ -570,7 +570,7 @@ void Mikey::enqueueSampling() mQueue->push( ( mNextTick & ~15 ) | 4 ); } -void Mikey::sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, DivDispatchOscBuffer** oscb ) +void Mikey::sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, int* oscb ) { size_t i = 0; while ( i < size ) diff --git a/src/engine/platform/sound/lynx/Mikey.hpp b/src/engine/platform/sound/lynx/Mikey.hpp index 9d0f6884e..0c002a56e 100644 --- a/src/engine/platform/sound/lynx/Mikey.hpp +++ b/src/engine/platform/sound/lynx/Mikey.hpp @@ -21,7 +21,7 @@ public: ~Mikey(); void write( uint8_t address, uint8_t value ); - void sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, DivDispatchOscBuffer** oscb = NULL ); + void sampleAudio( int16_t* bufL, int16_t* bufR, size_t size, int* oscb = NULL ); uint8_t const* getRegisterPool(); diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index 3bee3dda3..e262f355a 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -460,8 +460,6 @@ void FurnaceGUI::drawChanOsc() { // I have a feeling this could be simplified to two FFTs or even one... // if you know how, please tell me - // TODO: utterly broken! - // initialization double phase=0.0; int displaySize=65536.0f*(fft->windowSize/1000.0f); From 49a8693dcb23c6ddd4a9db3688bd0a7b8ff5db26 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 2 Mar 2025 16:14:49 -0500 Subject: [PATCH 10/11] new chan osc, part 7 i am done --- src/engine/platform/opl.cpp | 162 ++++++++++++++------ src/engine/platform/opll.cpp | 38 +++-- src/engine/platform/pce.cpp | 12 +- src/engine/platform/pcspkr.cpp | 2 - src/engine/platform/pokey.cpp | 36 ++++- src/engine/platform/rf5c68.cpp | 19 ++- src/engine/platform/scc.cpp | 12 +- src/engine/platform/scvtone.cpp | 18 ++- src/engine/platform/scvwave.cpp | 9 +- src/engine/platform/segapcm.cpp | 12 +- src/engine/platform/sid2.cpp | 15 +- src/engine/platform/sid3.cpp | 14 +- src/engine/platform/sm8521.cpp | 15 +- src/engine/platform/sms.cpp | 28 +++- src/engine/platform/sound/pokey/AltASAP.cpp | 16 +- src/engine/platform/sound/pokey/AltASAP.hpp | 5 +- src/engine/platform/supervision.cpp | 16 +- src/engine/platform/swan.cpp | 12 +- src/engine/platform/t6w28.cpp | 12 +- src/engine/platform/ted.cpp | 14 +- src/engine/platform/tia.cpp | 14 +- src/engine/platform/tx81z.cpp | 12 +- src/engine/platform/vb.cpp | 12 +- src/engine/platform/vera.cpp | 27 +++- src/engine/platform/vic20.cpp | 13 +- src/engine/platform/vrc6.cpp | 18 ++- src/engine/platform/x1_010.cpp | 12 +- src/engine/platform/ym2203.cpp | 38 ++++- src/engine/platform/ym2608.cpp | 50 ++++-- src/engine/platform/ym2610.cpp | 48 ++++-- src/engine/platform/ym2610b.cpp | 48 ++++-- src/engine/platform/ym2610shared.h | 2 +- src/engine/platform/ymz280b.cpp | 21 ++- src/engine/platform/zxbeeper.cpp | 14 +- src/engine/platform/zxbeeperquadtone.cpp | 27 ++-- 35 files changed, 606 insertions(+), 217 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index bdeb3489d..93e38e4b9 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -188,6 +188,10 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) { thread_local ymfm::ymfm_output<2> aOut; thread_local short pcmBuf[24]; + for (int i=0; ibegin(len); + } + for (size_t h=0; h>3; os[1]-=aOut.data[0]>>3; - oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=aOut.data[0]>>1; + oscBuf[adpcmChan]->putSample(h,aOut.data[0]>>1); } else { - oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=0; + oscBuf[adpcmChan]->putSample(h,0); } } @@ -277,13 +281,13 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) { if (fm.channel[i].out[3]!=NULL) { chOut+=*fm.channel[ch].out[3]; } - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<(i==melodicChans?1:2),-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut<<(i==melodicChans?1:2),-32768,32767)); } // special - oscBuf[melodicChans+1]->data[oscBuf[melodicChans+1]->needle++]=fm.slot[16].out*4; - oscBuf[melodicChans+2]->data[oscBuf[melodicChans+2]->needle++]=fm.slot[14].out*4; - oscBuf[melodicChans+3]->data[oscBuf[melodicChans+3]->needle++]=fm.slot[17].out*4; - oscBuf[melodicChans+4]->data[oscBuf[melodicChans+4]->needle++]=fm.slot[13].out*4; + oscBuf[melodicChans+1]->putSample(h,fm.slot[16].out*4); + oscBuf[melodicChans+2]->putSample(h,fm.slot[14].out*4); + oscBuf[melodicChans+3]->putSample(h,fm.slot[17].out*4); + oscBuf[melodicChans+4]->putSample(h,fm.slot[13].out*4); } else { for (int i=0; idata[oscBuf[i]->needle++]=CLAMP(chOut<<2,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut<<2,-32768,32767)); } } if (chipType==4) { for (int i=pcmChanOffs; idata[oscBuf[i]->needle++]=CLAMP(pcmBuf[i-pcmChanOffs],-32768,32767); + oscBuf[i]->putSample(h,CLAMP(pcmBuf[i-pcmChanOffs],-32768,32767)); } } @@ -344,6 +348,10 @@ void DivPlatformOPL::acquire_nuked(short** buf, size_t len) { buf[5][h]=os[5]; } } + + for (int i=0; iend(len); + } } void DivPlatformOPL::acquire_ymfm1(short** buf, size_t len) { @@ -356,6 +364,10 @@ void DivPlatformOPL::acquire_ymfm1(short** buf, size_t len) { fmChan[i]=fme->debug_channel(i); } + for (int i=0; ibegin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767)); } - oscBuf[7]->data[oscBuf[7]->needle++]=CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767); - oscBuf[8]->data[oscBuf[8]->needle++]=CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767); - oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767); - oscBuf[10]->data[oscBuf[10]->needle++]=CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767); + oscBuf[7]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767)); + oscBuf[8]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767)); + oscBuf[9]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767)); + oscBuf[10]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767)); } else { for (int i=0; i<9; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767)); } } } + + for (int i=0; iend(len); + } } void DivPlatformOPL::acquire_ymfm2(short** buf, size_t len) { @@ -401,6 +417,10 @@ void DivPlatformOPL::acquire_ymfm2(short** buf, size_t len) { fmChan[i]=fme->debug_channel(i); } + for (int i=0; ibegin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767)); } - oscBuf[7]->data[oscBuf[7]->needle++]=CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767); - oscBuf[8]->data[oscBuf[8]->needle++]=CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767); - oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767); - oscBuf[10]->data[oscBuf[10]->needle++]=CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767); + oscBuf[7]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767)); + oscBuf[8]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767)); + oscBuf[9]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767)); + oscBuf[10]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767)); } else { for (int i=0; i<9; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767)); } } } + + for (int i=0; iend(len); + } } void DivPlatformOPL::acquire_ymfm8950(short** buf, size_t len) { @@ -447,6 +471,10 @@ void DivPlatformOPL::acquire_ymfm8950(short** buf, size_t len) { fmChan[i]=fme->debug_channel(i); } + for (int i=0; ibegin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767)); } - oscBuf[7]->data[oscBuf[7]->needle++]=CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767); - oscBuf[8]->data[oscBuf[8]->needle++]=CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767); - oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767); - oscBuf[10]->data[oscBuf[10]->needle++]=CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767); - oscBuf[11]->data[oscBuf[11]->needle++]=CLAMP(abe->get_last_out(0),-32768,32767); + oscBuf[7]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<2,-32768,32767)); + oscBuf[8]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<2,-32768,32767)); + oscBuf[9]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<2,-32768,32767)); + oscBuf[10]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<2,-32768,32767)); + oscBuf[11]->putSample(h,CLAMP(abe->get_last_out(0),-32768,32767)); } else { for (int i=0; i<9; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fmChan[i]->debug_output(0)<<2,-32768,32767)); } - oscBuf[9]->data[oscBuf[9]->needle++]=CLAMP(abe->get_last_out(0),-32768,32767); + oscBuf[9]->putSample(h,CLAMP(abe->get_last_out(0),-32768,32767)); } } + + for (int i=0; iend(len); + } } void DivPlatformOPL::acquire_ymfm3(short** buf, size_t len) { @@ -494,6 +526,10 @@ void DivPlatformOPL::acquire_ymfm3(short** buf, size_t len) { fmChan[i]=fme->debug_channel(i); } + for (int i=0; ibegin(len); + } + for (size_t h=0; hdebug_output(3); } if (i==15) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut,-32768,32767)); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767)); } } - oscBuf[16]->data[oscBuf[16]->needle++]=CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767); - oscBuf[17]->data[oscBuf[17]->needle++]=CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767); - oscBuf[18]->data[oscBuf[18]->needle++]=CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767); - oscBuf[19]->data[oscBuf[19]->needle++]=CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767); + oscBuf[16]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767)); + oscBuf[17]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767)); + oscBuf[18]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767)); + oscBuf[19]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767)); } else { for (int i=0; i<18; i++) { unsigned char ch=outChanMap[i]; @@ -575,10 +611,14 @@ void DivPlatformOPL::acquire_ymfm3(short** buf, size_t len) { if (chOut==0) { chOut=fmChan[ch]->debug_output(3); } - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767)); } } } + + for (int i=0; iend(len); + } } void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) { @@ -597,6 +637,10 @@ void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) { pcmChan[i]=pcme->debug_channel(i); } + for (int i=0; ibegin(len); + } + for (size_t h=0; hdebug_output(3); } if (i==15) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut,-32768,32767)); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767)); } } - oscBuf[16]->data[oscBuf[16]->needle++]=CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767); - oscBuf[17]->data[oscBuf[17]->needle++]=CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767); - oscBuf[18]->data[oscBuf[18]->needle++]=CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767); - oscBuf[19]->data[oscBuf[19]->needle++]=CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767); + oscBuf[16]->putSample(h,CLAMP(fmChan[7]->debug_special2()<<1,-32768,32767)); + oscBuf[17]->putSample(h,CLAMP(fmChan[8]->debug_special1()<<1,-32768,32767)); + oscBuf[18]->putSample(h,CLAMP(fmChan[8]->debug_special2()<<1,-32768,32767)); + oscBuf[19]->putSample(h,CLAMP(fmChan[7]->debug_special1()<<1,-32768,32767)); } else { for (int i=0; i<18; i++) { unsigned char ch=outChanMap[i]; @@ -667,7 +711,7 @@ void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) { if (chOut==0) { chOut=fmChan[ch]->debug_output(3); } - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(chOut<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(chOut<<1,-32768,32767)); } } for (int i=0; i<24; i++) { @@ -676,9 +720,13 @@ void DivPlatformOPL::acquire_ymfm4(short** buf, size_t len) { chOut+=pcmChan[i]->debug_output(1); chOut+=pcmChan[i]->debug_output(2); chOut+=pcmChan[i]->debug_output(3); - oscBuf[oscOffs]->data[oscBuf[oscOffs]->needle++]=CLAMP(chOut<<1,-32768,32767); + oscBuf[oscOffs]->putSample(h,CLAMP(chOut<<1,-32768,32767)); } } + + for (int i=0; iend(len); + } } static const int cycleMap[18]={ @@ -707,6 +755,10 @@ void DivPlatformOPL::acquire_nukedLLE2(short** buf, size_t len) { int chOut[11]; thread_local ymfm::ymfm_output<2> aOut; + for (int i=0; ibegin(len); + } + for (size_t h=0; h32767) chOut[i]=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=chOut[i]; + oscBuf[i]->putSample(h,chOut[i]); } if (chipType==8950) { @@ -835,9 +887,9 @@ void DivPlatformOPL::acquire_nukedLLE2(short** buf, size_t len) { if (!isMuted[adpcmChan]) { dacOut-=aOut.data[0]>>3; - oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=aOut.data[0]>>1; + oscBuf[adpcmChan]->putSample(h,aOut.data[0]>>1); } else { - oscBuf[adpcmChan]->data[oscBuf[adpcmChan]->needle++]=0; + oscBuf[adpcmChan]->putSample(h,0); } } @@ -846,12 +898,20 @@ void DivPlatformOPL::acquire_nukedLLE2(short** buf, size_t len) { buf[0][h]=dacOut; } + + for (int i=0; iend(len); + } } void DivPlatformOPL::acquire_nukedLLE3(short** buf, size_t len) { int chOut[20]; int ch=0; + for (int i=0; ibegin(len); + } + for (size_t h=0; h32767) chOut[i]=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=chOut[i]; + oscBuf[i]->putSample(h,chOut[i]); } for (int i=0; iend(len); + } } void DivPlatformOPL::acquire(short** buf, size_t len) { @@ -3146,7 +3210,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { compatYPitch=flags.getBool("compatYPitch",false); for (int i=0; i<44; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index aafed906b..f7687cc2a 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -47,6 +47,10 @@ void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) { thread_local int o[2]; thread_local int os; + for (int i=0; i<11; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=6 && properDrums) || !isMuted[nextOut]) { os+=(o[0]+o[1]); - if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->data[oscBuf[nextOut]->needle++]=(o[0]+o[1])<<6; + if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->putSample(h,(o[0]+o[1])<<6); } else { - if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->data[oscBuf[nextOut]->needle++]=0; + if (vrc7 || (fm.rm_enable&0x20)) oscBuf[nextOut]->putSample(h,0); } } if (!(vrc7 || (fm.rm_enable&0x20))) for (int i=0; i<9; i++) { unsigned char ch=visMapOPLL[i]; if ((i>=6 && properDrums) || !isMuted[ch]) { - oscBuf[ch]->data[oscBuf[ch]->needle++]=(fm.output_ch[i])<<6; + oscBuf[ch]->putSample(h,(fm.output_ch[i])<<6); } else { - oscBuf[ch]->data[oscBuf[ch]->needle++]=0; + oscBuf[ch]->putSample(h,0); } } os*=50; @@ -89,6 +93,10 @@ void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) { if (os>32767) os=32767; buf[0][h]=os; } + + for (int i=0; i<11; i++) { + oscBuf[i]->end(len); + } } void DivPlatformOPLL::acquire_ymfm(short** buf, size_t len) { @@ -101,6 +109,10 @@ static const unsigned char freakingDrumMap[5]={ void DivPlatformOPLL::acquire_emu(short** buf, size_t len) { thread_local int os; + for (int i=0; i<11; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=6 && properDrums) { - oscBuf[i]->data[oscBuf[i]->needle++]=(-fm_emu->ch_out[freakingDrumMap[i-6]])<<3; + oscBuf[i]->putSample(h,(-fm_emu->ch_out[freakingDrumMap[i-6]])<<3); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=(-fm_emu->ch_out[i])<<3; + oscBuf[i]->putSample(h,(-fm_emu->ch_out[i])<<3); } } } + + for (int i=0; i<11; i++) { + oscBuf[i]->end(len); + } } void DivPlatformOPLL::acquire(short** buf, size_t len) { @@ -1175,15 +1191,7 @@ void DivPlatformOPLL::setFlags(const DivConfig& flags) { rate=chipClock/36; } for (int i=0; i<11; i++) { - if (selCore==1) { - oscBuf[i]->rate=rate; - } else { - if (i>=6 && properDrumsSys) { - oscBuf[i]->rate=rate; - } else { - oscBuf[i]->rate=rate/2; - } - } + oscBuf[i]->setRate(rate); } noTopHatFreq=flags.getBool("noTopHatFreq",false); fixedAll=flags.getBool("fixedAll",true); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index a0ffd32a1..858546738 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -55,6 +55,10 @@ const char** DivPlatformPCE::getRegisterSheet() { } void DivPlatformPCE::acquire(short** buf, size_t len) { + for (int i=0; i<6; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hResetTS(0); for (int i=0; i<6; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(pce->channel[i].blip_prev_samp[0]+pce->channel[i].blip_prev_samp[1],-32768,32767); + oscBuf[i]->putSample(h,CLAMP(pce->channel[i].blip_prev_samp[0]+pce->channel[i].blip_prev_samp[1],-32768,32767)); } tempL[0]=(tempL[0]>>1)+(tempL[0]>>2); @@ -115,6 +119,10 @@ void DivPlatformPCE::acquire(short** buf, size_t len) { buf[0][h]=tempL[0]; buf[1][h]=tempR[0]; } + + for (int i=0; i<6; i++) { + oscBuf[i]->end(len); + } } void DivPlatformPCE::updateWave(int ch) { @@ -656,7 +664,7 @@ void DivPlatformPCE::setFlags(const DivConfig& flags) { antiClickEnabled=!flags.getBool("noAntiClick",false); rate=chipClock/(coreQuality>>1); for (int i=0; i<6; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } if (pce!=NULL) { diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index 1dec2dbdd..4f519774d 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -354,9 +354,7 @@ void DivPlatformPCSpeaker::acquire_real(blip_buffer_t** bb, size_t off, size_t l } } out=(pos>(freq>>1) && !isMuted[0])?32767:0; - oscBuf->data[oscBuf->needle++]=out; } else { - oscBuf->data[oscBuf->needle++]=0; } //buf[0][i]=0; } diff --git a/src/engine/platform/pokey.cpp b/src/engine/platform/pokey.cpp index b9aa25142..6780e1f98 100644 --- a/src/engine/platform/pokey.cpp +++ b/src/engine/platform/pokey.cpp @@ -74,6 +74,10 @@ void DivPlatformPOKEY::acquire(short** buf, size_t len) { } void DivPlatformPOKEY::acquireMZ(short* buf, size_t len) { + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=14) { oscBufDelay=0; - oscBuf[0]->data[oscBuf[0]->needle++]=pokey.outvol_0<<10; - oscBuf[1]->data[oscBuf[1]->needle++]=pokey.outvol_1<<10; - oscBuf[2]->data[oscBuf[2]->needle++]=pokey.outvol_2<<10; - oscBuf[3]->data[oscBuf[3]->needle++]=pokey.outvol_3<<10; + oscBuf[0]->putSample(h,pokey.outvol_0<<10); + oscBuf[1]->putSample(h,pokey.outvol_1<<10); + oscBuf[2]->putSample(h,pokey.outvol_2<<10); + oscBuf[3]->putSample(h,pokey.outvol_3<<10); } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformPOKEY::acquireASAP(short* buf, size_t len) { + thread_local short oscB[4]; + while (!writes.empty()) { QueuedWrite w=writes.front(); altASAP.write(w.addr, w.val); writes.pop(); } + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=2) { oscBufDelay=0; - buf[h]=altASAP.sampleAudio(oscBuf); + buf[h]=altASAP.sampleAudio(oscB); + + for (int i=0; i<4; i++) { + oscBuf[i]->putSample(h,oscB[i]); + } } else { buf[h]=altASAP.sampleAudio(); } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformPOKEY::tick(bool sysTick) { @@ -488,14 +510,14 @@ void DivPlatformPOKEY::setFlags(const DivConfig& flags) { if (useAltASAP) { rate=chipClock/7; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate/2; + oscBuf[i]->setRate(rate); } altASAP.init(chipClock,rate); altASAP.reset(); } else { rate=chipClock; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate/14; + oscBuf[i]->setRate(rate); } } } diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index a74a9ebce..5582a6230 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -68,17 +68,26 @@ void DivPlatformRF5C68::acquire(short** buf, size_t len) { memset(bufC[i],0,256*sizeof(short)); } - while (len > 0) { - size_t blockLen=MIN(len,256); + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + + size_t lenCopy=len; + while (lenCopy > 0) { + size_t blockLen=MIN(lenCopy,256); short* bufPtrs[2]={&buf[0][pos],&buf[1][pos]}; rf5c68.sound_stream_update(bufPtrs,chBufPtrs,blockLen); for (int i=0; i<8; i++) { for (size_t j=0; jdata[oscBuf[i]->needle++]=(bufC[i*2][j]+bufC[i*2+1][j])>>1; + oscBuf[i]->putSample(pos+j,(bufC[i*2][j]+bufC[i*2+1][j])>>1); } } pos+=blockLen; - len-=blockLen; + lenCopy-=blockLen; + } + + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); } } @@ -375,7 +384,7 @@ void DivPlatformRF5C68::setFlags(const DivConfig& flags) { chipType=flags.getInt("chipType",0); rate=chipClock/384; for (int i=0; i<8; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } rf5c68=(chipType==1)?rf5c164_device():rf5c68_device(); rf5c68.device_start(sampleMem); diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index c17487dde..cec5f7364 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -81,15 +81,23 @@ const char** DivPlatformSCC::getRegisterSheet() { } void DivPlatformSCC::acquire(short** buf, size_t len) { + for (int i=0; i<5; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; htick(coreQuality); short out=(short)scc->out()<<5; buf[0][h]=out; for (int i=0; i<5; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=scc->voice_out(i)<<7; + oscBuf[i]->putSample(h,scc->voice_out(i)<<7); } } + + for (int i=0; i<5; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSCC::updateWave(int ch) { @@ -385,7 +393,7 @@ void DivPlatformSCC::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/(coreQuality>>1); for (int i=0; i<5; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/scvtone.cpp b/src/engine/platform/scvtone.cpp index d589f44ae..96ba326d5 100644 --- a/src/engine/platform/scvtone.cpp +++ b/src/engine/platform/scvtone.cpp @@ -37,6 +37,10 @@ const char** DivPlatformSCVTone::getRegisterSheet() { } void DivPlatformSCVTone::acquire(short** buf, size_t len) { + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[0]->needle++]=scv.chout[0]<<3; - oscBuf[1]->data[oscBuf[1]->needle++]=scv.chout[1]<<3; - oscBuf[2]->data[oscBuf[2]->needle++]=scv.chout[2]<<3; - oscBuf[3]->data[oscBuf[3]->needle++]=scv.chout[3]<<3; + oscBuf[0]->putSample(h,scv.chout[0]<<3); + oscBuf[1]->putSample(h,scv.chout[1]<<3); + oscBuf[2]->putSample(h,scv.chout[2]<<3); + oscBuf[3]->putSample(h,scv.chout[3]<<3); + } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); } } @@ -334,7 +342,7 @@ void DivPlatformSCVTone::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } //upd1771c_sound_set_clock(&scv,(unsigned int)chipClock,8); } diff --git a/src/engine/platform/scvwave.cpp b/src/engine/platform/scvwave.cpp index ddcf57cce..5525a5dc6 100644 --- a/src/engine/platform/scvwave.cpp +++ b/src/engine/platform/scvwave.cpp @@ -37,6 +37,8 @@ const char** DivPlatformSCVWave::getRegisterSheet() { } void DivPlatformSCVWave::acquire(short** buf, size_t len) { + oscBuf[0]->begin(len); + for (size_t h=0; hdata[oscBuf[0]->needle++]=buf[0][h]; + oscBuf[0]->putSample(h,buf[0][h]); } + + oscBuf[0]->end(len); } void DivPlatformSCVWave::tick(bool sysTick) { @@ -324,9 +328,8 @@ void DivPlatformSCVWave::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<1; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } - //upd1771c_sound_set_clock(&scv,(unsigned int)chipClock,8); } void DivPlatformSCVWave::poke(unsigned int addr, unsigned short val) { diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 794fb4d50..f93731d34 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -29,6 +29,10 @@ void DivPlatformSegaPCM::acquire(short** buf, size_t len) { thread_local int os[2]; + for (int i=0; i<16; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=(pcm.lastOut[i][0]+pcm.lastOut[i][1])>>1; + oscBuf[i]->putSample(h,(pcm.lastOut[i][0]+pcm.lastOut[i][1])>>1); } } + + for (int i=0; i<16; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSegaPCM::tick(bool sysTick) { @@ -551,7 +559,7 @@ void DivPlatformSegaPCM::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/256; for (int i=0; i<16; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } oldSlides=flags.getBool("oldSlides",false); diff --git a/src/engine/platform/sid2.cpp b/src/engine/platform/sid2.cpp index 7b77133d1..219953869 100644 --- a/src/engine/platform/sid2.cpp +++ b/src/engine/platform/sid2.cpp @@ -73,8 +73,11 @@ const char** DivPlatformSID2::getRegisterSheet() { return regCheatSheetSID2; } -void DivPlatformSID2::acquire(short** buf, size_t len) -{ +void DivPlatformSID2::acquire(short** buf, size_t len) { + for (int i=0; i<3; i++) { + oscBuf[i]->begin(len); + } + for (size_t i=0; ichan_out[j]>>2; if (co<-32768) co=-32768; if (co>32767) co=32767; - oscBuf[j]->data[oscBuf[j]->needle++]=co; + oscBuf[j]->putSample(i,co); } } } + + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSID2::updateFilter(int channel) @@ -710,7 +717,7 @@ void DivPlatformSID2::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock; for (int i=0; i<3; i++) { - oscBuf[i]->rate=rate/16; + oscBuf[i]->setRate(rate); } keyPriority=flags.getBool("keyPriority",true); diff --git a/src/engine/platform/sid3.cpp b/src/engine/platform/sid3.cpp index 4465b9794..284488428 100644 --- a/src/engine/platform/sid3.cpp +++ b/src/engine/platform/sid3.cpp @@ -94,6 +94,10 @@ const char** DivPlatformSID3::getRegisterSheet() { void DivPlatformSID3::acquire(short** buf, size_t len) { + for (int i=0; ibegin(len); + } + for (size_t i=0; idata[oscBuf[j]->needle++] = sid3->muted[j] ? 0 : (sid3->channel_output[j] / 4); + oscBuf[j]->putSample(i,sid3->muted[j] ? 0 : (sid3->channel_output[j] / 4)); } - oscBuf[SID3_NUM_CHANNELS - 1]->data[oscBuf[SID3_NUM_CHANNELS - 1]->needle++] = sid3->muted[SID3_NUM_CHANNELS - 1] ? 0 : (sid3->wave_channel_output / 4); + oscBuf[SID3_NUM_CHANNELS - 1]->putSample(i,sid3->muted[SID3_NUM_CHANNELS - 1] ? 0 : (sid3->wave_channel_output / 4)); } } + + for (int i=0; iend(len); + } } void DivPlatformSID3::updateFlags(int channel, bool gate) @@ -1351,7 +1359,7 @@ void DivPlatformSID3::setFlags(const DivConfig& flags) { rate=chipClock; sid3_set_clock_rate(sid3, chipClock); for (int i=0; irate=rate/8; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/sm8521.cpp b/src/engine/platform/sm8521.cpp index 0f3ea0b43..5d86e5991 100644 --- a/src/engine/platform/sm8521.cpp +++ b/src/engine/platform/sm8521.cpp @@ -54,13 +54,22 @@ void DivPlatformSM8521::acquire(short** buf, size_t len) { regPool[w.addr&0xff]=w.val; writes.pop(); } + + for (int i=0; i<3; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=sm8521.sg[i].base.out<<7; + oscBuf[i]->putSample(h,sm8521.sg[i].base.out<<7); } - oscBuf[2]->data[oscBuf[2]->needle++]=sm8521.noise.base.out<<7; + oscBuf[2]->putSample(h,sm8521.noise.base.out<<7); + } + + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); } } @@ -369,7 +378,7 @@ void DivPlatformSM8521::setFlags(const DivConfig& flags) { antiClickEnabled=!flags.getBool("noAntiClick",false); rate=chipClock/4/coreQuality; // CKIN -> fCLK(/2) -> Function blocks (/2) for (int i=0; i<3; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 85cb21e5a..54a667883 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -63,6 +63,11 @@ void DivPlatformSMS::poolWrite(unsigned short a, unsigned char v) { void DivPlatformSMS::acquire_nuked(short** buf, size_t len) { int oL=0; int oR=0; + + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=0; + oscBuf[i]->putSample(h,0); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=sn_nuked.vol_table[sn_nuked.volume_out[i]]*3; + oscBuf[i]->putSample(h,sn_nuked.vol_table[sn_nuked.volume_out[i]]*3); } } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSMS::acquire_mame(short** buf, size_t len) { @@ -122,6 +131,11 @@ void DivPlatformSMS::acquire_mame(short** buf, size_t len) { writes.pop(); } + + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hsound_stream_update(outs,1); for (int i=0; i<4; i++) { if (isMuted[i]) { - oscBuf[i]->data[oscBuf[i]->needle++]=0; + oscBuf[i]->putSample(h,0); } else { - oscBuf[i]->data[oscBuf[i]->needle++]=sn->get_channel_output(i)*3; + oscBuf[i]->putSample(h,sn->get_channel_output(i)*3); } } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSMS::acquire(short** buf, size_t len) { @@ -638,7 +656,7 @@ void DivPlatformSMS::setFlags(const DivConfig& flags) { rate=chipClock/divider; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/sound/pokey/AltASAP.cpp b/src/engine/platform/sound/pokey/AltASAP.cpp index e66750278..33011e653 100644 --- a/src/engine/platform/sound/pokey/AltASAP.cpp +++ b/src/engine/platform/sound/pokey/AltASAP.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2022 tildearrow and contributors + * Copyright (C) 2021-2025 tildearrow and contributors * * Original author: Piotr Fusik (http://asap.sourceforge.net) * Rewritten based on Mikey emulation by Waldemar Pawlaszek @@ -490,7 +490,7 @@ public: } } - int16_t sampleAudio( DivDispatchOscBuffer** oscb ) + int16_t sampleAudio( short* oscb ) { for ( ;; ) { @@ -504,10 +504,10 @@ public: if ( oscb != nullptr ) { - oscb[0]->data[oscb[0]->needle++]=ch0 * MAGICK_OSC_VOLUME_BOOSTER; - oscb[1]->data[oscb[1]->needle++]=ch1 * MAGICK_OSC_VOLUME_BOOSTER; - oscb[2]->data[oscb[2]->needle++]=ch2 * MAGICK_OSC_VOLUME_BOOSTER; - oscb[3]->data[oscb[3]->needle++]=ch3 * MAGICK_OSC_VOLUME_BOOSTER; + oscb[0]=ch0 * MAGICK_OSC_VOLUME_BOOSTER; + oscb[1]=ch1 * MAGICK_OSC_VOLUME_BOOSTER; + oscb[2]=ch2 * MAGICK_OSC_VOLUME_BOOSTER; + oscb[3]=ch3 * MAGICK_OSC_VOLUME_BOOSTER; } enqueueSampling(); @@ -612,7 +612,7 @@ private: }; //Initializing periods with safe defaults -Pokey::Pokey() : mPokeyClock{ (uint32_t)COLOR_NTSC / 2 }, mSampleRate{ mPokeyClock / 7 }, mPokey{} +Pokey::Pokey() : mPokeyClock{ (uint32_t)3579545.4545454545454545454545454545454644484879993035705375307 / 2 }, mSampleRate{ mPokeyClock / 7 }, mPokey{} { } @@ -638,7 +638,7 @@ void Pokey::write( uint8_t address, uint8_t value ) mPokey->write( address, value ); } -int16_t Pokey::sampleAudio( DivDispatchOscBuffer** oscb ) +int16_t Pokey::sampleAudio( short* oscb ) { assert( mPokey ); return mPokey->sampleAudio( oscb ); diff --git a/src/engine/platform/sound/pokey/AltASAP.hpp b/src/engine/platform/sound/pokey/AltASAP.hpp index c159e9d5e..26769a635 100644 --- a/src/engine/platform/sound/pokey/AltASAP.hpp +++ b/src/engine/platform/sound/pokey/AltASAP.hpp @@ -3,9 +3,6 @@ #include #include -// can you forgive me -#include "../../../dispatch.h" - namespace AltASAP { @@ -20,7 +17,7 @@ public: ~Pokey(); void write( uint8_t address, uint8_t value ); - int16_t sampleAudio( DivDispatchOscBuffer** oscb = nullptr ); + int16_t sampleAudio( short* oscb = nullptr ); uint8_t const* getRegisterPool(); diff --git a/src/engine/platform/supervision.cpp b/src/engine/platform/supervision.cpp index 529f11032..506e7b871 100644 --- a/src/engine/platform/supervision.cpp +++ b/src/engine/platform/supervision.cpp @@ -58,10 +58,15 @@ const char** DivPlatformSupervision::getRegisterSheet() { void DivPlatformSupervision::acquire(short** buf, size_t len) { int mask_bits=0; - for (int i=0; i<4; i++) + for (int i=0; i<4; i++) { mask_bits |= isMuted[i]?0:8>>i; + } supervision_set_mute_mask(&svision,mask_bits); + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=CLAMP((((int)s[2+i])-128)*256,-32768,32767); + oscBuf[i]->putSample(h,CLAMP((((int)s[2+i])-128)*256,-32768,32767)); } tempL[0]=(tempL[0]>>1)+(tempL[0]>>2); @@ -91,11 +96,14 @@ void DivPlatformSupervision::acquire(short** buf, size_t len) { buf[0][h]=tempL[0]; buf[1][h]=tempR[0]; } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSupervision::tick(bool sysTick) { for (int i=0; i<4; i++) { - chan[i].std.next(); if (chan[i].std.vol.had) { chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15); @@ -477,7 +485,7 @@ void DivPlatformSupervision::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/64; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } supervision_sound_set_clock(&svision,(unsigned int)chipClock); supervision_sound_set_flags(&svision,(unsigned int)otherFlags); diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 6fb5afc3e..338f8fd0b 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -54,6 +54,10 @@ const char** DivPlatformSwan::getRegisterSheet() { } void DivPlatformSwan::acquire(short** buf, size_t len) { + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=(ws->sample_cache[i][0]+ws->sample_cache[i][1])<<6; + oscBuf[i]->putSample(h,(ws->sample_cache[i][0]+ws->sample_cache[i][1])<<6); } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformSwan::updateWave(int ch) { @@ -607,7 +615,7 @@ void DivPlatformSwan::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/coreQuality; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index c445c25a2..4ce244a60 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -36,6 +36,10 @@ const char** DivPlatformT6W28::getRegisterSheet() { } void DivPlatformT6W28::acquire(short** buf, size_t len) { + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=(out[i][1].curValue+out[i][2].curValue)<<7; + oscBuf[i]->putSample(h,(out[i][1].curValue+out[i][2].curValue)<<7); tempL+=out[i][1].curValue<<7; tempR+=out[i][2].curValue<<7; } @@ -67,6 +71,10 @@ void DivPlatformT6W28::acquire(short** buf, size_t len) { buf[0][h]=tempL; buf[1][h]=tempR; } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformT6W28::writeOutVol(int ch) { @@ -364,7 +372,7 @@ void DivPlatformT6W28::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/16; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } easyNoise=!flags.getBool("noEasyNoise",false); diff --git a/src/engine/platform/ted.cpp b/src/engine/platform/ted.cpp index 431c4f340..46c38ebd6 100644 --- a/src/engine/platform/ted.cpp +++ b/src/engine/platform/ted.cpp @@ -40,6 +40,10 @@ const char** DivPlatformTED::getRegisterSheet() { } void DivPlatformTED::acquire(short** buf, size_t len) { + for (int i=0; i<2; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[0]->needle++]=(ted.voice0_output_enabled && ted.voice0_sign)?(ted.volume<<1):0; - oscBuf[1]->data[oscBuf[1]->needle++]=(ted.voice1_output_enabled && ((ted.noise && (!(ted.noise_shift_register&1))) || (!ted.noise && ted.voice1_sign)))?(ted.volume<<1):0; + oscBuf[0]->putSample(h,(ted.voice0_output_enabled && ted.voice0_sign)?(ted.volume<<1):0); + oscBuf[1]->putSample(h,(ted.voice1_output_enabled && ((ted.noise && (!(ted.noise_shift_register&1))) || (!ted.noise && ted.voice1_sign)))?(ted.volume<<1):0); + } + + for (int i=0; i<2; i++) { + oscBuf[i]->end(len); } } @@ -322,7 +330,7 @@ void DivPlatformTED::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/8; for (int i=0; i<2; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } keyPriority=flags.getBool("keyPriority",true); } diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index 216578b86..8f846f6bc 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -39,6 +39,10 @@ const char** DivPlatformTIA::getRegisterSheet() { } void DivPlatformTIA::acquire(short** buf, size_t len) { + for (int i=0; i<2; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=114) { chanOscCounter=0; - oscBuf[0]->data[oscBuf[0]->needle++]=tia.myChannelOut[0]; - oscBuf[1]->data[oscBuf[1]->needle++]=tia.myChannelOut[1]; + oscBuf[0]->putSample(h,tia.myChannelOut[0]); + oscBuf[1]->putSample(h,tia.myChannelOut[1]); } } + + for (int i=0; i<2; i++) { + oscBuf[i]->end(len); + } } unsigned char DivPlatformTIA::dealWithFreq(unsigned char shape, int base, int pitch) { @@ -471,7 +479,7 @@ void DivPlatformTIA::setFlags(const DivConfig& flags) { softwarePitch=flags.getBool("softwarePitch",false); oldPitch=flags.getBool("oldPitch",false); for (int i=0; i<2; i++) { - oscBuf[i]->rate=rate/114; + oscBuf[i]->setRate(rate); } tia.reset(mixingType); } diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 579ec1157..9bf490c51 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -62,6 +62,10 @@ void DivPlatformTX81Z::acquire(short** buf, size_t len) { ymfm::ym2414::fm_engine* fme=fm_ymfm->debug_engine(); + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hgenerate(&out_ymfm); for (int i=0; i<8; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1),-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1),-32768,32767)); } os[0]=out_ymfm.data[0]; @@ -96,6 +100,10 @@ void DivPlatformTX81Z::acquire(short** buf, size_t len) { buf[0][h]=os[0]; buf[1][h]=os[1]; } + + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } } static unsigned char noteMap[12]={ @@ -1114,7 +1122,7 @@ void DivPlatformTX81Z::setFlags(const DivConfig& flags) { rate=chipClock/64; for (int i=0; i<8; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index 75529e644..bf73025b2 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -94,6 +94,10 @@ const char** DivPlatformVB::getRegisterSheet() { } void DivPlatformVB::acquire(short** buf, size_t len) { + for (int i=0; i<6; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=(vb->last_output[i][0]+vb->last_output[i][1])*8; + oscBuf[i]->putSample(h,(vb->last_output[i][0]+vb->last_output[i][1])*8); tempL+=vb->last_output[i][0]; tempR+=vb->last_output[i][1]; } @@ -120,6 +124,10 @@ void DivPlatformVB::acquire(short** buf, size_t len) { buf[0][h]=tempL; buf[1][h]=tempR; } + + for (int i=0; i<6; i++) { + oscBuf[i]->end(len); + } } void DivPlatformVB::updateWave(int ch) { @@ -586,7 +594,7 @@ void DivPlatformVB::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/coreQuality; for (int i=0; i<6; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } romMode=flags.getBool("romMode",false); diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 1845b6dd6..4bd4683c3 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -58,12 +58,17 @@ const char** DivPlatformVERA::getRegisterSheet() { // TODO: possible sample offset latency... void DivPlatformVERA::acquire(short** buf, size_t len) { + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + // both PSG part and PCM part output a full 16-bit range, putting bufL/R // argument right into both could cause an overflow short whyCallItBuf[4][128]; size_t pos=0; + size_t lenCopy=0; DivSample* s=parent->getSample(chan[16].pcm.sample); - while (len>0) { + while (lenCopy>0) { if (s->samples>0 && chan[16].pcm.possamples) { while (pcm_is_fifo_almost_empty(pcm)) { short tmp_l=0; @@ -109,24 +114,30 @@ void DivPlatformVERA::acquire(short** buf, size_t len) { // just let the buffer run out chan[16].pcm.sample=-1; } - int curLen=MIN(len,128); + int curLen=MIN(lenCopy,128); memset(whyCallItBuf,0,sizeof(whyCallItBuf)); pcm_render(pcm,whyCallItBuf[2],whyCallItBuf[3],curLen); for (int i=0; idata[oscBuf[i]->needle++]=psg->channels[i].lastOut; + for (int j=0; j<16; j++) { + oscBuf[j]->putSample(pos,psg->channels[j].lastOut); } + int pcmOut=(whyCallItBuf[2][i]+whyCallItBuf[3][i])>>1; if (pcmOut<-32768) pcmOut=-32768; if (pcmOut>32767) pcmOut=32767; - oscBuf[16]->data[oscBuf[16]->needle++]=pcmOut; + oscBuf[16]->putSample(pos,pcmOut); + + pos++; } - len-=curLen; + lenCopy-=curLen; + } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); } } @@ -537,7 +548,7 @@ void DivPlatformVERA::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/512; for (int i=0; i<17; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index e01e9fae5..6f74b6e0a 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -46,6 +46,11 @@ void DivPlatformVIC20::acquire(short** buf, size_t len) { 0b0, 0b10, 0b100, 0b110, 0b1000, 0b1010, 0b1011, 0b1110, 0b10010, 0b10100, 0b10110, 0b11000, 0b11010, 0b100100, 0b101010, 0b101100 }; + + for (int i=0; i<4; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=vic->ch[i].out?(vic->volume<<11):0; + oscBuf[i]->putSample(h,vic->ch[i].out?(vic->volume<<11):0); } } + + for (int i=0; i<4; i++) { + oscBuf[i]->end(len); + } } void DivPlatformVIC20::calcAndWriteOutVol(int ch, int env) { @@ -345,7 +354,7 @@ void DivPlatformVIC20::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index d1c8372fa..a6fe57734 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -47,7 +47,11 @@ const char** DivPlatformVRC6::getRegisterSheet() { } void DivPlatformVRC6::acquire(short** buf, size_t len) { - for (size_t i=0; ibegin(len); + } + + for (size_t h=0; h32767) sample=32767; if (sample<-32768) sample=-32768; - buf[0][i]=sample; + buf[0][h]=sample; // Oscilloscope buffer part if (++writeOscBuf>=32) { writeOscBuf=0; for (int i=0; i<2; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=vrc6.pulse_out(i)<<11; + oscBuf[i]->putSample(h,vrc6.pulse_out(i)<<11); } - oscBuf[2]->data[oscBuf[2]->needle++]=vrc6.sawtooth_out()<<10; + oscBuf[2]->putSample(h,vrc6.sawtooth_out()<<10); } // Command part @@ -128,6 +132,10 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) { writes.pop(); } } + + for (int i=0; i<3; i++) { + oscBuf[i]->end(len); + } } void DivPlatformVRC6::tick(bool sysTick) { @@ -541,7 +549,7 @@ void DivPlatformVRC6::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock; for (int i=0; i<3; i++) { - oscBuf[i]->rate=rate/32; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index a6c24f377..ef0278dd4 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -206,6 +206,10 @@ const char** DivPlatformX1_010::getRegisterSheet() { } void DivPlatformX1_010::acquire(short** buf, size_t len) { + for (int i=0; i<16; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; hdata[oscBuf[i]->needle++]=CLAMP(vo,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(vo,-32768,32767)); } } + + for (int i=0; i<16; i++) { + oscBuf[i]->end(len); + } } u8 DivPlatformX1_010::read_byte(u32 address) { @@ -965,7 +973,7 @@ void DivPlatformX1_010::setFlags(const DivConfig& flags) { stereo=flags.getBool("stereo",false); isBanked=flags.getBool("isBanked",false); for (int i=0; i<16; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index a020b48b0..fa4bd2d20 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -169,6 +169,10 @@ void DivPlatformYM2203::acquire_combo(short** buf, size_t len) { thread_local int os; thread_local short ignored[2]; + for (int i=0; i<7; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -236,13 +240,17 @@ void DivPlatformYM2203::acquire_combo(short** buf, size_t len) { buf[0][h]=os; for (int i=0; i<3; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767)); } for (int i=(3+isCSM); i<(6+isCSM); i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-(2+isCSM)]<<1; + oscBuf[i]->putSample(h,fmout.data[i-(2+isCSM)]<<1); } } + + for (int i=0; i<7; i++) { + oscBuf[i]->end(len); + } } void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) { @@ -255,6 +263,10 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) { fmChan[i]=fme->debug_channel(i); } + for (int i=0; i<7; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -294,13 +306,17 @@ void DivPlatformYM2203::acquire_ymfm(short** buf, size_t len) { for (int i=0; i<3; i++) { int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1; - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(out,-32768,32767)); } for (int i=(3+isCSM); i<(6+isCSM); i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=fmout.data[i-(2+isCSM)]<<1; + oscBuf[i]->putSample(h,fmout.data[i-(2+isCSM)]<<1); } } + + for (int i=0; i<7; i++) { + oscBuf[i]->end(len); + } } static const unsigned char subCycleMap[6]={ @@ -310,6 +326,10 @@ static const unsigned char subCycleMap[6]={ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { thread_local int fmOut[6]; + for (int i=0; i<7; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h32767) fmOut[i]=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i]; + oscBuf[i]->putSample(h,fmOut[i]); } // SSG for (int i=0; i<3; i++) { - oscBuf[i+3]->data[oscBuf[i+3]->needle++]=fm_lle.o_analog_ch[i]*32767; + oscBuf[i+3]->putSample(h,fm_lle.o_analog_ch[i]*32767); } // DAC @@ -461,6 +481,10 @@ void DivPlatformYM2203::acquire_lle(short** buf, size_t len) { buf[0][h]=outL; } + + for (int i=0; i<7; i++) { + oscBuf[i]->end(len); + } } void DivPlatformYM2203::fillStream(std::vector& stream, int sRate, size_t len) { @@ -1386,7 +1410,7 @@ void DivPlatformYM2203::setFlags(const DivConfig& flags) { rate=fm->sample_rate(chipClock); } for (int i=0; i<7; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } immWrite(0x2d,0xff); immWrite(prescale,0xff); diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 1380c0b50..5dc024a70 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -320,6 +320,10 @@ void DivPlatformYM2608::acquire_combo(short** buf, size_t len) { adpcmAChan[i]=aae->debug_channel(i); } + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -406,19 +410,23 @@ void DivPlatformYM2608::acquire_combo(short** buf, size_t len) { for (int i=0; i<(psgChanOffs-isCSM); i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767)); } ssge->get_last_out(ssgOut); for (int i=psgChanOffs; idata[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1; + oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1); } for (int i=adpcmAChanOffs; idata[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1; + oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1); } - oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1; + oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1); + } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); } } @@ -439,6 +447,10 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) { adpcmAChan[i]=aae->debug_channel(i); } + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -482,19 +494,23 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) { for (int i=0; i<6; i++) { int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1; - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(out,-32768,32767)); } ssge->get_last_out(ssgOut); for (int i=(6+isCSM); i<(9+isCSM); i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-6-isCSM]<<1; + oscBuf[i]->putSample(h,ssgOut.data[i-6-isCSM]<<1); } for (int i=(9+isCSM); i<(15+isCSM); i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=(adpcmAChan[i-9-isCSM]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1))>>1; + oscBuf[i]->putSample(h,(adpcmAChan[i-9-isCSM]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1))>>1); } - oscBuf[15+isCSM]->data[oscBuf[15+isCSM]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1; + oscBuf[15+isCSM]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1); + } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); } } @@ -505,6 +521,10 @@ static const unsigned char subCycleMap[6]={ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { thread_local int fmOut[6]; + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h32767) fmOut[i]=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i]; + oscBuf[i]->putSample(h,fmOut[i]); } // SSG for (int i=0; i<3; i++) { - oscBuf[i+6]->data[oscBuf[i+6]->needle++]=fm_lle.o_analog_ch[i]*32767; + oscBuf[i+6]->putSample(h,fm_lle.o_analog_ch[i]*32767); } // RSS for (int i=0; i<6; i++) { if (rssOut[i]<-32768) rssOut[i]=-32768; if (rssOut[i]>32767) rssOut[i]=32767; - oscBuf[9+i]->data[oscBuf[9+i]->needle++]=rssOut[i]; + oscBuf[9+i]->putSample(h,rssOut[i]); } // ADPCM - oscBuf[15]->data[oscBuf[15]->needle++]=fm_lle.ac_ad_output; + oscBuf[15]->putSample(h,fm_lle.ac_ad_output); // DAC int accm1=(short)dacOut[1]; @@ -686,6 +706,10 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { buf[0][h]=outL; buf[1][h]=outR; } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); + } } void DivPlatformYM2608::fillStream(std::vector& stream, int sRate, size_t len) { @@ -2018,7 +2042,7 @@ void DivPlatformYM2608::setFlags(const DivConfig& flags) { rate=fm->sample_rate(chipClock); } for (int i=0; i<17; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } immWrite(0x2d,0xff); immWrite(prescale,0xff); diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 025e75208..a12048230 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -256,6 +256,10 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) { adpcmAChan[i]=aae->debug_channel(i); } + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -338,19 +342,23 @@ void DivPlatformYM2610::acquire_combo(short** buf, size_t len) { for (int i=0; i<(psgChanOffs-isCSM); i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[bchOffs[i]]<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[bchOffs[i]]<<1,-32768,32767)); } ssge->get_last_out(ssgOut); for (int i=psgChanOffs; idata[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1; + oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1); } for (int i=adpcmAChanOffs; idata[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1; + oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1); } - oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1; + oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1); + } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); } } @@ -373,6 +381,10 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) { adpcmAChan[i]=aae->debug_channel(i); } + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -416,19 +428,23 @@ void DivPlatformYM2610::acquire_ymfm(short** buf, size_t len) { for (int i=0; i<(psgChanOffs-isCSM); i++) { int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1; - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(out,-32768,32767)); } ssge->get_last_out(ssgOut); for (int i=psgChanOffs; idata[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1; + oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1); } for (int i=adpcmAChanOffs; idata[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1; + oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1); } - oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1; + oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1); + } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); } } @@ -439,6 +455,10 @@ static const unsigned char subCycleMap[6]={ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) { thread_local int fmOut[6]; + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h32767) fmOut[i]=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i]; + oscBuf[i]->putSample(h,fmOut[i]); } // SSG for (int i=0; i<3; i++) { - oscBuf[i+4]->data[oscBuf[i+4]->needle++]=fm_lle.o_analog_ch[i]*32767; + oscBuf[i+4]->putSample(h,fm_lle.o_analog_ch[i]*32767); } // RSS for (int i=0; i<6; i++) { if (rssOut[i]<-32768) rssOut[i]=-32768; if (rssOut[i]>32767) rssOut[i]=32767; - oscBuf[7+i]->data[oscBuf[7+i]->needle++]=rssOut[i]; + oscBuf[7+i]->putSample(h,rssOut[i]); } // ADPCM - oscBuf[13]->data[oscBuf[13]->needle++]=fm_lle.ac_ad_output; + oscBuf[13]->putSample(h,fm_lle.ac_ad_output); // DAC int accm1=(short)dacOut[1]; @@ -618,6 +638,10 @@ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) { buf[0][h]=outL; buf[1][h]=outR; } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); + } } void DivPlatformYM2610::tick(bool sysTick) { diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 55fbef1d5..bdad880ce 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -320,6 +320,10 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) { adpcmAChan[i]=aae->debug_channel(i); } + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -406,19 +410,23 @@ void DivPlatformYM2610B::acquire_combo(short** buf, size_t len) { for (int i=0; i<(psgChanOffs-isCSM); i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(fm_nuked.ch_out[i]<<1,-32768,32767)); } ssge->get_last_out(ssgOut); for (int i=psgChanOffs; idata[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1; + oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1); } for (int i=adpcmAChanOffs; idata[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1; + oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1); } - oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1; + oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1); + } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); } } @@ -439,6 +447,10 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) { adpcmAChan[i]=aae->debug_channel(i); } + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h OPN ay->runDAC(); @@ -482,19 +494,23 @@ void DivPlatformYM2610B::acquire_ymfm(short** buf, size_t len) { for (int i=0; i<(psgChanOffs-isCSM); i++) { int out=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1))<<1; - oscBuf[i]->data[oscBuf[i]->needle++]=CLAMP(out,-32768,32767); + oscBuf[i]->putSample(h,CLAMP(out,-32768,32767)); } ssge->get_last_out(ssgOut); for (int i=psgChanOffs; idata[oscBuf[i]->needle++]=ssgOut.data[i-psgChanOffs]<<1; + oscBuf[i]->putSample(h,ssgOut.data[i-psgChanOffs]<<1); } for (int i=adpcmAChanOffs; idata[oscBuf[i]->needle++]=(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1; + oscBuf[i]->putSample(h,(adpcmAChan[i-adpcmAChanOffs]->get_last_out(0)+adpcmAChan[i-adpcmAChanOffs]->get_last_out(1))>>1); } - oscBuf[adpcmBChanOffs]->data[oscBuf[adpcmBChanOffs]->needle++]=(abe->get_last_out(0)+abe->get_last_out(1))>>1; + oscBuf[adpcmBChanOffs]->putSample(h,(abe->get_last_out(0)+abe->get_last_out(1))>>1); + } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); } } @@ -507,6 +523,10 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) { fm_lle.ym2610b=1; + for (int i=0; i<17; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h32767) fmOut[i]=32767; - oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i]; + oscBuf[i]->putSample(h,fmOut[i]); } // SSG for (int i=0; i<3; i++) { - oscBuf[i+6]->data[oscBuf[i+6]->needle++]=fm_lle.o_analog_ch[i]*32767; + oscBuf[i+6]->putSample(h,fm_lle.o_analog_ch[i]*32767); } // RSS for (int i=0; i<6; i++) { if (rssOut[i]<-32768) rssOut[i]=-32768; if (rssOut[i]>32767) rssOut[i]=32767; - oscBuf[9+i]->data[oscBuf[9+i]->needle++]=rssOut[i]; + oscBuf[9+i]->putSample(h,rssOut[i]); } // ADPCM - oscBuf[15]->data[oscBuf[15]->needle++]=fm_lle.ac_ad_output; + oscBuf[15]->putSample(h,fm_lle.ac_ad_output); // DAC int accm1=(short)dacOut[1]; @@ -686,6 +706,10 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) { buf[0][h]=outL; buf[1][h]=outR; } + + for (int i=0; i<17; i++) { + oscBuf[i]->end(len); + } } void DivPlatformYM2610B::tick(bool sysTick) { diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index 2586aac20..9854d6248 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -323,7 +323,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN { rate=fm->sample_rate(chipClock); } for (int i=0; i<17; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 214a1e869..146ac38bb 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -59,15 +59,22 @@ const char** DivPlatformYMZ280B::getRegisterSheet() { return regCheatSheetYMZ280B; } +// not this crap again... I hate while loops! void DivPlatformYMZ280B::acquire(short** buf, size_t len) { short why[16][256]; short *bufPtrs[16]={ why[0],why[1],why[2],why[3],why[4],why[5],why[6],why[7], why[8],why[9],why[10],why[11],why[12],why[13],why[14],why[15] }; + + for (int i=0; i<8; i++) { + oscBuf[i]->begin(len); + } + + size_t lenCopy=len; size_t pos=0; - while (len > 0) { - size_t blockLen = MIN(len, 256); + while (lenCopy > 0) { + size_t blockLen = MIN(lenCopy, 256); ymz280b.sound_stream_update(bufPtrs, blockLen); for (size_t i=0; idata[oscBuf[j]->needle++]=(short)(((int)why[j*2][i]+why[j*2+1][i])/4); + oscBuf[j]->putSample(pos,(short)(((int)why[j*2][i]+why[j*2+1][i])/4)); } buf[0][pos]=(short)(dataL/8); buf[1][pos]=(short)(dataR/8); pos++; } - len-=blockLen; + lenCopy-=blockLen; + } + + for (int i=0; i<8; i++) { + oscBuf[i]->end(len); } } @@ -531,7 +542,7 @@ void DivPlatformYMZ280B::setFlags(const DivConfig& flags) { break; } for (int i=0; i<8; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index 1d3ccb421..7e0dbe74d 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -28,6 +28,10 @@ const char** DivPlatformZXBeeper::getRegisterSheet() { } void DivPlatformZXBeeper::acquire(short** buf, size_t len) { + for (int i=0; i<1; i++) { + oscBuf[i]->begin(len); + } + bool o=false; for (size_t h=0; hdata[oscBuf[0]->needle++]=o?16384:-16384; + oscBuf[0]->putSample(h,o?16384:-16384); continue; } @@ -65,7 +69,11 @@ void DivPlatformZXBeeper::acquire(short** buf, size_t len) { if (++curChan>=6) curChan=0; buf[0][h]=o?16384:0; - oscBuf[0]->data[oscBuf[0]->needle++]=o?16384:-16384; + oscBuf[0]->putSample(h,o?16384:-16384); + } + + for (int i=0; i<1; i++) { + oscBuf[i]->end(len); } } @@ -304,7 +312,7 @@ void DivPlatformZXBeeper::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/4; for (int i=0; i<6; i++) { - oscBuf[i]->rate=rate; + oscBuf[i]->setRate(rate); } } diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index 9c75df430..5fd27689c 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -30,6 +30,10 @@ const char** DivPlatformZXBeeperQuadTone::getRegisterSheet() { } void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) { + for (int i=0; i<5; i++) { + oscBuf[i]->begin(len); + } + for (size_t h=0; h=0 && curSamplesong.sampleLen) { @@ -51,12 +55,12 @@ void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) { if (sampleActive) { buf[0][h]=chan[4].out?32767:0; if (outputClock==0) { - oscBuf[0]->data[oscBuf[0]->needle++]=0; - oscBuf[1]->data[oscBuf[1]->needle++]=0; - oscBuf[2]->data[oscBuf[2]->needle++]=0; - oscBuf[3]->data[oscBuf[3]->needle++]=0; + oscBuf[0]->putSample(h,0); + oscBuf[1]->putSample(h,0); + oscBuf[2]->putSample(h,0); + oscBuf[3]->putSample(h,0); } - oscBuf[4]->data[oscBuf[4]->needle++]=buf[0][h]; + oscBuf[4]->putSample(h,buf[0][h]); } else { int ch=outputClock/2; int b=ch*4; @@ -72,7 +76,7 @@ void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) { } else { oscOut=16383; } - oscBuf[ch]->data[oscBuf[ch]->needle++]=oscOut; + oscBuf[ch]->putSample(h,oscOut); } if (!isMuted[ch]) o=chan[ch].out&0x10; if (noHiss) { @@ -85,10 +89,14 @@ void DivPlatformZXBeeperQuadTone::acquire(short** buf, size_t len) { buf[0][h]=o?32767:0; } chan[ch].out<<=1; - oscBuf[4]->data[oscBuf[4]->needle++]=0; + oscBuf[4]->putSample(h,0); } outputClock=(outputClock+1)&7; } + + for (int i=0; i<5; i++) { + oscBuf[i]->end(len); + } } void DivPlatformZXBeeperQuadTone::tick(bool sysTick) { @@ -385,10 +393,9 @@ void DivPlatformZXBeeperQuadTone::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/40; noHiss=flags.getBool("noHiss",false); - for (int i=0; i<4; i++) { - oscBuf[i]->rate=rate/8; + for (int i=0; i<5; i++) { + oscBuf[i]->setRate(rate); } - oscBuf[4]->rate=rate; } void DivPlatformZXBeeperQuadTone::poke(unsigned int addr, unsigned short val) { From 6813c30e3a30b9a7b3bdd3641f4947ee06077b73 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 2 Mar 2025 18:02:38 -0500 Subject: [PATCH 11/11] new chan osc, part 8 fix remaining bugs --- src/engine/platform/msm6258.cpp | 2 +- src/engine/platform/tx81z.cpp | 2 +- src/engine/platform/vera.cpp | 2 +- src/gui/chanOsc.cpp | 9 +++++---- src/gui/gui.h | 3 ++- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index a6a19f100..91547feb6 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -92,7 +92,7 @@ void DivPlatformMSM6258::acquire(short** buf, size_t len) { } else { buf[0][h]=(msmPan&2)?0:msmOut; buf[1][h]=(msmPan&1)?0:msmOut; - oscBuf[0]->putSample(h,msmPan?(msmOut>>1):0); + oscBuf[0]->putSample(h,(msmPan!=3)?(msmOut>>1):0); } } diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 9bf490c51..1a1b1134e 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -102,7 +102,7 @@ void DivPlatformTX81Z::acquire(short** buf, size_t len) { } for (int i=0; i<8; i++) { - oscBuf[i]->begin(len); + oscBuf[i]->end(len); } } diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 4bd4683c3..9a7692039 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -66,7 +66,7 @@ void DivPlatformVERA::acquire(short** buf, size_t len) { // argument right into both could cause an overflow short whyCallItBuf[4][128]; size_t pos=0; - size_t lenCopy=0; + size_t lenCopy=len; DivSample* s=parent->getSample(chan[16].pcm.sample); while (lenCopy>0) { if (s->samples>0 && chan[16].pcm.possamples) { diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index e262f355a..a9b574cd7 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -643,7 +643,6 @@ void FurnaceGUI::drawChanOsc() { float minLevel=1.0f; float maxLevel=-1.0f; - float dcOff=0.0f; if (debugFFT) { // FFT debug code! @@ -717,7 +716,8 @@ void FurnaceGUI::drawChanOsc() { if (maxLeveldcOff; + fft->dcOff+=(y-fft->dcOff)*0.001; if (yOut<-0.5f) yOut=-0.5f; if (yOut>0.5f) yOut=0.5f; yOut*=chanOscAmplify*2.0f; @@ -737,14 +737,15 @@ void FurnaceGUI::drawChanOsc() { if (maxLeveldcOff; + fft->dcOff+=(y-fft->dcOff)*0.001; if (yOut<-0.5f) yOut=-0.5f; if (yOut>0.5f) yOut=0.5f; yOut*=chanOscAmplify*2.0f; fft->oscTex[kTex]=yOut; } } - dcOff=(minLevel+maxLevel)*0.5f; + //dcOff=(minLevel+maxLevel)*0.5f; if (!(rend->supportsDrawOsc() && settings.shaderOsc)) { for (unsigned short j=0; j