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 18 20:20:09 2017 +0000
Revision:
12:162abc242b3a
Parent:
11:aa12eb46aa02
Speaker amp turn on fixed

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 11:aa12eb46aa02 254 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 255 soundInit();
Pokitto 12:162abc242b3a 256 ampEnable(true);
Pokitto 6:72f87b7c7400 257 #endif
Pokitto 6:72f87b7c7400 258 #if (NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 259 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 260 #if POK_GBSOUND > 0
Pokitto 6:72f87b7c7400 261 prescaler = 1;
Pokitto 6:72f87b7c7400 262 for(byte i=0; i<NUM_CHANNELS; i++){
Pokitto 6:72f87b7c7400 263 chanVolumes[i] = VOLUME_CHANNEL_MAX;
Pokitto 6:72f87b7c7400 264 changeInstrumentSet(defaultInstruments, i); //load default instruments. #0:square wave, #1: noise
Pokitto 6:72f87b7c7400 265 command(CMD_INSTRUMENT, 0, 0, i); //set the default instrument to square wave
Pokitto 6:72f87b7c7400 266 }
Pokitto 6:72f87b7c7400 267 #endif // POK_GBSOUND
Pokitto 6:72f87b7c7400 268 #endif //POK_ENABLE_SOUND
Pokitto 6:72f87b7c7400 269 #endif
Pokitto 6:72f87b7c7400 270 }
Pokitto 6:72f87b7c7400 271
Pokitto 6:72f87b7c7400 272 void Sound::playTrack(const uint16_t* track, uint8_t channel){
Pokitto 6:72f87b7c7400 273 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 274 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 275 return;
Pokitto 6:72f87b7c7400 276 stopTrack(channel);
Pokitto 6:72f87b7c7400 277 trackCursor[channel] = 0;
Pokitto 6:72f87b7c7400 278 trackData[channel] = (uint16_t*)track;
Pokitto 6:72f87b7c7400 279 trackIsPlaying[channel] = true;
Pokitto 6:72f87b7c7400 280 #endif
Pokitto 6:72f87b7c7400 281 }
Pokitto 6:72f87b7c7400 282
Pokitto 6:72f87b7c7400 283 void Sound::stopTrack(uint8_t channel){
Pokitto 6:72f87b7c7400 284 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 285 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 286 return;
Pokitto 6:72f87b7c7400 287 trackIsPlaying[channel] = false;
Pokitto 6:72f87b7c7400 288 stopPattern(channel);
Pokitto 6:72f87b7c7400 289 #endif
Pokitto 6:72f87b7c7400 290 }
Pokitto 6:72f87b7c7400 291
Pokitto 6:72f87b7c7400 292 void Sound::stopTrack(){
Pokitto 6:72f87b7c7400 293 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 294 for(uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 6:72f87b7c7400 295 stopTrack(i);
Pokitto 6:72f87b7c7400 296 }
Pokitto 6:72f87b7c7400 297 #endif
Pokitto 6:72f87b7c7400 298 }
Pokitto 6:72f87b7c7400 299
Pokitto 6:72f87b7c7400 300 void Sound::updateTrack(uint8_t channel){
Pokitto 6:72f87b7c7400 301 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 302 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 303 return;
Pokitto 6:72f87b7c7400 304 if(trackIsPlaying[channel] && !patternIsPlaying[channel]){
Pokitto 6:72f87b7c7400 305 uint16_t data = pgm_read_word(trackData[channel] + trackCursor[channel]);
Pokitto 6:72f87b7c7400 306 if(data == 0xFFFF){ //en of the track
Pokitto 6:72f87b7c7400 307 trackIsPlaying[channel] = false;
Pokitto 6:72f87b7c7400 308 return;
Pokitto 6:72f87b7c7400 309 }
Pokitto 6:72f87b7c7400 310 uint8_t patternID = data & 0xFF;
Pokitto 6:72f87b7c7400 311 data >>= 8;
Pokitto 6:72f87b7c7400 312 patternPitch[channel] = data;
Pokitto 6:72f87b7c7400 313 playPattern((const uint16_t*)pgm_read_word(&(patternSet[channel][patternID])), channel);
Pokitto 6:72f87b7c7400 314 trackCursor[channel] ++;
Pokitto 6:72f87b7c7400 315 }
Pokitto 6:72f87b7c7400 316 #endif
Pokitto 6:72f87b7c7400 317 }
Pokitto 6:72f87b7c7400 318
Pokitto 6:72f87b7c7400 319 void Sound::updateTrack(){
Pokitto 6:72f87b7c7400 320 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 321 for (uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 6:72f87b7c7400 322 updateTrack(i);
Pokitto 6:72f87b7c7400 323 }
Pokitto 6:72f87b7c7400 324 #endif
Pokitto 6:72f87b7c7400 325 }
Pokitto 6:72f87b7c7400 326
Pokitto 6:72f87b7c7400 327 void Sound::changePatternSet(const uint16_t* const* patterns, uint8_t channel){
Pokitto 6:72f87b7c7400 328 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 329 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 330 return;
Pokitto 6:72f87b7c7400 331 patternSet[channel] = (uint16_t**)patterns;
Pokitto 6:72f87b7c7400 332 #endif
Pokitto 6:72f87b7c7400 333 }
Pokitto 6:72f87b7c7400 334
Pokitto 6:72f87b7c7400 335 void Sound::playPattern(const uint16_t* pattern, uint8_t channel){
Pokitto 6:72f87b7c7400 336 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 337 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 338 return;
Pokitto 6:72f87b7c7400 339 stopPattern(channel);
Pokitto 6:72f87b7c7400 340 patternData[channel] = (uint16_t*)pattern;
Pokitto 6:72f87b7c7400 341 patternCursor[channel] = 0;
Pokitto 6:72f87b7c7400 342 patternIsPlaying[channel] = true;
Pokitto 6:72f87b7c7400 343 noteVolume[channel] = 9;
Pokitto 6:72f87b7c7400 344 //reinit commands
Pokitto 6:72f87b7c7400 345 volumeSlideStepDuration[channel] = 0;
Pokitto 6:72f87b7c7400 346 arpeggioStepDuration[channel] = 0;
Pokitto 6:72f87b7c7400 347 tremoloStepDuration[channel] = 0;
Pokitto 6:72f87b7c7400 348 #endif
Pokitto 6:72f87b7c7400 349 }
Pokitto 6:72f87b7c7400 350
Pokitto 6:72f87b7c7400 351 void Sound::updatePattern(){
Pokitto 6:72f87b7c7400 352 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 353 for (uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 6:72f87b7c7400 354 updatePattern(i);
Pokitto 6:72f87b7c7400 355 }
Pokitto 6:72f87b7c7400 356 #endif
Pokitto 6:72f87b7c7400 357 }
Pokitto 6:72f87b7c7400 358
Pokitto 6:72f87b7c7400 359 void Sound::changeInstrumentSet(const uint16_t* const* instruments, uint8_t channel){
Pokitto 6:72f87b7c7400 360 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 361 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 362 return;
Pokitto 6:72f87b7c7400 363 instrumentSet[channel] = (uint16_t**)instruments;
Pokitto 6:72f87b7c7400 364 #endif
Pokitto 6:72f87b7c7400 365 }
Pokitto 6:72f87b7c7400 366
Pokitto 6:72f87b7c7400 367 void Sound::updatePattern(uint8_t i){
Pokitto 6:72f87b7c7400 368 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 369 if(i>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 370 return;
Pokitto 6:72f87b7c7400 371 if(patternIsPlaying[i]){
Pokitto 6:72f87b7c7400 372 if(noteDuration[i]==0){//if the end of the previous note is reached
Pokitto 6:72f87b7c7400 373
Pokitto 6:72f87b7c7400 374 uint16_t data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 6:72f87b7c7400 375
Pokitto 6:72f87b7c7400 376 if(data == 0){ //end of the pattern reached
Pokitto 6:72f87b7c7400 377 if(patternLooping[i] == true){
Pokitto 6:72f87b7c7400 378 patternCursor[i] = 0;
Pokitto 6:72f87b7c7400 379 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 6:72f87b7c7400 380 }
Pokitto 6:72f87b7c7400 381 else{
Pokitto 6:72f87b7c7400 382 patternIsPlaying[i] = false;
Pokitto 6:72f87b7c7400 383 if(trackIsPlaying[i]){ //if this pattern is part of a track, get the next pattern
Pokitto 6:72f87b7c7400 384 updateTrack(i);
Pokitto 6:72f87b7c7400 385 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 6:72f87b7c7400 386 } else {
Pokitto 6:72f87b7c7400 387 stopNote(i);
Pokitto 6:72f87b7c7400 388 //Serial.print("pattern end\n");
Pokitto 6:72f87b7c7400 389 return;
Pokitto 6:72f87b7c7400 390 }
Pokitto 6:72f87b7c7400 391 }
Pokitto 6:72f87b7c7400 392 }
Pokitto 6:72f87b7c7400 393
Pokitto 6:72f87b7c7400 394 while (data & 0x0001){ //read all commands and instrument changes
Pokitto 6:72f87b7c7400 395 data >>= 2;
Pokitto 6:72f87b7c7400 396 //Serial.print("\ncmd\t");
Pokitto 6:72f87b7c7400 397 uint8_t cmd = data & 0x0F;
Pokitto 6:72f87b7c7400 398 data >>= 4;
Pokitto 6:72f87b7c7400 399 uint8_t X = data & 0x1F;
Pokitto 6:72f87b7c7400 400 data >>= 5;
Pokitto 6:72f87b7c7400 401 int8_t Y = data - 16;
Pokitto 6:72f87b7c7400 402 command(cmd,X,Y,i);
Pokitto 6:72f87b7c7400 403 patternCursor[i]++;
Pokitto 6:72f87b7c7400 404 data = pgm_read_word(patternCursor[i] + patternData[i]);
Pokitto 6:72f87b7c7400 405 }
Pokitto 6:72f87b7c7400 406 data >>= 2;
Pokitto 6:72f87b7c7400 407
Pokitto 6:72f87b7c7400 408 uint8_t pitch = data & 0x003F;
Pokitto 6:72f87b7c7400 409 data >>= 6;
Pokitto 6:72f87b7c7400 410
Pokitto 6:72f87b7c7400 411 uint8_t duration = data;
Pokitto 6:72f87b7c7400 412 if(pitch != 63){
Pokitto 6:72f87b7c7400 413 }
Pokitto 6:72f87b7c7400 414
Pokitto 6:72f87b7c7400 415 playNote(pitch, duration, i);
Pokitto 6:72f87b7c7400 416
Pokitto 6:72f87b7c7400 417 patternCursor[i]++;
Pokitto 6:72f87b7c7400 418 }
Pokitto 6:72f87b7c7400 419 }
Pokitto 6:72f87b7c7400 420 #endif
Pokitto 6:72f87b7c7400 421 }
Pokitto 6:72f87b7c7400 422
Pokitto 6:72f87b7c7400 423 void Sound::stopPattern(uint8_t channel){
Pokitto 6:72f87b7c7400 424 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 425 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 426 return;
Pokitto 6:72f87b7c7400 427 stopNote(channel);
Pokitto 6:72f87b7c7400 428 patternIsPlaying[channel] = false;
Pokitto 6:72f87b7c7400 429 #endif
Pokitto 6:72f87b7c7400 430 }
Pokitto 6:72f87b7c7400 431
Pokitto 6:72f87b7c7400 432 void Sound::stopPattern(){
Pokitto 6:72f87b7c7400 433 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 434 for(uint8_t i=0; i<NUM_CHANNELS; i++){
Pokitto 6:72f87b7c7400 435 stopPattern(i);
Pokitto 6:72f87b7c7400 436 }
Pokitto 6:72f87b7c7400 437 #endif
Pokitto 6:72f87b7c7400 438 }
Pokitto 6:72f87b7c7400 439
Pokitto 6:72f87b7c7400 440 void Sound::command(uint8_t cmd, uint8_t X, int8_t Y, uint8_t i){
Pokitto 6:72f87b7c7400 441 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 442 if(i>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 443 return;
Pokitto 6:72f87b7c7400 444 switch(cmd){
Pokitto 6:72f87b7c7400 445 case CMD_VOLUME: //volume
Pokitto 6:72f87b7c7400 446 X = constrain((int8_t)X, 0, 10);
Pokitto 6:72f87b7c7400 447 noteVolume[i] = X;
Pokitto 6:72f87b7c7400 448 break;
Pokitto 6:72f87b7c7400 449 case CMD_INSTRUMENT: //instrument
Pokitto 6:72f87b7c7400 450 instrumentData[i] = (uint16_t*)pgm_read_word(&(instrumentSet[i][X]));
Pokitto 6:72f87b7c7400 451 instrumentLength[i] = pgm_read_word(&(instrumentData[i][0])) & 0x00FF; //8 LSB
Pokitto 6:72f87b7c7400 452 instrumentLength[i] *= prescaler;
Pokitto 6:72f87b7c7400 453 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 454 instrumentLooping[i] *= prescaler;
Pokitto 6:72f87b7c7400 455 break;
Pokitto 6:72f87b7c7400 456 case CMD_SLIDE: //volume slide
Pokitto 6:72f87b7c7400 457 volumeSlideStepDuration[i] = X * prescaler;
Pokitto 6:72f87b7c7400 458 volumeSlideStepSize[i] = Y;
Pokitto 6:72f87b7c7400 459 break;
Pokitto 6:72f87b7c7400 460 case CMD_ARPEGGIO:
Pokitto 6:72f87b7c7400 461 arpeggioStepDuration[i] = X * prescaler;
Pokitto 6:72f87b7c7400 462 arpeggioStepSize[i] = Y;
Pokitto 6:72f87b7c7400 463 break;
Pokitto 6:72f87b7c7400 464 case CMD_TREMOLO:
Pokitto 6:72f87b7c7400 465 tremoloStepDuration[i] = X * prescaler;
Pokitto 6:72f87b7c7400 466 tremoloStepSize[i] = Y;
Pokitto 6:72f87b7c7400 467 break;
Pokitto 6:72f87b7c7400 468 default:
Pokitto 6:72f87b7c7400 469 break;
Pokitto 6:72f87b7c7400 470 }
Pokitto 6:72f87b7c7400 471 #endif
Pokitto 6:72f87b7c7400 472 }
Pokitto 6:72f87b7c7400 473
Pokitto 6:72f87b7c7400 474 void Sound::playNote(uint8_t pitch, uint8_t duration, uint8_t channel){
Pokitto 6:72f87b7c7400 475 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 476 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 477 return;
Pokitto 6:72f87b7c7400 478 //set note
Pokitto 6:72f87b7c7400 479 notePitch[channel] = pitch;
Pokitto 6:72f87b7c7400 480 noteDuration[channel] = duration * prescaler;
Pokitto 6:72f87b7c7400 481 //reinit vars
Pokitto 6:72f87b7c7400 482 instrumentNextChange[channel] = 0;
Pokitto 6:72f87b7c7400 483 instrumentCursor[channel] = 0;
Pokitto 6:72f87b7c7400 484 notePlaying[channel] = true;
Pokitto 6:72f87b7c7400 485 _chanState[channel] = true;
Pokitto 6:72f87b7c7400 486 commandsCounter[channel] = 0;
Pokitto 6:72f87b7c7400 487 #endif
Pokitto 6:72f87b7c7400 488 }
Pokitto 6:72f87b7c7400 489
Pokitto 6:72f87b7c7400 490 void Sound::stopNote(uint8_t channel) {
Pokitto 6:72f87b7c7400 491 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 492 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 493 return;
Pokitto 6:72f87b7c7400 494 notePlaying[channel] = false;
Pokitto 6:72f87b7c7400 495 //counters
Pokitto 6:72f87b7c7400 496 noteDuration[channel] = 0;
Pokitto 6:72f87b7c7400 497 instrumentCursor[channel] = 0;
Pokitto 6:72f87b7c7400 498 commandsCounter[channel] = 0;
Pokitto 6:72f87b7c7400 499 //output
Pokitto 6:72f87b7c7400 500 _chanOutput[channel] = 0;
Pokitto 6:72f87b7c7400 501 _chanOutputVolume[channel] = 0;
Pokitto 6:72f87b7c7400 502 _chanState[channel] = false;
Pokitto 6:72f87b7c7400 503 updateOutput();
Pokitto 6:72f87b7c7400 504 #endif
Pokitto 6:72f87b7c7400 505 }
Pokitto 6:72f87b7c7400 506
Pokitto 6:72f87b7c7400 507 void Sound::stopNote() {
Pokitto 6:72f87b7c7400 508 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 509 for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) {
Pokitto 6:72f87b7c7400 510 stopNote(channel);
Pokitto 6:72f87b7c7400 511 }
Pokitto 6:72f87b7c7400 512 #endif
Pokitto 6:72f87b7c7400 513 }
Pokitto 6:72f87b7c7400 514
Pokitto 6:72f87b7c7400 515 void Sound::updateNote() {
Pokitto 6:72f87b7c7400 516 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 517 for (uint8_t i = 0; i < NUM_CHANNELS; i++) {
Pokitto 6:72f87b7c7400 518 updateNote(i);
Pokitto 6:72f87b7c7400 519 }
Pokitto 6:72f87b7c7400 520 #endif
Pokitto 6:72f87b7c7400 521 }
Pokitto 6:72f87b7c7400 522
Pokitto 6:72f87b7c7400 523 void Sound::updateNote(uint8_t i) {
Pokitto 6:72f87b7c7400 524 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 525 if(i>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 526 return;
Pokitto 6:72f87b7c7400 527 if (notePlaying[i]) {
Pokitto 6:72f87b7c7400 528
Pokitto 6:72f87b7c7400 529 if(noteDuration[i] == 0){
Pokitto 6:72f87b7c7400 530 stopNote(i);
Pokitto 6:72f87b7c7400 531 //Serial.println("note end");
Pokitto 6:72f87b7c7400 532 return;
Pokitto 6:72f87b7c7400 533 } else {
Pokitto 6:72f87b7c7400 534 noteDuration[i]--;
Pokitto 6:72f87b7c7400 535 }
Pokitto 6:72f87b7c7400 536
Pokitto 6:72f87b7c7400 537 if (instrumentNextChange[i] == 0) {
Pokitto 6:72f87b7c7400 538
Pokitto 6:72f87b7c7400 539 //read the step data from the progmem and decode it
Pokitto 6:72f87b7c7400 540 uint16_t thisStep = pgm_read_word(&(instrumentData[i][1 + instrumentCursor[i]]));
Pokitto 6:72f87b7c7400 541
Pokitto 6:72f87b7c7400 542 stepVolume[i] = thisStep & 0x0007;
Pokitto 6:72f87b7c7400 543 thisStep >>= 3;
Pokitto 6:72f87b7c7400 544
Pokitto 6:72f87b7c7400 545 uint8_t stepNoise = thisStep & 0x0001;
Pokitto 6:72f87b7c7400 546 thisStep >>= 1;
Pokitto 6:72f87b7c7400 547
Pokitto 6:72f87b7c7400 548 uint8_t stepDuration = thisStep & 0x003F;
Pokitto 6:72f87b7c7400 549 thisStep >>= 6;
Pokitto 6:72f87b7c7400 550
Pokitto 6:72f87b7c7400 551 stepPitch[i] = thisStep;
Pokitto 6:72f87b7c7400 552
Pokitto 6:72f87b7c7400 553 //apply the step settings
Pokitto 6:72f87b7c7400 554 instrumentNextChange[i] = stepDuration * prescaler;
Pokitto 6:72f87b7c7400 555
Pokitto 6:72f87b7c7400 556 _chanNoise[i] = stepNoise;
Pokitto 6:72f87b7c7400 557
Pokitto 6:72f87b7c7400 558
Pokitto 6:72f87b7c7400 559 instrumentCursor[i]++;
Pokitto 6:72f87b7c7400 560
Pokitto 6:72f87b7c7400 561 if (instrumentCursor[i] >= instrumentLength[i]) {
Pokitto 6:72f87b7c7400 562 if (instrumentLooping[i]) {
Pokitto 6:72f87b7c7400 563 instrumentCursor[i] = instrumentLength[i] - instrumentLooping[i];
Pokitto 6:72f87b7c7400 564 } else {
Pokitto 6:72f87b7c7400 565 stopNote(i);
Pokitto 6:72f87b7c7400 566 }
Pokitto 6:72f87b7c7400 567 }
Pokitto 6:72f87b7c7400 568 }
Pokitto 6:72f87b7c7400 569 instrumentNextChange[i]--;
Pokitto 6:72f87b7c7400 570
Pokitto 6:72f87b7c7400 571 commandsCounter[i]++;
Pokitto 6:72f87b7c7400 572
Pokitto 6:72f87b7c7400 573 //UPDATE VALUES
Pokitto 6:72f87b7c7400 574 //pitch
Pokitto 6:72f87b7c7400 575 outputPitch[i] = notePitch[i] + stepPitch[i] + patternPitch[i];
Pokitto 6:72f87b7c7400 576 if(arpeggioStepDuration[i]){
Pokitto 6:72f87b7c7400 577 outputPitch[i] += commandsCounter[i] / arpeggioStepDuration[i] * arpeggioStepSize[i];
Pokitto 6:72f87b7c7400 578 }
Pokitto 6:72f87b7c7400 579 outputPitch[i] = (outputPitch[i] + NUM_PITCH) % NUM_PITCH; //wrap
Pokitto 6:72f87b7c7400 580 //volume
Pokitto 6:72f87b7c7400 581 outputVolume[i] = noteVolume[i];
Pokitto 6:72f87b7c7400 582 if(volumeSlideStepDuration[i]){
Pokitto 6:72f87b7c7400 583 outputVolume[i] += commandsCounter[i] / volumeSlideStepDuration[i] * volumeSlideStepSize[i];
Pokitto 6:72f87b7c7400 584 }
Pokitto 6:72f87b7c7400 585 if(tremoloStepDuration[i]){
Pokitto 6:72f87b7c7400 586 outputVolume[i] += ((commandsCounter[i]/tremoloStepDuration[i]) % 2) * tremoloStepSize[i];
Pokitto 6:72f87b7c7400 587 }
Pokitto 6:72f87b7c7400 588 outputVolume[i] = constrain(outputVolume[i], 0, 9);
Pokitto 6:72f87b7c7400 589 if(notePitch[i] == 63){
Pokitto 6:72f87b7c7400 590 outputVolume[i] = 0;
Pokitto 6:72f87b7c7400 591 }
Pokitto 6:72f87b7c7400 592 // jonnehw noInterrupts();
Pokitto 6:72f87b7c7400 593 _chanHalfPeriod[i] = pgm_read_byte(_halfPeriods + outputPitch[i]);
Pokitto 6:72f87b7c7400 594 _chanOutput[i] = _chanOutputVolume[i] = outputVolume[i] * (globalVolume>>GLOBVOL_SHIFT) * chanVolumes[i] * stepVolume[i];
Pokitto 6:72f87b7c7400 595 //Serial.println(outputVolume[i]);
Pokitto 6:72f87b7c7400 596 // jonnehw interrupts();
Pokitto 6:72f87b7c7400 597 }
Pokitto 6:72f87b7c7400 598 #endif
Pokitto 6:72f87b7c7400 599 }
Pokitto 6:72f87b7c7400 600
Pokitto 6:72f87b7c7400 601 void Sound::setChannelHalfPeriod(uint8_t channel, uint8_t halfPeriod) {
Pokitto 6:72f87b7c7400 602 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 603 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 604 return;
Pokitto 6:72f87b7c7400 605 _chanHalfPeriod[channel] = halfPeriod;
Pokitto 6:72f87b7c7400 606 _chanState[channel] = false;
Pokitto 6:72f87b7c7400 607 _chanCount[channel] = 0;
Pokitto 6:72f87b7c7400 608 updateOutput();
Pokitto 6:72f87b7c7400 609 #endif
Pokitto 6:72f87b7c7400 610 }
Pokitto 6:72f87b7c7400 611
Pokitto 6:72f87b7c7400 612
Pokitto 6:72f87b7c7400 613 void Sound::generateOutput() {
Pokitto 6:72f87b7c7400 614 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 615 bool outputChanged = false;
Pokitto 6:72f87b7c7400 616 //no for loop here, for the performance sake (this function runs 15 000 times per second...)
Pokitto 6:72f87b7c7400 617 //CHANNEL 0
Pokitto 6:72f87b7c7400 618 if (_chanOutputVolume[0]) {
Pokitto 6:72f87b7c7400 619 _chanCount[0]++;
Pokitto 6:72f87b7c7400 620 if (_chanCount[0] >= _chanHalfPeriod[0]) {
Pokitto 6:72f87b7c7400 621 outputChanged = true;
Pokitto 6:72f87b7c7400 622 _chanState[0] = !_chanState[0];
Pokitto 6:72f87b7c7400 623 _chanCount[0] = 0;
Pokitto 6:72f87b7c7400 624 if (_chanNoise[0]) {
Pokitto 6:72f87b7c7400 625 _rand = 67 * _rand + 71;
Pokitto 6:72f87b7c7400 626 _chanOutput[0] = _rand % _chanOutputVolume[0];
Pokitto 6:72f87b7c7400 627 }
Pokitto 6:72f87b7c7400 628 }
Pokitto 6:72f87b7c7400 629 }
Pokitto 6:72f87b7c7400 630
Pokitto 6:72f87b7c7400 631
Pokitto 6:72f87b7c7400 632 //CHANNEL 1
Pokitto 6:72f87b7c7400 633 #if (NUM_CHANNELS > 1)
Pokitto 6:72f87b7c7400 634 if (_chanOutputVolume[1]) {
Pokitto 6:72f87b7c7400 635 _chanCount[1]++;
Pokitto 6:72f87b7c7400 636 if (_chanCount[1] >= _chanHalfPeriod[1]) {
Pokitto 6:72f87b7c7400 637 outputChanged = true;
Pokitto 6:72f87b7c7400 638 _chanState[1] = !_chanState[1];
Pokitto 6:72f87b7c7400 639 _chanCount[1] = 0;
Pokitto 6:72f87b7c7400 640 if (_chanNoise[1]) {
Pokitto 6:72f87b7c7400 641 _rand = 67 * _rand + 71;
Pokitto 6:72f87b7c7400 642 _chanOutput[1] = _rand % _chanOutputVolume[1];
Pokitto 6:72f87b7c7400 643 }
Pokitto 6:72f87b7c7400 644 }
Pokitto 6:72f87b7c7400 645 }
Pokitto 6:72f87b7c7400 646 #endif
Pokitto 6:72f87b7c7400 647
Pokitto 6:72f87b7c7400 648 //CHANNEL 2
Pokitto 6:72f87b7c7400 649 #if (NUM_CHANNELS > 2)
Pokitto 6:72f87b7c7400 650 if (_chanOutputVolume[2]) {
Pokitto 6:72f87b7c7400 651 _chanCount[2]++;
Pokitto 6:72f87b7c7400 652 if (_chanCount[2] >= _chanHalfPeriod[2]) {
Pokitto 6:72f87b7c7400 653 outputChanged = true;
Pokitto 6:72f87b7c7400 654 _chanState[2] = !_chanState[2];
Pokitto 6:72f87b7c7400 655 _chanCount[2] = 0;
Pokitto 6:72f87b7c7400 656 if (_chanNoise[2]) {
Pokitto 6:72f87b7c7400 657 _rand = 67 * _rand + 71;
Pokitto 6:72f87b7c7400 658 _chanOutput[2] = _rand % _chanOutputVolume[2];
Pokitto 6:72f87b7c7400 659 }
Pokitto 6:72f87b7c7400 660 }
Pokitto 6:72f87b7c7400 661 }
Pokitto 6:72f87b7c7400 662 #endif
Pokitto 6:72f87b7c7400 663
Pokitto 6:72f87b7c7400 664 //CHANNEL 3
Pokitto 6:72f87b7c7400 665 #if (NUM_CHANNELS > 3)
Pokitto 6:72f87b7c7400 666 if (_chanOutputVolume[3]) {
Pokitto 6:72f87b7c7400 667 _chanCount[3]++;
Pokitto 6:72f87b7c7400 668 if (_chanCount[3] >= _chanHalfPeriod[3]) {
Pokitto 6:72f87b7c7400 669 outputChanged = true;
Pokitto 6:72f87b7c7400 670 _chanState[3] = !_chanState[3];
Pokitto 6:72f87b7c7400 671 _chanCount[3] = 0;
Pokitto 6:72f87b7c7400 672 if (_chanNoise[3]) {
Pokitto 6:72f87b7c7400 673 _rand = 67 * _rand + 71;
Pokitto 6:72f87b7c7400 674 _chanOutput[3] = _rand % _chanOutputVolume[3];
Pokitto 6:72f87b7c7400 675 }
Pokitto 6:72f87b7c7400 676 }
Pokitto 6:72f87b7c7400 677 }
Pokitto 6:72f87b7c7400 678 #endif
Pokitto 6:72f87b7c7400 679
Pokitto 6:72f87b7c7400 680 #if POK_STREAMING_MUSIC
Pokitto 6:72f87b7c7400 681 if (streamstep) {
Pokitto 6:72f87b7c7400 682 outputChanged=true;
Pokitto 6:72f87b7c7400 683 }
Pokitto 6:72f87b7c7400 684 #endif
Pokitto 6:72f87b7c7400 685
Pokitto 6:72f87b7c7400 686 if (outputChanged) {
Pokitto 6:72f87b7c7400 687 updateOutput();
Pokitto 6:72f87b7c7400 688 }
Pokitto 6:72f87b7c7400 689 #endif
Pokitto 6:72f87b7c7400 690 }
Pokitto 6:72f87b7c7400 691
Pokitto 6:72f87b7c7400 692 void Sound::updateOutput() {
Pokitto 6:72f87b7c7400 693 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 694 uint8_t output = 0;
Pokitto 6:72f87b7c7400 695
Pokitto 6:72f87b7c7400 696 //CHANNEL 0
Pokitto 6:72f87b7c7400 697 if (_chanState[0]) {
Pokitto 6:72f87b7c7400 698 output += _chanOutput[0];
Pokitto 6:72f87b7c7400 699 }
Pokitto 6:72f87b7c7400 700
Pokitto 6:72f87b7c7400 701 //CHANNEL 1
Pokitto 6:72f87b7c7400 702 #if (NUM_CHANNELS > 1)
Pokitto 6:72f87b7c7400 703 if (_chanState[1]) {
Pokitto 6:72f87b7c7400 704 output += _chanOutput[1];
Pokitto 6:72f87b7c7400 705 }
Pokitto 6:72f87b7c7400 706 #endif
Pokitto 6:72f87b7c7400 707
Pokitto 6:72f87b7c7400 708 //CHANNEL 2
Pokitto 6:72f87b7c7400 709 #if (NUM_CHANNELS > 2)
Pokitto 6:72f87b7c7400 710 if (_chanState[2]) {
Pokitto 6:72f87b7c7400 711 output += _chanOutput[2];
Pokitto 6:72f87b7c7400 712 }
Pokitto 6:72f87b7c7400 713 #endif
Pokitto 6:72f87b7c7400 714
Pokitto 6:72f87b7c7400 715 //CHANNEL 3
Pokitto 6:72f87b7c7400 716 #if (NUM_CHANNELS > 3)
Pokitto 6:72f87b7c7400 717 if (_chanState[3]) {
Pokitto 6:72f87b7c7400 718 output += _chanOutput[3];
Pokitto 6:72f87b7c7400 719 }
Pokitto 6:72f87b7c7400 720 #endif
Pokitto 6:72f87b7c7400 721
Pokitto 6:72f87b7c7400 722 #ifndef POK_SIM
Pokitto 6:72f87b7c7400 723 #if POK_ENABLE_SOUND
Pokitto 6:72f87b7c7400 724 /** HARDWARE **/
Pokitto 6:72f87b7c7400 725
Pokitto 6:72f87b7c7400 726 #if POK_STREAMING_MUSIC
Pokitto 6:72f87b7c7400 727 if (streamstep) {
Pokitto 6:72f87b7c7400 728 pwmout_write(&audiopwm,(float)sbyte/(float)255);
Pokitto 6:72f87b7c7400 729 }
Pokitto 6:72f87b7c7400 730 #endif
Pokitto 6:72f87b7c7400 731 dac_write((uint8_t)output); //direct hardware mixing baby !
Pokitto 6:72f87b7c7400 732 soundbyte = output;
Pokitto 6:72f87b7c7400 733 #endif //POK_ENABLE_SOUND
Pokitto 6:72f87b7c7400 734 #else
Pokitto 6:72f87b7c7400 735 /** SIMULATOR **/
Pokitto 6:72f87b7c7400 736 #if POK_STREAMING_MUSIC
Pokitto 6:72f87b7c7400 737 if (streamstep) {
Pokitto 6:72f87b7c7400 738 uint16_t o = output + sbyte;
Pokitto 6:72f87b7c7400 739 output = o/2;
Pokitto 6:72f87b7c7400 740 }
Pokitto 6:72f87b7c7400 741 #endif
Pokitto 6:72f87b7c7400 742 soundbyte = output;
Pokitto 6:72f87b7c7400 743 #endif // POK_SIM
Pokitto 6:72f87b7c7400 744 #endif
Pokitto 6:72f87b7c7400 745 }
Pokitto 6:72f87b7c7400 746
Pokitto 6:72f87b7c7400 747 void Sound::setPatternLooping(bool loop, uint8_t channel) {
Pokitto 6:72f87b7c7400 748 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 749 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 750 return;
Pokitto 6:72f87b7c7400 751 patternLooping[channel] = loop;
Pokitto 6:72f87b7c7400 752 #endif
Pokitto 6:72f87b7c7400 753 }
Pokitto 6:72f87b7c7400 754
Pokitto 6:72f87b7c7400 755 void Sound::playOK(){
Pokitto 6:72f87b7c7400 756 #if POK_GBSOUND
Pokitto 6:72f87b7c7400 757 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 758 playPattern(playOKPattern,0);
Pokitto 6:72f87b7c7400 759 #endif
Pokitto 6:72f87b7c7400 760 #endif // POK_GBSOUND
Pokitto 6:72f87b7c7400 761 }
Pokitto 6:72f87b7c7400 762
Pokitto 6:72f87b7c7400 763 void Sound::playCancel(){
Pokitto 6:72f87b7c7400 764 #if POK_GBSOUND
Pokitto 6:72f87b7c7400 765 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 766 playPattern(playCancelPattern,0);
Pokitto 6:72f87b7c7400 767 #endif
Pokitto 6:72f87b7c7400 768 #endif
Pokitto 6:72f87b7c7400 769 }
Pokitto 6:72f87b7c7400 770
Pokitto 6:72f87b7c7400 771 void Sound::playTick(){
Pokitto 6:72f87b7c7400 772 #if POK_GBSOUND
Pokitto 6:72f87b7c7400 773 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 774 playPattern(playTickP,0);
Pokitto 6:72f87b7c7400 775 #endif
Pokitto 6:72f87b7c7400 776 #endif // POK_GBSOUND
Pokitto 6:72f87b7c7400 777 }
Pokitto 6:72f87b7c7400 778
Pokitto 6:72f87b7c7400 779 void Sound::setVolume(int16_t volume) {
Pokitto 6:72f87b7c7400 780 //#if NUM_CHANNELS > 0
Pokitto 6:72f87b7c7400 781 if (volume<0) volume = 0;
Pokitto 6:72f87b7c7400 782 if (volume>volumeMax) volume = volumeMax;
Pokitto 6:72f87b7c7400 783 globalVolume = volume; // % (volumeMax+1);
Pokitto 6:72f87b7c7400 784 #ifndef POK_SIM
Pokitto 6:72f87b7c7400 785 volume = (volume / 2)-10;
Pokitto 6:72f87b7c7400 786 if (volume<0) volume = 0;
Pokitto 12:162abc242b3a 787 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 788 setHWvolume(volume);
Pokitto 6:72f87b7c7400 789 #endif
Pokitto 6:72f87b7c7400 790 #endif
Pokitto 6:72f87b7c7400 791 #if POK_SHOW_VOLUME > 0
Pokitto 6:72f87b7c7400 792 c.volbar_visible = VOLUMEBAR_TIMEOUT;
Pokitto 6:72f87b7c7400 793 #endif
Pokitto 6:72f87b7c7400 794 //#endif
Pokitto 6:72f87b7c7400 795 }
Pokitto 6:72f87b7c7400 796
Pokitto 6:72f87b7c7400 797 uint16_t Sound::getVolume() {
Pokitto 6:72f87b7c7400 798 //#if NUM_CHANNELS > 0
Pokitto 6:72f87b7c7400 799 return globalVolume;
Pokitto 6:72f87b7c7400 800 //#else
Pokitto 6:72f87b7c7400 801 // return 0;
Pokitto 6:72f87b7c7400 802 //#endif
Pokitto 6:72f87b7c7400 803 }
Pokitto 6:72f87b7c7400 804
Pokitto 6:72f87b7c7400 805 void Sound::setVolume(int8_t volume, uint8_t channel) {
Pokitto 6:72f87b7c7400 806 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 807 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 808 return;
Pokitto 6:72f87b7c7400 809 volume = (volume > VOLUME_CHANNEL_MAX) ? VOLUME_CHANNEL_MAX : volume;
Pokitto 6:72f87b7c7400 810 volume = (volume < 0) ? 0 : volume;
Pokitto 6:72f87b7c7400 811 chanVolumes[channel] = volume;
Pokitto 6:72f87b7c7400 812 #endif
Pokitto 6:72f87b7c7400 813 }
Pokitto 6:72f87b7c7400 814
Pokitto 6:72f87b7c7400 815 uint8_t Sound::getVolume(uint8_t channel) {
Pokitto 6:72f87b7c7400 816 #if(NUM_CHANNELS > 0)
Pokitto 6:72f87b7c7400 817 if(channel>=NUM_CHANNELS)
Pokitto 6:72f87b7c7400 818 return 255;
Pokitto 6:72f87b7c7400 819 return (chanVolumes[channel]);
Pokitto 6:72f87b7c7400 820 #else
Pokitto 6:72f87b7c7400 821 return 0;
Pokitto 6:72f87b7c7400 822 #endif
Pokitto 6:72f87b7c7400 823 }
Pokitto 6:72f87b7c7400 824
Pokitto 6:72f87b7c7400 825 void Sound::playTone(uint8_t os, int frq, uint8_t amp, uint8_t wav,uint8_t arpmode)
Pokitto 6:72f87b7c7400 826 {
Pokitto 6:72f87b7c7400 827 if (wav>5) wav=0;
Pokitto 6:72f87b7c7400 828 if (arpmode>MAX_ARPMODE) arpmode=MAX_ARPMODE;
Pokitto 6:72f87b7c7400 829 if (os==1) setOSC(&osc1,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0);
Pokitto 6:72f87b7c7400 830 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 831 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 832 }
Pokitto 6:72f87b7c7400 833
Pokitto 6:72f87b7c7400 834 void Sound::playTone(uint8_t os, uint16_t frq, uint8_t volume, uint32_t duration)
Pokitto 6:72f87b7c7400 835 {
Pokitto 6:72f87b7c7400 836 if (os==1) setOSC(&osc1,1,WSAW,frq,volume,duration);
Pokitto 6:72f87b7c7400 837 else if (os==2) setOSC(&osc2,1,WTRI,frq,volume,duration);
Pokitto 6:72f87b7c7400 838 else if (os==3) setOSC(&osc3,1,WTRI,frq,volume,duration);
Pokitto 6:72f87b7c7400 839 }
Pokitto 6:72f87b7c7400 840
Pokitto 6:72f87b7c7400 841 uint8_t Sound::ampIsOn()
Pokitto 6:72f87b7c7400 842 {
Pokitto 6:72f87b7c7400 843 #ifdef POK_SIM
Pokitto 6:72f87b7c7400 844 return core.ampIsOn();
Pokitto 6:72f87b7c7400 845 #else
Pokitto 12:162abc242b3a 846 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 847 return Pokitto::ampIsOn();
Pokitto 6:72f87b7c7400 848 #endif
Pokitto 6:72f87b7c7400 849 #endif // POK_SIM
Pokitto 6:72f87b7c7400 850 return 0;
Pokitto 6:72f87b7c7400 851 }
Pokitto 6:72f87b7c7400 852
Pokitto 6:72f87b7c7400 853 void Sound::ampEnable(uint8_t v) {
Pokitto 6:72f87b7c7400 854 #ifdef POK_SIM
Pokitto 6:72f87b7c7400 855 core.ampEnable(v);
Pokitto 6:72f87b7c7400 856 #else
Pokitto 12:162abc242b3a 857 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 858 Pokitto::ampEnable(v);
Pokitto 6:72f87b7c7400 859 #endif
Pokitto 6:72f87b7c7400 860 #endif // POK_SIM
Pokitto 6:72f87b7c7400 861
Pokitto 6:72f87b7c7400 862 }
Pokitto 6:72f87b7c7400 863
Pokitto 6:72f87b7c7400 864 int Sound::playMusicStream(char* filename)
Pokitto 6:72f87b7c7400 865 {
Pokitto 6:72f87b7c7400 866 return playMusicStream(filename,0);
Pokitto 6:72f87b7c7400 867 }
Pokitto 6:72f87b7c7400 868
Pokitto 6:72f87b7c7400 869 int Sound::playMusicStream()
Pokitto 6:72f87b7c7400 870 {
Pokitto 6:72f87b7c7400 871 #if POK_STREAMING_MUSIC >0
Pokitto 6:72f87b7c7400 872 if (currentPtr) {
Pokitto 6:72f87b7c7400 873 pokPlayStream();
Pokitto 6:72f87b7c7400 874 return 1;
Pokitto 6:72f87b7c7400 875 } else return 0; //no stream
Pokitto 6:72f87b7c7400 876 #endif // POK_STREAMING_MUSIC
Pokitto 6:72f87b7c7400 877 }
Pokitto 6:72f87b7c7400 878
Pokitto 6:72f87b7c7400 879 void Sound::pauseMusicStream() {
Pokitto 12:162abc242b3a 880 #if POK_ENABLE_SOUND > 0
Pokitto 6:72f87b7c7400 881 pokPauseStream();
Pokitto 6:72f87b7c7400 882 #endif
Pokitto 6:72f87b7c7400 883 }
Pokitto 6:72f87b7c7400 884
Pokitto 6:72f87b7c7400 885 int Sound::playMusicStream(char* filename, uint8_t options)
Pokitto 6:72f87b7c7400 886 {
Pokitto 6:72f87b7c7400 887 #if POK_STREAMING_MUSIC
Pokitto 6:72f87b7c7400 888 uint8_t result;
Pokitto 6:72f87b7c7400 889 result = pokInitSD();
Pokitto 6:72f87b7c7400 890 if (!isThisFileOpen(filename)) {
Pokitto 6:72f87b7c7400 891 fileClose(); // close any open files
Pokitto 6:72f87b7c7400 892 result = fileOpen(filename,FILE_MODE_OVERWRITE | FILE_MODE_BINARY);
Pokitto 6:72f87b7c7400 893 }
Pokitto 6:72f87b7c7400 894
Pokitto 6:72f87b7c7400 895 if (result) {
Pokitto 6:72f87b7c7400 896 currentPtr = 0; // mark that no stream is available
Pokitto 6:72f87b7c7400 897 return 0; // opening music file failed
Pokitto 6:72f87b7c7400 898 }
Pokitto 6:72f87b7c7400 899
Pokitto 6:72f87b7c7400 900 fileReadBytes(&buffers[0][0],BUFFER_SIZE);
Pokitto 6:72f87b7c7400 901 fileReadBytes(&buffers[1][0],BUFFER_SIZE);
Pokitto 6:72f87b7c7400 902 fileReadBytes(&buffers[2][0],BUFFER_SIZE);
Pokitto 6:72f87b7c7400 903 fileReadBytes(&buffers[3][0],BUFFER_SIZE);
Pokitto 6:72f87b7c7400 904 currentBuffer = 0;
Pokitto 6:72f87b7c7400 905 currentPtr = buffers[currentBuffer];
Pokitto 6:72f87b7c7400 906 endPtr = currentPtr + BUFFER_SIZE;
Pokitto 6:72f87b7c7400 907
Pokitto 6:72f87b7c7400 908 //streaming = STR_PLAYING|options;
Pokitto 6:72f87b7c7400 909
Pokitto 6:72f87b7c7400 910 if (!options) pokPlayStream(); // activate stream
Pokitto 6:72f87b7c7400 911 #endif //POK_STREAMING_MUSIC
Pokitto 6:72f87b7c7400 912 return 1; // opening music file succeeded
Pokitto 6:72f87b7c7400 913 }
Pokitto 6:72f87b7c7400 914