PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Committer:
Pokitto
Date:
Wed Oct 18 08:35:20 2017 +0000
Revision:
11:aa12eb46aa02
Parent:
6:72f87b7c7400
Child:
12:162abc242b3a
Mistake in Sound.begin 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 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