Merge pull request #800 from laoo/ASAP_POKEY
ASAP POKEY small fix and refactorings
This commit is contained in:
		
						commit
						66f2b05287
					
				|  | @ -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) { | void DivPlatformPOKEY::acquireASAP(short* buf, size_t start, size_t len) { | ||||||
|   while (!writes.empty()) { |   while (!writes.empty()) { | ||||||
|     QueuedWrite w=writes.front(); |     QueuedWrite w=writes.front(); | ||||||
|     altASAP->write(w.addr, w.val); |     altASAP.write(w.addr, w.val); | ||||||
|     writes.pop(); |     writes.pop(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   for (size_t h=start; h<start+len; h++) { |   for (size_t h=start; h<start+len; h++) { | ||||||
|     if (++oscBufDelay>=2) { |     if (++oscBufDelay>=2) { | ||||||
|       oscBufDelay=0; |       oscBufDelay=0; | ||||||
|       buf[h]=altASAP->sampleAudio(oscBuf); |       buf[h]=altASAP.sampleAudio(oscBuf); | ||||||
|     } else { |     } else { | ||||||
|       buf[h]=altASAP->sampleAudio(); |       buf[h]=altASAP.sampleAudio(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -396,7 +396,7 @@ DivDispatchOscBuffer* DivPlatformPOKEY::getOscBuffer(int ch) { | ||||||
| 
 | 
 | ||||||
| unsigned char* DivPlatformPOKEY::getRegisterPool() { | unsigned char* DivPlatformPOKEY::getRegisterPool() { | ||||||
|   if (useAltASAP) { |   if (useAltASAP) { | ||||||
|     return const_cast<unsigned char*>(altASAP->getRegisterPool()); |     return const_cast<unsigned char*>(altASAP.getRegisterPool()); | ||||||
|   } else { |   } else { | ||||||
|     return regPool; |     return regPool; | ||||||
|   } |   } | ||||||
|  | @ -418,7 +418,7 @@ void DivPlatformPOKEY::reset() { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (useAltASAP) { |   if (useAltASAP) { | ||||||
|     altASAP->reset(); |     altASAP.reset(); | ||||||
|   } else { |   } else { | ||||||
|     ResetPokeyState(&pokey); |     ResetPokeyState(&pokey); | ||||||
|   } |   } | ||||||
|  | @ -454,10 +454,7 @@ void DivPlatformPOKEY::setFlags(const DivConfig& flags) { | ||||||
|     for (int i=0; i<4; i++) { |     for (int i=0; i<4; i++) { | ||||||
|       oscBuf[i]->rate=rate/2; |       oscBuf[i]->rate=rate/2; | ||||||
|     } |     } | ||||||
|     if (altASAP) { |     altASAP.init(chipClock,rate); | ||||||
|       delete altASAP; |  | ||||||
|     } |  | ||||||
|     altASAP=new AltASAP::Pokey(chipClock,rate); |  | ||||||
|   } else { |   } else { | ||||||
|     rate=chipClock; |     rate=chipClock; | ||||||
|     for (int i=0; i<4; i++) { |     for (int i=0; i<4; i++) { | ||||||
|  | @ -479,7 +476,6 @@ int DivPlatformPOKEY::init(DivEngine* p, int channels, int sugRate, const DivCon | ||||||
|   dumpWrites=false; |   dumpWrites=false; | ||||||
|   skipRegisterWrites=false; |   skipRegisterWrites=false; | ||||||
|   oscBufDelay=0; |   oscBufDelay=0; | ||||||
|   altASAP=NULL; |  | ||||||
|   for (int i=0; i<4; i++) { |   for (int i=0; i<4; i++) { | ||||||
|     isMuted[i]=false; |     isMuted[i]=false; | ||||||
|     oscBuf[i]=new DivDispatchOscBuffer; |     oscBuf[i]=new DivDispatchOscBuffer; | ||||||
|  | @ -498,9 +494,6 @@ void DivPlatformPOKEY::quit() { | ||||||
|   for (int i=0; i<4; i++) { |   for (int i=0; i<4; i++) { | ||||||
|     delete oscBuf[i]; |     delete oscBuf[i]; | ||||||
|   } |   } | ||||||
|   if (altASAP) { |  | ||||||
|     delete altASAP; |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DivPlatformPOKEY::setAltASAP(bool value) { | void DivPlatformPOKEY::setAltASAP(bool value) { | ||||||
|  |  | ||||||
|  | @ -52,7 +52,7 @@ class DivPlatformPOKEY: public DivDispatch { | ||||||
|   bool audctlChanged; |   bool audctlChanged; | ||||||
|   unsigned char oscBufDelay; |   unsigned char oscBufDelay; | ||||||
|   PokeyState pokey; |   PokeyState pokey; | ||||||
|   AltASAP::Pokey* altASAP; |   AltASAP::Pokey altASAP; | ||||||
|   bool useAltASAP; |   bool useAltASAP; | ||||||
|   unsigned char regPool[16]; |   unsigned char regPool[16]; | ||||||
|   friend void putDispatchChip(void*,int); |   friend void putDispatchChip(void*,int); | ||||||
|  |  | ||||||
|  | @ -37,6 +37,9 @@ static constexpr int64_t CNT_MAX = std::numeric_limits<int64_t>::max() & ~7; | ||||||
| static constexpr int MuteFrequency = 1; | static constexpr int MuteFrequency = 1; | ||||||
| static constexpr int MuteInit = 2; | static constexpr int MuteInit = 2; | ||||||
| static constexpr int MuteSerialInput = 8; | 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 | struct PokeyBase | ||||||
| { | { | ||||||
|  | @ -219,15 +222,15 @@ public: | ||||||
|     int32_t volume = value & 0x0f; |     int32_t volume = value & 0x0f; | ||||||
|     if ( ( value & 0x10 ) != 0 ) |     if ( ( value & 0x10 ) != 0 ) | ||||||
|     { |     { | ||||||
|       mDelta = volume; |       mDelta = volume * MAGICK_VOLUME_BOOSTER; | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|       muteUltrasound( cycle ); |       muteUltrasound( cycle ); | ||||||
|       if ( mDelta > 0 ) |       if ( mDelta > 0 ) | ||||||
|         mDelta = volume; |         mDelta = volume * MAGICK_VOLUME_BOOSTER; | ||||||
|       else |       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<ActionQueue>() }, |   PokeyPimpl( uint32_t pokeyClock, uint32_t sampleRate ) : PokeyBase{}, mQueue{ std::make_unique<ActionQueue>() }, | ||||||
|     mAudioChannels{ AudioChannel{ *mQueue, 0u }, AudioChannel{ *mQueue, 1u }, AudioChannel{ *mQueue, 2u }, AudioChannel{ *mQueue, 3u } }, |     mAudioChannels{ AudioChannel{ *mQueue, 0u }, AudioChannel{ *mQueue, 1u }, AudioChannel{ *mQueue, 2u }, AudioChannel{ *mQueue, 3u } }, | ||||||
|     mRegisterPool{}, mPokeyClock{ pokeyClock * 8 }, mTick{}, mNextTick{}, mSampleRate{ sampleRate }, mSamplesRemainder{}, |     mRegisterPool{}, mTick{}, mNextTick{}, | ||||||
|     mReloadCycles1{ 28 }, mReloadCycles3{ 28 }, mDivCycles{ 28 }, |     mReloadCycles1{ 28 }, mReloadCycles3{ 28 }, mDivCycles{ 28 }, mSampleRate{ sampleRate }, mSamplesRemainder{}, | ||||||
|     mTicksPerSample{ mPokeyClock / mSampleRate, mPokeyClock % mSampleRate } |     mTicksPerSample{ ( pokeyClock * 8 ) / mSampleRate, ( pokeyClock * 8 ) % mSampleRate } | ||||||
|   { |   { | ||||||
|     std::fill_n( mRegisterPool.data(), mRegisterPool.size(), (uint8_t)0xff ); |     std::fill_n( mRegisterPool.data(), mRegisterPool.size(), (uint8_t)0xff ); | ||||||
|     enqueueSampling(); |     enqueueSampling(); | ||||||
|  | @ -501,10 +504,10 @@ public: | ||||||
| 
 | 
 | ||||||
|         if ( oscb != nullptr ) |         if ( oscb != nullptr ) | ||||||
|         { |         { | ||||||
|           oscb[0]->data[oscb[0]->needle++]=ch0; |           oscb[0]->data[oscb[0]->needle++]=ch0 * MAGICK_OSC_VOLUME_BOOSTER; | ||||||
|           oscb[1]->data[oscb[1]->needle++]=ch1; |           oscb[1]->data[oscb[1]->needle++]=ch1 * MAGICK_OSC_VOLUME_BOOSTER; | ||||||
|           oscb[2]->data[oscb[2]->needle++]=ch2; |           oscb[2]->data[oscb[2]->needle++]=ch2 * MAGICK_OSC_VOLUME_BOOSTER; | ||||||
|           oscb[3]->data[oscb[3]->needle++]=ch3; |           oscb[3]->data[oscb[3]->needle++]=ch3 * MAGICK_OSC_VOLUME_BOOSTER; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         enqueueSampling(); |         enqueueSampling(); | ||||||
|  | @ -598,45 +601,53 @@ private: | ||||||
| 
 | 
 | ||||||
|   std::array<uint8_t, 4 * 2 + 1> mRegisterPool; |   std::array<uint8_t, 4 * 2 + 1> mRegisterPool; | ||||||
| 
 | 
 | ||||||
|   uint32_t mPokeyClock; |  | ||||||
|   uint64_t mTick; |   uint64_t mTick; | ||||||
|   uint64_t mNextTick; |   uint64_t mNextTick; | ||||||
|  |   int64_t mReloadCycles1; | ||||||
|  |   int64_t mReloadCycles3; | ||||||
|  |   int64_t mDivCycles; | ||||||
|   uint32_t mSampleRate; |   uint32_t mSampleRate; | ||||||
|   uint32_t mSamplesRemainder; |   uint32_t mSamplesRemainder; | ||||||
|   int mReloadCycles1; |  | ||||||
|   int mReloadCycles3; |  | ||||||
|   int mDivCycles; |  | ||||||
|   std::pair<uint32_t, uint32_t> mTicksPerSample; |   std::pair<uint32_t, uint32_t> mTicksPerSample; | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | //Initializing periods with safe defaults
 | ||||||
| Pokey::Pokey( uint32_t pokeyClock, uint32_t sampleRate ) : mPokey{ std::make_unique<PokeyPimpl>( mPokeyClock, mSampleRate ) }, mPokeyClock{ pokeyClock }, mSampleRate{ sampleRate } | 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<PokeyPimpl>( mPokeyClock, mSampleRate ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Pokey::~Pokey() | Pokey::~Pokey() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Pokey::write( uint8_t address, uint8_t value ) | void Pokey::write( uint8_t address, uint8_t value ) | ||||||
| { | { | ||||||
|  |   assert( mPokey ); | ||||||
|   mPokey->write( address, value ); |   mPokey->write( address, value ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int16_t Pokey::sampleAudio( DivDispatchOscBuffer** oscb ) | 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() | uint8_t const* Pokey::getRegisterPool() | ||||||
| { | { | ||||||
|  |   assert( mPokey ); | ||||||
|   return mPokey->getRegisterPool(); |   return mPokey->getRegisterPool(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Pokey::reset() |  | ||||||
| { |  | ||||||
|   mPokey = std::make_unique<PokeyPimpl>( mPokeyClock, mSampleRate ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -15,7 +15,8 @@ class Pokey | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 
 | 
 | ||||||
|   Pokey( uint32_t pokeyClock, uint32_t sampleRate ); |   Pokey(); | ||||||
|  |   void init( uint32_t pokeyClock, uint32_t sampleRate ); | ||||||
|   ~Pokey(); |   ~Pokey(); | ||||||
| 
 | 
 | ||||||
|   void write( uint8_t address, uint8_t value ); |   void write( uint8_t address, uint8_t value ); | ||||||
|  | @ -26,10 +27,9 @@ public: | ||||||
|   void reset(); |   void reset(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 
 |  | ||||||
|   std::unique_ptr<PokeyPimpl> mPokey; |  | ||||||
|   uint32_t mPokeyClock; |   uint32_t mPokeyClock; | ||||||
|   uint32_t mSampleRate; |   uint32_t mSampleRate; | ||||||
|  |   std::unique_ptr<PokeyPimpl> mPokey; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 tildearrow
						tildearrow