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

Dependents:   Sensitive

Fork of PokittoLib by Jonne Valola

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Synth_songfuncs.cpp Source File

Synth_songfuncs.cpp

Go to the documentation of this file.
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