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:
Wed Oct 11 20:35:52 2017 +0000
Revision:
6:72f87b7c7400
Child:
11:aa12eb46aa02
Fixed PokittoLib to fully working. Includes mbed-src

Who changed what in which revision?

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