PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Fri Jan 05 02:19:51 2018 +0000
Revision:
28:958b71c4b92a
Parent:
24:9561281d0378
Sound level stored in EEPROM, sound output improved

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 24:9561281d0378 1 /**************************************************************************/
Pokitto 24:9561281d0378 2 /*!
Pokitto 24:9561281d0378 3 @file PokittoSound.cpp
Pokitto 24:9561281d0378 4 @author Jonne Valola
Pokitto 24:9561281d0378 5
Pokitto 24:9561281d0378 6 @section LICENSE
Pokitto 24:9561281d0378 7
Pokitto 24:9561281d0378 8 Software License Agreement (BSD License)
Pokitto 24:9561281d0378 9
Pokitto 24:9561281d0378 10 Copyright (c) 2016, Jonne Valola
Pokitto 24:9561281d0378 11 All rights reserved.
Pokitto 24:9561281d0378 12
Pokitto 24:9561281d0378 13 Redistribution and use in source and binary forms, with or without
Pokitto 24:9561281d0378 14 modification, are permitted provided that the following conditions are met:
Pokitto 24:9561281d0378 15 1. Redistributions of source code must retain the above copyright
Pokitto 24:9561281d0378 16 notice, this list of conditions and the following disclaimer.
Pokitto 24:9561281d0378 17 2. Redistributions in binary form must reproduce the above copyright
Pokitto 24:9561281d0378 18 notice, this list of conditions and the following disclaimer in the
Pokitto 24:9561281d0378 19 documentation and/or other materials provided with the distribution.
Pokitto 24:9561281d0378 20 3. Neither the name of the copyright holders nor the
Pokitto 24:9561281d0378 21 names of its contributors may be used to endorse or promote products
Pokitto 24:9561281d0378 22 derived from this software without specific prior written permission.
Pokitto 24:9561281d0378 23
Pokitto 24:9561281d0378 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
Pokitto 24:9561281d0378 25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Pokitto 24:9561281d0378 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Pokitto 24:9561281d0378 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
Pokitto 24:9561281d0378 28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Pokitto 24:9561281d0378 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Pokitto 24:9561281d0378 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Pokitto 24:9561281d0378 31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Pokitto 24:9561281d0378 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Pokitto 24:9561281d0378 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Pokitto 24:9561281d0378 34 */
Pokitto 24:9561281d0378 35 /**************************************************************************/
Pokitto 24:9561281d0378 36
Pokitto 24:9561281d0378 37 /*
Pokitto 24:9561281d0378 38 * NOTE:
Pokitto 24:9561281d0378 39 * API of the Pokitto Sound library is partially identical to the Gamebuino Sound API.
Pokitto 24:9561281d0378 40 * Due to the difference in architecture (ARM Cortex-M0+ in mbed environment vs. 8-bit AVR)
Pokitto 24:9561281d0378 41 * large parts are not identical. Most functions were rewritten, with only API remaining.
Pokitto 24:9561281d0378 42 * We want to give attribution to the original author's project:
Pokitto 24:9561281d0378 43 *
Pokitto 24:9561281d0378 44 * License for Gamebuino-identical code:
Pokitto 24:9561281d0378 45 *
Pokitto 24:9561281d0378 46 * (C) Copyright 2014 Aur�lien Rodot. All rights reserved.
Pokitto 24:9561281d0378 47 *
Pokitto 24:9561281d0378 48 * This file is part of the Gamebuino Library (http://gamebuino.com)
Pokitto 24:9561281d0378 49 *
Pokitto 24:9561281d0378 50 * The Gamebuino Library is free software: you can redistribute it and/or modify
Pokitto 24:9561281d0378 51 * it under the terms of the GNU Lesser General Public License as published by
Pokitto 24:9561281d0378 52 * the Free Software Foundation, either version 3 of the License, or
Pokitto 24:9561281d0378 53 * (at your option) any later version.
Pokitto 24:9561281d0378 54 *
Pokitto 24:9561281d0378 55 * This program is distributed in the hope that it will be useful,
Pokitto 24:9561281d0378 56 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Pokitto 24:9561281d0378 57 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Pokitto 24:9561281d0378 58 * GNU Lesser General Public License for more details.
Pokitto 24:9561281d0378 59 *
Pokitto 24:9561281d0378 60 * You should have received a copy of the GNU Lesser General Public License
Pokitto 24:9561281d0378 61 * along with this program. If not, see <http://www.gnu.org/licenses/>
Pokitto 24:9561281d0378 62 */
Pokitto 24:9561281d0378 63
Pokitto 24:9561281d0378 64 #include "PokittoSound.h"
Pokitto 24:9561281d0378 65 #include "Pokitto_settings.h"
Pokitto 24:9561281d0378 66 #include "PokittoCore.h"
Pokitto 24:9561281d0378 67 #include "Synth.h"
Pokitto 24:9561281d0378 68
Pokitto 24:9561281d0378 69 #ifndef POK_SIM
Pokitto 24:9561281d0378 70 #include "HWSound.h"
Pokitto 24:9561281d0378 71 #else
Pokitto 24:9561281d0378 72 #include "SimSound.h"
Pokitto 24:9561281d0378 73 #include "PokittoSimulator.h"
Pokitto 24:9561281d0378 74 #endif
Pokitto 24:9561281d0378 75
Pokitto 24:9561281d0378 76 typedef uint8_t byte;
Pokitto 24:9561281d0378 77
Pokitto 24:9561281d0378 78 using namespace Pokitto;
Pokitto 24:9561281d0378 79
Pokitto 24:9561281d0378 80 Pokitto::Core _soundc;
Pokitto 24:9561281d0378 81
Pokitto 24:9561281d0378 82 uint8_t Sound::prescaler;
Pokitto 24:9561281d0378 83 uint16_t Sound::globalVolume;
Pokitto 24:9561281d0378 84 uint16_t Sound::volumeMax = VOLUME_HEADPHONE_MAX;
Pokitto 24:9561281d0378 85
Pokitto 24:9561281d0378 86 bool Sound::trackIsPlaying[NUM_CHANNELS];
Pokitto 24:9561281d0378 87 bool Sound::patternIsPlaying[NUM_CHANNELS];
Pokitto 24:9561281d0378 88 uint8_t Sound::outputPitch[NUM_CHANNELS];
Pokitto 24:9561281d0378 89 int8_t Sound::outputVolume[NUM_CHANNELS];
Pokitto 24:9561281d0378 90
Pokitto 24:9561281d0378 91 uint16_t *Sound::trackData[NUM_CHANNELS];
Pokitto 24:9561281d0378 92 uint8_t Sound::trackCursor[NUM_CHANNELS];
Pokitto 24:9561281d0378 93 uint16_t **Sound::patternSet[NUM_CHANNELS];
Pokitto 24:9561281d0378 94 int8_t Sound::patternPitch[NUM_CHANNELS];
Pokitto 24:9561281d0378 95
Pokitto 24:9561281d0378 96 // pattern data
Pokitto 24:9561281d0378 97 uint16_t *Sound::patternData[NUM_CHANNELS];
Pokitto 24:9561281d0378 98 uint16_t **Sound::instrumentSet[NUM_CHANNELS];
Pokitto 24:9561281d0378 99 bool Sound::patternLooping[NUM_CHANNELS];
Pokitto 24:9561281d0378 100 uint16_t Sound::patternCursor[NUM_CHANNELS];
Pokitto 24:9561281d0378 101
Pokitto 24:9561281d0378 102 // note data
Pokitto 24:9561281d0378 103 uint8_t Sound::notePitch[NUM_CHANNELS];
Pokitto 24:9561281d0378 104 uint8_t Sound::noteDuration[NUM_CHANNELS];
Pokitto 24:9561281d0378 105 int8_t Sound::noteVolume[NUM_CHANNELS];
Pokitto 24:9561281d0378 106 bool Sound::notePlaying[NUM_CHANNELS];
Pokitto 24:9561281d0378 107
Pokitto 24:9561281d0378 108 // commands data
Pokitto 24:9561281d0378 109 int8_t Sound::commandsCounter[NUM_CHANNELS];
Pokitto 24:9561281d0378 110 int8_t Sound::volumeSlideStepDuration[NUM_CHANNELS];
Pokitto 24:9561281d0378 111 int8_t Sound::volumeSlideStepSize[NUM_CHANNELS];
Pokitto 24:9561281d0378 112 uint8_t Sound::arpeggioStepDuration[NUM_CHANNELS];
Pokitto 24:9561281d0378 113 int8_t Sound::arpeggioStepSize[NUM_CHANNELS];
Pokitto 24:9561281d0378 114 uint8_t Sound::tremoloStepDuration[NUM_CHANNELS];
Pokitto 24:9561281d0378 115 int8_t Sound::tremoloStepSize[NUM_CHANNELS];
Pokitto 24:9561281d0378 116
Pokitto 24:9561281d0378 117 // instrument data
Pokitto 24:9561281d0378 118 uint16_t *Sound::instrumentData[NUM_CHANNELS];
Pokitto 24:9561281d0378 119 uint8_t Sound::instrumentLength[NUM_CHANNELS]; //number of steps in the instrument
Pokitto 24:9561281d0378 120 uint8_t Sound::instrumentLooping[NUM_CHANNELS]; //how many steps to loop on when the last step of the instrument is reached
Pokitto 24:9561281d0378 121 uint16_t Sound::instrumentCursor[NUM_CHANNELS]; //which step is being played
Pokitto 24:9561281d0378 122 uint8_t Sound::instrumentNextChange[NUM_CHANNELS]; //how many frames before the next step
Pokitto 24:9561281d0378 123
Pokitto 24:9561281d0378 124 //current step data
Pokitto 24:9561281d0378 125 int8_t Sound::stepVolume[NUM_CHANNELS];
Pokitto 24:9561281d0378 126 uint8_t Sound::stepPitch[NUM_CHANNELS];
Pokitto 24:9561281d0378 127 uint8_t Sound::chanVolumes[NUM_CHANNELS];
Pokitto 24:9561281d0378 128
Pokitto 24:9561281d0378 129 #if (POK_ENABLE_SOUND < 1)
Pokitto 24:9561281d0378 130 #define NUM_CHANNELS 0
Pokitto 24:9561281d0378 131 #endif
Pokitto 24:9561281d0378 132
Pokitto 24:9561281d0378 133 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 134 #ifndef POK_SIM
Pokitto 24:9561281d0378 135 uint8_t sbyte;
Pokitto 24:9561281d0378 136 #else
Pokitto 24:9561281d0378 137 uint8_t sbyte;
Pokitto 24:9561281d0378 138 float pwm1;
Pokitto 24:9561281d0378 139 #endif // POK_SIM
Pokitto 24:9561281d0378 140
Pokitto 24:9561281d0378 141 //declare these variables globally for faster access
Pokitto 24:9561281d0378 142 uint8_t _rand = 1;
Pokitto 24:9561281d0378 143 uint8_t _chanCount[NUM_CHANNELS]; //counts until the next change of the waveform
Pokitto 24:9561281d0378 144 bool _chanState[NUM_CHANNELS]; //if the waveform is currently high or low
Pokitto 24:9561281d0378 145 uint8_t _chanHalfPeriod[NUM_CHANNELS]; //duration of half the period of the waveform
Pokitto 24:9561281d0378 146 uint8_t _chanOutputVolume[NUM_CHANNELS]; //amplitude of the outputted waveform
Pokitto 24:9561281d0378 147 uint8_t _chanOutput[NUM_CHANNELS]; //current value of the outputted waveform
Pokitto 24:9561281d0378 148 bool _chanNoise[NUM_CHANNELS]; //if a random value should be added to the waveform to generate noise
Pokitto 24:9561281d0378 149
Pokitto 24:9561281d0378 150 #if POK_GBSOUND > 0
Pokitto 24:9561281d0378 151 const uint16_t squareWaveInstrument[] = {0x0101, 0x03F7};
Pokitto 24:9561281d0378 152 const uint16_t noiseInstrument[] = {0x0101, 0x03FF};
Pokitto 24:9561281d0378 153 const uint16_t* const defaultInstruments[] = {squareWaveInstrument,noiseInstrument};
Pokitto 24:9561281d0378 154
Pokitto 24:9561281d0378 155 const uint16_t playOKPattern[] = {0x0005,0x138,0x168,0x0000};
Pokitto 24:9561281d0378 156 const uint16_t playCancelPattern[] = {0x0005,0x168,0x138,0x0000};
Pokitto 24:9561281d0378 157 const uint16_t playTickP[] = {0x0045,0x168,0x0000};
Pokitto 24:9561281d0378 158 #endif
Pokitto 24:9561281d0378 159 #if(EXTENDED_NOTE_RANGE > 0)
Pokitto 24:9561281d0378 160 //extended note range
Pokitto 24:9561281d0378 161 #define NUM_PITCH 59
Pokitto 24:9561281d0378 162 const uint8_t _halfPeriods[NUM_PITCH] = {246,232,219,207,195,184,174,164,155,146,138,130,123,116,110,104,98,92,87,82,78,73,69,65,62,58,55,52,49,46,44,41,39,37,35,33,31,29,28,26,25,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6};
Pokitto 24:9561281d0378 163 #else
Pokitto 24:9561281d0378 164 //regular note range
Pokitto 24:9561281d0378 165 #define NUM_PITCH 36
Pokitto 24:9561281d0378 166 const uint8_t _halfPeriods[NUM_PITCH] = {246,232,219,207,195,184,174,164,155,146,138,130,123,116,110,104,98,92,87,82,78,73,69,65,62,58,55,52,49,46,44,41,39,37,35,33};
Pokitto 24:9561281d0378 167 #endif
Pokitto 24:9561281d0378 168
Pokitto 24:9561281d0378 169 #endif
Pokitto 24:9561281d0378 170
Pokitto 24:9561281d0378 171 void Pokitto::audio_IRQ() {
Pokitto 24:9561281d0378 172 #if POK_STREAMING_MUSIC > 0
Pokitto 24:9561281d0378 173 #if POK_STREAMFREQ_HALVE > 0
Pokitto 24:9561281d0378 174 streamstep = 1-streamstep;
Pokitto 24:9561281d0378 175 #else
Pokitto 24:9561281d0378 176 streamstep=1;
Pokitto 24:9561281d0378 177 #endif
Pokitto 24:9561281d0378 178
Pokitto 24:9561281d0378 179 streamstep &= streamon; //check if stream is on
Pokitto 24:9561281d0378 180
Pokitto 24:9561281d0378 181 if(streamvol && streamstep) {
Pokitto 24:9561281d0378 182 uint8_t output = (*currentPtr++);
Pokitto 24:9561281d0378 183 sbyte = output;
Pokitto 24:9561281d0378 184 } else {
Pokitto 24:9561281d0378 185 sbyte = 0; // duty cycle
Pokitto 24:9561281d0378 186 }
Pokitto 24:9561281d0378 187
Pokitto 24:9561281d0378 188 if (currentPtr >= endPtr)
Pokitto 24:9561281d0378 189 {
Pokitto 24:9561281d0378 190 currentBuffer++;
Pokitto 24:9561281d0378 191 if (currentBuffer==4) currentBuffer=0;
Pokitto 24:9561281d0378 192 currentPtr = buffers[currentBuffer];
Pokitto 24:9561281d0378 193 endPtr = currentPtr + BUFFER_SIZE;
Pokitto 24:9561281d0378 194 }
Pokitto 24:9561281d0378 195
Pokitto 24:9561281d0378 196 #endif // POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 197 #if (NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 198 Sound::generateOutput();
Pokitto 24:9561281d0378 199 #endif
Pokitto 24:9561281d0378 200 }
Pokitto 24:9561281d0378 201
Pokitto 24:9561281d0378 202 void Sound::volumeUp() {
Pokitto 24:9561281d0378 203 if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()+VOLUME_STEP*2);
Pokitto 24:9561281d0378 204 else setVolume(getVolume()+VOLUME_STEP);
Pokitto 24:9561281d0378 205 }
Pokitto 24:9561281d0378 206
Pokitto 24:9561281d0378 207 void Sound::volumeDown() {
Pokitto 24:9561281d0378 208 if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()-VOLUME_STEP*4);
Pokitto 24:9561281d0378 209 else setVolume(getVolume()-VOLUME_STEP);
Pokitto 24:9561281d0378 210 }
Pokitto 24:9561281d0378 211
Pokitto 24:9561281d0378 212
Pokitto 24:9561281d0378 213 void Sound::setMaxVol(int16_t v) {
Pokitto 24:9561281d0378 214 if (v < 0) v = 0; //prevent nasty wraparound
Pokitto 24:9561281d0378 215 if (v > VOLUME_SPEAKER_MAX) {
Pokitto 24:9561281d0378 216 v = VOLUME_SPEAKER_MAX;
Pokitto 24:9561281d0378 217 }
Pokitto 24:9561281d0378 218 volumeMax = v;
Pokitto 24:9561281d0378 219 setVolume(globalVolume);
Pokitto 24:9561281d0378 220 }
Pokitto 24:9561281d0378 221
Pokitto 24:9561281d0378 222 uint16_t Sound::getMaxVol() {
Pokitto 24:9561281d0378 223 return volumeMax;
Pokitto 24:9561281d0378 224 }
Pokitto 24:9561281d0378 225
Pokitto 24:9561281d0378 226 void Sound::updateStream() {
Pokitto 24:9561281d0378 227 #if POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 228 if (oldBuffer != currentBuffer) {
Pokitto 24:9561281d0378 229 if (currentBuffer==0) fileReadBytes(&buffers[3][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 230 else if (currentBuffer==1) fileReadBytes(&buffers[0][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 231 else if (currentBuffer==2) fileReadBytes(&buffers[1][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 232 else fileReadBytes(&buffers[2][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 233 oldBuffer = currentBuffer;
Pokitto 24:9561281d0378 234 streamcounter += BUFFER_SIZE;
Pokitto 24:9561281d0378 235 }
Pokitto 24:9561281d0378 236
Pokitto 24:9561281d0378 237 #ifndef POK_SIM
Pokitto 24:9561281d0378 238 if ( streamcounter > fs.fsize - (BUFFER_SIZE)) {
Pokitto 24:9561281d0378 239 #else
Pokitto 24:9561281d0378 240 if ( streamcounter > getFileLength() - (BUFFER_SIZE)) {
Pokitto 24:9561281d0378 241 #endif
Pokitto 24:9561281d0378 242 streamcounter=0;
Pokitto 24:9561281d0378 243 #if POK_STREAM_LOOP > 0
Pokitto 24:9561281d0378 244 fileRewind();
Pokitto 24:9561281d0378 245 #endif
Pokitto 24:9561281d0378 246 #ifndef POK_SIM
Pokitto 24:9561281d0378 247 streamon=0;
Pokitto 24:9561281d0378 248 #endif // POK_SIM
Pokitto 24:9561281d0378 249 }
Pokitto 24:9561281d0378 250 #endif
Pokitto 24:9561281d0378 251 }
Pokitto 24:9561281d0378 252
Pokitto 24:9561281d0378 253 void Sound::begin() {
Pokitto 24:9561281d0378 254 #if POK_ENABLE_SOUND > 0
Pokitto 24:9561281d0378 255 soundInit();
Pokitto 24:9561281d0378 256 ampEnable(true);
Pokitto 24:9561281d0378 257 #endif
Pokitto 24:9561281d0378 258 #if (NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 259 #if POK_ENABLE_SOUND > 0
Pokitto 24:9561281d0378 260 #if POK_GBSOUND > 0
Pokitto 24:9561281d0378 261 prescaler = 1;
Pokitto 24:9561281d0378 262 for(byte i=0; i<NUM_CHANNELS; i++){
Pokitto 24:9561281d0378 263 chanVolumes[i] = VOLUME_CHANNEL_MAX;
Pokitto 24:9561281d0378 264 changeInstrumentSet(defaultInstruments, i); //load default instruments. #0:square wave, #1: noise
Pokitto 24:9561281d0378 265 command(CMD_INSTRUMENT, 0, 0, i); //set the default instrument to square wave
Pokitto 24:9561281d0378 266 }
Pokitto 24:9561281d0378 267 #endif // POK_GBSOUND
Pokitto 24:9561281d0378 268 #endif //POK_ENABLE_SOUND
Pokitto 24:9561281d0378 269 #endif
Pokitto 24:9561281d0378 270 }
Pokitto 24:9561281d0378 271
Pokitto 24:9561281d0378 272 void Sound::playTrack(const uint16_t* track, uint8_t channel){
Pokitto 24:9561281d0378 273 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 274 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 275 return;
Pokitto 24:9561281d0378 276 stopTrack(channel);
Pokitto 24:9561281d0378 277 trackCursor[channel] = 0;
Pokitto 24:9561281d0378 278 trackData[channel] = (uint16_t*)track;
Pokitto 24:9561281d0378 279 trackIsPlaying[channel] = true;
Pokitto 24:9561281d0378 280 #endif
Pokitto 24:9561281d0378 281 }
Pokitto 24:9561281d0378 282
Pokitto 24:9561281d0378 283 void Sound::stopTrack(uint8_t channel){
Pokitto 24:9561281d0378 284 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 285 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 286 return;
Pokitto 24:9561281d0378 287 trackIsPlaying[channel] = false;
Pokitto 24:9561281d0378 288 stopPattern(channel);
Pokitto 24:9561281d0378 289 #endif
Pokitto 24:9561281d0378 290 }
Pokitto 24:9561281d0378 291
Pokitto 24:9561281d0378 292 void Sound::stopTrack(){
Pokitto 24:9561281d0378 293 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 294 for(uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 24:9561281d0378 295 stopTrack(i);
Pokitto 24:9561281d0378 296 }
Pokitto 24:9561281d0378 297 #endif
Pokitto 24:9561281d0378 298 }
Pokitto 24:9561281d0378 299
Pokitto 24:9561281d0378 300 void Sound::updateTrack(uint8_t channel){
Pokitto 24:9561281d0378 301 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 302 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 303 return;
Pokitto 24:9561281d0378 304 if(trackIsPlaying[channel] && !patternIsPlaying[channel]){
Pokitto 24:9561281d0378 305 uint16_t data = pgm_read_word(trackData[channel] + trackCursor[channel]);
Pokitto 24:9561281d0378 306 if(data == 0xFFFF){ //en of the track
Pokitto 24:9561281d0378 307 trackIsPlaying[channel] = false;
Pokitto 24:9561281d0378 308 return;
Pokitto 24:9561281d0378 309 }
Pokitto 24:9561281d0378 310 uint8_t patternID = data & 0xFF;
Pokitto 24:9561281d0378 311 data >>= 8;
Pokitto 24:9561281d0378 312 patternPitch[channel] = data;
Pokitto 24:9561281d0378 313 playPattern((const uint16_t*)pgm_read_word(&(patternSet[channel][patternID])), channel);
Pokitto 24:9561281d0378 314 trackCursor[channel] ++;
Pokitto 24:9561281d0378 315 }
Pokitto 24:9561281d0378 316 #endif
Pokitto 24:9561281d0378 317 }
Pokitto 24:9561281d0378 318
Pokitto 24:9561281d0378 319 void Sound::updateTrack(){
Pokitto 24:9561281d0378 320 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 321 for (uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 24:9561281d0378 322 updateTrack(i);
Pokitto 24:9561281d0378 323 }
Pokitto 24:9561281d0378 324 #endif
Pokitto 24:9561281d0378 325 }
Pokitto 24:9561281d0378 326
Pokitto 24:9561281d0378 327 void Sound::changePatternSet(const uint16_t* const* patterns, uint8_t channel){
Pokitto 24:9561281d0378 328 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 329 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 330 return;
Pokitto 24:9561281d0378 331 patternSet[channel] = (uint16_t**)patterns;
Pokitto 24:9561281d0378 332 #endif
Pokitto 24:9561281d0378 333 }
Pokitto 24:9561281d0378 334
Pokitto 24:9561281d0378 335 void Sound::playPattern(const uint16_t* pattern, uint8_t channel){
Pokitto 24:9561281d0378 336 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 337 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 338 return;
Pokitto 24:9561281d0378 339 stopPattern(channel);
Pokitto 24:9561281d0378 340 patternData[channel] = (uint16_t*)pattern;
Pokitto 24:9561281d0378 341 patternCursor[channel] = 0;
Pokitto 24:9561281d0378 342 patternIsPlaying[channel] = true;
Pokitto 24:9561281d0378 343 noteVolume[channel] = 9;
Pokitto 24:9561281d0378 344 //reinit commands
Pokitto 24:9561281d0378 345 volumeSlideStepDuration[channel] = 0;
Pokitto 24:9561281d0378 346 arpeggioStepDuration[channel] = 0;
Pokitto 24:9561281d0378 347 tremoloStepDuration[channel] = 0;
Pokitto 24:9561281d0378 348 #endif
Pokitto 24:9561281d0378 349 }
Pokitto 24:9561281d0378 350
Pokitto 24:9561281d0378 351 void Sound::updatePattern(){
Pokitto 24:9561281d0378 352 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 353 for (uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 24:9561281d0378 354 updatePattern(i);
Pokitto 24:9561281d0378 355 }
Pokitto 24:9561281d0378 356 #endif
Pokitto 24:9561281d0378 357 }
Pokitto 24:9561281d0378 358
Pokitto 24:9561281d0378 359 void Sound::changeInstrumentSet(const uint16_t* const* instruments, uint8_t channel){
Pokitto 24:9561281d0378 360 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 361 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 362 return;
Pokitto 24:9561281d0378 363 instrumentSet[channel] = (uint16_t**)instruments;
Pokitto 24:9561281d0378 364 #endif
Pokitto 24:9561281d0378 365 }
Pokitto 24:9561281d0378 366
Pokitto 24:9561281d0378 367 void Sound::updatePattern(uint8_t i){
Pokitto 24:9561281d0378 368 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 369 if(i>=NUM_CHANNELS)
Pokitto 24:9561281d0378 370 return;
Pokitto 24:9561281d0378 371 if(patternIsPlaying[i]){
Pokitto 24:9561281d0378 372 if(noteDuration[i]==0){//if the end of the previous note is reached
Pokitto 24:9561281d0378 373
Pokitto 24:9561281d0378 374 uint16_t data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 24:9561281d0378 375
Pokitto 24:9561281d0378 376 if(data == 0){ //end of the pattern reached
Pokitto 24:9561281d0378 377 if(patternLooping[i] == true){
Pokitto 24:9561281d0378 378 patternCursor[i] = 0;
Pokitto 24:9561281d0378 379 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 24:9561281d0378 380 }
Pokitto 24:9561281d0378 381 else{
Pokitto 24:9561281d0378 382 patternIsPlaying[i] = false;
Pokitto 24:9561281d0378 383 if(trackIsPlaying[i]){ //if this pattern is part of a track, get the next pattern
Pokitto 24:9561281d0378 384 updateTrack(i);
Pokitto 24:9561281d0378 385 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 24:9561281d0378 386 } else {
Pokitto 24:9561281d0378 387 stopNote(i);
Pokitto 24:9561281d0378 388 //Serial.print("pattern end\n");
Pokitto 24:9561281d0378 389 return;
Pokitto 24:9561281d0378 390 }
Pokitto 24:9561281d0378 391 }
Pokitto 24:9561281d0378 392 }
Pokitto 24:9561281d0378 393
Pokitto 24:9561281d0378 394 while (data & 0x0001){ //read all commands and instrument changes
Pokitto 24:9561281d0378 395 data >>= 2;
Pokitto 24:9561281d0378 396 //Serial.print("\ncmd\t");
Pokitto 24:9561281d0378 397 uint8_t cmd = data & 0x0F;
Pokitto 24:9561281d0378 398 data >>= 4;
Pokitto 24:9561281d0378 399 uint8_t X = data & 0x1F;
Pokitto 24:9561281d0378 400 data >>= 5;
Pokitto 24:9561281d0378 401 int8_t Y = data - 16;
Pokitto 24:9561281d0378 402 command(cmd,X,Y,i);
Pokitto 24:9561281d0378 403 patternCursor[i]++;
Pokitto 24:9561281d0378 404 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 24:9561281d0378 405 }
Pokitto 24:9561281d0378 406 data >>= 2;
Pokitto 24:9561281d0378 407
Pokitto 24:9561281d0378 408 uint8_t pitch = data & 0x003F;
Pokitto 24:9561281d0378 409 data >>= 6;
Pokitto 24:9561281d0378 410
Pokitto 24:9561281d0378 411 uint8_t duration = data;
Pokitto 24:9561281d0378 412 if(pitch != 63){
Pokitto 24:9561281d0378 413 }
Pokitto 24:9561281d0378 414
Pokitto 24:9561281d0378 415 playNote(pitch, duration, i);
Pokitto 24:9561281d0378 416
Pokitto 24:9561281d0378 417 patternCursor[i]++;
Pokitto 24:9561281d0378 418 }
Pokitto 24:9561281d0378 419 }
Pokitto 24:9561281d0378 420 #endif
Pokitto 24:9561281d0378 421 }
Pokitto 24:9561281d0378 422
Pokitto 24:9561281d0378 423 void Sound::stopPattern(uint8_t channel){
Pokitto 24:9561281d0378 424 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 425 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 426 return;
Pokitto 24:9561281d0378 427 stopNote(channel);
Pokitto 24:9561281d0378 428 patternIsPlaying[channel] = false;
Pokitto 24:9561281d0378 429 #endif
Pokitto 24:9561281d0378 430 }
Pokitto 24:9561281d0378 431
Pokitto 24:9561281d0378 432 void Sound::stopPattern(){
Pokitto 24:9561281d0378 433 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 434 for(uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 24:9561281d0378 435 stopPattern(i);
Pokitto 24:9561281d0378 436 }
Pokitto 24:9561281d0378 437 #endif
Pokitto 24:9561281d0378 438 }
Pokitto 24:9561281d0378 439
Pokitto 24:9561281d0378 440 void Sound::command(uint8_t cmd, uint8_t X, int8_t Y, uint8_t i){
Pokitto 24:9561281d0378 441 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 442 if(i>=NUM_CHANNELS)
Pokitto 24:9561281d0378 443 return;
Pokitto 24:9561281d0378 444 switch(cmd){
Pokitto 24:9561281d0378 445 case CMD_VOLUME: //volume
Pokitto 24:9561281d0378 446 X = constrain((int8_t)X, 0, 10);
Pokitto 24:9561281d0378 447 noteVolume[i] = X;
Pokitto 24:9561281d0378 448 break;
Pokitto 24:9561281d0378 449 case CMD_INSTRUMENT: //instrument
Pokitto 24:9561281d0378 450 instrumentData[i] = (uint16_t*)pgm_read_word(&(instrumentSet[i][X]));
Pokitto 24:9561281d0378 451 instrumentLength[i] = pgm_read_word(&(instrumentData[i][0])) & 0x00FF; //8 LSB
Pokitto 24:9561281d0378 452 instrumentLength[i] *= prescaler;
Pokitto 24:9561281d0378 453 instrumentLooping[i] = min2((pgm_read_word(&(instrumentData[i][0])) >> 8), instrumentLength[i]); //8 MSB - check that the loop is shorter than the instrument length
Pokitto 24:9561281d0378 454 instrumentLooping[i] *= prescaler;
Pokitto 24:9561281d0378 455 break;
Pokitto 24:9561281d0378 456 case CMD_SLIDE: //volume slide
Pokitto 24:9561281d0378 457 volumeSlideStepDuration[i] = X * prescaler;
Pokitto 24:9561281d0378 458 volumeSlideStepSize[i] = Y;
Pokitto 24:9561281d0378 459 break;
Pokitto 24:9561281d0378 460 case CMD_ARPEGGIO:
Pokitto 24:9561281d0378 461 arpeggioStepDuration[i] = X * prescaler;
Pokitto 24:9561281d0378 462 arpeggioStepSize[i] = Y;
Pokitto 24:9561281d0378 463 break;
Pokitto 24:9561281d0378 464 case CMD_TREMOLO:
Pokitto 24:9561281d0378 465 tremoloStepDuration[i] = X * prescaler;
Pokitto 24:9561281d0378 466 tremoloStepSize[i] = Y;
Pokitto 24:9561281d0378 467 break;
Pokitto 24:9561281d0378 468 default:
Pokitto 24:9561281d0378 469 break;
Pokitto 24:9561281d0378 470 }
Pokitto 24:9561281d0378 471 #endif
Pokitto 24:9561281d0378 472 }
Pokitto 24:9561281d0378 473
Pokitto 24:9561281d0378 474 void Sound::playNote(uint8_t pitch, uint8_t duration, uint8_t channel){
Pokitto 24:9561281d0378 475 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 476 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 477 return;
Pokitto 24:9561281d0378 478 //set note
Pokitto 24:9561281d0378 479 notePitch[channel] = pitch;
Pokitto 24:9561281d0378 480 noteDuration[channel] = duration * prescaler;
Pokitto 24:9561281d0378 481 //reinit vars
Pokitto 24:9561281d0378 482 instrumentNextChange[channel] = 0;
Pokitto 24:9561281d0378 483 instrumentCursor[channel] = 0;
Pokitto 24:9561281d0378 484 notePlaying[channel] = true;
Pokitto 24:9561281d0378 485 _chanState[channel] = true;
Pokitto 24:9561281d0378 486 commandsCounter[channel] = 0;
Pokitto 24:9561281d0378 487 #endif
Pokitto 24:9561281d0378 488 }
Pokitto 24:9561281d0378 489
Pokitto 24:9561281d0378 490 void Sound::stopNote(uint8_t channel) {
Pokitto 24:9561281d0378 491 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 492 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 493 return;
Pokitto 24:9561281d0378 494 notePlaying[channel] = false;
Pokitto 24:9561281d0378 495 //counters
Pokitto 24:9561281d0378 496 noteDuration[channel] = 0;
Pokitto 24:9561281d0378 497 instrumentCursor[channel] = 0;
Pokitto 24:9561281d0378 498 commandsCounter[channel] = 0;
Pokitto 24:9561281d0378 499 //output
Pokitto 24:9561281d0378 500 _chanOutput[channel] = 0;
Pokitto 24:9561281d0378 501 _chanOutputVolume[channel] = 0;
Pokitto 24:9561281d0378 502 _chanState[channel] = false;
Pokitto 24:9561281d0378 503 updateOutput();
Pokitto 24:9561281d0378 504 #endif
Pokitto 24:9561281d0378 505 }
Pokitto 24:9561281d0378 506
Pokitto 24:9561281d0378 507 void Sound::stopNote() {
Pokitto 24:9561281d0378 508 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 509 for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) {
Pokitto 24:9561281d0378 510 stopNote(channel);
Pokitto 24:9561281d0378 511 }
Pokitto 24:9561281d0378 512 #endif
Pokitto 24:9561281d0378 513 }
Pokitto 24:9561281d0378 514
Pokitto 24:9561281d0378 515 void Sound::updateNote() {
Pokitto 24:9561281d0378 516 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 517 for (uint8_t i = 0; i < NUM_CHANNELS; i++) {
Pokitto 24:9561281d0378 518 updateNote(i);
Pokitto 24:9561281d0378 519 }
Pokitto 24:9561281d0378 520 #endif
Pokitto 24:9561281d0378 521 }
Pokitto 24:9561281d0378 522
Pokitto 24:9561281d0378 523 void Sound::updateNote(uint8_t i) {
Pokitto 24:9561281d0378 524 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 525 if(i>=NUM_CHANNELS)
Pokitto 24:9561281d0378 526 return;
Pokitto 24:9561281d0378 527 if (notePlaying[i]) {
Pokitto 24:9561281d0378 528
Pokitto 24:9561281d0378 529 if(noteDuration[i] == 0){
Pokitto 24:9561281d0378 530 stopNote(i);
Pokitto 24:9561281d0378 531 //Serial.println("note end");
Pokitto 24:9561281d0378 532 return;
Pokitto 24:9561281d0378 533 } else {
Pokitto 24:9561281d0378 534 noteDuration[i]--;
Pokitto 24:9561281d0378 535 }
Pokitto 24:9561281d0378 536
Pokitto 24:9561281d0378 537 if (instrumentNextChange[i] == 0) {
Pokitto 24:9561281d0378 538
Pokitto 24:9561281d0378 539 //read the step data from the progmem and decode it
Pokitto 24:9561281d0378 540 uint16_t thisStep = pgm_read_word(&(instrumentData[i][1 + instrumentCursor[i]]));
Pokitto 24:9561281d0378 541
Pokitto 24:9561281d0378 542 stepVolume[i] = thisStep & 0x0007;
Pokitto 24:9561281d0378 543 thisStep >>= 3;
Pokitto 24:9561281d0378 544
Pokitto 24:9561281d0378 545 uint8_t stepNoise = thisStep & 0x0001;
Pokitto 24:9561281d0378 546 thisStep >>= 1;
Pokitto 24:9561281d0378 547
Pokitto 24:9561281d0378 548 uint8_t stepDuration = thisStep & 0x003F;
Pokitto 24:9561281d0378 549 thisStep >>= 6;
Pokitto 24:9561281d0378 550
Pokitto 24:9561281d0378 551 stepPitch[i] = thisStep;
Pokitto 24:9561281d0378 552
Pokitto 24:9561281d0378 553 //apply the step settings
Pokitto 24:9561281d0378 554 instrumentNextChange[i] = stepDuration * prescaler;
Pokitto 24:9561281d0378 555
Pokitto 24:9561281d0378 556 _chanNoise[i] = stepNoise;
Pokitto 24:9561281d0378 557
Pokitto 24:9561281d0378 558
Pokitto 24:9561281d0378 559 instrumentCursor[i]++;
Pokitto 24:9561281d0378 560
Pokitto 24:9561281d0378 561 if (instrumentCursor[i] >= instrumentLength[i]) {
Pokitto 24:9561281d0378 562 if (instrumentLooping[i]) {
Pokitto 24:9561281d0378 563 instrumentCursor[i] = instrumentLength[i] - instrumentLooping[i];
Pokitto 24:9561281d0378 564 } else {
Pokitto 24:9561281d0378 565 stopNote(i);
Pokitto 24:9561281d0378 566 }
Pokitto 24:9561281d0378 567 }
Pokitto 24:9561281d0378 568 }
Pokitto 24:9561281d0378 569 instrumentNextChange[i]--;
Pokitto 24:9561281d0378 570
Pokitto 24:9561281d0378 571 commandsCounter[i]++;
Pokitto 24:9561281d0378 572
Pokitto 24:9561281d0378 573 //UPDATE VALUES
Pokitto 24:9561281d0378 574 //pitch
Pokitto 24:9561281d0378 575 outputPitch[i] = notePitch[i] + stepPitch[i] + patternPitch[i];
Pokitto 24:9561281d0378 576 if(arpeggioStepDuration[i]){
Pokitto 24:9561281d0378 577 outputPitch[i] += commandsCounter[i] / arpeggioStepDuration[i] * arpeggioStepSize[i];
Pokitto 24:9561281d0378 578 }
Pokitto 24:9561281d0378 579 outputPitch[i] = (outputPitch[i] + NUM_PITCH) % NUM_PITCH; //wrap
Pokitto 24:9561281d0378 580 //volume
Pokitto 24:9561281d0378 581 outputVolume[i] = noteVolume[i];
Pokitto 24:9561281d0378 582 if(volumeSlideStepDuration[i]){
Pokitto 24:9561281d0378 583 outputVolume[i] += commandsCounter[i] / volumeSlideStepDuration[i] * volumeSlideStepSize[i];
Pokitto 24:9561281d0378 584 }
Pokitto 24:9561281d0378 585 if(tremoloStepDuration[i]){
Pokitto 24:9561281d0378 586 outputVolume[i] += ((commandsCounter[i]/tremoloStepDuration[i]) % 2) * tremoloStepSize[i];
Pokitto 24:9561281d0378 587 }
Pokitto 24:9561281d0378 588 outputVolume[i] = constrain(outputVolume[i], 0, 9);
Pokitto 24:9561281d0378 589 if(notePitch[i] == 63){
Pokitto 24:9561281d0378 590 outputVolume[i] = 0;
Pokitto 24:9561281d0378 591 }
Pokitto 24:9561281d0378 592 // jonnehw noInterrupts();
Pokitto 24:9561281d0378 593 _chanHalfPeriod[i] = pgm_read_byte(_halfPeriods + outputPitch[i]);
Pokitto 24:9561281d0378 594 _chanOutput[i] = _chanOutputVolume[i] = outputVolume[i] * (globalVolume>>GLOBVOL_SHIFT) * chanVolumes[i] * stepVolume[i];
Pokitto 24:9561281d0378 595 //Serial.println(outputVolume[i]);
Pokitto 24:9561281d0378 596 // jonnehw interrupts();
Pokitto 24:9561281d0378 597 }
Pokitto 24:9561281d0378 598 #endif
Pokitto 24:9561281d0378 599 }
Pokitto 24:9561281d0378 600
Pokitto 24:9561281d0378 601 void Sound::setChannelHalfPeriod(uint8_t channel, uint8_t halfPeriod) {
Pokitto 24:9561281d0378 602 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 603 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 604 return;
Pokitto 24:9561281d0378 605 _chanHalfPeriod[channel] = halfPeriod;
Pokitto 24:9561281d0378 606 _chanState[channel] = false;
Pokitto 24:9561281d0378 607 _chanCount[channel] = 0;
Pokitto 24:9561281d0378 608 updateOutput();
Pokitto 24:9561281d0378 609 #endif
Pokitto 24:9561281d0378 610 }
Pokitto 24:9561281d0378 611
Pokitto 24:9561281d0378 612
Pokitto 24:9561281d0378 613 void Sound::generateOutput() {
Pokitto 24:9561281d0378 614 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 615 bool outputChanged = false;
Pokitto 24:9561281d0378 616 //no for loop here, for the performance sake (this function runs 15 000 times per second...)
Pokitto 24:9561281d0378 617 //CHANNEL 0
Pokitto 24:9561281d0378 618 if (_chanOutputVolume[0]) {
Pokitto 24:9561281d0378 619 _chanCount[0]++;
Pokitto 24:9561281d0378 620 if (_chanCount[0] >= _chanHalfPeriod[0]) {
Pokitto 24:9561281d0378 621 outputChanged = true;
Pokitto 24:9561281d0378 622 _chanState[0] = !_chanState[0];
Pokitto 24:9561281d0378 623 _chanCount[0] = 0;
Pokitto 24:9561281d0378 624 if (_chanNoise[0]) {
Pokitto 24:9561281d0378 625 _rand = 67 * _rand + 71;
Pokitto 24:9561281d0378 626 _chanOutput[0] = _rand % _chanOutputVolume[0];
Pokitto 24:9561281d0378 627 }
Pokitto 24:9561281d0378 628 }
Pokitto 24:9561281d0378 629 }
Pokitto 24:9561281d0378 630
Pokitto 24:9561281d0378 631
Pokitto 24:9561281d0378 632 //CHANNEL 1
Pokitto 24:9561281d0378 633 #if (NUM_CHANNELS > 1)
Pokitto 24:9561281d0378 634 if (_chanOutputVolume[1]) {
Pokitto 24:9561281d0378 635 _chanCount[1]++;
Pokitto 24:9561281d0378 636 if (_chanCount[1] >= _chanHalfPeriod[1]) {
Pokitto 24:9561281d0378 637 outputChanged = true;
Pokitto 24:9561281d0378 638 _chanState[1] = !_chanState[1];
Pokitto 24:9561281d0378 639 _chanCount[1] = 0;
Pokitto 24:9561281d0378 640 if (_chanNoise[1]) {
Pokitto 24:9561281d0378 641 _rand = 67 * _rand + 71;
Pokitto 24:9561281d0378 642 _chanOutput[1] = _rand % _chanOutputVolume[1];
Pokitto 24:9561281d0378 643 }
Pokitto 24:9561281d0378 644 }
Pokitto 24:9561281d0378 645 }
Pokitto 24:9561281d0378 646 #endif
Pokitto 24:9561281d0378 647
Pokitto 24:9561281d0378 648 //CHANNEL 2
Pokitto 24:9561281d0378 649 #if (NUM_CHANNELS > 2)
Pokitto 24:9561281d0378 650 if (_chanOutputVolume[2]) {
Pokitto 24:9561281d0378 651 _chanCount[2]++;
Pokitto 24:9561281d0378 652 if (_chanCount[2] >= _chanHalfPeriod[2]) {
Pokitto 24:9561281d0378 653 outputChanged = true;
Pokitto 24:9561281d0378 654 _chanState[2] = !_chanState[2];
Pokitto 24:9561281d0378 655 _chanCount[2] = 0;
Pokitto 24:9561281d0378 656 if (_chanNoise[2]) {
Pokitto 24:9561281d0378 657 _rand = 67 * _rand + 71;
Pokitto 24:9561281d0378 658 _chanOutput[2] = _rand % _chanOutputVolume[2];
Pokitto 24:9561281d0378 659 }
Pokitto 24:9561281d0378 660 }
Pokitto 24:9561281d0378 661 }
Pokitto 24:9561281d0378 662 #endif
Pokitto 24:9561281d0378 663
Pokitto 24:9561281d0378 664 //CHANNEL 3
Pokitto 24:9561281d0378 665 #if (NUM_CHANNELS > 3)
Pokitto 24:9561281d0378 666 if (_chanOutputVolume[3]) {
Pokitto 24:9561281d0378 667 _chanCount[3]++;
Pokitto 24:9561281d0378 668 if (_chanCount[3] >= _chanHalfPeriod[3]) {
Pokitto 24:9561281d0378 669 outputChanged = true;
Pokitto 24:9561281d0378 670 _chanState[3] = !_chanState[3];
Pokitto 24:9561281d0378 671 _chanCount[3] = 0;
Pokitto 24:9561281d0378 672 if (_chanNoise[3]) {
Pokitto 24:9561281d0378 673 _rand = 67 * _rand + 71;
Pokitto 24:9561281d0378 674 _chanOutput[3] = _rand % _chanOutputVolume[3];
Pokitto 24:9561281d0378 675 }
Pokitto 24:9561281d0378 676 }
Pokitto 24:9561281d0378 677 }
Pokitto 24:9561281d0378 678 #endif
Pokitto 24:9561281d0378 679
Pokitto 24:9561281d0378 680 #if POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 681 if (streamstep) {
Pokitto 24:9561281d0378 682 outputChanged=true;
Pokitto 24:9561281d0378 683 }
Pokitto 24:9561281d0378 684 #endif
Pokitto 24:9561281d0378 685
Pokitto 24:9561281d0378 686 if (outputChanged) {
Pokitto 24:9561281d0378 687 updateOutput();
Pokitto 24:9561281d0378 688 }
Pokitto 24:9561281d0378 689 #endif
Pokitto 24:9561281d0378 690 }
Pokitto 24:9561281d0378 691
Pokitto 24:9561281d0378 692 void Sound::updateOutput() {
Pokitto 24:9561281d0378 693 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 694 uint8_t output = 0;
Pokitto 24:9561281d0378 695
Pokitto 24:9561281d0378 696 //CHANNEL 0
Pokitto 24:9561281d0378 697 if (_chanState[0]) {
Pokitto 24:9561281d0378 698 output += _chanOutput[0];
Pokitto 24:9561281d0378 699 }
Pokitto 24:9561281d0378 700
Pokitto 24:9561281d0378 701 //CHANNEL 1
Pokitto 24:9561281d0378 702 #if (NUM_CHANNELS > 1)
Pokitto 24:9561281d0378 703 if (_chanState[1]) {
Pokitto 24:9561281d0378 704 output += _chanOutput[1];
Pokitto 24:9561281d0378 705 }
Pokitto 24:9561281d0378 706 #endif
Pokitto 24:9561281d0378 707
Pokitto 24:9561281d0378 708 //CHANNEL 2
Pokitto 24:9561281d0378 709 #if (NUM_CHANNELS > 2)
Pokitto 24:9561281d0378 710 if (_chanState[2]) {
Pokitto 24:9561281d0378 711 output += _chanOutput[2];
Pokitto 24:9561281d0378 712 }
Pokitto 24:9561281d0378 713 #endif
Pokitto 24:9561281d0378 714
Pokitto 24:9561281d0378 715 //CHANNEL 3
Pokitto 24:9561281d0378 716 #if (NUM_CHANNELS > 3)
Pokitto 24:9561281d0378 717 if (_chanState[3]) {
Pokitto 24:9561281d0378 718 output += _chanOutput[3];
Pokitto 24:9561281d0378 719 }
Pokitto 24:9561281d0378 720 #endif
Pokitto 24:9561281d0378 721
Pokitto 24:9561281d0378 722 #ifndef POK_SIM
Pokitto 24:9561281d0378 723 #if POK_ENABLE_SOUND
Pokitto 24:9561281d0378 724 /** HARDWARE **/
Pokitto 24:9561281d0378 725
Pokitto 24:9561281d0378 726 #if POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 727 if (streamstep) {
Pokitto 24:9561281d0378 728 pwmout_write(&audiopwm,(float)sbyte/(float)255);
Pokitto 24:9561281d0378 729 }
Pokitto 24:9561281d0378 730 #endif
Pokitto 24:9561281d0378 731 dac_write((uint8_t)output); //direct hardware mixing baby !
Pokitto 24:9561281d0378 732 soundbyte = output;
Pokitto 24:9561281d0378 733 #endif //POK_ENABLE_SOUND
Pokitto 24:9561281d0378 734 #else
Pokitto 24:9561281d0378 735 /** SIMULATOR **/
Pokitto 24:9561281d0378 736 #if POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 737 if (streamstep) {
Pokitto 24:9561281d0378 738 uint16_t o = output + sbyte;
Pokitto 24:9561281d0378 739 output = o/2;
Pokitto 24:9561281d0378 740 }
Pokitto 24:9561281d0378 741 #endif
Pokitto 24:9561281d0378 742 soundbyte = output;
Pokitto 24:9561281d0378 743 #endif // POK_SIM
Pokitto 24:9561281d0378 744 #endif
Pokitto 24:9561281d0378 745 }
Pokitto 24:9561281d0378 746
Pokitto 24:9561281d0378 747 void Sound::setPatternLooping(bool loop, uint8_t channel) {
Pokitto 24:9561281d0378 748 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 749 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 750 return;
Pokitto 24:9561281d0378 751 patternLooping[channel] = loop;
Pokitto 24:9561281d0378 752 #endif
Pokitto 24:9561281d0378 753 }
Pokitto 24:9561281d0378 754
Pokitto 24:9561281d0378 755 void Sound::playOK(){
Pokitto 24:9561281d0378 756 #if POK_GBSOUND
Pokitto 24:9561281d0378 757 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 758 playPattern(playOKPattern,0);
Pokitto 24:9561281d0378 759 #endif
Pokitto 24:9561281d0378 760 #endif // POK_GBSOUND
Pokitto 24:9561281d0378 761 }
Pokitto 24:9561281d0378 762
Pokitto 24:9561281d0378 763 void Sound::playCancel(){
Pokitto 24:9561281d0378 764 #if POK_GBSOUND
Pokitto 24:9561281d0378 765 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 766 playPattern(playCancelPattern,0);
Pokitto 24:9561281d0378 767 #endif
Pokitto 24:9561281d0378 768 #endif
Pokitto 24:9561281d0378 769 }
Pokitto 24:9561281d0378 770
Pokitto 24:9561281d0378 771 void Sound::playTick(){
Pokitto 24:9561281d0378 772 #if POK_GBSOUND
Pokitto 24:9561281d0378 773 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 774 playPattern(playTickP,0);
Pokitto 24:9561281d0378 775 #endif
Pokitto 24:9561281d0378 776 #endif // POK_GBSOUND
Pokitto 24:9561281d0378 777 }
Pokitto 24:9561281d0378 778
Pokitto 24:9561281d0378 779 void Sound::setVolume(int16_t volume) {
Pokitto 24:9561281d0378 780 //#if NUM_CHANNELS > 0
Pokitto 24:9561281d0378 781 if (volume<0) volume = 0;
Pokitto 24:9561281d0378 782 if (volume>volumeMax) volume = volumeMax;
Pokitto 24:9561281d0378 783 globalVolume = volume; // % (volumeMax+1);
Pokitto 24:9561281d0378 784 #ifndef POK_SIM
Pokitto 24:9561281d0378 785 volume = (volume / 2)-10;
Pokitto 24:9561281d0378 786 if (volume<0) volume = 0;
Pokitto 24:9561281d0378 787 #if POK_ENABLE_SOUND > 0
Pokitto 24:9561281d0378 788 setHWvolume(volume);
Pokitto 24:9561281d0378 789 #endif
Pokitto 24:9561281d0378 790 #endif
Pokitto 24:9561281d0378 791 #if POK_SHOW_VOLUME > 0
Pokitto 24:9561281d0378 792 _soundc.volbar_visible = VOLUMEBAR_TIMEOUT;
Pokitto 24:9561281d0378 793 #endif
Pokitto 24:9561281d0378 794 //#endif
Pokitto 24:9561281d0378 795 }
Pokitto 24:9561281d0378 796
Pokitto 24:9561281d0378 797 uint16_t Sound::getVolume() {
Pokitto 24:9561281d0378 798 //#if NUM_CHANNELS > 0
Pokitto 24:9561281d0378 799 return globalVolume;
Pokitto 24:9561281d0378 800 //#else
Pokitto 24:9561281d0378 801 // return 0;
Pokitto 24:9561281d0378 802 //#endif
Pokitto 24:9561281d0378 803 }
Pokitto 24:9561281d0378 804
Pokitto 24:9561281d0378 805 void Sound::setVolume(int8_t volume, uint8_t channel) {
Pokitto 24:9561281d0378 806 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 807 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 808 return;
Pokitto 24:9561281d0378 809 volume = (volume > VOLUME_CHANNEL_MAX) ? VOLUME_CHANNEL_MAX : volume;
Pokitto 24:9561281d0378 810 volume = (volume < 0) ? 0 : volume;
Pokitto 24:9561281d0378 811 chanVolumes[channel] = volume;
Pokitto 24:9561281d0378 812 #endif
Pokitto 24:9561281d0378 813 }
Pokitto 24:9561281d0378 814
Pokitto 24:9561281d0378 815 uint8_t Sound::getVolume(uint8_t channel) {
Pokitto 24:9561281d0378 816 #if(NUM_CHANNELS > 0)
Pokitto 24:9561281d0378 817 if(channel>=NUM_CHANNELS)
Pokitto 24:9561281d0378 818 return 255;
Pokitto 24:9561281d0378 819 return (chanVolumes[channel]);
Pokitto 24:9561281d0378 820 #else
Pokitto 24:9561281d0378 821 return 0;
Pokitto 24:9561281d0378 822 #endif
Pokitto 24:9561281d0378 823 }
Pokitto 24:9561281d0378 824
Pokitto 24:9561281d0378 825 void Sound::playTone(uint8_t os, int frq, uint8_t amp, uint8_t wav,uint8_t arpmode)
Pokitto 24:9561281d0378 826 {
Pokitto 24:9561281d0378 827 if (wav>5) wav=0;
Pokitto 24:9561281d0378 828 if (arpmode>MAX_ARPMODE) arpmode=MAX_ARPMODE;
Pokitto 24:9561281d0378 829 if (os==1) setOSC(&osc1,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
Pokitto 24:9561281d0378 830 else if (os==2) setOSC(&osc2,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
Pokitto 24:9561281d0378 831 else if (os==3) setOSC(&osc3,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
Pokitto 24:9561281d0378 832 }
Pokitto 24:9561281d0378 833
Pokitto 24:9561281d0378 834 void Sound::playTone(uint8_t os, uint16_t frq, uint8_t volume, uint32_t duration)
Pokitto 24:9561281d0378 835 {
Pokitto 24:9561281d0378 836 if (os==1) setOSC(&osc1,1,WSAW,frq,volume,duration);
Pokitto 24:9561281d0378 837 else if (os==2) setOSC(&osc2,1,WTRI,frq,volume,duration);
Pokitto 24:9561281d0378 838 else if (os==3) setOSC(&osc3,1,WTRI,frq,volume,duration);
Pokitto 24:9561281d0378 839 }
Pokitto 24:9561281d0378 840
Pokitto 24:9561281d0378 841 uint8_t Sound::ampIsOn()
Pokitto 24:9561281d0378 842 {
Pokitto 24:9561281d0378 843 #ifdef POK_SIM
Pokitto 24:9561281d0378 844 return core.ampIsOn();
Pokitto 24:9561281d0378 845 #else
Pokitto 24:9561281d0378 846 #if POK_ENABLE_SOUND > 0
Pokitto 24:9561281d0378 847 return Pokitto::ampIsOn();
Pokitto 24:9561281d0378 848 #endif
Pokitto 24:9561281d0378 849 #endif // POK_SIM
Pokitto 24:9561281d0378 850 return 0;
Pokitto 24:9561281d0378 851 }
Pokitto 24:9561281d0378 852
Pokitto 24:9561281d0378 853 void Sound::ampEnable(uint8_t v) {
Pokitto 24:9561281d0378 854 #ifdef POK_SIM
Pokitto 24:9561281d0378 855 core.ampEnable(v);
Pokitto 24:9561281d0378 856 #else
Pokitto 24:9561281d0378 857 #if POK_ENABLE_SOUND > 0
Pokitto 24:9561281d0378 858 Pokitto::ampEnable(v);
Pokitto 24:9561281d0378 859 #endif
Pokitto 24:9561281d0378 860 #endif // POK_SIM
Pokitto 24:9561281d0378 861
Pokitto 24:9561281d0378 862 }
Pokitto 24:9561281d0378 863
Pokitto 24:9561281d0378 864 int Sound::playMusicStream(char* filename)
Pokitto 24:9561281d0378 865 {
Pokitto 24:9561281d0378 866 return playMusicStream(filename,0);
Pokitto 24:9561281d0378 867 }
Pokitto 24:9561281d0378 868
Pokitto 24:9561281d0378 869 int Sound::playMusicStream()
Pokitto 24:9561281d0378 870 {
Pokitto 24:9561281d0378 871 #if POK_STREAMING_MUSIC >0
Pokitto 24:9561281d0378 872 if (currentPtr) {
Pokitto 24:9561281d0378 873 pokPlayStream();
Pokitto 24:9561281d0378 874 return 1;
Pokitto 24:9561281d0378 875 } else return 0; //no stream
Pokitto 24:9561281d0378 876 #endif // POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 877 }
Pokitto 24:9561281d0378 878
Pokitto 24:9561281d0378 879 void Sound::pauseMusicStream() {
Pokitto 24:9561281d0378 880 #if POK_ENABLE_SOUND > 0
Pokitto 24:9561281d0378 881 pokPauseStream();
Pokitto 24:9561281d0378 882 #endif
Pokitto 24:9561281d0378 883 }
Pokitto 24:9561281d0378 884
Pokitto 24:9561281d0378 885 int Sound::playMusicStream(char* filename, uint8_t options)
Pokitto 24:9561281d0378 886 {
Pokitto 24:9561281d0378 887 #if POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 888 uint8_t result;
Pokitto 24:9561281d0378 889 result = pokInitSD();
Pokitto 24:9561281d0378 890 if (!isThisFileOpen(filename)) {
Pokitto 24:9561281d0378 891 fileClose(); // close any open files
Pokitto 24:9561281d0378 892 result = fileOpen(filename,FILE_MODE_OVERWRITE | FILE_MODE_BINARY);
Pokitto 24:9561281d0378 893 }
Pokitto 24:9561281d0378 894
Pokitto 24:9561281d0378 895 if (result) {
Pokitto 24:9561281d0378 896 currentPtr = 0; // mark that no stream is available
Pokitto 24:9561281d0378 897 return 0; // opening music file failed
Pokitto 24:9561281d0378 898 }
Pokitto 24:9561281d0378 899
Pokitto 24:9561281d0378 900 fileReadBytes(&buffers[0][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 901 fileReadBytes(&buffers[1][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 902 fileReadBytes(&buffers[2][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 903 fileReadBytes(&buffers[3][0],BUFFER_SIZE);
Pokitto 24:9561281d0378 904 currentBuffer = 0;
Pokitto 24:9561281d0378 905 currentPtr = buffers[currentBuffer];
Pokitto 24:9561281d0378 906 endPtr = currentPtr + BUFFER_SIZE;
Pokitto 24:9561281d0378 907
Pokitto 24:9561281d0378 908 //streaming = STR_PLAYING|options;
Pokitto 24:9561281d0378 909
Pokitto 24:9561281d0378 910 if (!options) pokPlayStream(); // activate stream
Pokitto 24:9561281d0378 911 #endif //POK_STREAMING_MUSIC
Pokitto 24:9561281d0378 912 return 1; // opening music file succeeded
Pokitto 24:9561281d0378 913 }
Pokitto 24:9561281d0378 914
Pokitto 24:9561281d0378 915