diff --git a/src/engine/platform/pokey.cpp b/src/engine/platform/pokey.cpp index 7427733c7..a6ddb78f1 100644 --- a/src/engine/platform/pokey.cpp +++ b/src/engine/platform/pokey.cpp @@ -96,16 +96,16 @@ void DivPlatformPOKEY::acquireMZ(short* buf, size_t start, size_t len) { void DivPlatformPOKEY::acquireASAP(short* buf, size_t start, size_t len) { while (!writes.empty()) { QueuedWrite w=writes.front(); - altASAP->write(w.addr, w.val); + altASAP.write(w.addr, w.val); writes.pop(); } for (size_t h=start; h=2) { oscBufDelay=0; - buf[h]=altASAP->sampleAudio(oscBuf); + buf[h]=altASAP.sampleAudio(oscBuf); } else { - buf[h]=altASAP->sampleAudio(); + buf[h]=altASAP.sampleAudio(); } } } @@ -396,7 +396,7 @@ DivDispatchOscBuffer* DivPlatformPOKEY::getOscBuffer(int ch) { unsigned char* DivPlatformPOKEY::getRegisterPool() { if (useAltASAP) { - return const_cast(altASAP->getRegisterPool()); + return const_cast(altASAP.getRegisterPool()); } else { return regPool; } @@ -418,7 +418,7 @@ void DivPlatformPOKEY::reset() { } if (useAltASAP) { - altASAP->reset(); + altASAP.reset(); } else { ResetPokeyState(&pokey); } @@ -454,10 +454,7 @@ void DivPlatformPOKEY::setFlags(const DivConfig& flags) { for (int i=0; i<4; i++) { oscBuf[i]->rate=rate/2; } - if (altASAP) { - delete altASAP; - } - altASAP=new AltASAP::Pokey(chipClock,rate); + altASAP.init(chipClock,rate); } else { rate=chipClock; for (int i=0; i<4; i++) { @@ -479,7 +476,6 @@ int DivPlatformPOKEY::init(DivEngine* p, int channels, int sugRate, const DivCon dumpWrites=false; skipRegisterWrites=false; oscBufDelay=0; - altASAP=NULL; for (int i=0; i<4; i++) { isMuted[i]=false; oscBuf[i]=new DivDispatchOscBuffer; @@ -488,7 +484,7 @@ int DivPlatformPOKEY::init(DivEngine* p, int channels, int sugRate, const DivCon if (!useAltASAP) { MZPOKEYSND_Init(&pokey); } - + setFlags(flags); reset(); return 6; @@ -498,9 +494,6 @@ void DivPlatformPOKEY::quit() { for (int i=0; i<4; i++) { delete oscBuf[i]; } - if (altASAP) { - delete altASAP; - } } void DivPlatformPOKEY::setAltASAP(bool value) { diff --git a/src/engine/platform/pokey.h b/src/engine/platform/pokey.h index f242ae7b5..e68178a2c 100644 --- a/src/engine/platform/pokey.h +++ b/src/engine/platform/pokey.h @@ -52,7 +52,7 @@ class DivPlatformPOKEY: public DivDispatch { bool audctlChanged; unsigned char oscBufDelay; PokeyState pokey; - AltASAP::Pokey* altASAP; + AltASAP::Pokey altASAP; bool useAltASAP; unsigned char regPool[16]; friend void putDispatchChip(void*,int); diff --git a/src/engine/platform/sound/pokey/AltASAP.cpp b/src/engine/platform/sound/pokey/AltASAP.cpp index 65ad339a2..21bc31a21 100644 --- a/src/engine/platform/sound/pokey/AltASAP.cpp +++ b/src/engine/platform/sound/pokey/AltASAP.cpp @@ -37,6 +37,9 @@ static constexpr int64_t CNT_MAX = std::numeric_limits::max() & ~7; static constexpr int MuteFrequency = 1; static constexpr int MuteInit = 2; static constexpr int MuteSerialInput = 8; +//just some magick value to match the audio level of mzpokeysnd +static constexpr int16_t MAGICK_VOLUME_BOOSTER = 160; +static constexpr int16_t MAGICK_OSC_VOLUME_BOOSTER = 4; struct PokeyBase { @@ -219,15 +222,15 @@ public: int32_t volume = value & 0x0f; if ( ( value & 0x10 ) != 0 ) { - mDelta = volume; + mDelta = volume * MAGICK_VOLUME_BOOSTER; } else { muteUltrasound( cycle ); if ( mDelta > 0 ) - mDelta = volume; + mDelta = volume * MAGICK_VOLUME_BOOSTER; else - mDelta = -volume; + mDelta = -volume * MAGICK_VOLUME_BOOSTER; } } @@ -283,9 +286,9 @@ public: PokeyPimpl( uint32_t pokeyClock, uint32_t sampleRate ) : PokeyBase{}, mQueue{ std::make_unique() }, mAudioChannels{ AudioChannel{ *mQueue, 0u }, AudioChannel{ *mQueue, 1u }, AudioChannel{ *mQueue, 2u }, AudioChannel{ *mQueue, 3u } }, - mRegisterPool{}, mPokeyClock{ pokeyClock * 8 }, mTick{}, mNextTick{}, mSampleRate{ sampleRate }, mSamplesRemainder{}, - mReloadCycles1{ 28 }, mReloadCycles3{ 28 }, mDivCycles{ 28 }, - mTicksPerSample{ mPokeyClock / mSampleRate, mPokeyClock % mSampleRate } + mRegisterPool{}, mTick{}, mNextTick{}, + mReloadCycles1{ 28 }, mReloadCycles3{ 28 }, mDivCycles{ 28 }, mSampleRate{ sampleRate }, mSamplesRemainder{}, + mTicksPerSample{ ( pokeyClock * 8 ) / mSampleRate, ( pokeyClock * 8 ) % mSampleRate } { std::fill_n( mRegisterPool.data(), mRegisterPool.size(), (uint8_t)0xff ); enqueueSampling(); @@ -468,7 +471,7 @@ public: for ( int i = 0; i < 4; i++ ) mAudioChannels[i].doStimer( cycle ); break; - case 0x0f: + case 0x0f: { if ( value == mSkctl ) break; @@ -501,10 +504,10 @@ public: if ( oscb != nullptr ) { - oscb[0]->data[oscb[0]->needle++]=ch0; - oscb[1]->data[oscb[1]->needle++]=ch1; - oscb[2]->data[oscb[2]->needle++]=ch2; - oscb[3]->data[oscb[3]->needle++]=ch3; + 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; } enqueueSampling(); @@ -598,45 +601,53 @@ private: std::array mRegisterPool; - uint32_t mPokeyClock; uint64_t mTick; uint64_t mNextTick; + int64_t mReloadCycles1; + int64_t mReloadCycles3; + int64_t mDivCycles; uint32_t mSampleRate; uint32_t mSamplesRemainder; - int mReloadCycles1; - int mReloadCycles3; - int mDivCycles; std::pair mTicksPerSample; - }; - -Pokey::Pokey( uint32_t pokeyClock, uint32_t sampleRate ) : mPokey{ std::make_unique( mPokeyClock, mSampleRate ) }, mPokeyClock{ pokeyClock }, mSampleRate{ sampleRate } +//Initializing periods with safe defaults +Pokey::Pokey() : mPokeyClock{ (uint32_t)COLOR_NTSC / 2 }, mSampleRate{ mPokeyClock / 7 }, mPokey{} { } +void Pokey::init( uint32_t pokeyClock, uint32_t sampleRate ) +{ + mPokey.reset(); + mPokeyClock = pokeyClock; + mSampleRate = sampleRate; +} + +void Pokey::reset() +{ + mPokey = std::make_unique( mPokeyClock, mSampleRate ); +} + Pokey::~Pokey() { } void Pokey::write( uint8_t address, uint8_t value ) { + assert( mPokey ); mPokey->write( address, value ); } int16_t Pokey::sampleAudio( DivDispatchOscBuffer** oscb ) { - return mPokey->sampleAudio( oscb ) * 160; //just some magick value to match the audio level of mzpokeysnd + assert( mPokey ); + return mPokey->sampleAudio( oscb ); } uint8_t const* Pokey::getRegisterPool() { + assert( mPokey ); return mPokey->getRegisterPool(); } -void Pokey::reset() -{ - mPokey = std::make_unique( mPokeyClock, mSampleRate ); -} - } diff --git a/src/engine/platform/sound/pokey/AltASAP.hpp b/src/engine/platform/sound/pokey/AltASAP.hpp index 930bf6aa1..c159e9d5e 100644 --- a/src/engine/platform/sound/pokey/AltASAP.hpp +++ b/src/engine/platform/sound/pokey/AltASAP.hpp @@ -15,7 +15,8 @@ class Pokey { public: - Pokey( uint32_t pokeyClock, uint32_t sampleRate ); + Pokey(); + void init( uint32_t pokeyClock, uint32_t sampleRate ); ~Pokey(); void write( uint8_t address, uint8_t value ); @@ -26,10 +27,9 @@ public: void reset(); private: - - std::unique_ptr mPokey; uint32_t mPokeyClock; uint32_t mSampleRate; + std::unique_ptr mPokey; }; }