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

Committer:
Pokitto
Date:
Mon Apr 02 22:37:22 2018 +0000
Revision:
36:771321e70814
Synced with Github repo

Who changed what in which revision?

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