PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)
Fork of PokittoLib by
Synth_songfuncs.cpp
00001 /**************************************************************************/ 00002 /*! 00003 @file Synth_songfuncs.cpp 00004 @author Jonne Valola 00005 00006 @section LICENSE 00007 00008 Software License Agreement (BSD License) 00009 00010 Copyright (c) 2016, Jonne Valola 00011 All rights reserved. 00012 00013 Redistribution and use in source and binary forms, with or without 00014 modification, are permitted provided that the following conditions are met: 00015 1. Redistributions of source code must retain the above copyright 00016 notice, this list of conditions and the following disclaimer. 00017 2. Redistributions in binary form must reproduce the above copyright 00018 notice, this list of conditions and the following disclaimer in the 00019 documentation and/or other materials provided with the distribution. 00020 3. Neither the name of the copyright holders nor the 00021 names of its contributors may be used to endorse or promote products 00022 derived from this software without specific prior written permission. 00023 00024 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY 00025 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00026 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 00028 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00029 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00031 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00033 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 /**************************************************************************/ 00036 00037 #include "PokittoDisk.h " 00038 #include "Synth.h " 00039 #ifdef POK_SIM 00040 #include "FileIO.h" 00041 #endif 00042 00043 /** SONG FUNCTIONS **/ 00044 00045 //uint8_t chunk1[CHUNKSIZE], chunk2[CHUNKSIZE]; // 8 rows, 3 channels (columns), 2 bytes per entry 00046 uint8_t chunk[2][CHUNKSIZE]; // 8 rows, 3 channels (columns), 2 bytes per entry 00047 uint8_t cc = 0; 00048 00049 00050 #if POK_ENABLE_SOUND > 0 00051 #if POK_ENABLE_SD > 0 00052 void updatePlaybackSD(uint8_t row) { 00053 // samplespertick determines how long the oscillators are active before they are recalculated (i.e. the next tick 00054 uint8_t i=0; 00055 00056 if (notetick > samplespertick ) { 00057 // TRACK 1 00058 //if (track1on) i = *song.instrument_stream[0]; 00059 i = 0xF; 00060 if (track1on) i = chunk[cc][row+1]>>4; 00061 if (i!=0xF) { 00062 setOSC(&osc1,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00063 chunk[cc][row],patch[i].vol, 00064 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00065 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00066 } 00067 // TRACK 2 00068 //if (track2on) i = *song.instrument_stream[1]; 00069 i = 0xF; 00070 if (track2on) i = chunk[cc][row+3]>>4; 00071 if (i!=0xF) { 00072 setOSC(&osc2,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00073 chunk[cc][row+2],patch[i].vol, 00074 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00075 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00076 } 00077 // TRACK 3 00078 i = 0xF; 00079 if (track3on) i = chunk[cc][row+5]>>4; 00080 if (i!=0xF) { 00081 setOSC(&osc3,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00082 chunk[cc][row]+4,patch[i].vol, 00083 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00084 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00085 } 00086 playerpos++; 00087 if (playerpos == PATTERNLENGTH) { 00088 // move to next song position 00089 playerpos = 0; 00090 /*sequencepos++; 00091 if (sequencepos > song.song_end) { 00092 if (song.song_loop == -1) { 00093 emptyOscillators(); 00094 playing = false; 00095 sequencepos--; 00096 } else { 00097 sequencepos = song.song_loop; 00098 } 00099 } 00100 playerpos = 0; 00101 initStreams(sequencepos); 00102 tableRefresh=true;*/ 00103 } 00104 notetick =0; 00105 } 00106 } 00107 00108 void updatePlayback() { 00109 // samplespertick determines how long the oscillators are active before they are recalculated (i.e. the next tick 00110 uint8_t i=0; 00111 00112 if (notetick > samplespertick ) { 00113 // TRACK 1 00114 if (track1on) i = *song.instrument_stream[0]; 00115 else i = 0; 00116 if (i) { 00117 setOSC(&osc1,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00118 *song.note_stream[0],patch[i].vol, 00119 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00120 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00121 } 00122 // TRACK 2 00123 if (track2on) i = *song.instrument_stream[1]; 00124 else i = 0; 00125 if (i) { 00126 setOSC(&osc2,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00127 *song.note_stream[1],patch[i].vol, 00128 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00129 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00130 } 00131 // TRACK 3 00132 if (track3on) i = *song.instrument_stream[2]; 00133 else i = 0; 00134 if (i) { 00135 setOSC(&osc3,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00136 *song.note_stream[2],patch[i].vol, 00137 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00138 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00139 } 00140 playerpos++; 00141 song.instrument_stream[0]++; 00142 song.note_stream[0]++; 00143 song.instrument_stream[1]++; 00144 song.note_stream[1]++; 00145 song.instrument_stream[2]++; 00146 song.note_stream[2]++; 00147 if (playerpos == PATTERNLENGTH) { 00148 // move to next song position 00149 sequencepos++; 00150 if (sequencepos > song.song_end) { 00151 if (song.song_loop == -1) { 00152 emptyOscillators(); 00153 playing = false; 00154 sequencepos--; 00155 } else { 00156 sequencepos = song.song_loop; 00157 } 00158 } 00159 playerpos = 0; 00160 initStreams(sequencepos); 00161 tableRefresh=true; 00162 } 00163 notetick =0; 00164 } 00165 } 00166 00167 void emptyPatches(){ 00168 for (int i=0; i<16; i++) { 00169 patch[i].vol = 127; 00170 patch[i].on = true; patch[i].wave = 1; patch[i].echo = 0; patch[i].count = 0; patch[i].cinc =0; 00171 patch[i].attack = 0; patch[i].loop = 0; patch[i].adsrphase = 0; patch[i].adsr = 0; patch[i].decay = 20; 00172 patch[i].pitchbend = 0; patch[i].bendrate = 0; patch[i].maxbend = 0; patch[i].sustain = 0; patch[i].release = 0, patch[i].overdrive = 0, patch[i].kick = 0; 00173 } 00174 } 00175 00176 void emptyBlocks(){ 00177 for (int i=0; i<MAXBLOCKS; i++) { 00178 for (int j = 0; j < PATTERNLENGTH; j++) { 00179 block[i].instrument[j] = 0; 00180 block[i].notenumber[j] = 255; 00181 } 00182 } 00183 } 00184 00185 void initStreams(uint8_t seqpos){ 00186 uint8_t blocknum; 00187 // retarget pointers for track 1 00188 // byte = pgm_read_byte(&(mydata[i][j])); 00189 blocknum=song.block_sequence[0][seqpos]; 00190 //blocknum=pgm_read_byte(Song+SONG_SEQUENCE+seqpos); 00191 song.instrument_stream[0]=&block[blocknum].instrument[0]; 00192 song.note_stream[0]=&block[blocknum].notenumber[0]; 00193 // retarget pointers for track 2 00194 blocknum=song.block_sequence[1][seqpos]; 00195 song.instrument_stream[1]=&block[blocknum].instrument[0]; 00196 song.note_stream[1]=&block[blocknum].notenumber[0]; 00197 // retarget pointers for track 3 00198 blocknum=song.block_sequence[2][seqpos]; 00199 song.instrument_stream[2]=&block[blocknum].instrument[0]; 00200 song.note_stream[2]=&block[blocknum].notenumber[0]; 00201 } 00202 00203 void emptySong(){ 00204 song.num_channels = 3; 00205 song.num_patches = 1; 00206 song.song_bpm = 120; 00207 song.num_patterns = 1; 00208 song.song_end = 0; 00209 song.song_loop = 0; // loop back to start 00210 song.rb_version = RBTRACKER_VERSION; 00211 for (uint8_t i = 0; i<10; i++) { 00212 song.block_sequence[0][i]=i*3; // track 1 00213 song.block_sequence[1][i]=i*3+1; // track 2 00214 song.block_sequence[2][i]=i*3+2; // track 3 00215 } 00216 song.instrument_stream[0] = &block[0].instrument[0]; 00217 song.note_stream[0] = &block[0].notenumber[0]; 00218 song.instrument_stream[1] = &block[1].instrument[0]; 00219 song.note_stream[1] = &block[1].notenumber[0]; 00220 song.instrument_stream[2] = &block[2].instrument[0]; 00221 song.note_stream[2] = &block[2].notenumber[0]; 00222 sequencepos = 0; 00223 } 00224 00225 int openSongFromSD(char* buffer) { 00226 if (!isThisFileOpen(buffer)) { 00227 fileClose(); // close any open files 00228 fileOpen(buffer,FILE_MODE_OVERWRITE | FILE_MODE_BINARY); 00229 } 00230 return isThisFileOpen(buffer); 00231 } 00232 00233 void writeChunkToSD(uint8_t* buffer) { 00234 if (fileOK()) { 00235 fileWriteBytes(buffer, CHUNKSIZE); 00236 } 00237 } 00238 00239 void readChunkFromSD(uint8_t* buffer) { 00240 if (fileOK()) { 00241 fileReadBytes(buffer, CHUNKSIZE); 00242 } 00243 } 00244 #endif 00245 #endif // POK_ENABLE_SOUND 00246
Generated on Tue Jul 12 2022 18:08:13 by 1.7.2