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:
Mon Apr 02 22:37:22 2018 +0000
Revision:
36:771321e70814
Synced with Github repo

Who changed what in which revision?

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