Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PokittoLib by
POKITTO_CORE/PokittoSound.cpp@2:968589ca3484, 2017-09-19 (annotated)
- Committer:
- Pokitto
- Date:
- Tue Sep 19 08:47:36 2017 +0000
- Revision:
- 2:968589ca3484
- Parent:
- 1:4b1511a0a2c2
- Child:
- 4:ecf2fe370c1c
Got rid of warnings at compile time
Who changed what in which revision?
| User | Revision | Line number | New 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 | 2:968589ca3484 | 150 | #if POK_GBSOUND > 0 |
| Pokitto | 0:e8b8f36b4505 | 151 | const uint16_t squareWaveInstrument[] = {0x0101, 0x03F7}; |
| Pokitto | 0:e8b8f36b4505 | 152 | const uint16_t noiseInstrument[] = {0x0101, 0x03FF}; |
| Pokitto | 0:e8b8f36b4505 | 153 | const uint16_t* const defaultInstruments[] = {squareWaveInstrument,noiseInstrument}; |
| Pokitto | 0:e8b8f36b4505 | 154 | |
| Pokitto | 0:e8b8f36b4505 | 155 | const uint16_t playOKPattern[] = {0x0005,0x138,0x168,0x0000}; |
| Pokitto | 0:e8b8f36b4505 | 156 | const uint16_t playCancelPattern[] = {0x0005,0x168,0x138,0x0000}; |
| Pokitto | 0:e8b8f36b4505 | 157 | const uint16_t playTickP[] = {0x0045,0x168,0x0000}; |
| Pokitto | 2:968589ca3484 | 158 | #endif |
| Pokitto | 0:e8b8f36b4505 | 159 | #if(EXTENDED_NOTE_RANGE > 0) |
| Pokitto | 0:e8b8f36b4505 | 160 | //extended note range |
| Pokitto | 0:e8b8f36b4505 | 161 | #define NUM_PITCH 59 |
| Pokitto | 0:e8b8f36b4505 | 162 | const uint8_t _halfPeriods[NUM_PITCH] = {246,232,219,207,195,184,174,164,155,146,138,130,123,116,110,104,98,92,87,82,78,73,69,65,62,58,55,52,49,46,44,41,39,37,35,33,31,29,28,26,25,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6}; |
| Pokitto | 0:e8b8f36b4505 | 163 | #else |
| Pokitto | 0:e8b8f36b4505 | 164 | //regular note range |
| Pokitto | 0:e8b8f36b4505 | 165 | #define NUM_PITCH 36 |
| Pokitto | 0:e8b8f36b4505 | 166 | const uint8_t _halfPeriods[NUM_PITCH] = {246,232,219,207,195,184,174,164,155,146,138,130,123,116,110,104,98,92,87,82,78,73,69,65,62,58,55,52,49,46,44,41,39,37,35,33}; |
| Pokitto | 0:e8b8f36b4505 | 167 | #endif |
| Pokitto | 0:e8b8f36b4505 | 168 | |
| Pokitto | 0:e8b8f36b4505 | 169 | #endif |
| Pokitto | 0:e8b8f36b4505 | 170 | |
| Pokitto | 0:e8b8f36b4505 | 171 | void Pokitto::audio_IRQ() { |
| Pokitto | 0:e8b8f36b4505 | 172 | #if POK_STREAMING_MUSIC > 0 |
| Pokitto | 0:e8b8f36b4505 | 173 | #if POK_STREAMFREQ_HALVE > 0 |
| Pokitto | 0:e8b8f36b4505 | 174 | streamstep = 1-streamstep; |
| Pokitto | 0:e8b8f36b4505 | 175 | #else |
| Pokitto | 0:e8b8f36b4505 | 176 | streamstep=1; |
| Pokitto | 0:e8b8f36b4505 | 177 | #endif |
| Pokitto | 0:e8b8f36b4505 | 178 | |
| Pokitto | 0:e8b8f36b4505 | 179 | streamstep &= streamon; //check if stream is on |
| Pokitto | 0:e8b8f36b4505 | 180 | |
| Pokitto | 0:e8b8f36b4505 | 181 | if(streamvol && streamstep) { |
| Pokitto | 0:e8b8f36b4505 | 182 | uint8_t output = (*currentPtr++); |
| Pokitto | 0:e8b8f36b4505 | 183 | sbyte = output; |
| Pokitto | 0:e8b8f36b4505 | 184 | } else { |
| Pokitto | 0:e8b8f36b4505 | 185 | sbyte = 0; // duty cycle |
| Pokitto | 0:e8b8f36b4505 | 186 | } |
| Pokitto | 0:e8b8f36b4505 | 187 | |
| Pokitto | 0:e8b8f36b4505 | 188 | if (currentPtr >= endPtr) |
| Pokitto | 0:e8b8f36b4505 | 189 | { |
| Pokitto | 0:e8b8f36b4505 | 190 | currentBuffer++; |
| Pokitto | 0:e8b8f36b4505 | 191 | if (currentBuffer==4) currentBuffer=0; |
| Pokitto | 0:e8b8f36b4505 | 192 | currentPtr = buffers[currentBuffer]; |
| Pokitto | 0:e8b8f36b4505 | 193 | endPtr = currentPtr + BUFFER_SIZE; |
| Pokitto | 0:e8b8f36b4505 | 194 | } |
| Pokitto | 0:e8b8f36b4505 | 195 | |
| Pokitto | 0:e8b8f36b4505 | 196 | #endif // POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 197 | #if (NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 198 | Sound::generateOutput(); |
| Pokitto | 0:e8b8f36b4505 | 199 | #endif |
| Pokitto | 0:e8b8f36b4505 | 200 | } |
| Pokitto | 0:e8b8f36b4505 | 201 | |
| Pokitto | 0:e8b8f36b4505 | 202 | void Sound::volumeUp() { |
| Pokitto | 0:e8b8f36b4505 | 203 | if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()+VOLUME_STEP*2); |
| Pokitto | 0:e8b8f36b4505 | 204 | else setVolume(getVolume()+VOLUME_STEP); |
| Pokitto | 0:e8b8f36b4505 | 205 | } |
| Pokitto | 0:e8b8f36b4505 | 206 | |
| Pokitto | 0:e8b8f36b4505 | 207 | void Sound::volumeDown() { |
| Pokitto | 0:e8b8f36b4505 | 208 | if (globalVolume>VOLUME_HEADPHONE_MAX) setVolume(getVolume()-VOLUME_STEP*4); |
| Pokitto | 0:e8b8f36b4505 | 209 | else setVolume(getVolume()-VOLUME_STEP); |
| Pokitto | 0:e8b8f36b4505 | 210 | } |
| Pokitto | 0:e8b8f36b4505 | 211 | |
| Pokitto | 0:e8b8f36b4505 | 212 | |
| Pokitto | 0:e8b8f36b4505 | 213 | void Sound::setMaxVol(int16_t v) { |
| Pokitto | 0:e8b8f36b4505 | 214 | if (v < 0) v = 0; //prevent nasty wraparound |
| Pokitto | 0:e8b8f36b4505 | 215 | if (v > VOLUME_SPEAKER_MAX) { |
| Pokitto | 0:e8b8f36b4505 | 216 | v = VOLUME_SPEAKER_MAX; |
| Pokitto | 0:e8b8f36b4505 | 217 | } |
| Pokitto | 0:e8b8f36b4505 | 218 | volumeMax = v; |
| Pokitto | 0:e8b8f36b4505 | 219 | setVolume(globalVolume); |
| Pokitto | 0:e8b8f36b4505 | 220 | } |
| Pokitto | 0:e8b8f36b4505 | 221 | |
| Pokitto | 0:e8b8f36b4505 | 222 | uint16_t Sound::getMaxVol() { |
| Pokitto | 0:e8b8f36b4505 | 223 | return volumeMax; |
| Pokitto | 0:e8b8f36b4505 | 224 | } |
| Pokitto | 0:e8b8f36b4505 | 225 | |
| Pokitto | 0:e8b8f36b4505 | 226 | void Sound::updateStream() { |
| Pokitto | 0:e8b8f36b4505 | 227 | #if POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 228 | if (oldBuffer != currentBuffer) { |
| Pokitto | 0:e8b8f36b4505 | 229 | if (currentBuffer==0) fileReadBytes(&buffers[3][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 230 | else if (currentBuffer==1) fileReadBytes(&buffers[0][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 231 | else if (currentBuffer==2) fileReadBytes(&buffers[1][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 232 | else fileReadBytes(&buffers[2][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 233 | oldBuffer = currentBuffer; |
| Pokitto | 0:e8b8f36b4505 | 234 | streamcounter += BUFFER_SIZE; |
| Pokitto | 0:e8b8f36b4505 | 235 | } |
| Pokitto | 0:e8b8f36b4505 | 236 | |
| Pokitto | 0:e8b8f36b4505 | 237 | #ifndef POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 238 | if ( streamcounter > fs.fsize - (BUFFER_SIZE)) { |
| Pokitto | 0:e8b8f36b4505 | 239 | #else |
| Pokitto | 0:e8b8f36b4505 | 240 | if ( streamcounter > getFileLength() - (BUFFER_SIZE)) { |
| Pokitto | 0:e8b8f36b4505 | 241 | #endif |
| Pokitto | 0:e8b8f36b4505 | 242 | streamcounter=0; |
| Pokitto | 0:e8b8f36b4505 | 243 | #if POK_STREAM_LOOP > 0 |
| Pokitto | 0:e8b8f36b4505 | 244 | fileRewind(); |
| Pokitto | 0:e8b8f36b4505 | 245 | #endif |
| Pokitto | 0:e8b8f36b4505 | 246 | #ifndef POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 247 | streamon=0; |
| Pokitto | 0:e8b8f36b4505 | 248 | #endif // POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 249 | } |
| Pokitto | 0:e8b8f36b4505 | 250 | #endif |
| Pokitto | 0:e8b8f36b4505 | 251 | } |
| Pokitto | 0:e8b8f36b4505 | 252 | |
| Pokitto | 0:e8b8f36b4505 | 253 | void Sound::begin() { |
| Pokitto | 1:4b1511a0a2c2 | 254 | #if POK_ENABLE_SOUND > 1 |
| Pokitto | 0:e8b8f36b4505 | 255 | soundInit(); |
| Pokitto | 1:4b1511a0a2c2 | 256 | #endif |
| Pokitto | 0:e8b8f36b4505 | 257 | #if (NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 258 | #if POK_ENABLE_SOUND > 0 |
| Pokitto | 0:e8b8f36b4505 | 259 | #if POK_GBSOUND > 0 |
| Pokitto | 0:e8b8f36b4505 | 260 | prescaler = 1; |
| Pokitto | 0:e8b8f36b4505 | 261 | for(byte i=0; i<NUM_CHANNELS; i++){ |
| Pokitto | 0:e8b8f36b4505 | 262 | chanVolumes[i] = VOLUME_CHANNEL_MAX; |
| Pokitto | 0:e8b8f36b4505 | 263 | changeInstrumentSet(defaultInstruments, i); //load default instruments. #0:square wave, #1: noise |
| Pokitto | 0:e8b8f36b4505 | 264 | command(CMD_INSTRUMENT, 0, 0, i); //set the default instrument to square wave |
| Pokitto | 0:e8b8f36b4505 | 265 | } |
| Pokitto | 0:e8b8f36b4505 | 266 | #endif // POK_GBSOUND |
| Pokitto | 0:e8b8f36b4505 | 267 | #endif //POK_ENABLE_SOUND |
| Pokitto | 0:e8b8f36b4505 | 268 | #endif |
| Pokitto | 0:e8b8f36b4505 | 269 | } |
| Pokitto | 0:e8b8f36b4505 | 270 | |
| Pokitto | 0:e8b8f36b4505 | 271 | void Sound::playTrack(const uint16_t* track, uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 272 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 273 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 274 | return; |
| Pokitto | 0:e8b8f36b4505 | 275 | stopTrack(channel); |
| Pokitto | 0:e8b8f36b4505 | 276 | trackCursor[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 277 | trackData[channel] = (uint16_t*)track; |
| Pokitto | 0:e8b8f36b4505 | 278 | trackIsPlaying[channel] = true; |
| Pokitto | 0:e8b8f36b4505 | 279 | #endif |
| Pokitto | 0:e8b8f36b4505 | 280 | } |
| Pokitto | 0:e8b8f36b4505 | 281 | |
| Pokitto | 0:e8b8f36b4505 | 282 | void Sound::stopTrack(uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 283 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 284 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 285 | return; |
| Pokitto | 0:e8b8f36b4505 | 286 | trackIsPlaying[channel] = false; |
| Pokitto | 0:e8b8f36b4505 | 287 | stopPattern(channel); |
| Pokitto | 0:e8b8f36b4505 | 288 | #endif |
| Pokitto | 0:e8b8f36b4505 | 289 | } |
| Pokitto | 0:e8b8f36b4505 | 290 | |
| Pokitto | 0:e8b8f36b4505 | 291 | void Sound::stopTrack(){ |
| Pokitto | 0:e8b8f36b4505 | 292 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 293 | for(uint8_t i=0; i<NUM_CHANNELS; i++){ |
| Pokitto | 0:e8b8f36b4505 | 294 | stopTrack(i); |
| Pokitto | 0:e8b8f36b4505 | 295 | } |
| Pokitto | 0:e8b8f36b4505 | 296 | #endif |
| Pokitto | 0:e8b8f36b4505 | 297 | } |
| Pokitto | 0:e8b8f36b4505 | 298 | |
| Pokitto | 0:e8b8f36b4505 | 299 | void Sound::updateTrack(uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 300 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 301 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 302 | return; |
| Pokitto | 0:e8b8f36b4505 | 303 | if(trackIsPlaying[channel] && !patternIsPlaying[channel]){ |
| Pokitto | 0:e8b8f36b4505 | 304 | uint16_t data = pgm_read_word(trackData[channel] + trackCursor[channel]); |
| Pokitto | 0:e8b8f36b4505 | 305 | if(data == 0xFFFF){ //en of the track |
| Pokitto | 0:e8b8f36b4505 | 306 | trackIsPlaying[channel] = false; |
| Pokitto | 0:e8b8f36b4505 | 307 | return; |
| Pokitto | 0:e8b8f36b4505 | 308 | } |
| Pokitto | 0:e8b8f36b4505 | 309 | uint8_t patternID = data & 0xFF; |
| Pokitto | 0:e8b8f36b4505 | 310 | data >>= 8; |
| Pokitto | 0:e8b8f36b4505 | 311 | patternPitch[channel] = data; |
| Pokitto | 0:e8b8f36b4505 | 312 | playPattern((const uint16_t*)pgm_read_word(&(patternSet[channel][patternID])), channel); |
| Pokitto | 0:e8b8f36b4505 | 313 | trackCursor[channel] ++; |
| Pokitto | 0:e8b8f36b4505 | 314 | } |
| Pokitto | 0:e8b8f36b4505 | 315 | #endif |
| Pokitto | 0:e8b8f36b4505 | 316 | } |
| Pokitto | 0:e8b8f36b4505 | 317 | |
| Pokitto | 0:e8b8f36b4505 | 318 | void Sound::updateTrack(){ |
| Pokitto | 0:e8b8f36b4505 | 319 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 320 | for (uint8_t i=0; i<NUM_CHANNELS; i++){ |
| Pokitto | 0:e8b8f36b4505 | 321 | updateTrack(i); |
| Pokitto | 0:e8b8f36b4505 | 322 | } |
| Pokitto | 0:e8b8f36b4505 | 323 | #endif |
| Pokitto | 0:e8b8f36b4505 | 324 | } |
| Pokitto | 0:e8b8f36b4505 | 325 | |
| Pokitto | 0:e8b8f36b4505 | 326 | void Sound::changePatternSet(const uint16_t* const* patterns, uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 327 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 328 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 329 | return; |
| Pokitto | 0:e8b8f36b4505 | 330 | patternSet[channel] = (uint16_t**)patterns; |
| Pokitto | 0:e8b8f36b4505 | 331 | #endif |
| Pokitto | 0:e8b8f36b4505 | 332 | } |
| Pokitto | 0:e8b8f36b4505 | 333 | |
| Pokitto | 0:e8b8f36b4505 | 334 | void Sound::playPattern(const uint16_t* pattern, uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 335 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 336 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 337 | return; |
| Pokitto | 0:e8b8f36b4505 | 338 | stopPattern(channel); |
| Pokitto | 0:e8b8f36b4505 | 339 | patternData[channel] = (uint16_t*)pattern; |
| Pokitto | 0:e8b8f36b4505 | 340 | patternCursor[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 341 | patternIsPlaying[channel] = true; |
| Pokitto | 0:e8b8f36b4505 | 342 | noteVolume[channel] = 9; |
| Pokitto | 0:e8b8f36b4505 | 343 | //reinit commands |
| Pokitto | 0:e8b8f36b4505 | 344 | volumeSlideStepDuration[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 345 | arpeggioStepDuration[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 346 | tremoloStepDuration[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 347 | #endif |
| Pokitto | 0:e8b8f36b4505 | 348 | } |
| Pokitto | 0:e8b8f36b4505 | 349 | |
| Pokitto | 0:e8b8f36b4505 | 350 | void Sound::updatePattern(){ |
| Pokitto | 0:e8b8f36b4505 | 351 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 352 | for (uint8_t i=0; i<NUM_CHANNELS; i++){ |
| Pokitto | 0:e8b8f36b4505 | 353 | updatePattern(i); |
| Pokitto | 0:e8b8f36b4505 | 354 | } |
| Pokitto | 0:e8b8f36b4505 | 355 | #endif |
| Pokitto | 0:e8b8f36b4505 | 356 | } |
| Pokitto | 0:e8b8f36b4505 | 357 | |
| Pokitto | 0:e8b8f36b4505 | 358 | void Sound::changeInstrumentSet(const uint16_t* const* instruments, uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 359 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 360 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 361 | return; |
| Pokitto | 0:e8b8f36b4505 | 362 | instrumentSet[channel] = (uint16_t**)instruments; |
| Pokitto | 0:e8b8f36b4505 | 363 | #endif |
| Pokitto | 0:e8b8f36b4505 | 364 | } |
| Pokitto | 0:e8b8f36b4505 | 365 | |
| Pokitto | 0:e8b8f36b4505 | 366 | void Sound::updatePattern(uint8_t i){ |
| Pokitto | 0:e8b8f36b4505 | 367 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 368 | if(i>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 369 | return; |
| Pokitto | 0:e8b8f36b4505 | 370 | if(patternIsPlaying[i]){ |
| Pokitto | 0:e8b8f36b4505 | 371 | if(noteDuration[i]==0){//if the end of the previous note is reached |
| Pokitto | 0:e8b8f36b4505 | 372 | |
| Pokitto | 0:e8b8f36b4505 | 373 | uint16_t data = pgm_read_word(patternCursor[i] + patternData[i]); |
| Pokitto | 0:e8b8f36b4505 | 374 | |
| Pokitto | 0:e8b8f36b4505 | 375 | if(data == 0){ //end of the pattern reached |
| Pokitto | 0:e8b8f36b4505 | 376 | if(patternLooping[i] == true){ |
| Pokitto | 0:e8b8f36b4505 | 377 | patternCursor[i] = 0; |
| Pokitto | 0:e8b8f36b4505 | 378 | data = pgm_read_word(patternCursor[i] + patternData[i]); |
| Pokitto | 0:e8b8f36b4505 | 379 | } |
| Pokitto | 0:e8b8f36b4505 | 380 | else{ |
| Pokitto | 0:e8b8f36b4505 | 381 | patternIsPlaying[i] = false; |
| Pokitto | 0:e8b8f36b4505 | 382 | if(trackIsPlaying[i]){ //if this pattern is part of a track, get the next pattern |
| Pokitto | 0:e8b8f36b4505 | 383 | updateTrack(i); |
| Pokitto | 0:e8b8f36b4505 | 384 | data = pgm_read_word(patternCursor[i] + patternData[i]); |
| Pokitto | 0:e8b8f36b4505 | 385 | } else { |
| Pokitto | 0:e8b8f36b4505 | 386 | stopNote(i); |
| Pokitto | 0:e8b8f36b4505 | 387 | //Serial.print("pattern end\n"); |
| Pokitto | 0:e8b8f36b4505 | 388 | return; |
| Pokitto | 0:e8b8f36b4505 | 389 | } |
| Pokitto | 0:e8b8f36b4505 | 390 | } |
| Pokitto | 0:e8b8f36b4505 | 391 | } |
| Pokitto | 0:e8b8f36b4505 | 392 | |
| Pokitto | 0:e8b8f36b4505 | 393 | while (data & 0x0001){ //read all commands and instrument changes |
| Pokitto | 0:e8b8f36b4505 | 394 | data >>= 2; |
| Pokitto | 0:e8b8f36b4505 | 395 | //Serial.print("\ncmd\t"); |
| Pokitto | 0:e8b8f36b4505 | 396 | uint8_t cmd = data & 0x0F; |
| Pokitto | 0:e8b8f36b4505 | 397 | data >>= 4; |
| Pokitto | 0:e8b8f36b4505 | 398 | uint8_t X = data & 0x1F; |
| Pokitto | 0:e8b8f36b4505 | 399 | data >>= 5; |
| Pokitto | 0:e8b8f36b4505 | 400 | int8_t Y = data - 16; |
| Pokitto | 0:e8b8f36b4505 | 401 | command(cmd,X,Y,i); |
| Pokitto | 0:e8b8f36b4505 | 402 | patternCursor[i]++; |
| Pokitto | 0:e8b8f36b4505 | 403 | data = pgm_read_word(patternCursor[i] + patternData[i]); |
| Pokitto | 0:e8b8f36b4505 | 404 | } |
| Pokitto | 0:e8b8f36b4505 | 405 | data >>= 2; |
| Pokitto | 0:e8b8f36b4505 | 406 | |
| Pokitto | 0:e8b8f36b4505 | 407 | uint8_t pitch = data & 0x003F; |
| Pokitto | 0:e8b8f36b4505 | 408 | data >>= 6; |
| Pokitto | 0:e8b8f36b4505 | 409 | |
| Pokitto | 0:e8b8f36b4505 | 410 | uint8_t duration = data; |
| Pokitto | 0:e8b8f36b4505 | 411 | if(pitch != 63){ |
| Pokitto | 0:e8b8f36b4505 | 412 | } |
| Pokitto | 0:e8b8f36b4505 | 413 | |
| Pokitto | 0:e8b8f36b4505 | 414 | playNote(pitch, duration, i); |
| Pokitto | 0:e8b8f36b4505 | 415 | |
| Pokitto | 0:e8b8f36b4505 | 416 | patternCursor[i]++; |
| Pokitto | 0:e8b8f36b4505 | 417 | } |
| Pokitto | 0:e8b8f36b4505 | 418 | } |
| Pokitto | 0:e8b8f36b4505 | 419 | #endif |
| Pokitto | 0:e8b8f36b4505 | 420 | } |
| Pokitto | 0:e8b8f36b4505 | 421 | |
| Pokitto | 0:e8b8f36b4505 | 422 | void Sound::stopPattern(uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 423 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 424 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 425 | return; |
| Pokitto | 0:e8b8f36b4505 | 426 | stopNote(channel); |
| Pokitto | 0:e8b8f36b4505 | 427 | patternIsPlaying[channel] = false; |
| Pokitto | 0:e8b8f36b4505 | 428 | #endif |
| Pokitto | 0:e8b8f36b4505 | 429 | } |
| Pokitto | 0:e8b8f36b4505 | 430 | |
| Pokitto | 0:e8b8f36b4505 | 431 | void Sound::stopPattern(){ |
| Pokitto | 0:e8b8f36b4505 | 432 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 433 | for(uint8_t i=0; i<NUM_CHANNELS; i++){ |
| Pokitto | 0:e8b8f36b4505 | 434 | stopPattern(i); |
| Pokitto | 0:e8b8f36b4505 | 435 | } |
| Pokitto | 0:e8b8f36b4505 | 436 | #endif |
| Pokitto | 0:e8b8f36b4505 | 437 | } |
| Pokitto | 0:e8b8f36b4505 | 438 | |
| Pokitto | 0:e8b8f36b4505 | 439 | void Sound::command(uint8_t cmd, uint8_t X, int8_t Y, uint8_t i){ |
| Pokitto | 0:e8b8f36b4505 | 440 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 441 | if(i>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 442 | return; |
| Pokitto | 0:e8b8f36b4505 | 443 | switch(cmd){ |
| Pokitto | 0:e8b8f36b4505 | 444 | case CMD_VOLUME: //volume |
| Pokitto | 2:968589ca3484 | 445 | X = constrain((int8_t)X, 0, 10); |
| Pokitto | 0:e8b8f36b4505 | 446 | noteVolume[i] = X; |
| Pokitto | 0:e8b8f36b4505 | 447 | break; |
| Pokitto | 0:e8b8f36b4505 | 448 | case CMD_INSTRUMENT: //instrument |
| Pokitto | 0:e8b8f36b4505 | 449 | instrumentData[i] = (uint16_t*)pgm_read_word(&(instrumentSet[i][X])); |
| Pokitto | 0:e8b8f36b4505 | 450 | instrumentLength[i] = pgm_read_word(&(instrumentData[i][0])) & 0x00FF; //8 LSB |
| Pokitto | 0:e8b8f36b4505 | 451 | instrumentLength[i] *= prescaler; |
| Pokitto | 0:e8b8f36b4505 | 452 | instrumentLooping[i] = min2((pgm_read_word(&(instrumentData[i][0])) >> 8), instrumentLength[i]); //8 MSB - check that the loop is shorter than the instrument length |
| Pokitto | 0:e8b8f36b4505 | 453 | instrumentLooping[i] *= prescaler; |
| Pokitto | 0:e8b8f36b4505 | 454 | break; |
| Pokitto | 0:e8b8f36b4505 | 455 | case CMD_SLIDE: //volume slide |
| Pokitto | 0:e8b8f36b4505 | 456 | volumeSlideStepDuration[i] = X * prescaler; |
| Pokitto | 0:e8b8f36b4505 | 457 | volumeSlideStepSize[i] = Y; |
| Pokitto | 0:e8b8f36b4505 | 458 | break; |
| Pokitto | 0:e8b8f36b4505 | 459 | case CMD_ARPEGGIO: |
| Pokitto | 0:e8b8f36b4505 | 460 | arpeggioStepDuration[i] = X * prescaler; |
| Pokitto | 0:e8b8f36b4505 | 461 | arpeggioStepSize[i] = Y; |
| Pokitto | 0:e8b8f36b4505 | 462 | break; |
| Pokitto | 0:e8b8f36b4505 | 463 | case CMD_TREMOLO: |
| Pokitto | 0:e8b8f36b4505 | 464 | tremoloStepDuration[i] = X * prescaler; |
| Pokitto | 0:e8b8f36b4505 | 465 | tremoloStepSize[i] = Y; |
| Pokitto | 0:e8b8f36b4505 | 466 | break; |
| Pokitto | 0:e8b8f36b4505 | 467 | default: |
| Pokitto | 0:e8b8f36b4505 | 468 | break; |
| Pokitto | 0:e8b8f36b4505 | 469 | } |
| Pokitto | 0:e8b8f36b4505 | 470 | #endif |
| Pokitto | 0:e8b8f36b4505 | 471 | } |
| Pokitto | 0:e8b8f36b4505 | 472 | |
| Pokitto | 0:e8b8f36b4505 | 473 | void Sound::playNote(uint8_t pitch, uint8_t duration, uint8_t channel){ |
| Pokitto | 0:e8b8f36b4505 | 474 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 475 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 476 | return; |
| Pokitto | 0:e8b8f36b4505 | 477 | //set note |
| Pokitto | 0:e8b8f36b4505 | 478 | notePitch[channel] = pitch; |
| Pokitto | 0:e8b8f36b4505 | 479 | noteDuration[channel] = duration * prescaler; |
| Pokitto | 0:e8b8f36b4505 | 480 | //reinit vars |
| Pokitto | 0:e8b8f36b4505 | 481 | instrumentNextChange[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 482 | instrumentCursor[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 483 | notePlaying[channel] = true; |
| Pokitto | 0:e8b8f36b4505 | 484 | _chanState[channel] = true; |
| Pokitto | 0:e8b8f36b4505 | 485 | commandsCounter[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 486 | #endif |
| Pokitto | 0:e8b8f36b4505 | 487 | } |
| Pokitto | 0:e8b8f36b4505 | 488 | |
| Pokitto | 0:e8b8f36b4505 | 489 | void Sound::stopNote(uint8_t channel) { |
| Pokitto | 0:e8b8f36b4505 | 490 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 491 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 492 | return; |
| Pokitto | 0:e8b8f36b4505 | 493 | notePlaying[channel] = false; |
| Pokitto | 0:e8b8f36b4505 | 494 | //counters |
| Pokitto | 0:e8b8f36b4505 | 495 | noteDuration[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 496 | instrumentCursor[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 497 | commandsCounter[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 498 | //output |
| Pokitto | 0:e8b8f36b4505 | 499 | _chanOutput[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 500 | _chanOutputVolume[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 501 | _chanState[channel] = false; |
| Pokitto | 0:e8b8f36b4505 | 502 | updateOutput(); |
| Pokitto | 0:e8b8f36b4505 | 503 | #endif |
| Pokitto | 0:e8b8f36b4505 | 504 | } |
| Pokitto | 0:e8b8f36b4505 | 505 | |
| Pokitto | 0:e8b8f36b4505 | 506 | void Sound::stopNote() { |
| Pokitto | 0:e8b8f36b4505 | 507 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 508 | for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { |
| Pokitto | 0:e8b8f36b4505 | 509 | stopNote(channel); |
| Pokitto | 0:e8b8f36b4505 | 510 | } |
| Pokitto | 0:e8b8f36b4505 | 511 | #endif |
| Pokitto | 0:e8b8f36b4505 | 512 | } |
| Pokitto | 0:e8b8f36b4505 | 513 | |
| Pokitto | 0:e8b8f36b4505 | 514 | void Sound::updateNote() { |
| Pokitto | 0:e8b8f36b4505 | 515 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 516 | for (uint8_t i = 0; i < NUM_CHANNELS; i++) { |
| Pokitto | 0:e8b8f36b4505 | 517 | updateNote(i); |
| Pokitto | 0:e8b8f36b4505 | 518 | } |
| Pokitto | 0:e8b8f36b4505 | 519 | #endif |
| Pokitto | 0:e8b8f36b4505 | 520 | } |
| Pokitto | 0:e8b8f36b4505 | 521 | |
| Pokitto | 0:e8b8f36b4505 | 522 | void Sound::updateNote(uint8_t i) { |
| Pokitto | 0:e8b8f36b4505 | 523 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 524 | if(i>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 525 | return; |
| Pokitto | 0:e8b8f36b4505 | 526 | if (notePlaying[i]) { |
| Pokitto | 0:e8b8f36b4505 | 527 | |
| Pokitto | 0:e8b8f36b4505 | 528 | if(noteDuration[i] == 0){ |
| Pokitto | 0:e8b8f36b4505 | 529 | stopNote(i); |
| Pokitto | 0:e8b8f36b4505 | 530 | //Serial.println("note end"); |
| Pokitto | 0:e8b8f36b4505 | 531 | return; |
| Pokitto | 0:e8b8f36b4505 | 532 | } else { |
| Pokitto | 0:e8b8f36b4505 | 533 | noteDuration[i]--; |
| Pokitto | 0:e8b8f36b4505 | 534 | } |
| Pokitto | 0:e8b8f36b4505 | 535 | |
| Pokitto | 0:e8b8f36b4505 | 536 | if (instrumentNextChange[i] == 0) { |
| Pokitto | 0:e8b8f36b4505 | 537 | |
| Pokitto | 0:e8b8f36b4505 | 538 | //read the step data from the progmem and decode it |
| Pokitto | 0:e8b8f36b4505 | 539 | uint16_t thisStep = pgm_read_word(&(instrumentData[i][1 + instrumentCursor[i]])); |
| Pokitto | 0:e8b8f36b4505 | 540 | |
| Pokitto | 0:e8b8f36b4505 | 541 | stepVolume[i] = thisStep & 0x0007; |
| Pokitto | 0:e8b8f36b4505 | 542 | thisStep >>= 3; |
| Pokitto | 0:e8b8f36b4505 | 543 | |
| Pokitto | 0:e8b8f36b4505 | 544 | uint8_t stepNoise = thisStep & 0x0001; |
| Pokitto | 0:e8b8f36b4505 | 545 | thisStep >>= 1; |
| Pokitto | 0:e8b8f36b4505 | 546 | |
| Pokitto | 0:e8b8f36b4505 | 547 | uint8_t stepDuration = thisStep & 0x003F; |
| Pokitto | 0:e8b8f36b4505 | 548 | thisStep >>= 6; |
| Pokitto | 0:e8b8f36b4505 | 549 | |
| Pokitto | 0:e8b8f36b4505 | 550 | stepPitch[i] = thisStep; |
| Pokitto | 0:e8b8f36b4505 | 551 | |
| Pokitto | 0:e8b8f36b4505 | 552 | //apply the step settings |
| Pokitto | 0:e8b8f36b4505 | 553 | instrumentNextChange[i] = stepDuration * prescaler; |
| Pokitto | 0:e8b8f36b4505 | 554 | |
| Pokitto | 0:e8b8f36b4505 | 555 | _chanNoise[i] = stepNoise; |
| Pokitto | 0:e8b8f36b4505 | 556 | |
| Pokitto | 0:e8b8f36b4505 | 557 | |
| Pokitto | 0:e8b8f36b4505 | 558 | instrumentCursor[i]++; |
| Pokitto | 0:e8b8f36b4505 | 559 | |
| Pokitto | 0:e8b8f36b4505 | 560 | if (instrumentCursor[i] >= instrumentLength[i]) { |
| Pokitto | 0:e8b8f36b4505 | 561 | if (instrumentLooping[i]) { |
| Pokitto | 0:e8b8f36b4505 | 562 | instrumentCursor[i] = instrumentLength[i] - instrumentLooping[i]; |
| Pokitto | 0:e8b8f36b4505 | 563 | } else { |
| Pokitto | 0:e8b8f36b4505 | 564 | stopNote(i); |
| Pokitto | 0:e8b8f36b4505 | 565 | } |
| Pokitto | 0:e8b8f36b4505 | 566 | } |
| Pokitto | 0:e8b8f36b4505 | 567 | } |
| Pokitto | 0:e8b8f36b4505 | 568 | instrumentNextChange[i]--; |
| Pokitto | 0:e8b8f36b4505 | 569 | |
| Pokitto | 0:e8b8f36b4505 | 570 | commandsCounter[i]++; |
| Pokitto | 0:e8b8f36b4505 | 571 | |
| Pokitto | 0:e8b8f36b4505 | 572 | //UPDATE VALUES |
| Pokitto | 0:e8b8f36b4505 | 573 | //pitch |
| Pokitto | 0:e8b8f36b4505 | 574 | outputPitch[i] = notePitch[i] + stepPitch[i] + patternPitch[i]; |
| Pokitto | 0:e8b8f36b4505 | 575 | if(arpeggioStepDuration[i]){ |
| Pokitto | 0:e8b8f36b4505 | 576 | outputPitch[i] += commandsCounter[i] / arpeggioStepDuration[i] * arpeggioStepSize[i]; |
| Pokitto | 0:e8b8f36b4505 | 577 | } |
| Pokitto | 0:e8b8f36b4505 | 578 | outputPitch[i] = (outputPitch[i] + NUM_PITCH) % NUM_PITCH; //wrap |
| Pokitto | 0:e8b8f36b4505 | 579 | //volume |
| Pokitto | 0:e8b8f36b4505 | 580 | outputVolume[i] = noteVolume[i]; |
| Pokitto | 0:e8b8f36b4505 | 581 | if(volumeSlideStepDuration[i]){ |
| Pokitto | 0:e8b8f36b4505 | 582 | outputVolume[i] += commandsCounter[i] / volumeSlideStepDuration[i] * volumeSlideStepSize[i]; |
| Pokitto | 0:e8b8f36b4505 | 583 | } |
| Pokitto | 0:e8b8f36b4505 | 584 | if(tremoloStepDuration[i]){ |
| Pokitto | 0:e8b8f36b4505 | 585 | outputVolume[i] += ((commandsCounter[i]/tremoloStepDuration[i]) % 2) * tremoloStepSize[i]; |
| Pokitto | 0:e8b8f36b4505 | 586 | } |
| Pokitto | 0:e8b8f36b4505 | 587 | outputVolume[i] = constrain(outputVolume[i], 0, 9); |
| Pokitto | 0:e8b8f36b4505 | 588 | if(notePitch[i] == 63){ |
| Pokitto | 0:e8b8f36b4505 | 589 | outputVolume[i] = 0; |
| Pokitto | 0:e8b8f36b4505 | 590 | } |
| Pokitto | 0:e8b8f36b4505 | 591 | // jonnehw noInterrupts(); |
| Pokitto | 0:e8b8f36b4505 | 592 | _chanHalfPeriod[i] = pgm_read_byte(_halfPeriods + outputPitch[i]); |
| Pokitto | 0:e8b8f36b4505 | 593 | _chanOutput[i] = _chanOutputVolume[i] = outputVolume[i] * (globalVolume>>GLOBVOL_SHIFT) * chanVolumes[i] * stepVolume[i]; |
| Pokitto | 0:e8b8f36b4505 | 594 | //Serial.println(outputVolume[i]); |
| Pokitto | 0:e8b8f36b4505 | 595 | // jonnehw interrupts(); |
| Pokitto | 0:e8b8f36b4505 | 596 | } |
| Pokitto | 0:e8b8f36b4505 | 597 | #endif |
| Pokitto | 0:e8b8f36b4505 | 598 | } |
| Pokitto | 0:e8b8f36b4505 | 599 | |
| Pokitto | 0:e8b8f36b4505 | 600 | void Sound::setChannelHalfPeriod(uint8_t channel, uint8_t halfPeriod) { |
| Pokitto | 0:e8b8f36b4505 | 601 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 602 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 603 | return; |
| Pokitto | 0:e8b8f36b4505 | 604 | _chanHalfPeriod[channel] = halfPeriod; |
| Pokitto | 0:e8b8f36b4505 | 605 | _chanState[channel] = false; |
| Pokitto | 0:e8b8f36b4505 | 606 | _chanCount[channel] = 0; |
| Pokitto | 0:e8b8f36b4505 | 607 | updateOutput(); |
| Pokitto | 0:e8b8f36b4505 | 608 | #endif |
| Pokitto | 0:e8b8f36b4505 | 609 | } |
| Pokitto | 0:e8b8f36b4505 | 610 | |
| Pokitto | 0:e8b8f36b4505 | 611 | |
| Pokitto | 0:e8b8f36b4505 | 612 | void Sound::generateOutput() { |
| Pokitto | 0:e8b8f36b4505 | 613 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 614 | bool outputChanged = false; |
| Pokitto | 0:e8b8f36b4505 | 615 | //no for loop here, for the performance sake (this function runs 15 000 times per second...) |
| Pokitto | 0:e8b8f36b4505 | 616 | //CHANNEL 0 |
| Pokitto | 0:e8b8f36b4505 | 617 | if (_chanOutputVolume[0]) { |
| Pokitto | 0:e8b8f36b4505 | 618 | _chanCount[0]++; |
| Pokitto | 0:e8b8f36b4505 | 619 | if (_chanCount[0] >= _chanHalfPeriod[0]) { |
| Pokitto | 0:e8b8f36b4505 | 620 | outputChanged = true; |
| Pokitto | 0:e8b8f36b4505 | 621 | _chanState[0] = !_chanState[0]; |
| Pokitto | 0:e8b8f36b4505 | 622 | _chanCount[0] = 0; |
| Pokitto | 0:e8b8f36b4505 | 623 | if (_chanNoise[0]) { |
| Pokitto | 0:e8b8f36b4505 | 624 | _rand = 67 * _rand + 71; |
| Pokitto | 0:e8b8f36b4505 | 625 | _chanOutput[0] = _rand % _chanOutputVolume[0]; |
| Pokitto | 0:e8b8f36b4505 | 626 | } |
| Pokitto | 0:e8b8f36b4505 | 627 | } |
| Pokitto | 0:e8b8f36b4505 | 628 | } |
| Pokitto | 0:e8b8f36b4505 | 629 | |
| Pokitto | 0:e8b8f36b4505 | 630 | |
| Pokitto | 0:e8b8f36b4505 | 631 | //CHANNEL 1 |
| Pokitto | 0:e8b8f36b4505 | 632 | #if (NUM_CHANNELS > 1) |
| Pokitto | 0:e8b8f36b4505 | 633 | if (_chanOutputVolume[1]) { |
| Pokitto | 0:e8b8f36b4505 | 634 | _chanCount[1]++; |
| Pokitto | 0:e8b8f36b4505 | 635 | if (_chanCount[1] >= _chanHalfPeriod[1]) { |
| Pokitto | 0:e8b8f36b4505 | 636 | outputChanged = true; |
| Pokitto | 0:e8b8f36b4505 | 637 | _chanState[1] = !_chanState[1]; |
| Pokitto | 0:e8b8f36b4505 | 638 | _chanCount[1] = 0; |
| Pokitto | 0:e8b8f36b4505 | 639 | if (_chanNoise[1]) { |
| Pokitto | 0:e8b8f36b4505 | 640 | _rand = 67 * _rand + 71; |
| Pokitto | 0:e8b8f36b4505 | 641 | _chanOutput[1] = _rand % _chanOutputVolume[1]; |
| Pokitto | 0:e8b8f36b4505 | 642 | } |
| Pokitto | 0:e8b8f36b4505 | 643 | } |
| Pokitto | 0:e8b8f36b4505 | 644 | } |
| Pokitto | 0:e8b8f36b4505 | 645 | #endif |
| Pokitto | 0:e8b8f36b4505 | 646 | |
| Pokitto | 0:e8b8f36b4505 | 647 | //CHANNEL 2 |
| Pokitto | 0:e8b8f36b4505 | 648 | #if (NUM_CHANNELS > 2) |
| Pokitto | 0:e8b8f36b4505 | 649 | if (_chanOutputVolume[2]) { |
| Pokitto | 0:e8b8f36b4505 | 650 | _chanCount[2]++; |
| Pokitto | 0:e8b8f36b4505 | 651 | if (_chanCount[2] >= _chanHalfPeriod[2]) { |
| Pokitto | 0:e8b8f36b4505 | 652 | outputChanged = true; |
| Pokitto | 0:e8b8f36b4505 | 653 | _chanState[2] = !_chanState[2]; |
| Pokitto | 0:e8b8f36b4505 | 654 | _chanCount[2] = 0; |
| Pokitto | 0:e8b8f36b4505 | 655 | if (_chanNoise[2]) { |
| Pokitto | 0:e8b8f36b4505 | 656 | _rand = 67 * _rand + 71; |
| Pokitto | 0:e8b8f36b4505 | 657 | _chanOutput[2] = _rand % _chanOutputVolume[2]; |
| Pokitto | 0:e8b8f36b4505 | 658 | } |
| Pokitto | 0:e8b8f36b4505 | 659 | } |
| Pokitto | 0:e8b8f36b4505 | 660 | } |
| Pokitto | 0:e8b8f36b4505 | 661 | #endif |
| Pokitto | 0:e8b8f36b4505 | 662 | |
| Pokitto | 0:e8b8f36b4505 | 663 | //CHANNEL 3 |
| Pokitto | 0:e8b8f36b4505 | 664 | #if (NUM_CHANNELS > 3) |
| Pokitto | 0:e8b8f36b4505 | 665 | if (_chanOutputVolume[3]) { |
| Pokitto | 0:e8b8f36b4505 | 666 | _chanCount[3]++; |
| Pokitto | 0:e8b8f36b4505 | 667 | if (_chanCount[3] >= _chanHalfPeriod[3]) { |
| Pokitto | 0:e8b8f36b4505 | 668 | outputChanged = true; |
| Pokitto | 0:e8b8f36b4505 | 669 | _chanState[3] = !_chanState[3]; |
| Pokitto | 0:e8b8f36b4505 | 670 | _chanCount[3] = 0; |
| Pokitto | 0:e8b8f36b4505 | 671 | if (_chanNoise[3]) { |
| Pokitto | 0:e8b8f36b4505 | 672 | _rand = 67 * _rand + 71; |
| Pokitto | 0:e8b8f36b4505 | 673 | _chanOutput[3] = _rand % _chanOutputVolume[3]; |
| Pokitto | 0:e8b8f36b4505 | 674 | } |
| Pokitto | 0:e8b8f36b4505 | 675 | } |
| Pokitto | 0:e8b8f36b4505 | 676 | } |
| Pokitto | 0:e8b8f36b4505 | 677 | #endif |
| Pokitto | 0:e8b8f36b4505 | 678 | |
| Pokitto | 0:e8b8f36b4505 | 679 | #if POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 680 | if (streamstep) { |
| Pokitto | 0:e8b8f36b4505 | 681 | outputChanged=true; |
| Pokitto | 0:e8b8f36b4505 | 682 | } |
| Pokitto | 0:e8b8f36b4505 | 683 | #endif |
| Pokitto | 0:e8b8f36b4505 | 684 | |
| Pokitto | 0:e8b8f36b4505 | 685 | if (outputChanged) { |
| Pokitto | 0:e8b8f36b4505 | 686 | updateOutput(); |
| Pokitto | 0:e8b8f36b4505 | 687 | } |
| Pokitto | 0:e8b8f36b4505 | 688 | #endif |
| Pokitto | 0:e8b8f36b4505 | 689 | } |
| Pokitto | 0:e8b8f36b4505 | 690 | |
| Pokitto | 0:e8b8f36b4505 | 691 | void Sound::updateOutput() { |
| Pokitto | 0:e8b8f36b4505 | 692 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 693 | uint8_t output = 0; |
| Pokitto | 0:e8b8f36b4505 | 694 | |
| Pokitto | 0:e8b8f36b4505 | 695 | //CHANNEL 0 |
| Pokitto | 0:e8b8f36b4505 | 696 | if (_chanState[0]) { |
| Pokitto | 0:e8b8f36b4505 | 697 | output += _chanOutput[0]; |
| Pokitto | 0:e8b8f36b4505 | 698 | } |
| Pokitto | 0:e8b8f36b4505 | 699 | |
| Pokitto | 0:e8b8f36b4505 | 700 | //CHANNEL 1 |
| Pokitto | 0:e8b8f36b4505 | 701 | #if (NUM_CHANNELS > 1) |
| Pokitto | 0:e8b8f36b4505 | 702 | if (_chanState[1]) { |
| Pokitto | 0:e8b8f36b4505 | 703 | output += _chanOutput[1]; |
| Pokitto | 0:e8b8f36b4505 | 704 | } |
| Pokitto | 0:e8b8f36b4505 | 705 | #endif |
| Pokitto | 0:e8b8f36b4505 | 706 | |
| Pokitto | 0:e8b8f36b4505 | 707 | //CHANNEL 2 |
| Pokitto | 0:e8b8f36b4505 | 708 | #if (NUM_CHANNELS > 2) |
| Pokitto | 0:e8b8f36b4505 | 709 | if (_chanState[2]) { |
| Pokitto | 0:e8b8f36b4505 | 710 | output += _chanOutput[2]; |
| Pokitto | 0:e8b8f36b4505 | 711 | } |
| Pokitto | 0:e8b8f36b4505 | 712 | #endif |
| Pokitto | 0:e8b8f36b4505 | 713 | |
| Pokitto | 0:e8b8f36b4505 | 714 | //CHANNEL 3 |
| Pokitto | 0:e8b8f36b4505 | 715 | #if (NUM_CHANNELS > 3) |
| Pokitto | 0:e8b8f36b4505 | 716 | if (_chanState[3]) { |
| Pokitto | 0:e8b8f36b4505 | 717 | output += _chanOutput[3]; |
| Pokitto | 0:e8b8f36b4505 | 718 | } |
| Pokitto | 0:e8b8f36b4505 | 719 | #endif |
| Pokitto | 0:e8b8f36b4505 | 720 | |
| Pokitto | 0:e8b8f36b4505 | 721 | #ifndef POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 722 | #if POK_ENABLE_SOUND |
| Pokitto | 0:e8b8f36b4505 | 723 | /** HARDWARE **/ |
| Pokitto | 0:e8b8f36b4505 | 724 | |
| Pokitto | 0:e8b8f36b4505 | 725 | #if POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 726 | if (streamstep) { |
| Pokitto | 0:e8b8f36b4505 | 727 | pwmout_write(&audiopwm,(float)sbyte/(float)255); |
| Pokitto | 0:e8b8f36b4505 | 728 | } |
| Pokitto | 0:e8b8f36b4505 | 729 | #endif |
| Pokitto | 0:e8b8f36b4505 | 730 | dac_write((uint8_t)output); //direct hardware mixing baby ! |
| Pokitto | 1:4b1511a0a2c2 | 731 | soundbyte = output; |
| Pokitto | 0:e8b8f36b4505 | 732 | #endif //POK_ENABLE_SOUND |
| Pokitto | 0:e8b8f36b4505 | 733 | #else |
| Pokitto | 0:e8b8f36b4505 | 734 | /** SIMULATOR **/ |
| Pokitto | 0:e8b8f36b4505 | 735 | #if POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 736 | if (streamstep) { |
| Pokitto | 0:e8b8f36b4505 | 737 | uint16_t o = output + sbyte; |
| Pokitto | 0:e8b8f36b4505 | 738 | output = o/2; |
| Pokitto | 0:e8b8f36b4505 | 739 | } |
| Pokitto | 0:e8b8f36b4505 | 740 | #endif |
| Pokitto | 0:e8b8f36b4505 | 741 | soundbyte = output; |
| Pokitto | 0:e8b8f36b4505 | 742 | #endif // POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 743 | #endif |
| Pokitto | 0:e8b8f36b4505 | 744 | } |
| Pokitto | 0:e8b8f36b4505 | 745 | |
| Pokitto | 0:e8b8f36b4505 | 746 | void Sound::setPatternLooping(bool loop, uint8_t channel) { |
| Pokitto | 0:e8b8f36b4505 | 747 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 748 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 749 | return; |
| Pokitto | 0:e8b8f36b4505 | 750 | patternLooping[channel] = loop; |
| Pokitto | 0:e8b8f36b4505 | 751 | #endif |
| Pokitto | 0:e8b8f36b4505 | 752 | } |
| Pokitto | 0:e8b8f36b4505 | 753 | |
| Pokitto | 0:e8b8f36b4505 | 754 | void Sound::playOK(){ |
| Pokitto | 0:e8b8f36b4505 | 755 | #if POK_GBSOUND |
| Pokitto | 0:e8b8f36b4505 | 756 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 757 | playPattern(playOKPattern,0); |
| Pokitto | 0:e8b8f36b4505 | 758 | #endif |
| Pokitto | 0:e8b8f36b4505 | 759 | #endif // POK_GBSOUND |
| Pokitto | 0:e8b8f36b4505 | 760 | } |
| Pokitto | 0:e8b8f36b4505 | 761 | |
| Pokitto | 0:e8b8f36b4505 | 762 | void Sound::playCancel(){ |
| Pokitto | 0:e8b8f36b4505 | 763 | #if POK_GBSOUND |
| Pokitto | 0:e8b8f36b4505 | 764 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 765 | playPattern(playCancelPattern,0); |
| Pokitto | 0:e8b8f36b4505 | 766 | #endif |
| Pokitto | 0:e8b8f36b4505 | 767 | #endif |
| Pokitto | 0:e8b8f36b4505 | 768 | } |
| Pokitto | 0:e8b8f36b4505 | 769 | |
| Pokitto | 0:e8b8f36b4505 | 770 | void Sound::playTick(){ |
| Pokitto | 0:e8b8f36b4505 | 771 | #if POK_GBSOUND |
| Pokitto | 0:e8b8f36b4505 | 772 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 773 | playPattern(playTickP,0); |
| Pokitto | 0:e8b8f36b4505 | 774 | #endif |
| Pokitto | 0:e8b8f36b4505 | 775 | #endif // POK_GBSOUND |
| Pokitto | 0:e8b8f36b4505 | 776 | } |
| Pokitto | 0:e8b8f36b4505 | 777 | |
| Pokitto | 0:e8b8f36b4505 | 778 | void Sound::setVolume(int16_t volume) { |
| Pokitto | 0:e8b8f36b4505 | 779 | //#if NUM_CHANNELS > 0 |
| Pokitto | 0:e8b8f36b4505 | 780 | if (volume<0) volume = 0; |
| Pokitto | 0:e8b8f36b4505 | 781 | if (volume>volumeMax) volume = volumeMax; |
| Pokitto | 0:e8b8f36b4505 | 782 | globalVolume = volume; // % (volumeMax+1); |
| Pokitto | 0:e8b8f36b4505 | 783 | #ifndef POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 784 | volume = (volume / 2)-10; |
| Pokitto | 0:e8b8f36b4505 | 785 | if (volume<0) volume = 0; |
| Pokitto | 0:e8b8f36b4505 | 786 | #if POK_ENABLE_SOUND > 1 |
| Pokitto | 0:e8b8f36b4505 | 787 | setHWvolume(volume); |
| Pokitto | 0:e8b8f36b4505 | 788 | #endif |
| Pokitto | 0:e8b8f36b4505 | 789 | #endif |
| Pokitto | 0:e8b8f36b4505 | 790 | #if POK_SHOW_VOLUME > 0 |
| Pokitto | 0:e8b8f36b4505 | 791 | c.volbar_visible = VOLUMEBAR_TIMEOUT; |
| Pokitto | 0:e8b8f36b4505 | 792 | #endif |
| Pokitto | 0:e8b8f36b4505 | 793 | //#endif |
| Pokitto | 0:e8b8f36b4505 | 794 | } |
| Pokitto | 0:e8b8f36b4505 | 795 | |
| Pokitto | 0:e8b8f36b4505 | 796 | uint16_t Sound::getVolume() { |
| Pokitto | 0:e8b8f36b4505 | 797 | //#if NUM_CHANNELS > 0 |
| Pokitto | 0:e8b8f36b4505 | 798 | return globalVolume; |
| Pokitto | 0:e8b8f36b4505 | 799 | //#else |
| Pokitto | 0:e8b8f36b4505 | 800 | // return 0; |
| Pokitto | 0:e8b8f36b4505 | 801 | //#endif |
| Pokitto | 0:e8b8f36b4505 | 802 | } |
| Pokitto | 0:e8b8f36b4505 | 803 | |
| Pokitto | 0:e8b8f36b4505 | 804 | void Sound::setVolume(int8_t volume, uint8_t channel) { |
| Pokitto | 0:e8b8f36b4505 | 805 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 806 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 807 | return; |
| Pokitto | 0:e8b8f36b4505 | 808 | volume = (volume > VOLUME_CHANNEL_MAX) ? VOLUME_CHANNEL_MAX : volume; |
| Pokitto | 0:e8b8f36b4505 | 809 | volume = (volume < 0) ? 0 : volume; |
| Pokitto | 0:e8b8f36b4505 | 810 | chanVolumes[channel] = volume; |
| Pokitto | 0:e8b8f36b4505 | 811 | #endif |
| Pokitto | 0:e8b8f36b4505 | 812 | } |
| Pokitto | 0:e8b8f36b4505 | 813 | |
| Pokitto | 0:e8b8f36b4505 | 814 | uint8_t Sound::getVolume(uint8_t channel) { |
| Pokitto | 0:e8b8f36b4505 | 815 | #if(NUM_CHANNELS > 0) |
| Pokitto | 0:e8b8f36b4505 | 816 | if(channel>=NUM_CHANNELS) |
| Pokitto | 0:e8b8f36b4505 | 817 | return 255; |
| Pokitto | 0:e8b8f36b4505 | 818 | return (chanVolumes[channel]); |
| Pokitto | 0:e8b8f36b4505 | 819 | #else |
| Pokitto | 0:e8b8f36b4505 | 820 | return 0; |
| Pokitto | 0:e8b8f36b4505 | 821 | #endif |
| Pokitto | 0:e8b8f36b4505 | 822 | } |
| Pokitto | 0:e8b8f36b4505 | 823 | |
| Pokitto | 0:e8b8f36b4505 | 824 | void Sound::playTone(uint8_t os, int frq, uint8_t amp, uint8_t wav,uint8_t arpmode) |
| Pokitto | 0:e8b8f36b4505 | 825 | { |
| Pokitto | 0:e8b8f36b4505 | 826 | if (wav>5) wav=0; |
| Pokitto | 0:e8b8f36b4505 | 827 | if (arpmode>MAX_ARPMODE) arpmode=MAX_ARPMODE; |
| Pokitto | 0:e8b8f36b4505 | 828 | if (os==1) setOSC(&osc1,1,wav,1,0,0,frq,amp,0,0,0,0,0,0,arpmode,0,0); |
| Pokitto | 0:e8b8f36b4505 | 829 | 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 | 830 | 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 | 831 | } |
| Pokitto | 0:e8b8f36b4505 | 832 | |
| Pokitto | 0:e8b8f36b4505 | 833 | void Sound::playTone(uint8_t os, uint16_t frq, uint8_t volume, uint32_t duration) |
| Pokitto | 0:e8b8f36b4505 | 834 | { |
| Pokitto | 0:e8b8f36b4505 | 835 | if (os==1) setOSC(&osc1,1,WSAW,frq,volume,duration); |
| Pokitto | 0:e8b8f36b4505 | 836 | else if (os==2) setOSC(&osc2,1,WTRI,frq,volume,duration); |
| Pokitto | 0:e8b8f36b4505 | 837 | else if (os==3) setOSC(&osc3,1,WTRI,frq,volume,duration); |
| Pokitto | 0:e8b8f36b4505 | 838 | } |
| Pokitto | 0:e8b8f36b4505 | 839 | |
| Pokitto | 0:e8b8f36b4505 | 840 | uint8_t Sound::ampIsOn() |
| Pokitto | 0:e8b8f36b4505 | 841 | { |
| Pokitto | 0:e8b8f36b4505 | 842 | #ifdef POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 843 | return core.ampIsOn(); |
| Pokitto | 0:e8b8f36b4505 | 844 | #else |
| Pokitto | 1:4b1511a0a2c2 | 845 | #if POK_ENABLE_SOUND > 1 |
| Pokitto | 0:e8b8f36b4505 | 846 | return Pokitto::ampIsOn(); |
| Pokitto | 1:4b1511a0a2c2 | 847 | #endif |
| Pokitto | 0:e8b8f36b4505 | 848 | #endif // POK_SIM |
| Pokitto | 2:968589ca3484 | 849 | return 0; |
| Pokitto | 0:e8b8f36b4505 | 850 | } |
| Pokitto | 0:e8b8f36b4505 | 851 | |
| Pokitto | 0:e8b8f36b4505 | 852 | void Sound::ampEnable(uint8_t v) { |
| Pokitto | 0:e8b8f36b4505 | 853 | #ifdef POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 854 | core.ampEnable(v); |
| Pokitto | 0:e8b8f36b4505 | 855 | #else |
| Pokitto | 1:4b1511a0a2c2 | 856 | #if POK_ENABLE_SOUND > 1 |
| Pokitto | 0:e8b8f36b4505 | 857 | Pokitto::ampEnable(v); |
| Pokitto | 1:4b1511a0a2c2 | 858 | #endif |
| Pokitto | 0:e8b8f36b4505 | 859 | #endif // POK_SIM |
| Pokitto | 0:e8b8f36b4505 | 860 | |
| Pokitto | 0:e8b8f36b4505 | 861 | } |
| Pokitto | 0:e8b8f36b4505 | 862 | |
| Pokitto | 0:e8b8f36b4505 | 863 | int Sound::playMusicStream(char* filename) |
| Pokitto | 0:e8b8f36b4505 | 864 | { |
| Pokitto | 2:968589ca3484 | 865 | return playMusicStream(filename,0); |
| Pokitto | 0:e8b8f36b4505 | 866 | } |
| Pokitto | 0:e8b8f36b4505 | 867 | |
| Pokitto | 0:e8b8f36b4505 | 868 | int Sound::playMusicStream() |
| Pokitto | 0:e8b8f36b4505 | 869 | { |
| Pokitto | 0:e8b8f36b4505 | 870 | #if POK_STREAMING_MUSIC >0 |
| Pokitto | 0:e8b8f36b4505 | 871 | if (currentPtr) { |
| Pokitto | 0:e8b8f36b4505 | 872 | pokPlayStream(); |
| Pokitto | 0:e8b8f36b4505 | 873 | return 1; |
| Pokitto | 0:e8b8f36b4505 | 874 | } else return 0; //no stream |
| Pokitto | 0:e8b8f36b4505 | 875 | #endif // POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 876 | } |
| Pokitto | 0:e8b8f36b4505 | 877 | |
| Pokitto | 0:e8b8f36b4505 | 878 | void Sound::pauseMusicStream() { |
| Pokitto | 1:4b1511a0a2c2 | 879 | #if POK_ENABLE_SOUND > 1 |
| Pokitto | 0:e8b8f36b4505 | 880 | pokPauseStream(); |
| Pokitto | 1:4b1511a0a2c2 | 881 | #endif |
| Pokitto | 0:e8b8f36b4505 | 882 | } |
| Pokitto | 0:e8b8f36b4505 | 883 | |
| Pokitto | 0:e8b8f36b4505 | 884 | int Sound::playMusicStream(char* filename, uint8_t options) |
| Pokitto | 0:e8b8f36b4505 | 885 | { |
| Pokitto | 0:e8b8f36b4505 | 886 | #if POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 887 | uint8_t result; |
| Pokitto | 0:e8b8f36b4505 | 888 | result = pokInitSD(); |
| Pokitto | 0:e8b8f36b4505 | 889 | if (!isThisFileOpen(filename)) { |
| Pokitto | 0:e8b8f36b4505 | 890 | fileClose(); // close any open files |
| Pokitto | 0:e8b8f36b4505 | 891 | result = fileOpen(filename,FILE_MODE_OVERWRITE | FILE_MODE_BINARY); |
| Pokitto | 0:e8b8f36b4505 | 892 | } |
| Pokitto | 0:e8b8f36b4505 | 893 | |
| Pokitto | 0:e8b8f36b4505 | 894 | if (result) { |
| Pokitto | 0:e8b8f36b4505 | 895 | currentPtr = 0; // mark that no stream is available |
| Pokitto | 0:e8b8f36b4505 | 896 | return 0; // opening music file failed |
| Pokitto | 0:e8b8f36b4505 | 897 | } |
| Pokitto | 0:e8b8f36b4505 | 898 | |
| Pokitto | 0:e8b8f36b4505 | 899 | fileReadBytes(&buffers[0][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 900 | fileReadBytes(&buffers[1][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 901 | fileReadBytes(&buffers[2][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 902 | fileReadBytes(&buffers[3][0],BUFFER_SIZE); |
| Pokitto | 0:e8b8f36b4505 | 903 | currentBuffer = 0; |
| Pokitto | 0:e8b8f36b4505 | 904 | currentPtr = buffers[currentBuffer]; |
| Pokitto | 0:e8b8f36b4505 | 905 | endPtr = currentPtr + BUFFER_SIZE; |
| Pokitto | 0:e8b8f36b4505 | 906 | |
| Pokitto | 0:e8b8f36b4505 | 907 | //streaming = STR_PLAYING|options; |
| Pokitto | 0:e8b8f36b4505 | 908 | |
| Pokitto | 0:e8b8f36b4505 | 909 | if (!options) pokPlayStream(); // activate stream |
| Pokitto | 0:e8b8f36b4505 | 910 | #endif //POK_STREAMING_MUSIC |
| Pokitto | 0:e8b8f36b4505 | 911 | return 1; // opening music file succeeded |
| Pokitto | 0:e8b8f36b4505 | 912 | } |
| Pokitto | 0:e8b8f36b4505 | 913 |
