Platform library for RETRO
Sound.h
- Committer:
- Architect
- Date:
- 2015-03-01
- Revision:
- 0:6f26c31d8573
File content as of revision 0:6f26c31d8573:
/* * (C) Copyright 2015 Valentin Ivanov. All rights reserved. * * This file is part of the RetroPlatform Library * * The RetroPlatform Library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> * * This library is inspired by Gamebuino Library (http://gamebuino.com) * from Aurélien Rodot. */ #ifndef SOUND_H #define SOUND_H #include <mbed.h> //commands #define CMD_VOLUME 0 #define CMD_INSTRUMENT 1 #define CMD_SLIDE 2 #define CMD_ARPEGGIO 3 #define CMD_TREMOLO 4 #define NUM_CHANNELS 3 //number of sound channels (no more than 4) #define VOLUME_GLOBAL_MAX 1 //7=instrument volume 9=note volume #define VOLUME_CHANNEL_MAX 255/NUM_CHANNELS/VOLUME_GLOBAL_MAX/7/9 #define boolean bool //A set of sequences typedef struct { uint16_t *Data; uint8_t Cursor; bool IsPlaying; } Track; //A sequence of commands and notes typedef struct { uint16_t *Data; bool Looping; uint16_t Cursor; bool IsPlaying; } Sequence; //A note of selected pitch, duration and volume typedef struct { uint8_t Pitch; uint8_t Duration; int8_t Volume; bool IsPlaying; } Note; typedef struct { int8_t Counter; int8_t volumeSlideStepDuration; int8_t volumeSlideStepSize; uint8_t arpeggioStepDuration; int8_t arpeggioStepSize; uint8_t tremoloStepDuration; int8_t tremoloStepSize; } Command; typedef struct { uint16_t **SequenceSet; uint16_t **InstrumentSet; uint8_t Volume; uint8_t Count; bool State; uint8_t HalfPeriod; uint8_t OutputVolume; uint8_t Output; bool Noise; int8_t SequencePitch; } AudioChannel; typedef struct { uint16_t *Data; uint8_t Length; uint8_t Looping; uint16_t Cursor; uint8_t NextChange; } Instrument; class Sound { Ticker timer; PwmOut speaker; Track tracks[NUM_CHANNELS]; Sequence sequences[NUM_CHANNELS]; Command commands[NUM_CHANNELS]; Instrument instruments[NUM_CHANNELS]; public: Sound(); void initialize(); void update() { updateTracks(); updateSequences(); updateNotes(); } void playTrack(const uint16_t* track, uint8_t channel); void updateTrack(uint8_t channel); void stopTrack(uint8_t channel); void stopTracks() { for(uint8_t channel=0; channel<NUM_CHANNELS; channel++) stopTrack(channel); } void updateTracks() { for(uint8_t channel=0; channel<NUM_CHANNELS; channel++) updateTrack(channel); } void changeSequenceSet(const uint16_t* const* patterns, uint8_t channel); bool isTrackPlaying(uint8_t channel) { return tracks[channel].IsPlaying; } void playSequence(const uint16_t* pattern, uint8_t channel); void changeInstrumentSet(const uint16_t* const* instruments, uint8_t channel); void updateSequence(uint8_t channel); void stopSequence(uint8_t channel); void stopSequences() { for(uint8_t channel=0; channel<NUM_CHANNELS; channel++) stopSequence(channel); } void updateSequences() { for(uint8_t channel=0; channel<NUM_CHANNELS; channel++) updateSequence(channel); } void playNote(uint8_t pitch, uint8_t duration, uint8_t channel); void updateNote(uint8_t i); void stopNote(uint8_t channel); void updateNotes() { for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) updateNote(channel); } void stopNotes() { for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) stopNote(channel); } void command(uint8_t cmd, uint8_t X, int8_t Y, uint8_t channel); uint8_t outputPitch[NUM_CHANNELS]; int8_t outputVolume[NUM_CHANNELS]; void setVolume(int8_t volume); uint8_t getVolume(); void setVolume(int8_t volume, uint8_t channel); uint8_t getVolume(uint8_t channel); uint8_t prescaler; void setChannelHalfPeriod(uint8_t channel, uint8_t halfPeriod); uint8_t globalVolume; uint8_t volumeMax; #if (NUM_CHANNELS > 0) //tracks data uint16_t **patternSet[NUM_CHANNELS]; int8_t patternPitch[NUM_CHANNELS]; // pattern data uint16_t **instrumentSet[NUM_CHANNELS]; // note data uint8_t notePitch[NUM_CHANNELS]; uint8_t noteDuration[NUM_CHANNELS]; int8_t noteVolume[NUM_CHANNELS]; boolean notePlaying[NUM_CHANNELS]; //current step data int8_t stepVolume[NUM_CHANNELS]; uint8_t stepPitch[NUM_CHANNELS]; uint8_t chanVolumes[NUM_CHANNELS]; uint8_t _chanCount[NUM_CHANNELS]; //counts until the next change of the waveform boolean _chanState[NUM_CHANNELS]; //if the waveform is currently high or low uint8_t _chanHalfPeriod[NUM_CHANNELS]; //duration of half the period of the waveform uint8_t _chanOutputVolume[NUM_CHANNELS]; //amplitude of the outputted waveform uint8_t _chanOutput[NUM_CHANNELS]; //current value of the outputted waveform boolean _chanNoise[NUM_CHANNELS]; //if a random value should be added to the waveform to generate noise #endif void updateOutput(); private: void generateOutput(); }; #endif /* SOUND_H */