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:
Sat Mar 23 20:03:34 2019 +0000
Revision:
66:6281a40d73e6
Parent:
58:5f58a2846a20
Updated pokittolib to current embitz dev branch

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