Version of Robotron arcade game using LPC1768, a Gameduino shield, a serial EEPROM (for high scores), two microswitch joysticks and two buttons plus a box to put it in. 20 levels of mayhem.
Dependencies: 25LCxxx_SPI CommonTypes Gameduino mbed
Diff: SoundManager.cpp
- Revision:
- 9:fa7e7b37b632
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SoundManager.cpp Sun Jun 09 14:28:53 2013 +0000 @@ -0,0 +1,129 @@ +/* + * SOURCE FILE : SoundManager.cpp + * + * Responsible for playing simple sounds. + * + */ + +#include "SoundManager.h" +#include "Notes.h" + +// An instance of the SoundManager class. +SoundManager SoundManager::Instance; + +/***************/ +/* CONSTRUCTOR */ +/***************/ +SoundManager::SoundManager() : + gd( (Gameduino*)NULL ) +{ +} + +/*****************************/ +/* UPDATE A SINGLE TUNE SLOT */ +/*****************************/ +// Do NOT call with a record containing zero in TuneAddress (a free slot). +void SoundManager::UpdateTuneSection( UInt8 voiceNum, TuneRecord *rec ) { + if( rec->Countdown > 0 ) { + rec->Countdown--; + } + else { + // Countdown has reached zero. Load next section of tune. + UInt8 noteNum = *(rec->TuneAddress++); + if( noteNum == 0 ) { + // End of tune. Silence voice and set tune address to NULL to + // indicate slot is free. + gd->voice( voiceNum, Gameduino::SineWave, 0, 0, 0 ); + rec->TuneAddress = (UInt8*)NULL; + } + else { + // Convert note number to frequency. + UInt16 frequency = Notes::NoteFrequencies[ noteNum ]; + // Read amplitude for next tune section and add biases. + UInt8 amp = *(rec->TuneAddress++); + // Start playing section. + gd->voice( voiceNum, rec->TuneWaveform, frequency, amp + rec->LeftAmpBias, amp + rec->RightAmpBias ); + // Set countdown according to length of this section. + rec->Countdown = *(rec->TuneAddress++); + } + } +} + +/************************/ +/* TRY AND PLAY A SOUND */ +/************************/ +// Pass address of tune in program memory in tuneAddress. +// Pass bias to apply to left speaker amplitude in leftAmpBias. +// Pass bias to apply to right speaker amplitude in leftAmpBias. +// Returns true if sound was started, false if no sound slots free. +bool SoundManager::PlaySound( const UInt8 *tuneAddress, UInt8 leftAmpBias, UInt8 rightAmpBias ) { + // Find a tune record that is free. + UInt8 i = 0; + TuneRecord *rec = tuneRecords; + while( ( i < VoiceCount ) && ( rec->TuneAddress != (UInt8*)NULL ) ) { + i++; + rec++; + } + if( i < VoiceCount ) { + // Found a free tune record. Initialise it. + rec->TuneWaveform = (Gameduino::WaveForm)*tuneAddress; + rec->TuneAddress = tuneAddress + 1; + rec->LeftAmpBias = leftAmpBias; + rec->RightAmpBias = rightAmpBias; + rec->Countdown = 0; + // Start playing first part of sound. + UpdateTuneSection( FirstVoice + i, rec ); + return true; + } + else { + // No free counter found. + return false; + } +} + +/****************************/ +/* UPDATE PLAYING OF SOUNDS */ +/****************************/ +// Should be called at regular intervals. +void SoundManager::Update( void ) { + TuneRecord *ptr = tuneRecords; + // Repeat for all tune records. + for( UInt8 i = 0; i < VoiceCount; ++i ) { + // Skip over any unused records (with TuneAddress of zero). + if( ptr->TuneAddress != (UInt8*)NULL ) { + UpdateTuneSection( FirstVoice + i, ptr ); + } + ptr++; + } +} + +/**********************************/ +/* COUNT NUMBER OF SOUNDS PLAYING */ +/**********************************/ +// Returns number of sounds playing. +UInt8 SoundManager::CountSoundsPlaying( void ) { + UInt8 count = 0; + TuneRecord *ptr = tuneRecords; + // Repeat for all tune records. + for( UInt8 i = 0; i < VoiceCount; ++i ) { + // If TuneAddress is not zero then increment count. + if( ptr->TuneAddress != (UInt8*)NULL ) { + count++; + } + ptr++; + } + return count; +} + +/******************************/ +/* SILENCE ALL SOUNDS PLAYING */ +/******************************/ +void SoundManager::SilenceAll( void ) { + TuneRecord *ptr = tuneRecords; + for( UInt8 i = 0; i < VoiceCount; ++i ) { + gd->voice( FirstVoice + i, Gameduino::SineWave, 0, 0, 0 ); + ptr->TuneAddress = (UInt8*)NULL; + ptr++; + } +} +