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 Oct 07 10:06:28 2018 +0000
Revision:
58:5f58a2846a20
Parent:
52:c04087025cab
Child:
66:6281a40d73e6
All warnings removed in mbed compilation

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 58:5f58a2846a20 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 58:5f58a2846a20 83 uint8_t const Pokitto::discrete_vol_levels[] = {0,32,64,96,128,160,192,224};
Pokitto 58:5f58a2846a20 84 uint8_t const Pokitto::discrete_vol_hw_levels[] = {0,27,64,96,36,117,127,127};
Pokitto 58:5f58a2846a20 85 uint8_t const Pokitto::discrete_vol_multipliers[] = {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 58:5f58a2846a20 138 #undef NUM_CHANNELS
Pokitto 52:c04087025cab 139 #define NUM_CHANNELS 0
Pokitto 52:c04087025cab 140 #endif
Pokitto 52:c04087025cab 141
Pokitto 52:c04087025cab 142 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 143 #ifndef POK_SIM
Pokitto 52:c04087025cab 144 uint32_t sbyte;
Pokitto 52:c04087025cab 145 #else
Pokitto 52:c04087025cab 146 uint32_t sbyte;
Pokitto 52:c04087025cab 147 float pwm1;
Pokitto 52:c04087025cab 148 #endif // POK_SIM
Pokitto 52:c04087025cab 149
Pokitto 52:c04087025cab 150 //declare these variables globally for faster access
Pokitto 52:c04087025cab 151 uint8_t _rand = 1;
Pokitto 52:c04087025cab 152 uint8_t _chanCount[NUM_CHANNELS]; //counts until the next change of the waveform
Pokitto 52:c04087025cab 153 bool _chanState[NUM_CHANNELS]; //if the waveform is currently high or low
Pokitto 52:c04087025cab 154 uint8_t _chanHalfPeriod[NUM_CHANNELS]; //duration of half the period of the waveform
Pokitto 52:c04087025cab 155 uint8_t _chanOutputVolume[NUM_CHANNELS]; //amplitude of the outputted waveform
Pokitto 52:c04087025cab 156 uint8_t _chanOutput[NUM_CHANNELS]; //current value of the outputted waveform
Pokitto 52:c04087025cab 157 bool _chanNoise[NUM_CHANNELS]; //if a random value should be added to the waveform to generate noise
Pokitto 52:c04087025cab 158
Pokitto 52:c04087025cab 159 #if POK_GBSOUND > 0
Pokitto 52:c04087025cab 160 const uint16_t squareWaveInstrument[] = {0x0101, 0x03F7};
Pokitto 52:c04087025cab 161 const uint16_t noiseInstrument[] = {0x0101, 0x03FF};
Pokitto 52:c04087025cab 162 const uint16_t* const defaultInstruments[] = {squareWaveInstrument,noiseInstrument};
Pokitto 52:c04087025cab 163
Pokitto 52:c04087025cab 164 const uint16_t playOKPattern[] = {0x0005,0x138,0x168,0x0000};
Pokitto 52:c04087025cab 165 const uint16_t playCancelPattern[] = {0x0005,0x168,0x138,0x0000};
Pokitto 52:c04087025cab 166 const uint16_t playTickP[] = {0x0045,0x168,0x0000};
Pokitto 52:c04087025cab 167 #endif
Pokitto 52:c04087025cab 168 #if(EXTENDED_NOTE_RANGE > 0)
Pokitto 52:c04087025cab 169 //extended note range
Pokitto 52:c04087025cab 170 #define NUM_PITCH 59
Pokitto 52:c04087025cab 171 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 172 #else
Pokitto 52:c04087025cab 173 //regular note range
Pokitto 52:c04087025cab 174 #define NUM_PITCH 36
Pokitto 52:c04087025cab 175 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 176 #endif
Pokitto 52:c04087025cab 177
Pokitto 52:c04087025cab 178 #endif
Pokitto 52:c04087025cab 179
Pokitto 52:c04087025cab 180 void Pokitto::audio_IRQ() {
Pokitto 52:c04087025cab 181 #if POK_STREAMING_MUSIC > 0
Pokitto 52:c04087025cab 182 #if POK_STREAMFREQ_HALVE > 0
Pokitto 52:c04087025cab 183 streamstep = 1-streamstep;
Pokitto 52:c04087025cab 184 #else
Pokitto 52:c04087025cab 185 streamstep=1;
Pokitto 52:c04087025cab 186 #endif
Pokitto 52:c04087025cab 187
Pokitto 52:c04087025cab 188 streamstep &= streamon; //check if stream is on
Pokitto 52:c04087025cab 189
Pokitto 52:c04087025cab 190 if(streamvol && streamstep) {
Pokitto 52:c04087025cab 191 uint8_t output = (*currentPtr++);
Pokitto 52:c04087025cab 192 sbyte = output;
Pokitto 52:c04087025cab 193 } else {
Pokitto 52:c04087025cab 194 sbyte = 0; // duty cycle
Pokitto 52:c04087025cab 195 }
Pokitto 52:c04087025cab 196
Pokitto 52:c04087025cab 197 if (currentPtr >= endPtr)
Pokitto 52:c04087025cab 198 {
Pokitto 52:c04087025cab 199 currentBuffer++;
Pokitto 52:c04087025cab 200 if (currentBuffer==4) currentBuffer=0;
Pokitto 52:c04087025cab 201 currentPtr = buffers[currentBuffer];
Pokitto 52:c04087025cab 202 endPtr = currentPtr + BUFFER_SIZE;
Pokitto 52:c04087025cab 203 }
Pokitto 52:c04087025cab 204
Pokitto 52:c04087025cab 205 #endif // POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 206 #if (NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 207 Sound::generateOutput();
Pokitto 52:c04087025cab 208 #endif
Pokitto 52:c04087025cab 209 }
Pokitto 52:c04087025cab 210
Pokitto 52:c04087025cab 211 void Sound::volumeUp() {
Pokitto 52:c04087025cab 212 Pokitto::discrete_vol++;
Pokitto 52:c04087025cab 213 if (discrete_vol>7) discrete_vol=7;
Pokitto 52:c04087025cab 214 globalVolume = discrete_vol_levels[discrete_vol];
Pokitto 52:c04087025cab 215 setVolume(globalVolume);
Pokitto 52:c04087025cab 216 //if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()+VOLUME_STEP*2);
Pokitto 52:c04087025cab 217 //else setVolume(getVolume()+VOLUME_STEP);
Pokitto 52:c04087025cab 218 }
Pokitto 52:c04087025cab 219
Pokitto 52:c04087025cab 220 void Sound::volumeDown() {
Pokitto 52:c04087025cab 221 if (discrete_vol) Pokitto::discrete_vol--;
Pokitto 52:c04087025cab 222 globalVolume = discrete_vol_levels[discrete_vol];
Pokitto 52:c04087025cab 223 setVolume(globalVolume);
Pokitto 52:c04087025cab 224 //if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()-VOLUME_STEP*4);
Pokitto 52:c04087025cab 225 //else setVolume(getVolume()-VOLUME_STEP);
Pokitto 52:c04087025cab 226 }
Pokitto 52:c04087025cab 227
Pokitto 52:c04087025cab 228
Pokitto 52:c04087025cab 229 void Sound::setMaxVol(int16_t v) {
Pokitto 52:c04087025cab 230 if (v < 0) v = 0; //prevent nasty wraparound
Pokitto 52:c04087025cab 231 if (v > VOLUME_SPEAKER_MAX) {
Pokitto 52:c04087025cab 232 v = VOLUME_SPEAKER_MAX;
Pokitto 52:c04087025cab 233 }
Pokitto 52:c04087025cab 234 volumeMax = v;
Pokitto 52:c04087025cab 235 setVolume(globalVolume);
Pokitto 52:c04087025cab 236 }
Pokitto 52:c04087025cab 237
Pokitto 52:c04087025cab 238 uint16_t Sound::getMaxVol() {
Pokitto 52:c04087025cab 239 return volumeMax;
Pokitto 52:c04087025cab 240 }
Pokitto 52:c04087025cab 241
Pokitto 52:c04087025cab 242 void Sound::updateStream() {
Pokitto 52:c04087025cab 243 #if POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 244 if (oldBuffer != currentBuffer) {
Pokitto 52:c04087025cab 245 if (currentBuffer==0) fileReadBytes(&buffers[3][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 246 else if (currentBuffer==1) fileReadBytes(&buffers[0][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 247 else if (currentBuffer==2) fileReadBytes(&buffers[1][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 248 else fileReadBytes(&buffers[2][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 249 oldBuffer = currentBuffer;
Pokitto 52:c04087025cab 250 streamcounter += BUFFER_SIZE;
Pokitto 52:c04087025cab 251 }
Pokitto 52:c04087025cab 252
Pokitto 52:c04087025cab 253 #ifndef POK_SIM
Pokitto 52:c04087025cab 254 if ( streamcounter > fs.fsize - (BUFFER_SIZE)) {
Pokitto 52:c04087025cab 255 #else
Pokitto 52:c04087025cab 256 if ( streamcounter > getFileLength() - (BUFFER_SIZE)) {
Pokitto 52:c04087025cab 257 #endif
Pokitto 52:c04087025cab 258 streamcounter=0;
Pokitto 52:c04087025cab 259 #if POK_STREAM_LOOP > 0
Pokitto 52:c04087025cab 260 fileRewind();
Pokitto 52:c04087025cab 261 #else
Pokitto 52:c04087025cab 262 #ifndef POK_SIM
Pokitto 52:c04087025cab 263 streamon=0;
Pokitto 52:c04087025cab 264 #endif // POK_SIM
Pokitto 52:c04087025cab 265 #endif // POK_STREAM_LOOP
Pokitto 52:c04087025cab 266 }
Pokitto 52:c04087025cab 267 #endif
Pokitto 52:c04087025cab 268 }
Pokitto 52:c04087025cab 269
Pokitto 52:c04087025cab 270 void Sound::begin() {
Pokitto 52:c04087025cab 271 #if POK_ENABLE_SOUND > 0
Pokitto 52:c04087025cab 272 soundInit();
Pokitto 52:c04087025cab 273 ampEnable(true);
Pokitto 52:c04087025cab 274 #endif
Pokitto 52:c04087025cab 275 #if (NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 276 #if POK_ENABLE_SOUND > 0
Pokitto 52:c04087025cab 277 #if POK_GBSOUND > 0
Pokitto 52:c04087025cab 278 prescaler = 1;
Pokitto 52:c04087025cab 279 for(byte i=0; i<NUM_CHANNELS; i++){
Pokitto 52:c04087025cab 280 chanVolumes[i] = VOLUME_CHANNEL_MAX;
Pokitto 52:c04087025cab 281 changeInstrumentSet(defaultInstruments, i); //load default instruments. #0:square wave, #1: noise
Pokitto 52:c04087025cab 282 command(CMD_INSTRUMENT, 0, 0, i); //set the default instrument to square wave
Pokitto 52:c04087025cab 283 }
Pokitto 52:c04087025cab 284 #endif // POK_GBSOUND
Pokitto 52:c04087025cab 285 #endif //POK_ENABLE_SOUND
Pokitto 52:c04087025cab 286 #endif
Pokitto 52:c04087025cab 287 }
Pokitto 52:c04087025cab 288
Pokitto 52:c04087025cab 289 void Sound::playTrack(const uint16_t* track, uint8_t channel){
Pokitto 52:c04087025cab 290 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 291 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 292 return;
Pokitto 52:c04087025cab 293 stopTrack(channel);
Pokitto 52:c04087025cab 294 trackCursor[channel] = 0;
Pokitto 52:c04087025cab 295 trackData[channel] = (uint16_t*)track;
Pokitto 52:c04087025cab 296 trackIsPlaying[channel] = true;
Pokitto 52:c04087025cab 297 #endif
Pokitto 52:c04087025cab 298 }
Pokitto 52:c04087025cab 299
Pokitto 52:c04087025cab 300 void Sound::stopTrack(uint8_t channel){
Pokitto 52:c04087025cab 301 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 302 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 303 return;
Pokitto 52:c04087025cab 304 trackIsPlaying[channel] = false;
Pokitto 52:c04087025cab 305 stopPattern(channel);
Pokitto 52:c04087025cab 306 #endif
Pokitto 52:c04087025cab 307 }
Pokitto 52:c04087025cab 308
Pokitto 52:c04087025cab 309 void Sound::stopTrack(){
Pokitto 52:c04087025cab 310 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 311 for(uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 52:c04087025cab 312 stopTrack(i);
Pokitto 52:c04087025cab 313 }
Pokitto 52:c04087025cab 314 #endif
Pokitto 52:c04087025cab 315 }
Pokitto 52:c04087025cab 316
Pokitto 52:c04087025cab 317 void Sound::updateTrack(uint8_t channel){
Pokitto 52:c04087025cab 318 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 319 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 320 return;
Pokitto 52:c04087025cab 321 if(trackIsPlaying[channel] && !patternIsPlaying[channel]){
Pokitto 52:c04087025cab 322 uint16_t data = pgm_read_word(trackData[channel] + trackCursor[channel]);
Pokitto 52:c04087025cab 323 if(data == 0xFFFF){ //en of the track
Pokitto 52:c04087025cab 324 trackIsPlaying[channel] = false;
Pokitto 52:c04087025cab 325 return;
Pokitto 52:c04087025cab 326 }
Pokitto 52:c04087025cab 327 uint8_t patternID = data & 0xFF;
Pokitto 52:c04087025cab 328 data >>= 8;
Pokitto 52:c04087025cab 329 patternPitch[channel] = data;
Pokitto 52:c04087025cab 330 playPattern((const uint16_t*)pgm_read_word(&(patternSet[channel][patternID])), channel);
Pokitto 52:c04087025cab 331 trackCursor[channel] ++;
Pokitto 52:c04087025cab 332 }
Pokitto 52:c04087025cab 333 #endif
Pokitto 52:c04087025cab 334 }
Pokitto 52:c04087025cab 335
Pokitto 52:c04087025cab 336 void Sound::updateTrack(){
Pokitto 52:c04087025cab 337 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 338 for (uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 52:c04087025cab 339 updateTrack(i);
Pokitto 52:c04087025cab 340 }
Pokitto 52:c04087025cab 341 #endif
Pokitto 52:c04087025cab 342 }
Pokitto 52:c04087025cab 343
Pokitto 52:c04087025cab 344 void Sound::changePatternSet(const uint16_t* const* patterns, uint8_t channel){
Pokitto 52:c04087025cab 345 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 346 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 347 return;
Pokitto 52:c04087025cab 348 patternSet[channel] = (uint16_t**)patterns;
Pokitto 52:c04087025cab 349 #endif
Pokitto 52:c04087025cab 350 }
Pokitto 52:c04087025cab 351
Pokitto 52:c04087025cab 352 void Sound::playPattern(const uint16_t* pattern, uint8_t channel){
Pokitto 52:c04087025cab 353 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 354 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 355 return;
Pokitto 52:c04087025cab 356 stopPattern(channel);
Pokitto 52:c04087025cab 357 patternData[channel] = (uint16_t*)pattern;
Pokitto 52:c04087025cab 358 patternCursor[channel] = 0;
Pokitto 52:c04087025cab 359 patternIsPlaying[channel] = true;
Pokitto 52:c04087025cab 360 noteVolume[channel] = 9;
Pokitto 52:c04087025cab 361 //reinit commands
Pokitto 52:c04087025cab 362 volumeSlideStepDuration[channel] = 0;
Pokitto 52:c04087025cab 363 arpeggioStepDuration[channel] = 0;
Pokitto 52:c04087025cab 364 tremoloStepDuration[channel] = 0;
Pokitto 52:c04087025cab 365 #endif
Pokitto 52:c04087025cab 366 }
Pokitto 52:c04087025cab 367
Pokitto 52:c04087025cab 368 void Sound::updatePattern(){
Pokitto 52:c04087025cab 369 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 370 for (uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 52:c04087025cab 371 updatePattern(i);
Pokitto 52:c04087025cab 372 }
Pokitto 52:c04087025cab 373 #endif
Pokitto 52:c04087025cab 374 }
Pokitto 52:c04087025cab 375
Pokitto 52:c04087025cab 376 void Sound::changeInstrumentSet(const uint16_t* const* instruments, uint8_t channel){
Pokitto 52:c04087025cab 377 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 378 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 379 return;
Pokitto 52:c04087025cab 380 instrumentSet[channel] = (uint16_t**)instruments;
Pokitto 52:c04087025cab 381 #endif
Pokitto 52:c04087025cab 382 }
Pokitto 52:c04087025cab 383
Pokitto 52:c04087025cab 384 void Sound::updatePattern(uint8_t i){
Pokitto 52:c04087025cab 385 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 386 if(i>=NUM_CHANNELS)
Pokitto 52:c04087025cab 387 return;
Pokitto 52:c04087025cab 388 if(patternIsPlaying[i]){
Pokitto 52:c04087025cab 389 if(noteDuration[i]==0){//if the end of the previous note is reached
Pokitto 52:c04087025cab 390
Pokitto 52:c04087025cab 391 uint16_t data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 52:c04087025cab 392
Pokitto 52:c04087025cab 393 if(data == 0){ //end of the pattern reached
Pokitto 52:c04087025cab 394 if(patternLooping[i] == true){
Pokitto 52:c04087025cab 395 patternCursor[i] = 0;
Pokitto 52:c04087025cab 396 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 52:c04087025cab 397 }
Pokitto 52:c04087025cab 398 else{
Pokitto 52:c04087025cab 399 patternIsPlaying[i] = false;
Pokitto 52:c04087025cab 400 if(trackIsPlaying[i]){ //if this pattern is part of a track, get the next pattern
Pokitto 52:c04087025cab 401 updateTrack(i);
Pokitto 52:c04087025cab 402 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 52:c04087025cab 403 } else {
Pokitto 52:c04087025cab 404 stopNote(i);
Pokitto 52:c04087025cab 405 //Serial.print("pattern end\n");
Pokitto 52:c04087025cab 406 return;
Pokitto 52:c04087025cab 407 }
Pokitto 52:c04087025cab 408 }
Pokitto 52:c04087025cab 409 }
Pokitto 52:c04087025cab 410
Pokitto 52:c04087025cab 411 while (data & 0x0001){ //read all commands and instrument changes
Pokitto 52:c04087025cab 412 data >>= 2;
Pokitto 52:c04087025cab 413 //Serial.print("\ncmd\t");
Pokitto 52:c04087025cab 414 uint8_t cmd = data & 0x0F;
Pokitto 52:c04087025cab 415 data >>= 4;
Pokitto 52:c04087025cab 416 uint8_t X = data & 0x1F;
Pokitto 52:c04087025cab 417 data >>= 5;
Pokitto 52:c04087025cab 418 int8_t Y = data - 16;
Pokitto 52:c04087025cab 419 command(cmd,X,Y,i);
Pokitto 52:c04087025cab 420 patternCursor[i]++;
Pokitto 52:c04087025cab 421 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 52:c04087025cab 422 }
Pokitto 52:c04087025cab 423 data >>= 2;
Pokitto 52:c04087025cab 424
Pokitto 52:c04087025cab 425 uint8_t pitch = data & 0x003F;
Pokitto 52:c04087025cab 426 data >>= 6;
Pokitto 52:c04087025cab 427
Pokitto 52:c04087025cab 428 uint8_t duration = data;
Pokitto 52:c04087025cab 429 if(pitch != 63){
Pokitto 52:c04087025cab 430 }
Pokitto 52:c04087025cab 431
Pokitto 52:c04087025cab 432 playNote(pitch, duration, i);
Pokitto 52:c04087025cab 433
Pokitto 52:c04087025cab 434 patternCursor[i]++;
Pokitto 52:c04087025cab 435 }
Pokitto 52:c04087025cab 436 }
Pokitto 52:c04087025cab 437 #endif
Pokitto 52:c04087025cab 438 }
Pokitto 52:c04087025cab 439
Pokitto 52:c04087025cab 440 void Sound::stopPattern(uint8_t channel){
Pokitto 52:c04087025cab 441 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 442 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 443 return;
Pokitto 52:c04087025cab 444 stopNote(channel);
Pokitto 52:c04087025cab 445 patternIsPlaying[channel] = false;
Pokitto 52:c04087025cab 446 #endif
Pokitto 52:c04087025cab 447 }
Pokitto 52:c04087025cab 448
Pokitto 52:c04087025cab 449 void Sound::stopPattern(){
Pokitto 52:c04087025cab 450 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 451 for(uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 52:c04087025cab 452 stopPattern(i);
Pokitto 52:c04087025cab 453 }
Pokitto 52:c04087025cab 454 #endif
Pokitto 52:c04087025cab 455 }
Pokitto 52:c04087025cab 456
Pokitto 52:c04087025cab 457 void Sound::command(uint8_t cmd, uint8_t X, int8_t Y, uint8_t i){
Pokitto 52:c04087025cab 458 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 459 if(i>=NUM_CHANNELS)
Pokitto 52:c04087025cab 460 return;
Pokitto 52:c04087025cab 461 switch(cmd){
Pokitto 52:c04087025cab 462 case CMD_VOLUME: //volume
Pokitto 52:c04087025cab 463 X = constrain((int8_t)X, 0, 10);
Pokitto 52:c04087025cab 464 noteVolume[i] = X;
Pokitto 52:c04087025cab 465 break;
Pokitto 52:c04087025cab 466 case CMD_INSTRUMENT: //instrument
Pokitto 52:c04087025cab 467 instrumentData[i] = (uint16_t*)pgm_read_word(&(instrumentSet[i][X]));
Pokitto 52:c04087025cab 468 instrumentLength[i] = pgm_read_word(&(instrumentData[i][0])) & 0x00FF; //8 LSB
Pokitto 52:c04087025cab 469 instrumentLength[i] *= prescaler;
Pokitto 52:c04087025cab 470 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 471 instrumentLooping[i] *= prescaler;
Pokitto 52:c04087025cab 472 break;
Pokitto 52:c04087025cab 473 case CMD_SLIDE: //volume slide
Pokitto 52:c04087025cab 474 volumeSlideStepDuration[i] = X * prescaler;
Pokitto 52:c04087025cab 475 volumeSlideStepSize[i] = Y;
Pokitto 52:c04087025cab 476 break;
Pokitto 52:c04087025cab 477 case CMD_ARPEGGIO:
Pokitto 52:c04087025cab 478 arpeggioStepDuration[i] = X * prescaler;
Pokitto 52:c04087025cab 479 arpeggioStepSize[i] = Y;
Pokitto 52:c04087025cab 480 break;
Pokitto 52:c04087025cab 481 case CMD_TREMOLO:
Pokitto 52:c04087025cab 482 tremoloStepDuration[i] = X * prescaler;
Pokitto 52:c04087025cab 483 tremoloStepSize[i] = Y;
Pokitto 52:c04087025cab 484 break;
Pokitto 52:c04087025cab 485 default:
Pokitto 52:c04087025cab 486 break;
Pokitto 52:c04087025cab 487 }
Pokitto 52:c04087025cab 488 #endif
Pokitto 52:c04087025cab 489 }
Pokitto 52:c04087025cab 490
Pokitto 52:c04087025cab 491 void Sound::playNote(uint8_t pitch, uint8_t duration, uint8_t channel){
Pokitto 52:c04087025cab 492 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 493 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 494 return;
Pokitto 52:c04087025cab 495 //set note
Pokitto 52:c04087025cab 496 notePitch[channel] = pitch;
Pokitto 52:c04087025cab 497 noteDuration[channel] = duration * prescaler;
Pokitto 52:c04087025cab 498 //reinit vars
Pokitto 52:c04087025cab 499 instrumentNextChange[channel] = 0;
Pokitto 52:c04087025cab 500 instrumentCursor[channel] = 0;
Pokitto 52:c04087025cab 501 notePlaying[channel] = true;
Pokitto 52:c04087025cab 502 _chanState[channel] = true;
Pokitto 52:c04087025cab 503 commandsCounter[channel] = 0;
Pokitto 52:c04087025cab 504 #endif
Pokitto 52:c04087025cab 505 }
Pokitto 52:c04087025cab 506
Pokitto 52:c04087025cab 507 void Sound::stopNote(uint8_t channel) {
Pokitto 52:c04087025cab 508 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 509 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 510 return;
Pokitto 52:c04087025cab 511 notePlaying[channel] = false;
Pokitto 52:c04087025cab 512 //counters
Pokitto 52:c04087025cab 513 noteDuration[channel] = 0;
Pokitto 52:c04087025cab 514 instrumentCursor[channel] = 0;
Pokitto 52:c04087025cab 515 commandsCounter[channel] = 0;
Pokitto 52:c04087025cab 516 //output
Pokitto 52:c04087025cab 517 _chanOutput[channel] = 0;
Pokitto 52:c04087025cab 518 _chanOutputVolume[channel] = 0;
Pokitto 52:c04087025cab 519 _chanState[channel] = false;
Pokitto 52:c04087025cab 520 updateOutput();
Pokitto 52:c04087025cab 521 #endif
Pokitto 52:c04087025cab 522 }
Pokitto 52:c04087025cab 523
Pokitto 52:c04087025cab 524 void Sound::stopNote() {
Pokitto 52:c04087025cab 525 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 526 for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) {
Pokitto 52:c04087025cab 527 stopNote(channel);
Pokitto 52:c04087025cab 528 }
Pokitto 52:c04087025cab 529 #endif
Pokitto 52:c04087025cab 530 }
Pokitto 52:c04087025cab 531
Pokitto 52:c04087025cab 532 void Sound::updateNote() {
Pokitto 52:c04087025cab 533 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 534 for (uint8_t i = 0; i < NUM_CHANNELS; i++) {
Pokitto 52:c04087025cab 535 updateNote(i);
Pokitto 52:c04087025cab 536 }
Pokitto 52:c04087025cab 537 #endif
Pokitto 52:c04087025cab 538 }
Pokitto 52:c04087025cab 539
Pokitto 52:c04087025cab 540 void Sound::updateNote(uint8_t i) {
Pokitto 52:c04087025cab 541 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 542 if(i>=NUM_CHANNELS)
Pokitto 52:c04087025cab 543 return;
Pokitto 52:c04087025cab 544 if (notePlaying[i]) {
Pokitto 52:c04087025cab 545
Pokitto 52:c04087025cab 546 if(noteDuration[i] == 0){
Pokitto 52:c04087025cab 547 stopNote(i);
Pokitto 52:c04087025cab 548 //Serial.println("note end");
Pokitto 52:c04087025cab 549 return;
Pokitto 52:c04087025cab 550 } else {
Pokitto 52:c04087025cab 551 noteDuration[i]--;
Pokitto 52:c04087025cab 552 }
Pokitto 52:c04087025cab 553
Pokitto 52:c04087025cab 554 if (instrumentNextChange[i] == 0) {
Pokitto 52:c04087025cab 555
Pokitto 52:c04087025cab 556 //read the step data from the progmem and decode it
Pokitto 52:c04087025cab 557 uint16_t thisStep = pgm_read_word(&(instrumentData[i][1 + instrumentCursor[i]]));
Pokitto 52:c04087025cab 558
Pokitto 52:c04087025cab 559 stepVolume[i] = thisStep & 0x0007;
Pokitto 52:c04087025cab 560 thisStep >>= 3;
Pokitto 52:c04087025cab 561
Pokitto 52:c04087025cab 562 uint8_t stepNoise = thisStep & 0x0001;
Pokitto 52:c04087025cab 563 thisStep >>= 1;
Pokitto 52:c04087025cab 564
Pokitto 52:c04087025cab 565 uint8_t stepDuration = thisStep & 0x003F;
Pokitto 52:c04087025cab 566 thisStep >>= 6;
Pokitto 52:c04087025cab 567
Pokitto 52:c04087025cab 568 stepPitch[i] = thisStep;
Pokitto 52:c04087025cab 569
Pokitto 52:c04087025cab 570 //apply the step settings
Pokitto 52:c04087025cab 571 instrumentNextChange[i] = stepDuration * prescaler;
Pokitto 52:c04087025cab 572
Pokitto 52:c04087025cab 573 _chanNoise[i] = stepNoise;
Pokitto 52:c04087025cab 574
Pokitto 52:c04087025cab 575
Pokitto 52:c04087025cab 576 instrumentCursor[i]++;
Pokitto 52:c04087025cab 577
Pokitto 52:c04087025cab 578 if (instrumentCursor[i] >= instrumentLength[i]) {
Pokitto 52:c04087025cab 579 if (instrumentLooping[i]) {
Pokitto 52:c04087025cab 580 instrumentCursor[i] = instrumentLength[i] - instrumentLooping[i];
Pokitto 52:c04087025cab 581 } else {
Pokitto 52:c04087025cab 582 stopNote(i);
Pokitto 52:c04087025cab 583 }
Pokitto 52:c04087025cab 584 }
Pokitto 52:c04087025cab 585 }
Pokitto 52:c04087025cab 586 instrumentNextChange[i]--;
Pokitto 52:c04087025cab 587
Pokitto 52:c04087025cab 588 commandsCounter[i]++;
Pokitto 52:c04087025cab 589
Pokitto 52:c04087025cab 590 //UPDATE VALUES
Pokitto 52:c04087025cab 591 //pitch
Pokitto 52:c04087025cab 592 outputPitch[i] = notePitch[i] + stepPitch[i] + patternPitch[i];
Pokitto 52:c04087025cab 593 if(arpeggioStepDuration[i]){
Pokitto 52:c04087025cab 594 outputPitch[i] += commandsCounter[i] / arpeggioStepDuration[i] * arpeggioStepSize[i];
Pokitto 52:c04087025cab 595 }
Pokitto 52:c04087025cab 596 outputPitch[i] = (outputPitch[i] + NUM_PITCH) % NUM_PITCH; //wrap
Pokitto 52:c04087025cab 597 //volume
Pokitto 52:c04087025cab 598 outputVolume[i] = noteVolume[i];
Pokitto 52:c04087025cab 599 if(volumeSlideStepDuration[i]){
Pokitto 52:c04087025cab 600 outputVolume[i] += commandsCounter[i] / volumeSlideStepDuration[i] * volumeSlideStepSize[i];
Pokitto 52:c04087025cab 601 }
Pokitto 52:c04087025cab 602 if(tremoloStepDuration[i]){
Pokitto 52:c04087025cab 603 outputVolume[i] += ((commandsCounter[i]/tremoloStepDuration[i]) % 2) * tremoloStepSize[i];
Pokitto 52:c04087025cab 604 }
Pokitto 52:c04087025cab 605 outputVolume[i] = constrain(outputVolume[i], 0, 9);
Pokitto 52:c04087025cab 606 if(notePitch[i] == 63){
Pokitto 52:c04087025cab 607 outputVolume[i] = 0;
Pokitto 52:c04087025cab 608 }
Pokitto 52:c04087025cab 609 // jonnehw noInterrupts();
Pokitto 52:c04087025cab 610 _chanHalfPeriod[i] = pgm_read_byte(_halfPeriods + outputPitch[i]);
Pokitto 52:c04087025cab 611 _chanOutput[i] = _chanOutputVolume[i] = outputVolume[i] * (globalVolume>>GLOBVOL_SHIFT) * chanVolumes[i] * stepVolume[i];
Pokitto 52:c04087025cab 612 //Serial.println(outputVolume[i]);
Pokitto 52:c04087025cab 613 // jonnehw interrupts();
Pokitto 52:c04087025cab 614 }
Pokitto 52:c04087025cab 615 #endif
Pokitto 52:c04087025cab 616 }
Pokitto 52:c04087025cab 617
Pokitto 52:c04087025cab 618 void Sound::setChannelHalfPeriod(uint8_t channel, uint8_t halfPeriod) {
Pokitto 52:c04087025cab 619 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 620 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 621 return;
Pokitto 52:c04087025cab 622 _chanHalfPeriod[channel] = halfPeriod;
Pokitto 52:c04087025cab 623 _chanState[channel] = false;
Pokitto 52:c04087025cab 624 _chanCount[channel] = 0;
Pokitto 52:c04087025cab 625 updateOutput();
Pokitto 52:c04087025cab 626 #endif
Pokitto 52:c04087025cab 627 }
Pokitto 52:c04087025cab 628
Pokitto 52:c04087025cab 629
Pokitto 52:c04087025cab 630 void Sound::generateOutput() {
Pokitto 52:c04087025cab 631 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 632 bool outputChanged = false;
Pokitto 52:c04087025cab 633 //no for loop here, for the performance sake (this function runs 15 000 times per second...)
Pokitto 52:c04087025cab 634 //CHANNEL 0
Pokitto 52:c04087025cab 635 if (_chanOutputVolume[0]) {
Pokitto 52:c04087025cab 636 _chanCount[0]++;
Pokitto 52:c04087025cab 637 if (_chanCount[0] >= _chanHalfPeriod[0]) {
Pokitto 52:c04087025cab 638 outputChanged = true;
Pokitto 52:c04087025cab 639 _chanState[0] = !_chanState[0];
Pokitto 52:c04087025cab 640 _chanCount[0] = 0;
Pokitto 52:c04087025cab 641 if (_chanNoise[0]) {
Pokitto 52:c04087025cab 642 _rand = 67 * _rand + 71;
Pokitto 52:c04087025cab 643 _chanOutput[0] = _rand % _chanOutputVolume[0];
Pokitto 52:c04087025cab 644 }
Pokitto 52:c04087025cab 645 }
Pokitto 52:c04087025cab 646 }
Pokitto 52:c04087025cab 647
Pokitto 52:c04087025cab 648
Pokitto 52:c04087025cab 649 //CHANNEL 1
Pokitto 52:c04087025cab 650 #if (NUM_CHANNELS > 1)
Pokitto 52:c04087025cab 651 if (_chanOutputVolume[1]) {
Pokitto 52:c04087025cab 652 _chanCount[1]++;
Pokitto 52:c04087025cab 653 if (_chanCount[1] >= _chanHalfPeriod[1]) {
Pokitto 52:c04087025cab 654 outputChanged = true;
Pokitto 52:c04087025cab 655 _chanState[1] = !_chanState[1];
Pokitto 52:c04087025cab 656 _chanCount[1] = 0;
Pokitto 52:c04087025cab 657 if (_chanNoise[1]) {
Pokitto 52:c04087025cab 658 _rand = 67 * _rand + 71;
Pokitto 52:c04087025cab 659 _chanOutput[1] = _rand % _chanOutputVolume[1];
Pokitto 52:c04087025cab 660 }
Pokitto 52:c04087025cab 661 }
Pokitto 52:c04087025cab 662 }
Pokitto 52:c04087025cab 663 #endif
Pokitto 52:c04087025cab 664
Pokitto 52:c04087025cab 665 //CHANNEL 2
Pokitto 52:c04087025cab 666 #if (NUM_CHANNELS > 2)
Pokitto 52:c04087025cab 667 if (_chanOutputVolume[2]) {
Pokitto 52:c04087025cab 668 _chanCount[2]++;
Pokitto 52:c04087025cab 669 if (_chanCount[2] >= _chanHalfPeriod[2]) {
Pokitto 52:c04087025cab 670 outputChanged = true;
Pokitto 52:c04087025cab 671 _chanState[2] = !_chanState[2];
Pokitto 52:c04087025cab 672 _chanCount[2] = 0;
Pokitto 52:c04087025cab 673 if (_chanNoise[2]) {
Pokitto 52:c04087025cab 674 _rand = 67 * _rand + 71;
Pokitto 52:c04087025cab 675 _chanOutput[2] = _rand % _chanOutputVolume[2];
Pokitto 52:c04087025cab 676 }
Pokitto 52:c04087025cab 677 }
Pokitto 52:c04087025cab 678 }
Pokitto 52:c04087025cab 679 #endif
Pokitto 52:c04087025cab 680
Pokitto 52:c04087025cab 681 //CHANNEL 3
Pokitto 52:c04087025cab 682 #if (NUM_CHANNELS > 3)
Pokitto 52:c04087025cab 683 if (_chanOutputVolume[3]) {
Pokitto 52:c04087025cab 684 _chanCount[3]++;
Pokitto 52:c04087025cab 685 if (_chanCount[3] >= _chanHalfPeriod[3]) {
Pokitto 52:c04087025cab 686 outputChanged = true;
Pokitto 52:c04087025cab 687 _chanState[3] = !_chanState[3];
Pokitto 52:c04087025cab 688 _chanCount[3] = 0;
Pokitto 52:c04087025cab 689 if (_chanNoise[3]) {
Pokitto 52:c04087025cab 690 _rand = 67 * _rand + 71;
Pokitto 52:c04087025cab 691 _chanOutput[3] = _rand % _chanOutputVolume[3];
Pokitto 52:c04087025cab 692 }
Pokitto 52:c04087025cab 693 }
Pokitto 52:c04087025cab 694 }
Pokitto 52:c04087025cab 695 #endif
Pokitto 52:c04087025cab 696
Pokitto 52:c04087025cab 697 #if POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 698 if (streamstep) {
Pokitto 52:c04087025cab 699 outputChanged=true;
Pokitto 52:c04087025cab 700 }
Pokitto 52:c04087025cab 701 #endif
Pokitto 52:c04087025cab 702
Pokitto 52:c04087025cab 703 if (outputChanged) {
Pokitto 52:c04087025cab 704 updateOutput();
Pokitto 52:c04087025cab 705 }
Pokitto 52:c04087025cab 706 #endif
Pokitto 52:c04087025cab 707 }
Pokitto 52:c04087025cab 708
Pokitto 52:c04087025cab 709 void Sound::updateOutput() {
Pokitto 52:c04087025cab 710 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 711 uint32_t output = 0;
Pokitto 52:c04087025cab 712
Pokitto 52:c04087025cab 713 //CHANNEL 0
Pokitto 52:c04087025cab 714 if (_chanState[0]) {
Pokitto 52:c04087025cab 715 output += _chanOutput[0];
Pokitto 52:c04087025cab 716 }
Pokitto 52:c04087025cab 717
Pokitto 52:c04087025cab 718 //CHANNEL 1
Pokitto 52:c04087025cab 719 #if (NUM_CHANNELS > 1)
Pokitto 52:c04087025cab 720 if (_chanState[1]) {
Pokitto 52:c04087025cab 721 output += _chanOutput[1];
Pokitto 52:c04087025cab 722 }
Pokitto 52:c04087025cab 723 #endif
Pokitto 52:c04087025cab 724
Pokitto 52:c04087025cab 725 //CHANNEL 2
Pokitto 52:c04087025cab 726 #if (NUM_CHANNELS > 2)
Pokitto 52:c04087025cab 727 if (_chanState[2]) {
Pokitto 52:c04087025cab 728 output += _chanOutput[2];
Pokitto 52:c04087025cab 729 }
Pokitto 52:c04087025cab 730 #endif
Pokitto 52:c04087025cab 731
Pokitto 52:c04087025cab 732 //CHANNEL 3
Pokitto 52:c04087025cab 733 #if (NUM_CHANNELS > 3)
Pokitto 52:c04087025cab 734 if (_chanState[3]) {
Pokitto 52:c04087025cab 735 output += _chanOutput[3];
Pokitto 52:c04087025cab 736 }
Pokitto 52:c04087025cab 737 #endif
Pokitto 52:c04087025cab 738
Pokitto 52:c04087025cab 739 #ifndef POK_SIM
Pokitto 52:c04087025cab 740 #if POK_ENABLE_SOUND
Pokitto 52:c04087025cab 741 /** HARDWARE **/
Pokitto 52:c04087025cab 742
Pokitto 52:c04087025cab 743 #if POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 744 if (streamstep) {
Pokitto 52:c04087025cab 745 //pwmout_write(&audiopwm,(float)(sbyte>>headPhoneLevel)/(float)255);
Pokitto 52:c04087025cab 746 sbyte *= discrete_vol_multipliers[discrete_vol];
Pokitto 52:c04087025cab 747 sbyte >>= 8;
Pokitto 52:c04087025cab 748 pwmout_write(&audiopwm,(float)(sbyte)/(float)255);
Pokitto 52:c04087025cab 749 }
Pokitto 52:c04087025cab 750 #endif
Pokitto 52:c04087025cab 751 output *= discrete_vol_multipliers[discrete_vol];
Pokitto 52:c04087025cab 752 output >>= 8;
Pokitto 52:c04087025cab 753 dac_write((uint8_t)output); //direct hardware mixing baby !
Pokitto 52:c04087025cab 754 soundbyte = output;
Pokitto 52:c04087025cab 755 #endif //POK_ENABLE_SOUND
Pokitto 52:c04087025cab 756 #else
Pokitto 52:c04087025cab 757 /** SIMULATOR **/
Pokitto 52:c04087025cab 758 #if POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 759 if (streamstep) {
Pokitto 52:c04087025cab 760 uint16_t o = output + sbyte;
Pokitto 52:c04087025cab 761 output = (o/2);//>>headPhoneLevel;
Pokitto 52:c04087025cab 762 }
Pokitto 52:c04087025cab 763 #endif
Pokitto 52:c04087025cab 764 soundbyte = output;//<<headPhoneLevel;
Pokitto 52:c04087025cab 765 #endif // POK_SIM
Pokitto 52:c04087025cab 766 #endif
Pokitto 52:c04087025cab 767 }
Pokitto 52:c04087025cab 768
Pokitto 52:c04087025cab 769 void Sound::setPatternLooping(bool loop, uint8_t channel) {
Pokitto 52:c04087025cab 770 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 771 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 772 return;
Pokitto 52:c04087025cab 773 patternLooping[channel] = loop;
Pokitto 52:c04087025cab 774 #endif
Pokitto 52:c04087025cab 775 }
Pokitto 52:c04087025cab 776
Pokitto 52:c04087025cab 777 void Sound::playOK(){
Pokitto 52:c04087025cab 778 #if POK_GBSOUND
Pokitto 52:c04087025cab 779 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 780 playPattern(playOKPattern,0);
Pokitto 52:c04087025cab 781 #endif
Pokitto 52:c04087025cab 782 #endif // POK_GBSOUND
Pokitto 52:c04087025cab 783 }
Pokitto 52:c04087025cab 784
Pokitto 52:c04087025cab 785 void Sound::playCancel(){
Pokitto 52:c04087025cab 786 #if POK_GBSOUND
Pokitto 52:c04087025cab 787 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 788 playPattern(playCancelPattern,0);
Pokitto 52:c04087025cab 789 #endif
Pokitto 52:c04087025cab 790 #endif
Pokitto 52:c04087025cab 791 }
Pokitto 52:c04087025cab 792
Pokitto 52:c04087025cab 793 void Sound::playTick(){
Pokitto 52:c04087025cab 794 #if POK_GBSOUND
Pokitto 52:c04087025cab 795 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 796 playPattern(playTickP,0);
Pokitto 52:c04087025cab 797 #endif
Pokitto 52:c04087025cab 798 #endif // POK_GBSOUND
Pokitto 52:c04087025cab 799 }
Pokitto 52:c04087025cab 800
Pokitto 52:c04087025cab 801 void Sound::setVolume(int16_t volume) {
Pokitto 52:c04087025cab 802 //#if NUM_CHANNELS > 0
Pokitto 52:c04087025cab 803 if (volume<0) volume = 0;
Pokitto 52:c04087025cab 804 //if (volume>volumeMax) volume = volumeMax;
Pokitto 52:c04087025cab 805 globalVolume = volume;
Pokitto 52:c04087025cab 806 #if POK_ENABLE_SOUND > 0
Pokitto 52:c04087025cab 807 discrete_vol = (volume>>5);
Pokitto 52:c04087025cab 808 #ifndef POK_SIM
Pokitto 52:c04087025cab 809 setHWvolume(discrete_vol_hw_levels[discrete_vol]); //boost volume if headphonelevel
Pokitto 52:c04087025cab 810 #endif
Pokitto 52:c04087025cab 811 #endif
Pokitto 52:c04087025cab 812 #if POK_SHOW_VOLUME > 0
Pokitto 52:c04087025cab 813 _soundc.volbar_visible = VOLUMEBAR_TIMEOUT;
Pokitto 52:c04087025cab 814 #endif
Pokitto 52:c04087025cab 815 //#endif
Pokitto 52:c04087025cab 816 }
Pokitto 52:c04087025cab 817
Pokitto 52:c04087025cab 818 uint16_t Sound::getVolume() {
Pokitto 52:c04087025cab 819 //#if NUM_CHANNELS > 0
Pokitto 52:c04087025cab 820 return globalVolume;
Pokitto 52:c04087025cab 821 //#else
Pokitto 52:c04087025cab 822 // return 0;
Pokitto 52:c04087025cab 823 //#endif
Pokitto 52:c04087025cab 824 }
Pokitto 52:c04087025cab 825
Pokitto 52:c04087025cab 826 void Sound::setVolume(int8_t volume, uint8_t channel) {
Pokitto 52:c04087025cab 827 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 828 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 829 return;
Pokitto 52:c04087025cab 830 volume = (volume > VOLUME_CHANNEL_MAX) ? VOLUME_CHANNEL_MAX : volume;
Pokitto 52:c04087025cab 831 volume = (volume < 0) ? 0 : volume;
Pokitto 52:c04087025cab 832 chanVolumes[channel] = volume;
Pokitto 52:c04087025cab 833 #endif
Pokitto 52:c04087025cab 834 }
Pokitto 52:c04087025cab 835
Pokitto 52:c04087025cab 836 uint8_t Sound::getVolume(uint8_t channel) {
Pokitto 52:c04087025cab 837 #if(NUM_CHANNELS > 0)
Pokitto 52:c04087025cab 838 if(channel>=NUM_CHANNELS)
Pokitto 52:c04087025cab 839 return 255;
Pokitto 52:c04087025cab 840 return (chanVolumes[channel]);
Pokitto 52:c04087025cab 841 #else
Pokitto 52:c04087025cab 842 return 0;
Pokitto 52:c04087025cab 843 #endif
Pokitto 52:c04087025cab 844 }
Pokitto 52:c04087025cab 845
Pokitto 52:c04087025cab 846 void Sound::playTone(uint8_t os, int frq, uint8_t amp, uint8_t wav,uint8_t arpmode)
Pokitto 52:c04087025cab 847 {
Pokitto 52:c04087025cab 848 if (wav>5) wav=0;
Pokitto 52:c04087025cab 849 if (arpmode>MAX_ARPMODE) arpmode=MAX_ARPMODE;
Pokitto 52:c04087025cab 850 if (os==1) setOSC(&osc1,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
Pokitto 52:c04087025cab 851 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 852 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 853 }
Pokitto 52:c04087025cab 854
Pokitto 52:c04087025cab 855 void Sound::playTone(uint8_t os, uint16_t frq, uint8_t volume, uint32_t duration)
Pokitto 52:c04087025cab 856 {
Pokitto 52:c04087025cab 857 if (os==1) setOSC(&osc1,1,WSQUARE,frq,volume,duration);
Pokitto 52:c04087025cab 858 else if (os==2) setOSC(&osc2,1,WTRI,frq,volume,duration);
Pokitto 52:c04087025cab 859 else if (os==3) setOSC(&osc3,1,WTRI,frq,volume,duration);
Pokitto 52:c04087025cab 860 }
Pokitto 52:c04087025cab 861
Pokitto 52:c04087025cab 862 uint8_t Sound::ampIsOn()
Pokitto 52:c04087025cab 863 {
Pokitto 52:c04087025cab 864 #ifdef POK_SIM
Pokitto 52:c04087025cab 865 return core.ampIsOn();
Pokitto 52:c04087025cab 866 #else
Pokitto 52:c04087025cab 867 #if POK_ENABLE_SOUND > 0
Pokitto 52:c04087025cab 868 return Pokitto::ampIsOn();
Pokitto 52:c04087025cab 869 #endif
Pokitto 52:c04087025cab 870 #endif // POK_SIM
Pokitto 52:c04087025cab 871 return 0;
Pokitto 52:c04087025cab 872 }
Pokitto 52:c04087025cab 873
Pokitto 52:c04087025cab 874 void Sound::ampEnable(uint8_t v) {
Pokitto 52:c04087025cab 875 #ifdef POK_SIM
Pokitto 52:c04087025cab 876 core.ampEnable(v);
Pokitto 52:c04087025cab 877 #else
Pokitto 52:c04087025cab 878 #if POK_ENABLE_SOUND > 0
Pokitto 52:c04087025cab 879 Pokitto::ampEnable(v);
Pokitto 52:c04087025cab 880 #endif
Pokitto 52:c04087025cab 881 #endif // POK_SIM
Pokitto 52:c04087025cab 882
Pokitto 52:c04087025cab 883 }
Pokitto 52:c04087025cab 884
Pokitto 52:c04087025cab 885 int Sound::playMusicStream(char* filename)
Pokitto 52:c04087025cab 886 {
Pokitto 52:c04087025cab 887 return playMusicStream(filename,FILE_MODE_READONLY | FILE_MODE_BINARY);
Pokitto 52:c04087025cab 888 }
Pokitto 52:c04087025cab 889
Pokitto 52:c04087025cab 890 int Sound::playMusicStream()
Pokitto 52:c04087025cab 891 {
Pokitto 52:c04087025cab 892 #if POK_STREAMING_MUSIC >0
Pokitto 52:c04087025cab 893 if (currentPtr) {
Pokitto 52:c04087025cab 894 pokPlayStream();
Pokitto 52:c04087025cab 895 return 1;
Pokitto 52:c04087025cab 896 } else return 0; //no stream
Pokitto 52:c04087025cab 897 #endif // POK_STREAMING_MUSIC
Pokitto 58:5f58a2846a20 898 return 0;
Pokitto 52:c04087025cab 899 }
Pokitto 52:c04087025cab 900
Pokitto 52:c04087025cab 901 void Sound::pauseMusicStream() {
Pokitto 52:c04087025cab 902 #if POK_ENABLE_SOUND > 0
Pokitto 52:c04087025cab 903 pokPauseStream();
Pokitto 52:c04087025cab 904 #endif
Pokitto 52:c04087025cab 905 }
Pokitto 52:c04087025cab 906
Pokitto 52:c04087025cab 907 int Sound::playMusicStream(char* filename, uint8_t options)
Pokitto 52:c04087025cab 908 {
Pokitto 52:c04087025cab 909 #if POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 910 uint8_t result;
Pokitto 52:c04087025cab 911 result = pokInitSD();
Pokitto 52:c04087025cab 912 if (!isThisFileOpen(filename)) {
Pokitto 52:c04087025cab 913 fileClose(); // close any open files
Pokitto 52:c04087025cab 914 result = fileOpen(filename,FILE_MODE_READONLY | FILE_MODE_BINARY);
Pokitto 52:c04087025cab 915 }
Pokitto 52:c04087025cab 916
Pokitto 52:c04087025cab 917 if (result) {
Pokitto 52:c04087025cab 918 currentPtr = 0; // mark that no stream is available
Pokitto 52:c04087025cab 919 return 0; // opening music file failed
Pokitto 52:c04087025cab 920 }
Pokitto 52:c04087025cab 921
Pokitto 52:c04087025cab 922 fileReadBytes(&buffers[0][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 923 fileReadBytes(&buffers[1][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 924 fileReadBytes(&buffers[2][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 925 fileReadBytes(&buffers[3][0],BUFFER_SIZE);
Pokitto 52:c04087025cab 926 currentBuffer = 0;
Pokitto 52:c04087025cab 927 currentPtr = buffers[currentBuffer];
Pokitto 52:c04087025cab 928 endPtr = currentPtr + BUFFER_SIZE;
Pokitto 52:c04087025cab 929
Pokitto 52:c04087025cab 930 //streaming = STR_PLAYING|options;
Pokitto 52:c04087025cab 931
Pokitto 52:c04087025cab 932 if (!options) pokPlayStream(); // activate stream
Pokitto 52:c04087025cab 933 #endif //POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 934 return 1; // opening music file succeeded
Pokitto 52:c04087025cab 935 }
Pokitto 52:c04087025cab 936
Pokitto 52:c04087025cab 937 uint32_t Sound::getMusicStreamElapsedSec() {
Pokitto 52:c04087025cab 938 #if POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 939 return streamcounter/POK_AUD_FREQ;
Pokitto 52:c04087025cab 940 #endif
Pokitto 52:c04087025cab 941 return 0;
Pokitto 52:c04087025cab 942 }
Pokitto 52:c04087025cab 943
Pokitto 52:c04087025cab 944 uint32_t Sound::getMusicStreamElapsedMilliSec() {
Pokitto 52:c04087025cab 945 #if POK_STREAMING_MUSIC
Pokitto 52:c04087025cab 946 return streamcounter/(POK_AUD_FREQ/1000);
Pokitto 52:c04087025cab 947 #endif
Pokitto 52:c04087025cab 948 return 0;
Pokitto 52:c04087025cab 949 }
Pokitto 52:c04087025cab 950