PokittoLib with changes to lcd refresh etc.

Dependents:   Pokittris

Fork of Pokitto by Pokitto Community Team

This is a fork by user @Spinal, and is used in Pokittris for testing. Do not import this to your own program.

Committer:
Pokitto
Date:
Mon Sep 18 12:34:05 2017 +0000
Revision:
1:4b1511a0a2c2
Parent:
0:e8b8f36b4505
Child:
2:968589ca3484
Changes done to make compile;

Who changed what in which revision?

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