Jonne Valola / PokittoLib Featured

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:
Sun Jul 01 06:32:37 2018 +0000
Revision:
52:c04087025cab
Child:
58:5f58a2846a20
PokittoCookie, faster Mode2 and Mode13 added

Who changed what in which revision?

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