PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)
Dependents: YATTT sd_map_test cPong SnowDemo ... more
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 TRACKER_EXAMPLE 00040 #include "Tracker.h" 00041 #endif // TRACKER 00042 #ifdef POK_SIM 00043 #include "FileIO.h" 00044 #endif 00045 00046 /** SONG FUNCTIONS **/ 00047 00048 //uint8_t chunk1[CHUNKSIZE], chunk2[CHUNKSIZE]; // 8 rows, 3 channels (columns), 2 bytes per entry 00049 uint8_t chunk[2][CHUNKSIZE]; // 8 rows, 3 channels (columns), 2 bytes per entry 00050 uint8_t cc = 0; 00051 00052 streamsFunction streamCallbackPtr; 00053 00054 #if POK_ENABLE_SOUND > 0 00055 00056 void updatePlaybackSD(uint8_t row) { 00057 // samplespertick determines how long the oscillators are active before they are recalculated (i.e. the next tick 00058 uint8_t i=0; 00059 00060 if (notetick > samplespertick ) { 00061 // TRACK 1 00062 //if (track1on) i = *song.instrument_stream[0]; 00063 i = 0xF; 00064 if (track1on) i = chunk[cc][row+1]>>4; 00065 if (i!=0xF) { 00066 setOSC(&osc1,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00067 chunk[cc][row],patch[i].vol, 00068 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00069 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00070 } 00071 // TRACK 2 00072 //if (track2on) i = *song.instrument_stream[1]; 00073 i = 0xF; 00074 if (track2on) i = chunk[cc][row+3]>>4; 00075 if (i!=0xF) { 00076 setOSC(&osc2,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00077 chunk[cc][row+2],patch[i].vol, 00078 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00079 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00080 } 00081 // TRACK 3 00082 i = 0xF; 00083 if (track3on) i = chunk[cc][row+5]>>4; 00084 if (i!=0xF) { 00085 setOSC(&osc3,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00086 chunk[cc][row]+4,patch[i].vol, 00087 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00088 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00089 } 00090 playerpos++; 00091 if (playerpos == PATTERNLENGTH) { 00092 // move to next song position 00093 playerpos = 0; 00094 /*sequencepos++; 00095 if (sequencepos > song.song_end) { 00096 if (song.song_loop == -1) { 00097 emptyOscillators(); 00098 playing = false; 00099 sequencepos--; 00100 } else { 00101 sequencepos = song.song_loop; 00102 } 00103 } 00104 playerpos = 0; 00105 initStreams(sequencepos); 00106 tableRefresh=true;*/ 00107 } 00108 notetick =0; 00109 } 00110 } 00111 00112 void updatePlayback() { 00113 // samplespertick determines how long the oscillators are active before they are recalculated (i.e. the next tick 00114 uint8_t i=0; 00115 00116 if (notetick > samplespertick ) { 00117 // TRACK 1 00118 if (track1on) i = *song.instrument_stream[0]; 00119 else i = 0; 00120 if (i) { 00121 setOSC(&osc1,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00122 *song.note_stream[0],patch[i].vol, 00123 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00124 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00125 } 00126 // TRACK 2 00127 if (track2on) i = *song.instrument_stream[1]; 00128 else i = 0; 00129 if (i) { 00130 setOSC(&osc2,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00131 *song.note_stream[1],patch[i].vol, 00132 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00133 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00134 } 00135 // TRACK 3 00136 if (track3on) i = *song.instrument_stream[2]; 00137 else i = 0; 00138 if (i) { 00139 setOSC(&osc3,1,patch[i].wave,patch[i].loop, patch[i].echo, patch[i].adsr, 00140 *song.note_stream[2],patch[i].vol, 00141 patch[i].attack, patch[i].decay, patch[i].sustain,patch[i].release, 00142 patch[i].maxbend, patch[i].bendrate, patch[i].arpmode, patch[i].overdrive, patch[i].kick ); 00143 } 00144 playerpos++; 00145 song.instrument_stream[0]++; 00146 song.note_stream[0]++; 00147 song.instrument_stream[1]++; 00148 song.note_stream[1]++; 00149 song.instrument_stream[2]++; 00150 song.note_stream[2]++; 00151 if (playerpos == PATTERNLENGTH) { 00152 // move to next song position 00153 sequencepos++; 00154 if (sequencepos > song.song_end) { 00155 if (song.song_loop == -1) { 00156 emptyOscillators(); 00157 playing = false; 00158 sequencepos--; 00159 } else { 00160 sequencepos = song.song_loop; 00161 } 00162 } 00163 playerpos = 0; 00164 #ifdef TRACKER_EXAMPLE 00165 tracker.initStreams(); 00166 #else 00167 initStreams(sequencepos); 00168 #endif // TRACKER_EXAMPLE 00169 //(*streamCallbackPtr)(); 00170 tableRefresh=true; 00171 } 00172 notetick =0; 00173 } 00174 } 00175 00176 void emptyPatches(){ 00177 for (int i=0; i<16; i++) { 00178 patch[i].vol = 127; 00179 patch[i].on = true; patch[i].wave = 1; patch[i].echo = 0; patch[i].count = 0; patch[i].cinc =0; 00180 patch[i].attack = 0; patch[i].loop = 0; patch[i].adsrphase = 0; patch[i].adsr = 0; patch[i].decay = 20; 00181 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; 00182 } 00183 } 00184 00185 void emptyBlocks(){ 00186 for (int i=0; i<MAXBLOCKS; i++) { 00187 for (int j = 0; j < PATTERNLENGTH; j++) { 00188 block[i].instrument[j] = 0; 00189 block[i].notenumber[j] = 255; 00190 } 00191 } 00192 } 00193 00194 void initStreams(uint8_t seqpos){ 00195 uint8_t blocknum; 00196 // retarget pointers for track 1 00197 // byte = pgm_read_byte(&(mydata[i][j])); 00198 blocknum=song.block_sequence[0][seqpos]; 00199 //blocknum=pgm_read_byte(Song+SONG_SEQUENCE+seqpos); 00200 song.instrument_stream[0]=&block[blocknum].instrument[0]; 00201 song.note_stream[0]=&block[blocknum].notenumber[0]; 00202 // retarget pointers for track 2 00203 blocknum=song.block_sequence[1][seqpos]; 00204 song.instrument_stream[1]=&block[blocknum].instrument[0]; 00205 song.note_stream[1]=&block[blocknum].notenumber[0]; 00206 // retarget pointers for track 3 00207 blocknum=song.block_sequence[2][seqpos]; 00208 song.instrument_stream[2]=&block[blocknum].instrument[0]; 00209 song.note_stream[2]=&block[blocknum].notenumber[0]; 00210 } 00211 00212 void emptySong(){ 00213 song.num_channels = 3; 00214 song.num_patches = 1; 00215 song.song_bpm = 120; 00216 song.num_patterns = 1; 00217 song.song_end = 0; 00218 song.song_loop = 0; // loop back to start 00219 song.rb_version = RBTRACKER_VERSION; 00220 for (uint8_t i = 0; i<10; i++) { 00221 song.block_sequence[0][i]=i*3; // track 1 00222 song.block_sequence[1][i]=i*3+1; // track 2 00223 song.block_sequence[2][i]=i*3+2; // track 3 00224 } 00225 song.instrument_stream[0] = &block[0].instrument[0]; 00226 song.note_stream[0] = &block[0].notenumber[0]; 00227 song.instrument_stream[1] = &block[1].instrument[0]; 00228 song.note_stream[1] = &block[1].notenumber[0]; 00229 song.instrument_stream[2] = &block[2].instrument[0]; 00230 song.note_stream[2] = &block[2].notenumber[0]; 00231 sequencepos = 0; 00232 } 00233 00234 #if POK_ENABLE_SD > 0 00235 00236 int openSongFromSD(char* buffer) { 00237 if (!isThisFileOpen(buffer)) { 00238 fileClose(); // close any open files 00239 fileOpen(buffer,FILE_MODE_OVERWRITE | FILE_MODE_BINARY); 00240 } 00241 return isThisFileOpen(buffer); 00242 } 00243 00244 void writeChunkToSD(uint8_t* buffer) { 00245 if (fileOK()) { 00246 fileWriteBytes(buffer, CHUNKSIZE); 00247 } 00248 } 00249 00250 void readChunkFromSD(uint8_t* buffer) { 00251 if (fileOK()) { 00252 fileReadBytes(buffer, CHUNKSIZE); 00253 } 00254 } 00255 00256 #endif // POK_ENABLE_SD 00257 00258 void registerStreamsCallback(streamsFunction ptr) { 00259 streamCallbackPtr = ptr; 00260 } 00261 00262 #endif // POK_ENABLE_SOUND 00263 00264
Generated on Tue Jul 12 2022 11:20:41 by 1.7.2