After decimating the enemy forces that have attacked your ship, you are charged with taking out as many of the remaining enemy fighters as possible. 3d space fighter game was initially written while I was testing some 3d routines I was implementing for a flight simulator, but my daughter started playing it and seemed to enjoy it so I added a few sound effects, explosions etc. and so this little game was born.
OneBitSound/SoundChannel.cpp
- Committer:
- taylorza
- Date:
- 2015-02-08
- Revision:
- 4:b857db213f10
- Parent:
- 1:9ff7384171ec
File content as of revision 4:b857db213f10:
#include "mbed.h" #include "Fix16.h" #include "SoundBlock.h" #include "SoundChannel.h" SoundChannel::SoundChannel() : _state(4) { } void SoundChannel::play(const SoundBlock soundBlocks[], int count) { _soundBlocks = soundBlocks; _count = count; _index = 0; _state = 0; } bool SoundChannel::update(bool &pinState) { switch(_state) { case 0 : startSoundBlock(); break; case 3 : // Stop sound pinState = _pinState = false; _state = 4; return true; case 4 : // No sound return false; } if (updateCounters()) { switch(_currentSoundBlock.getToneType()) { case SoundBlock::Tone : updateTone(); pinState = _pinState; return true; case SoundBlock::Noise : updateNoise(); pinState = _pinState; return true; case SoundBlock::Pause : return false; } } return false; } void SoundChannel::updateTone() { switch(_state) { case 1: // High { _pinState = true; _pitchHighCounter -= fix16_one; if (_pitchHighCounter <= 0) { _pinState = false; _pitchHighCounter += _basePitchHighCount; _state = 2; } } break; case 2: // Low { _pinState = false; _pitchLowCounter -= fix16_one; if (_pitchLowCounter <= 0) { _pinState = true; _pitchLowCounter += _basePitchLowCount; _state = 1; } } break; } } void SoundChannel::updateNoise() { switch(_state) { case 1: // High/Low { _pitchHighCounter -= fix16_one; if (_pitchHighCounter <= 0) { _pinState = (SoundChannel::lfsr_rand() & 1) == 1; _pitchHighCounter += _basePitchHighCount; } } break; } } void SoundChannel::startSoundBlock() { _currentSoundBlock = _soundBlocks[_index]; _stepCounter = _currentSoundBlock.getStepCount(); _stepDurationCounter = _currentSoundBlock.getStepDuration(); _pitchOffset = 0; _dutyOffset = 0; updateAudioCounters(); _pitchHighCounter = _basePitchHighCount; _pitchLowCounter = _basePitchLowCount; _state = 1; } bool SoundChannel::updateCounters() { --_stepDurationCounter; if (_stepDurationCounter == 0) { --_stepCounter; if (_stepCounter == 0) { ++_index; if (_index == _count) { _state = 3; return false; } else { _state = 0; } } else { fix16_t pitchSlide = _currentSoundBlock.getPitchSlide(); int8_t dutySlide = _currentSoundBlock.getDutySlide(); if ( pitchSlide != 0 || dutySlide != 0) { _pitchOffset += pitchSlide; _dutyOffset += dutySlide; updateAudioCounters(); } _stepDurationCounter = _currentSoundBlock.getStepDuration(); } } return true; } void SoundChannel::updateAudioCounters() { fix16_t pitch = _currentSoundBlock.getPitch(_pitchOffset); if (pitch == 0) pitch = fix16_one; if (_currentSoundBlock.getToneType() == SoundBlock::Noise) pitch = fix16_div(pitch, fix16_100); _basePitchHighCount = fix16_mul(pitch, _currentSoundBlock.getDuty(_dutyOffset) * 0x100); _basePitchLowCount = pitch - _basePitchHighCount; } uint16_t SoundChannel::lfsr_rand() { static uint16_t lfsr = 0xACE1u; lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u); return lfsr; }