From 035e1f82249cedbd7a4be667616c06b13228ea57 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:34:35 +0100 Subject: [PATCH 01/37] Update spi.c --- bfin_lib/src/spi.c | 106 ++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/bfin_lib/src/spi.c b/bfin_lib/src/spi.c index cf54f9732..c3e2c2bb1 100644 --- a/bfin_lib/src/spi.c +++ b/bfin_lib/src/spi.c @@ -31,6 +31,9 @@ static void spi_set_param(u32 idx, ParamValue pv) { // return byte to load for next MISO u8 spi_process(u8 rx) { static ParamValueSwap pval; + static ParamValueSwap o; + static ParamValueSwap s; + switch(byte) { /// caveman style case statement case eCom : @@ -62,14 +65,12 @@ u8 spi_process(u8 rx) { processAudio = 0; return processAudio; break; - - case MSG_OFFSET_COM : - byte = eOffset0; - break; - - case MSG_SAMPLE_COM : - byte = eSample0; - break; + case MSG_OFFSET_COM: + byte = eOffset0; + break; + case MSG_SAMPLE_COM: + byte = eSample0; + break; default: break; @@ -268,53 +269,48 @@ u8 spi_process(u8 rx) { return 0; // don't care break; - - // set offset - case eOffset0 : - byte = eOffset1; - o.asByte[3] = rx; - return 0; - break; - case eOffset1 : - byte = eOffset2; - o.asByte[2] = rx; - return 0; - break; - case eOffset2 : - byte = eOffset3; - o.asByte[1] = rx; - return 0; - break; - case eOffset3 : - o.asByte[0] = rx; - module_set_offset(o.asInt); - byte = eCom; - return 0; - break; - - // set sample - case eSample0 : - byte = eSample1; - s.asByte[3] = rx; - return 0; - break; - case eSample1 : - byte = eSample2; - s.asByte[2] = rx; - return 0; - break; - case eSample2 : - byte = eSample3; - s.asByte[1] = rx; - return 0; - break; - case eSample3 : - s.asByte[0] = rx; - module_set_sample(s.asInt); - byte = eCom; - return 0; - break; - + case eOffset0 : + byte = eOffset1; + o.asByte[3] = rx; + return 0; + break; + case eOffset1 : + byte = eOffset2; + o.asByte[2] = rx; + return 0; + break; + case eOffset2 : + byte = eOffset3; + o.asByte[1] = rx; + return 0; + break; + case eOffset3 : + o.asByte[0] = rx; + module_set_offset(o.asInt); + byte = eCom; + return 0; + break; + case eSample0 : + byte = eSample1; + s.asByte[3] = rx; + return 0; + break; + case eSample1 : + byte = eSample2; + s.asByte[2] = rx; + return 0; + break; + case eSample2 : + byte = eSample3; + s.asByte[1] = rx; + return 0; + break; + case eSample3 : + s.asByte[0] = rx; + module_set_sample(s.asInt); + byte = eCom; + return 0; + break; default: byte = eCom; // reset From 915f5df09ac87cfe2c94632b6711cc525f3f27e0 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:36:17 +0100 Subject: [PATCH 02/37] Update module.h --- bfin_lib/src/module.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bfin_lib/src/module.h b/bfin_lib/src/module.h index 40a17b52c..0894fd90a 100644 --- a/bfin_lib/src/module.h +++ b/bfin_lib/src/module.h @@ -61,6 +61,10 @@ extern void module_init(void); extern void module_deinit(void); // callback extern void module_process_frame(void); +// sample offset +extern void module_set_offset(s32 offset); +// sample +extern void module_set_sample(s32 sample); // set parameter extern void module_set_param(u32 idx, ParamValue val); From a2d991e5c460566b69c633f0bfbf31fd26049713 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:40:42 +0100 Subject: [PATCH 03/37] Update bfin.h --- avr32/src/bfin.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/avr32/src/bfin.h b/avr32/src/bfin.h index 56fd1d88f..2e6748a08 100644 --- a/avr32/src/bfin.h +++ b/avr32/src/bfin.h @@ -14,6 +14,7 @@ //! max size of blackfin ldr file #define BFIN_LDR_MAX_BYTES 0x12000 +#define BFIN_SDRAM_MAX_BYTES 0x4000000 //! wait for busy pin to clear void bfin_wait(void); @@ -36,6 +37,12 @@ void bfin_get_module_name(volatile char* buf); //! get loaded module version void bfin_get_module_version(ModuleVersion* vers); +//! start sample transfer +extern void bfin_sample_start(s32 offset); + +//! end sample transfer +extern void bfin_sample_end(void); + //! enable audio processing extern void bfin_enable(void); From 3900fb51716a494f913046ee6c774adcc32c949c Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:42:06 +0100 Subject: [PATCH 04/37] Update bfin.c --- avr32/src/bfin.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/avr32/src/bfin.c b/avr32/src/bfin.c index 476bb04ae..86647f731 100644 --- a/avr32/src/bfin.c +++ b/avr32/src/bfin.c @@ -210,6 +210,41 @@ void bfin_get_module_version(ModuleVersion* vers) { app_resume(); } +void bfin_sample_start(s32 offset) { + ParamValueSwap o; + + // send offset + o.asInt = offset; + + bfin_wait(); + spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS); + + // set command + spi_write(BFIN_SPI, MSG_OFFSET_COM); + while (!(BFIN_SPI->sr & AVR32_SPI_SR_TXEMPTY_MASK)) { ;; }; + + // byte 1 + spi_write(BFIN_SPI, o.asByte[0]); + while (!(BFIN_SPI->sr & AVR32_SPI_SR_TXEMPTY_MASK)) { ;; }; + + // byte 2 + spi_write(BFIN_SPI, o.asByte[1]); + while (!(BFIN_SPI->sr & AVR32_SPI_SR_TXEMPTY_MASK)) { ;; }; + + // byte 3 + spi_write(BFIN_SPI, o.asByte[2]); + while (!(BFIN_SPI->sr & AVR32_SPI_SR_TXEMPTY_MASK)) { ;; }; + + // byte 4 + spi_write(BFIN_SPI, o.asByte[3]); + while (!(BFIN_SPI->sr & AVR32_SPI_SR_TXEMPTY_MASK)) { ;; }; +} + +void bfin_sample_end(void) { + bfin_wait(); + spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS); +} + void bfin_enable(void) { // enable audio processing spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS); From 905daab117ecf432ddf345cc37e393168620389c Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:42:48 +0100 Subject: [PATCH 05/37] Update filesystem.h --- avr32/src/filesystem.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/avr32/src/filesystem.h b/avr32/src/filesystem.h index c592e0d4a..f39dc3ba1 100644 --- a/avr32/src/filesystem.h +++ b/avr32/src/filesystem.h @@ -8,8 +8,6 @@ //===================================== //==== vars -// transfer-done flag -//extern volatile u8 fsEndTransfer; // Local RAM buffer to store data to/from the SD/MMC card extern volatile U8 pdcaRxBuf[FS_BUF_SIZE]; extern volatile U8 pdcaTxBuf[FS_BUF_SIZE]; @@ -20,8 +18,6 @@ extern volatile avr32_pdca_channel_t* pdcaTxChan; //==================================== //==== funcs extern int fat_init(void); - -//PRGM SAMPLE TRANSFER PR extern int bfin_sample_transfer(unsigned long sector, unsigned long bytes); #endif // h guard From 4e6f98e13c4364771dfd56ab5874693051a65bfe Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:44:54 +0100 Subject: [PATCH 06/37] Update filesystem.c --- avr32/src/filesystem.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/avr32/src/filesystem.c b/avr32/src/filesystem.c index 577436b43..da900245c 100644 --- a/avr32/src/filesystem.c +++ b/avr32/src/filesystem.c @@ -34,8 +34,6 @@ volatile avr32_pdca_channel_t *pdcaTxChan; //---- low level i/o int media_read(unsigned long sector, unsigned char *buffer, unsigned long sector_count); - -// PRGM SAMPLE TRANSFER PR, REMOVED FLAG! int media_read(unsigned long sector, unsigned char *buffer, unsigned long sector_count) { unsigned long i; @@ -126,7 +124,6 @@ int fat_init(void) { } } -//PRGM SAMPLE TRANSFER PR; THIS COULD MAYBE LIVE SOMEWHER ELSE.. int bfin_sample_transfer(unsigned long sector, unsigned long bytes) { unsigned long i; From ade093b22784bd87f253809adc9bb7beb5692ad3 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:46:12 +0100 Subject: [PATCH 07/37] Update files.h --- apps/bees/src/files.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/bees/src/files.h b/apps/bees/src/files.h index 3cacfe630..9b15c84c2 100644 --- a/apps/bees/src/files.h +++ b/apps/bees/src/files.h @@ -3,6 +3,7 @@ #include "types.h" #include "util.h" +#include "filesystem.h" //includes fat_filelib.h EXTERN_C_BEGIN // initialize filesystem navigation @@ -63,6 +64,9 @@ extern u8 files_get_scaler_count(void); // return 1 on success, 0 on failure extern u8 files_load_scaler_name(const char* name, s32* dst, u32 dstSize); +//----- samples +extern void files_load_samples(void); + //----- param descriptors // search for named .dsc file and load into network param desc memory extern u8 files_load_desc(const char* name); From f14ed352a7cadce275ffb5bcac2364de182ce680 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:49:11 +0100 Subject: [PATCH 08/37] Update files.c --- apps/bees/src/files.c | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/apps/bees/src/files.c b/apps/bees/src/files.c index ca1f4068b..7ca48c9d3 100644 --- a/apps/bees/src/files.c +++ b/apps/bees/src/files.c @@ -43,6 +43,7 @@ #define DSP_PATH "/mod/" #define SCENES_PATH "/data/bees/scenes/" #define SCALERS_PATH "/data/bees/scalers/" +#define SAMPLES_PATH "/data/bees/samples/" // endinanness // #define SCALER_LE 1 @@ -66,6 +67,7 @@ typedef struct _dirList { static dirList_t dspList; static dirList_t sceneList; static dirList_t scalerList; +static dirList_t sampleList; //---------------------------------- //---- static functions @@ -77,6 +79,8 @@ static const char* list_get_name(dirList_t* list, u8 idx); // get read file pointer if found (caller must close) // set size by pointer static void* list_open_file_name(dirList_t* list, const char* name, const char* mode, u32* size); +// load sample file with path +static void load_sample_withPath(const char *path); // fake fread: no size arg, always byte @@ -432,6 +436,34 @@ u8 files_load_scaler_name(const char* name, s32* dst, u32 dstSize) { return ret; } +//////////////////////// +//// samples +void files_load_samples(void) { + FL_DIR dirstat; + struct fs_dir_ent dirent; + sampleList.num = 0; + + char *fpath = (char*)alloc_mem(64 * (sizeof(char*))); + + // check directory for samples + strcpy(sampleList.path, SAMPLES_PATH); + + if (fl_opendir(sampleList.path, &dirstat)) + { + while (fl_readdir(&dirstat, &dirent) == 0) + { + if(!(dirent.is_dir)) + { + strcpy(fpath, sampleList.path); + strcat(fpath, dirent.filename); + load_sample_withPath(fpath); + sampleList.num++; + } + } + } + + free(fpath); +} //--------------------- //------ static @@ -695,3 +727,69 @@ void files_load_sample(u8 n) { } } +static void load_sample_withPath(const char *path) { + void *fp; + + static u32 sdramMemory = BFIN_SDRAM_MAX_BYTES; + static u32 sdramOffset = 0; + u32 fsize, foffset, fchunk, ssize; + + delay_ms(10); + + fp = fl_fopen(path, "r"); + fsize = ((FL_FILE*)(fp))->filelength; + foffset = ((FL_FILE*)(fp))->bytenum % FAT_SECTOR_SIZE; + + ssize = fsize / sizeof(s32); + + // verify available SDRAM + if ((sdramMemory -= ssize) > 0) + { + if (fp != NULL) + { + render_boot(path); + + app_pause(); + + bfin_sample_start(sdramOffset); + + do + { + if (fsize < FAT_SECTOR_SIZE) + { + fchunk = fsize; + } + else + { + fchunk = FAT_SECTOR_SIZE; + } + fsize -= fchunk; + + bfin_sample_transfer(fl_return_sector(fp, foffset), fchunk); + + foffset += 1; + ((FL_FILE*)(fp))->bytenum += fchunk; + } + while (fsize > 0); + + bfin_sample_end(); + + // refresh sdram offset + sdramOffset += ssize; + + fl_fclose(fp); + + app_resume(); + } + else + { + render_boot("sample file error"); + fl_fclose(fp); + } + } + else + { + render_boot("SDRAM limit error"); + fl_fclose(fp); + } +} From 073c30c7d20c8614bd373ce003c0322f911c42f0 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:50:39 +0100 Subject: [PATCH 09/37] Update fat_filelib.h --- avr32/src/fat_io_lib/fat_filelib.h | 1 + 1 file changed, 1 insertion(+) diff --git a/avr32/src/fat_io_lib/fat_filelib.h b/avr32/src/fat_io_lib/fat_filelib.h index d3da92b60..fa8dc4763 100644 --- a/avr32/src/fat_io_lib/fat_filelib.h +++ b/avr32/src/fat_io_lib/fat_filelib.h @@ -81,6 +81,7 @@ int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr); void fl_shutdown(void); // Standard API +uint32 fl_return_sector(FL_FILE *file, uint32 offset); void *fl_fopen(const char *path, const char *modifiers); void fl_fclose(void *file); int fl_fflush(void *file); From 3723248e6ce1dd5f11e829d0cdaec71e5310977e Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:51:31 +0100 Subject: [PATCH 10/37] Update fat_filelib.c --- avr32/src/fat_io_lib/fat_filelib.c | 69 ++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/avr32/src/fat_io_lib/fat_filelib.c b/avr32/src/fat_io_lib/fat_filelib.c index e6f9142f9..698871ac1 100644 --- a/avr32/src/fat_io_lib/fat_filelib.c +++ b/avr32/src/fat_io_lib/fat_filelib.c @@ -605,6 +605,75 @@ static uint32 _read_sectors(FL_FILE *file, uint32 offset, uint8 *buffer, // External API //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// fl_return_sector: Return current file offset +//----------------------------------------------------------------------------- + +uint32 fl_return_sector(FL_FILE *file, uint32 offset) +{ + uint32 Sector = 0; + uint32 ClusterIdx = 0; + uint32 Cluster = 0; + uint32 i; + + // Find cluster index within file & sector with cluster + ClusterIdx = offset / _fs.sectors_per_cluster; + Sector = offset - (ClusterIdx * _fs.sectors_per_cluster); + + // Quick lookup for next link in the chain + if (ClusterIdx == file->last_fat_lookup.ClusterIdx) + Cluster = file->last_fat_lookup.CurrentCluster; + // Else walk the chain + else + { + // Starting from last recorded cluster? + if (ClusterIdx && ClusterIdx == file->last_fat_lookup.ClusterIdx + 1) + { + i = file->last_fat_lookup.ClusterIdx; + Cluster = file->last_fat_lookup.CurrentCluster; + } + // Start searching from the beginning.. + else + { + // Set start of cluster chain to initial value + i = 0; + Cluster = file->startcluster; + } + + // Follow chain to find cluster to read + for ( ;ilast_fat_lookup.CurrentCluster = Cluster; + file->last_fat_lookup.ClusterIdx = ClusterIdx; + } + } + + // If end of cluster chain then return false + if (Cluster == FAT32_LAST_CLUSTER) + return 0; + + // Calculate sector address + return fatfs_lba_of_cluster(&_fs, Cluster) + Sector; +} + //----------------------------------------------------------------------------- // fl_init: Initialise library //----------------------------------------------------------------------------- From 2c2c35bf0be5d88a4a8c9d7e5f85719217183ae2 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:52:53 +0100 Subject: [PATCH 11/37] Update interrupts.c --- avr32/src/interrupts.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/avr32/src/interrupts.c b/avr32/src/interrupts.c index a03a0c3f3..06c54cd16 100644 --- a/avr32/src/interrupts.c +++ b/avr32/src/interrupts.c @@ -84,8 +84,6 @@ static void irq_pdca(void) { // enable all interrupts. cpu_irq_enable(); - - //REMOVED FLAG, SEE filesystem.c } // timer irq From 8fcef235cf267f1ec91bf6c2c8e52a5163622cd1 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:54:22 +0100 Subject: [PATCH 12/37] Update protocol.h --- common/protocol.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/common/protocol.h b/common/protocol.h index 98a5d4137..97b538be7 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -32,9 +32,9 @@ // get param change CPU use (0 - 0x7fffffff) #define MSG_GET_CONTROL_CPU_COM 10 -// PRGM SAMPLE TRANSFER, THESE WOULD BE ADDED WITH APPROPRIATE ID's! -#define MSG_OFFSET_COM X -#define MSG_SAMPLE_COM Y +// sample transfer commands +#define MSG_OFFSET_COM 11 +#define MSG_SAMPLE_COM 12 // enumerate state-machine nodes for sending and receiving SPI. @@ -95,6 +95,18 @@ typedef enum { eModuleVersionRev0, eModuleVersionRev1, + // sample offset + eOffset0, + eOffset1, + eOffset2, + eOffset3, + + // sample + eSample0, + eSample1, + eSample2, + eSample3, + // buffer eBufferNumBytes0, eBufferNumBytes1, @@ -112,18 +124,6 @@ typedef enum { eGetControlCpuData1, eGetControlCpuData2, - // offset - eOffset0, - eOffset1, - eOffset2, - eOffset3, - - // sample - eSample0, - eSample1, - eSample2, - eSample3, - eNumSpiBytes } eSpiByte; From 8057b9d4a89f4c549c81718828cb88e98bbab7a9 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:57:31 +0100 Subject: [PATCH 13/37] Update app_bees.c --- apps/bees/src/app_bees.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/bees/src/app_bees.c b/apps/bees/src/app_bees.c index ce81a7309..a9f0bfd9d 100644 --- a/apps/bees/src/app_bees.c +++ b/apps/bees/src/app_bees.c @@ -47,8 +47,8 @@ const AppVersion beesVersion = { .min = MIN , .maj = MAJ , .rev = REV }; //--- static vars static char versionString[12] = VERSIONSTRING; -#define DEFAULT_LDR "waves.ldr" -#define DEFAULT_DSC "waves.dsc" +#define DEFAULT_LDR "mix.ldr" +#define DEFAULT_DSC "mix.dsc" // this is called during hardware initialization. // allocate memory. @@ -131,8 +131,8 @@ u8 app_launch(eLaunchState state) { bfin_wait_ready(); // print_dbg("\r\n enable DSP audio..."); - render_boot("enabling audio"); - bfin_enable(); + //render_boot("enabling audio"); + //bfin_enable(); } else { @@ -163,6 +163,15 @@ u8 app_launch(eLaunchState state) { } + // load samples + bfin_disable(); + print_dbg("\r\n load samples..."); + files_load_samples(); + + print_dbg("\r\n enable DSP audio..."); + render_boot("enabling audio"); + bfin_enable(); + // init pages (fill graphics buffers) render_boot("initializing gfx"); print_dbg("\r\n pages_init..."); From 0a514c769acf48fc7d1905d35dceb4fb21bdeca7 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Thu, 22 Mar 2018 23:58:41 +0100 Subject: [PATCH 14/37] Update init.c --- avr32/src/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avr32/src/init.c b/avr32/src/init.c index f3adf563c..8cd223765 100644 --- a/avr32/src/init.c +++ b/avr32/src/init.c @@ -256,7 +256,7 @@ void init_bfin_resources(void) { .spck_delay = 0, // .trans_delay = 0, //// try and reduce this... - .trans_delay = 20, + .trans_delay = 1, .stay_act = 1, .spi_mode = 1, .modfdis = 1 From b000aee518d05946997ccc13babd2b91dcf96f6d Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Fri, 23 Mar 2018 00:04:42 +0100 Subject: [PATCH 15/37] Update mix.c --- modules/mix/mix.c | 272 +++++++++++++++++++++++----------------------- 1 file changed, 133 insertions(+), 139 deletions(-) diff --git a/modules/mix/mix.c b/modules/mix/mix.c index ac71728e8..da7fb4955 100644 --- a/modules/mix/mix.c +++ b/modules/mix/mix.c @@ -14,6 +14,7 @@ //-- aleph/common headers #include "types.h" +#include //-- aleph/bfin-lib headers // global variables @@ -34,120 +35,112 @@ // parameter lists and constants #include "params.h" -// customized module data structure -// this will be located at the top of SDRAM (64MB) -// all other variables (code, stack, heap) are located in SRAM (64K) -typedef struct _mixData { - //... here is where you would put other large data structures. - - // for example, a multichannel delay module would need an audio buffer: - // volatile fract32 audioBuffer[NUM_BUFS][FRAMES_PER_BUF]; - - // bear in mind that access to SDRAM is significantly slower than SRAM (10-20 cycles!) - // so don't put anything here that doesn't need the extra space. -} mixData; - -//------------------------- -//----- extern variables (initialized here) - - -// global pointer to module descriptor. -// required by the aleph-bfin library! -ModuleData* gModuleData; +#define BUFFERSIZE 0x100000 -//-----------------------bfin_lib/src/ -//------ static variables +typedef struct _sampleBuffer { + volatile fract32 *data; //pointer to data + u32 samples; //count of samples +} sampleBuffer; -/* - here's the actual memory for module descriptor and param data - global pointers are to point at these here during module init. - we do it in this indirect way, because - a) modules have variable param count - b) in an extreme case, might need to locate param data in SDRAM - ( until recently, SDRAM contained full param descriptors.) -*/ -static ModuleData super; -static ParamData mParamData[eParamNumParams]; +typedef struct _bufferHead { + sampleBuffer *buf; //pointer to buffer + u32 idx; //current idx +} bufferHead; -// input values -static fract32 adcVal[4]; -static filter_1p_lo adcSlew[4]; +static void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples); +static void buffer_head_init(bufferHead *head, sampleBuffer *buf); +static s32 buffer_head_play(bufferHead *head); +typedef struct _mixData { + ModuleData super; + ParamData mParamData[eParamNumParams]; + + volatile fract32 sampleBuffer[BUFFERSIZE]; +} mixData; -// cv values (16 bits, but use fract32 and audio integrators) -static fract32 cvVal[4]; -static filter_1p_lo cvSlew[4]; -// current channel to update - see below in process_cv() -static u8 cvChan = 0; +ModuleData *gModuleData; +mixData *data; +sampleBuffer onchipbuffer[4]; +u32 offset = 0; -// audio output bus -static fract32 outBus = 0; +bufferHead heads[4]; -//----------------- -//--- static function declaration +fract32 adcVal[4] = { 0, 0, 0, 0 }; +filter_1p_lo adcSlew[4]; +fract32 cvVal[4] = { 0, 0, 0, 0 }; +filter_1p_lo cvSlew[4]; +u8 cvChan = 0; +fract32 outBus = 0; -// update cv output static void process_cv(void); - -// small helper function to set parameter initial values static inline void param_setup(u32 id, ParamValue v) { - // set the input data so that bfin core will report it - // back to the controller via SPI, when requested. - // (bees will make such a request of each param at launch to sync with network.) - // this is also how a polled analysis parameter would work. - gModuleData->paramData[id].value = v; - module_set_param(id, v); + gModuleData->paramData[id].value = v; + module_set_param(id, v); } - -//---------------------- -//----- external functions - void module_init(void) { - // initialize module superclass data - // by setting global pointers to our own data - gModuleData = &super; - gModuleData->paramData = mParamData; - gModuleData->numParams = eParamNumParams; - - // initialize 1pole filters for input attenuation slew - filter_1p_lo_init( &(adcSlew[0]), 0 ); - filter_1p_lo_init( &(adcSlew[1]), 0 ); - filter_1p_lo_init( &(adcSlew[2]), 0 ); - filter_1p_lo_init( &(adcSlew[3]), 0 ); - - // initialize 1pole filters for cv output slew - filter_1p_lo_init( &(cvSlew[0]), 0 ); - filter_1p_lo_init( &(cvSlew[1]), 0 ); - filter_1p_lo_init( &(cvSlew[2]), 0 ); - filter_1p_lo_init( &(cvSlew[3]), 0 ); - - - // set initial param values - // constants are from params.h - param_setup(eParam_cv0, 0 ); - param_setup(eParam_cv1, 0 ); - param_setup(eParam_cv2, 0 ); - param_setup(eParam_cv3, 0 ); - - // set amp to 1/4 (-12db) with right-shift intrinsic - param_setup(eParam_adc0, PARAM_AMP_MAX >> 2 ); - param_setup(eParam_adc1, PARAM_AMP_MAX >> 2 ); - param_setup(eParam_adc2, PARAM_AMP_MAX >> 2 ); - param_setup(eParam_adc3, PARAM_AMP_MAX >> 2 ); - - // set slew defaults. the value is pretty arbitrary - param_setup(eParam_adcSlew0, PARAM_SLEW_DEFAULT); - param_setup(eParam_adcSlew1, PARAM_SLEW_DEFAULT); - param_setup(eParam_adcSlew2, PARAM_SLEW_DEFAULT); - param_setup(eParam_adcSlew3, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew0, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew1, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew2, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew3, PARAM_SLEW_DEFAULT); - - - + data = (mixData*)SDRAM_ADDRESS; + gModuleData = &(data->super); + strcpy(gModuleData->name, "mix"); + gModuleData->paramData = data->mParamData; + gModuleData->numParams = eParamNumParams; + + u32 n, i; + + for(n=0; n<4; n++) + { + buffer_init(&(onchipbuffer[n]), data->sampleBuffer, BUFFERSIZE); + } + + for(n=0; n<4; n++) + { + buffer_head_init(&(heads[n]), &(onchipbuffer[n])); + } + + for(i=0; isampleBuffer[i] = 0x00000000; + } + + offset = 0; + + // init parameters +// for(n=0; n> 2 ); + param_setup(eParam_adc1, PARAM_AMP_MAX >> 2 ); + param_setup(eParam_adc2, PARAM_AMP_MAX >> 2 ); + param_setup(eParam_adc3, PARAM_AMP_MAX >> 2 ); + + // set slew defaults. the value is pretty arbitrary + param_setup(eParam_adcSlew0, PARAM_SLEW_DEFAULT); + param_setup(eParam_adcSlew1, PARAM_SLEW_DEFAULT); + param_setup(eParam_adcSlew2, PARAM_SLEW_DEFAULT); + param_setup(eParam_adcSlew3, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew0, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew1, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew2, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew3, PARAM_SLEW_DEFAULT); } // de-init (never actually used on blackfin, but maybe by emulator) @@ -165,46 +158,33 @@ u32 module_get_num_params(void) { // frame process function! // called each audio frame from codec interrupt handler // ( bad, i know, see github issues list ) -void module_process_frame(void) { - - //--- process slew - - // - // update filters, calling "class method" on pointer to each - adcVal[0] = filter_1p_lo_next( &(adcSlew[0]) ); - adcVal[1] = filter_1p_lo_next( &(adcSlew[1]) ); - adcVal[2] = filter_1p_lo_next( &(adcSlew[2]) ); - adcVal[3] = filter_1p_lo_next( &(adcSlew[3]) ); - - //--- mix - - // zero the output bus - outBus = 0; - - /* - note the use of fract32 arithmetic intrinsics! - these are fast saturating multiplies/adds for 32bit signed fractions in [-1, 1) - there are also intrinsics for fr16, mixed modes, and conversions. - for details see: - http://blackfin.uclinux.org/doku.php?id=toolchain:built-in_functions - */ - // scale each input and add it to the bus - outBus = add_fr1x32( outBus, mult_fr1x32x32(in[0], adcVal[0]) ); - outBus = add_fr1x32( outBus, mult_fr1x32x32(in[1], adcVal[1]) ); - outBus = add_fr1x32( outBus, mult_fr1x32x32(in[2], adcVal[2]) ); - outBus = add_fr1x32( outBus, mult_fr1x32x32(in[3], adcVal[3]) ); - - // copy the bus to all the outputs - out[0] = outBus; - out[1] = outBus; - out[2] = outBus; - out[3] = outBus; - - - //--- cv - process_cv(); +void module_process_frame(void) { + heads[0].idx += 1; + if (heads[0].idx > 48000) + { + heads[0].idx = 0; + } + + out[0] = out[1] = buffer_head_play(&(heads[0])); + + /* + const fract32 c = 1664525 ; + const fract32 a = 1013904223 ; + static fract32 x = 666; + x = x * c + a; + */ } +// sample offset +void module_set_offset(ParamValue v) { + offset = v; +} + +// sample +void module_set_sample(ParamValue v) { + data->sampleBuffer[offset] = v; + offset++; +} // parameter set function void module_set_param(u32 idx, ParamValue v) { @@ -309,3 +289,17 @@ void process_cv(void) { cvChan = 0; } } + +void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples) { + buf->data = data; + buf->samples = samples; +} + +void buffer_head_init(bufferHead *head, sampleBuffer *buf) { + head->buf = buf; + head->idx = 0; +} + +s32 buffer_head_play(bufferHead *head) { + return head->buf->data[head->idx]; +} From 50c6b3b00e095994a5cc0b56446d8a4912ba1e1a Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Fri, 23 Mar 2018 00:05:29 +0100 Subject: [PATCH 16/37] Update mix.lds --- modules/mix/mix.lds | 266 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 248 insertions(+), 18 deletions(-) diff --git a/modules/mix/mix.lds b/modules/mix/mix.lds index 800eb82dc..aa7690c63 100755 --- a/modules/mix/mix.lds +++ b/modules/mix/mix.lds @@ -1,25 +1,255 @@ /* - * Copyright (C) 2007, 2008 Analog Devices, Inc. - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ +* Copyright (C) 2007, 2008 Analog Devices, Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice is included verbatim in any distributions. No written agreement, +* license, or royalty fee is required for any of the authorized uses. +* Modifications to this software may be copyrighted by their authors +* and need not follow the licensing terms described here, provided that +* the new terms are clearly indicated on the first page of each file where +* they apply. +*/ /* The default linker script, for single core blackfin standalone executables */ MEMORY { - MEM_L1_CODE : ORIGIN = 0xFFA00000, LENGTH = 0x10000 - MEM_L1_CODE_CACHE : ORIGIN = 0xFFA10000, LENGTH = 0x4000 - MEM_L1_SCRATCH : ORIGIN = 0xFFB00000, LENGTH = 0x1000 - MEM_L1_DATA_B : ORIGIN = 0xFF900000, LENGTH = 0x8000 - MEM_L1_DATA_A : ORIGIN = 0xFF800000, LENGTH = 0x8000 - MEM_L2 : ORIGIN = 0xFEB00000, LENGTH = 0x0 +MEM_L1_CODE : ORIGIN = 0xFFA00000, LENGTH = 0x10000 +MEM_L1_CODE_CACHE : ORIGIN = 0xFFA10000, LENGTH = 0x4000 +MEM_L1_SCRATCH : ORIGIN = 0xFFB00000, LENGTH = 0x1000 +MEM_L1_DATA_B : ORIGIN = 0xFF900000, LENGTH = 0x8000 +MEM_L1_DATA_A : ORIGIN = 0xFF800000, LENGTH = 0x8000 +MEM_L2 : ORIGIN = 0xFEB00000, LENGTH = 0x0 +} + +OUTPUT_FORMAT("elf32-bfin", "elf32-bfin", +"elf32-bfin") +OUTPUT_ARCH(bfin) +ENTRY(__start) + +SECTIONS +{ +/* Read-only sections, merged into text segment: */ +PROVIDE (__executable_start = 0x0); . = 0x0; +.interp : { *(.interp) } +.hash : { *(.hash) } +.dynsym : { *(.dynsym) } +.dynstr : { *(.dynstr) } +.gnu.version : { *(.gnu.version) } +.gnu.version_d : { *(.gnu.version_d) } +.gnu.version_r : { *(.gnu.version_r) } +.rel.init : { *(.rel.init) } +.rela.init : { *(.rela.init) } +.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } +.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } +.rel.fini : { *(.rel.fini) } +.rela.fini : { *(.rela.fini) } +.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } +.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } +.rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } +.rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } +.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } +.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } +.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } +.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } +.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } +.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } +.rel.ctors : { *(.rel.ctors) } +.rela.ctors : { *(.rela.ctors) } +.rel.dtors : { *(.rel.dtors) } +.rela.dtors : { *(.rela.dtors) } +.rel.got : { *(.rel.got) } +.rela.got : { *(.rela.got) } +.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } +.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } +.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } +.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } +.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } +.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } +.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } +.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } +.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } +.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } +.rel.plt : { *(.rel.plt) } +.rela.plt : { *(.rela.plt) } + +.l2 : +{ +*(.l2 .l2.*) +} >MEM_L2 =0 + +.text : +{ +*(.text .stub .text.* .gnu.linkonce.t.* .l1.text .l1.text.*) +KEEP (*(.text.*personality*)) +/* .gnu.warning sections are handled specially by elf32.em. */ +*(.gnu.warning) +} >MEM_L1_CODE =0 + +.init : +{ +KEEP (*(.init)) +} >MEM_L1_CODE =0 +.plt : { *(.plt) } >MEM_L1_CODE +.fini : + +{ +KEEP (*(.fini)) +} >MEM_L1_CODE =0 + +PROVIDE (__etext = .); +PROVIDE (_etext = .); +PROVIDE (etext = .); +.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } >MEM_L1_DATA_A +.rodata1 : { *(.rodata1) } >MEM_L1_DATA_A + +.sdata2 : +{ +*(.sdata2 .sdata2.* .gnu.linkonce.s2.*) +} >MEM_L1_DATA_A + +.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } >MEM_L1_DATA_A +.eh_frame_hdr : { *(.eh_frame_hdr) } >MEM_L1_DATA_A +.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } >MEM_L1_DATA_A +.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >MEM_L1_DATA_A +/* Adjust the address for the data segment. We want to adjust up to +the same address within the page on the next page up. */ +. = ALIGN(0x1000) + (. & (0x1000 - 1)); +/* Exception handling */ +.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } >MEM_L1_DATA_A +.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >MEM_L1_DATA_A +/* Thread Local Storage sections */ +.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } >MEM_L1_DATA_A +.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } >MEM_L1_DATA_A +.preinit_array : +{ +PROVIDE_HIDDEN (___preinit_array_start = .); +KEEP (*(.preinit_array)) +PROVIDE_HIDDEN (___preinit_array_end = .); +} >MEM_L1_DATA_A +.init_array : +{ +PROVIDE_HIDDEN (___init_array_start = .); +KEEP (*(SORT(.init_array.*))) +KEEP (*(.init_array)) +PROVIDE_HIDDEN (___init_array_end = .); +} >MEM_L1_DATA_A +.fini_array : +{ +PROVIDE_HIDDEN (___fini_array_start = .); +KEEP (*(.fini_array)) +KEEP (*(SORT(.fini_array.*))) +PROVIDE_HIDDEN (___fini_array_end = .); +} >MEM_L1_DATA_A + +.ctors : +{ +/* gcc uses crtbegin.o to find the start of +the constructors, so we make sure it is +first. Because this is a wildcard, it +doesn't matter if the user does not +actually link against crtbegin.o; the +linker won't look for a file to match a +wildcard. The wildcard also means that it +doesn't matter which directory crtbegin.o +is in. */ +KEEP (*crtbegin*.o(.ctors)) +/* We don't want to include the .ctor section from +the crtend.o file until after the sorted ctors. +The .ctor section from the crtend file contains the +end of ctors marker and it must be last */ +KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) +KEEP (*(SORT(.ctors.*))) +KEEP (*(.ctors)) +} >MEM_L1_DATA_A + +.dtors : +{ +KEEP (*crtbegin*.o(.dtors)) +KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) +KEEP (*(SORT(.dtors.*))) +KEEP (*(.dtors)) +} >MEM_L1_DATA_A + +.jcr : { KEEP (*(.jcr)) } >MEM_L1_DATA_A +.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } >MEM_L1_DATA_A +.dynamic : { *(.dynamic) } >MEM_L1_DATA_A +.data : +{ +*(.data .data.* .gnu.linkonce.d.* .l1.data .l1.data.*) +KEEP (*(.gnu.linkonce.d.*personality*)) +SORT(CONSTRUCTORS) +} >MEM_L1_DATA_A +.data1 : { *(.data1) } >MEM_L1_DATA_A +.got : { *(.got.plt) *(.got) } >MEM_L1_DATA_A +/* We want the small data sections together, so single-instruction offsets +can access them all, and initialized data all before uninitialized, so +we can shorten the on-disk segment size. */ +.sdata : +{ +*(.sdata .sdata.* .gnu.linkonce.s.*) +} >MEM_L1_DATA_A +__edata = .; PROVIDE (_edata = .); +.sbss : +{ +__bss_start = .; +*(.dynsbss) +*(.sbss .sbss.* .gnu.linkonce.sb.*) +*(.scommon) +} >MEM_L1_DATA_A +.bss : +{ +*(.dynbss) +*(.bss .bss.* .gnu.linkonce.b.*) +*(COMMON) +/* Align here to ensure that the .bss section occupies space up to +_end. Align after .bss to ensure correct alignment even if the +.bss section disappears because there are no input sections. +FIXME: Why do we need it? When there is no .bss section, we don't +pad the .data section. */ +. = ALIGN(. != 0 ? 32 / 8 : 1); +__bss_end = .; +} >MEM_L1_DATA_A +. = ALIGN(32 / 8); +. = ALIGN(32 / 8); +__end = .; PROVIDE (_end = .); +/* Stabs debugging sections. */ +.stab 0 : { *(.stab) } +.stabstr 0 : { *(.stabstr) } +.stab.excl 0 : { *(.stab.excl) } +.stab.exclstr 0 : { *(.stab.exclstr) } +.stab.index 0 : { *(.stab.index) } +.stab.indexstr 0 : { *(.stab.indexstr) } +.comment 0 : { *(.comment) } +/* DWARF debug sections. +Symbols in the DWARF debugging sections are relative to the beginning +of the section so we begin them at 0. */ +/* DWARF 1 */ +.debug 0 : { *(.debug) } +.line 0 : { *(.line) } +/* GNU DWARF 1 extensions */ +.debug_srcinfo 0 : { *(.debug_srcinfo) } +.debug_sfnames 0 : { *(.debug_sfnames) } +/* DWARF 1.1 and DWARF 2 */ +.debug_aranges 0 : { *(.debug_aranges) } +.debug_pubnames 0 : { *(.debug_pubnames) } +/* DWARF 2 */ +.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } +.debug_abbrev 0 : { *(.debug_abbrev) } +.debug_line 0 : { *(.debug_line) } +.debug_frame 0 : { *(.debug_frame) } +.debug_str 0 : { *(.debug_str) } +.debug_loc 0 : { *(.debug_loc) } +.debug_macinfo 0 : { *(.debug_macinfo) } +/* SGI/MIPS DWARF 2 extensions */ +.debug_weaknames 0 : { *(.debug_weaknames) } +.debug_funcnames 0 : { *(.debug_funcnames) } +.debug_typenames 0 : { *(.debug_typenames) } +.debug_varnames 0 : { *(.debug_varnames) } + +__stack_end = ORIGIN(MEM_L1_SCRATCH) + LENGTH(MEM_L1_SCRATCH); + +/DISCARD/ : { *(.note.GNU-stack) } } From 2dbd77858068837b72cb5a3d14fd91921e6ede7d Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 09:58:13 +0100 Subject: [PATCH 17/37] Update app_bees.c --- apps/bees/src/app_bees.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/apps/bees/src/app_bees.c b/apps/bees/src/app_bees.c index a9f0bfd9d..013728718 100644 --- a/apps/bees/src/app_bees.c +++ b/apps/bees/src/app_bees.c @@ -47,8 +47,8 @@ const AppVersion beesVersion = { .min = MIN , .maj = MAJ , .rev = REV }; //--- static vars static char versionString[12] = VERSIONSTRING; -#define DEFAULT_LDR "mix.ldr" -#define DEFAULT_DSC "mix.dsc" +#define DEFAULT_LDR "waves.ldr" +#define DEFAULT_DSC "waves.dsc" // this is called during hardware initialization. // allocate memory. @@ -130,9 +130,9 @@ u8 app_launch(eLaunchState state) { render_boot("waiting for DSP init..."); bfin_wait_ready(); - // print_dbg("\r\n enable DSP audio..."); - //render_boot("enabling audio"); - //bfin_enable(); + print_dbg("\r\n enable DSP audio..."); + render_boot("enabling audio"); + bfin_enable(); } else { @@ -163,15 +163,6 @@ u8 app_launch(eLaunchState state) { } - // load samples - bfin_disable(); - print_dbg("\r\n load samples..."); - files_load_samples(); - - print_dbg("\r\n enable DSP audio..."); - render_boot("enabling audio"); - bfin_enable(); - // init pages (fill graphics buffers) render_boot("initializing gfx"); print_dbg("\r\n pages_init..."); From 93e34175578ff0efad85db4d5a7e8aa274defe16 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:01:18 +0100 Subject: [PATCH 18/37] Update bfin.h --- avr32/src/bfin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avr32/src/bfin.h b/avr32/src/bfin.h index 2e6748a08..e5735f796 100644 --- a/avr32/src/bfin.h +++ b/avr32/src/bfin.h @@ -14,7 +14,7 @@ //! max size of blackfin ldr file #define BFIN_LDR_MAX_BYTES 0x12000 -#define BFIN_SDRAM_MAX_BYTES 0x4000000 +#define BFIN_SDRAM_MAX_FRACT32 0x1000000 //! wait for busy pin to clear void bfin_wait(void); From 482312ea29bf3ca7683eb3ae95aac5903cc9d90b Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:04:50 +0100 Subject: [PATCH 19/37] Update pages.h --- apps/bees/src/pages.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/bees/src/pages.h b/apps/bees/src/pages.h index 6eb2a63b9..f26f8761a 100644 --- a/apps/bees/src/pages.h +++ b/apps/bees/src/pages.h @@ -37,6 +37,7 @@ typedef enum { ePageOps, ePageScenes, ePageDsp, + ePageSamples, ePageGathered, ePagePlay, } ePage; @@ -90,6 +91,7 @@ extern void init_page_presets(void); extern void init_page_ops(void); extern void init_page_scenes(void); extern void init_page_dsp(void); +extern void init_page_samples(void); extern void init_page_gathered(void); extern void init_page_play(void); @@ -100,6 +102,7 @@ extern void select_presets(void); extern void select_ops(void); extern void select_scenes(void); extern void select_dsp(void); +extern void select_samples(void); extern void select_gathered(void); extern void select_play(void); @@ -111,6 +114,7 @@ extern void redraw_presets(void); extern void redraw_ops(void); extern void redraw_scenes(void); extern void redraw_dsp(void); +extern void redraw_samples(void); extern void redraw_gathered(void); extern void redraw_play(void); From a8a8f060b07509165340033a1f0990080fff08d3 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:06:31 +0100 Subject: [PATCH 20/37] Update pages.h --- apps/bees/src/pages.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bees/src/pages.h b/apps/bees/src/pages.h index f26f8761a..19ad45b46 100644 --- a/apps/bees/src/pages.h +++ b/apps/bees/src/pages.h @@ -14,7 +14,7 @@ //-- define //! number of pages (including modal pages) -#define NUM_PAGES 8 +#define NUM_PAGES 9 //! enum of key handlers per menu page typedef enum { From 9726ed83c27c176a2ed7d039129385dd5a2ef31a Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:08:08 +0100 Subject: [PATCH 21/37] Update pages.c --- apps/bees/src/pages.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/bees/src/pages.c b/apps/bees/src/pages.c index d35989647..1a5915e0b 100644 --- a/apps/bees/src/pages.c +++ b/apps/bees/src/pages.c @@ -61,6 +61,10 @@ page_t pages[NUM_PAGES] = { .select_fn = &select_dsp, // select function .encSens = { ENC_THRESH_LISTSCROLL, ENC_THRESH_PAGESCROLL, 0, 0, }, // encoder sens }, + { .name = "SAMPLES", + .select_fn = &select_samples, // select function + .encSens = { ENC_THRESH_LISTSCROLL, ENC_THRESH_PAGESCROLL, 8, 8, }, // encoder sens + }, // modal: { .name = "GATHERED", .select_fn = &select_gathered , // select function @@ -116,6 +120,7 @@ static u8 check_edit_char(char c) { void pages_init(void) { init_page_ins(); init_page_dsp(); + init_page_samples(); init_page_ops(); init_page_outs(); init_page_play(); @@ -131,6 +136,7 @@ void pages_init(void) { set_page(pageIdx); redraw_dsp(); + redraw_samples(); redraw_outs(); redraw_ops(); redraw_presets(); From 757ce60c0029b1947bd880552b9014b39e053c96 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:10:20 +0100 Subject: [PATCH 22/37] Add files via upload --- apps/bees/src/pages/page_samples.c | 288 +++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 apps/bees/src/pages/page_samples.c diff --git a/apps/bees/src/pages/page_samples.c b/apps/bees/src/pages/page_samples.c new file mode 100644 index 000000000..f3e9ef2e7 --- /dev/null +++ b/apps/bees/src/pages/page_samples.c @@ -0,0 +1,288 @@ +/* + page_samples.c +*/ + +// asf +#include "print_funcs.h" + +// aleph-avr32 +#include "bfin.h" + +// bees +#include "files.h" +#include "handler.h" +#include "net.h" +#include "pages.h" +#include "render.h" +#include "scene.h" + +//------------------------- +//---- static variables + + +// constant pointer to this page's selection +static s16* const pageSelect = &(pages[ePageSamples].select); + +// scroll region +static region scrollRegion = { .w = 128, .h = 64, .x = 0, .y = 0 }; +// scroll manager +static scroll centerScroll; + +// handler declarations +static void handle_enc_3(s32 val); +static void handle_enc_2(s32 val); +static void handle_enc_1(s32 val); +static void handle_enc_0(s32 val); +static void handle_key_0(s32 val); +static void handle_key_1(s32 val); +static void handle_key_2(s32 val); +static void handle_key_3(s32 val); + +// fill tmp region with new content +// given input index +static void render_line(s16 idx, u16 max) { + region_fill(lineRegion, 0x0); + if((idx > max) || (idx < 0)) { return; } + clearln(); + appendln((const char*)files_get_sample_name(idx)); + endln(); + font_string_region_clip(lineRegion, lineBuf, 0, 0, 0xa, 0); +} + + +// scroll the current selection +static void select_scroll(s32 dir) { + const s32 max = files_get_sample_count() - 1; + // index for new content + s16 newIdx; + s16 newSel; + + // cancel actions + pages_reset_keypressed(); + + if(dir < 0) { + /// SCROLL DOWN + // if selection is already zero, do nothing + if(*pageSelect == 0) { + // print_dbg("\r\n reached min selection in inputs scroll. "); + return; + } + // remove highlight from old center + render_scroll_apply_hl(SCROLL_CENTER_LINE, 0); + // decrement selection + newSel = *pageSelect - 1; + ///// these bounds checks shouldn't really be needed here... + // if(newSel < 0) { newSel = 0; } + // if(newSel > max ) { newSel = max; } + *pageSelect = newSel; + // add new content at top + newIdx = newSel - SCROLL_LINES_BELOW; + if(newIdx < 0) { + // empty row + region_fill(lineRegion, 0); + } else { + render_line(newIdx, max); + } + // render tmp region to bottom of scroll + // (this also updates scroll byte offset) + render_to_scroll_top(); + // add highlight to new center + render_scroll_apply_hl(SCROLL_CENTER_LINE, 1); + + } else { + // SCROLL UP + // if selection is already max, do nothing + if(*pageSelect == max) { + // print_dbg("\r\n reached max selection in inputs scroll. "); + return; + } + // remove highlight from old center + render_scroll_apply_hl(SCROLL_CENTER_LINE, 0); + // increment selection + newSel = *pageSelect + 1; + ///// these bounds checks shouldn't really be needed here... + // if(newSel < 0) { newSel = 0; } + // if(newSel > max ) { newSel = max; } + ///// + *pageSelect = newSel; + // add new content at bottom of screen + newIdx = newSel + SCROLL_LINES_ABOVE; + if(newIdx > max) { + // empty row + region_fill(lineRegion, 0); + } else { + render_line(newIdx, max); + } + // render tmp region to bottom of scroll + // (this also updates scroll byte offset) + render_to_scroll_bottom(); + // add highlight to new center + render_scroll_apply_hl(SCROLL_CENTER_LINE, 1); + } +} + +// display the function key labels according to current state +static void show_foot0(void) { + u8 fill = 0; + if(keyPressed == 0) { + fill = 0x5; + } + region_fill(footRegion[0], fill); + font_string_region_clip(footRegion[0], "LOAD", 0, 0, 0xf, fill); +} + +#if BFIN_INTERNAL_FLASH +static void show_foot1(void) { +u8 fill = 0; +if(keyPressed == 1) { +fill = 0x5; +} +region_fill(footRegion[1], fill); +font_string_region_clip(footRegion[1], "WRITE", 0, 0, 0xf, fill); + +} +#endif + +static void show_foot(void) { +show_foot0(); +#if BFIN_INTERNAL_FLASH +show_foot1(); +#endif +} + +// function keys +void handle_key_0(s32 val) { + // load module + if(val == 0) { return; } + if(check_key(0)) { + notify("loading samples..."); + + net_disconnect_params(); + + bfin_wait_ready(); + bfin_disable(); + + files_load_samples(); + + bfin_wait_ready(); + bfin_enable(); + + redraw_ins(); + redraw_samples(); + + notify("finished loading."); + } + show_foot(); +} + +void handle_key_1(s32 val) { +#if BFIN_INTERNAL_FLASH + + if(val == 0) { return; } + if(check_key(1)) { + notify("writing..."); + files_store_default_dsp(*pageSelect); + notify("done writing."); + } + show_foot(); + +#endif +} + +void handle_key_2(s32 val) { + // nothing +} + +void handle_key_3(s32 val) { + // nothing +} + +// enc 0 : scroll page +void handle_enc_3(s32 val) { + // nothing +} + +// enc 1 : scroll selection +void handle_enc_2(s32 val) { + // nothing +} + +void handle_enc_1(s32 val) { + // scroll page + if(val > 0) { + set_page(ePageOps); + } else { + set_page(ePageDsp); + } +} + +void handle_enc_0(s32 val) { + select_scroll(val); +} + +//---------------------- +// ---- extern +// init +void init_page_samples(void) { + u8 i, n; + u16 max = files_get_sample_count() - 1; + print_dbg("\r\n alloc SAMPLES page"); + // allocate regions + region_alloc(&scrollRegion); + // init scroll + scroll_init(¢erScroll, &scrollRegion); + // fill regions + region_fill(&scrollRegion, 0x0); + // fill the scroll with actual line values... + n = 3; + i = 0; + //// need to actually set the scroll region at least temporarily + render_set_scroll(¢erScroll); + // also, reset scroller! + while(i<5) { + render_line(i, max); + render_to_scroll_line(n, i == 0 ? 1 : 0); + ++n; + ++i; + } +} + +// select +void select_samples(void) { + // assign global scroll region pointer + // also marks dirty + render_set_scroll(¢erScroll); + // other regions are static in top-level render, with global handles + render_reset_custom_region(); + region_fill(headRegion, 0x0); + font_string_region_clip(headRegion, "SAMPLES", 0, 0, 0xf, 0x1); + show_foot(); + // assign handlers + app_event_handlers[ kEventEncoder0 ] = &handle_enc_0 ; + app_event_handlers[ kEventEncoder1 ] = &handle_enc_1 ; + app_event_handlers[ kEventEncoder2 ] = &handle_enc_2 ; + app_event_handlers[ kEventEncoder3 ] = &handle_enc_3 ; + app_event_handlers[ kEventSwitch0 ] = &handle_key_0 ; + app_event_handlers[ kEventSwitch1 ] = &handle_key_1 ; + app_event_handlers[ kEventSwitch2 ] = &handle_key_2 ; + app_event_handlers[ kEventSwitch3 ] = &handle_key_3 ; +} + +// redraw all lines, based on current selection +void redraw_samples(void) { + u8 i=0; + u8 n = *pageSelect - 3; + + // set scroll region + // FIXME: should be separate function i guess + render_set_scroll(¢erScroll); + + + print_dbg("\r\n redraw_samples() "); + while(i<8) { + render_line( n, 0xa ); + render_to_scroll_line(i, n == *pageSelect ? 1 : 0); + ++i; + ++n; + } +} From 8d9b61a8e98de7fa4335c7454d22f382e55b6f68 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:12:01 +0100 Subject: [PATCH 23/37] Update page_dsp.c --- apps/bees/src/pages/page_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bees/src/pages/page_dsp.c b/apps/bees/src/pages/page_dsp.c index 2333831d5..63d6dc340 100644 --- a/apps/bees/src/pages/page_dsp.c +++ b/apps/bees/src/pages/page_dsp.c @@ -209,7 +209,7 @@ void handle_enc_2(s32 val) { void handle_enc_1(s32 val) { // scroll page if(val > 0) { - set_page(ePageOps); + set_page(ePageSamples); } else { set_page(ePageScenes); } From e1350203091002a6673da98bbfe213d30e8d7c2d Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:14:02 +0100 Subject: [PATCH 24/37] Update page_ops.c --- apps/bees/src/pages/page_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bees/src/pages/page_ops.c b/apps/bees/src/pages/page_ops.c index 02839dad8..5422a3ad0 100644 --- a/apps/bees/src/pages/page_ops.c +++ b/apps/bees/src/pages/page_ops.c @@ -306,7 +306,7 @@ void handle_enc_1(s32 val) { if(val > 0) { set_page(ePageIns); } else { - set_page(ePageDsp); + set_page(ePageSamples); } } From 780eead7bb6d628912d3d3fdda64cc1c98f4431a Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:15:19 +0100 Subject: [PATCH 25/37] Update files.h --- apps/bees/src/files.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/bees/src/files.h b/apps/bees/src/files.h index 9b15c84c2..bf6680cbe 100644 --- a/apps/bees/src/files.h +++ b/apps/bees/src/files.h @@ -65,6 +65,8 @@ extern u8 files_get_scaler_count(void); extern u8 files_load_scaler_name(const char* name, s32* dst, u32 dstSize); //----- samples +extern const volatile char* files_get_sample_name(u8 idx); +extern u8 files_get_sample_count(void); extern void files_load_samples(void); //----- param descriptors From f3cd71c084497946ccd454a61c36d9b89aba21bc Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:17:32 +0100 Subject: [PATCH 26/37] Update files.c --- apps/bees/src/files.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/apps/bees/src/files.c b/apps/bees/src/files.c index 7ca48c9d3..1a48f3568 100644 --- a/apps/bees/src/files.c +++ b/apps/bees/src/files.c @@ -80,7 +80,7 @@ static const char* list_get_name(dirList_t* list, u8 idx); // set size by pointer static void* list_open_file_name(dirList_t* list, const char* name, const char* mode, u32* size); // load sample file with path -static void load_sample_withPath(const char *path); +static u32 load_sample_withPath(const char *path, u32 offset); // fake fread: no size arg, always byte @@ -438,10 +438,22 @@ u8 files_load_scaler_name(const char* name, s32* dst, u32 dstSize) { //////////////////////// //// samples + +// return filename for sample given index in list +const volatile char* files_get_sample_name(u8 idx) { + return list_get_name(&sampleList, idx); +} + +// return count of sample files +u8 files_get_sample_count(void) { + return sampleList.num; +} + void files_load_samples(void) { FL_DIR dirstat; struct fs_dir_ent dirent; sampleList.num = 0; + u32 offset = 0; char *fpath = (char*)alloc_mem(64 * (sizeof(char*))); @@ -456,7 +468,7 @@ void files_load_samples(void) { { strcpy(fpath, sampleList.path); strcat(fpath, dirent.filename); - load_sample_withPath(fpath); + offset += load_sample_withPath(fpath, offset); sampleList.num++; } } @@ -727,11 +739,9 @@ void files_load_sample(u8 n) { } } -static void load_sample_withPath(const char *path) { +static u32 load_sample_withPath(const char *path, u32 offset) { void *fp; - static u32 sdramMemory = BFIN_SDRAM_MAX_BYTES; - static u32 sdramOffset = 0; u32 fsize, foffset, fchunk, ssize; delay_ms(10); @@ -743,7 +753,7 @@ static void load_sample_withPath(const char *path) { ssize = fsize / sizeof(s32); // verify available SDRAM - if ((sdramMemory -= ssize) > 0) + if (offset < BFIN_SDRAM_MAX_FRACT32) { if (fp != NULL) { @@ -751,7 +761,7 @@ static void load_sample_withPath(const char *path) { app_pause(); - bfin_sample_start(sdramOffset); + bfin_sample_start(offset); do { @@ -774,22 +784,25 @@ static void load_sample_withPath(const char *path) { bfin_sample_end(); - // refresh sdram offset - sdramOffset += ssize; - fl_fclose(fp); app_resume(); + + return ssize; } else { render_boot("sample file error"); fl_fclose(fp); + + return 0; } } else { render_boot("SDRAM limit error"); fl_fclose(fp); + + return 0; } } From a6c7cef54673c16d186a081b36116ca99b28dd91 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:28:28 +0100 Subject: [PATCH 27/37] Update params.h --- modules/mix/params.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/mix/params.h b/modules/mix/params.h index 9c572e185..1bc3469d6 100644 --- a/modules/mix/params.h +++ b/modules/mix/params.h @@ -9,12 +9,21 @@ #define PARAM_CV_MAX 0x7fffffff #define PARAM_SLEW_MAX 0x7fffffff +#define PARAM_SECONDS_MAX 0x003c0000 +#define PARAM_SECONDS_RADIX 7 + // something pretty fast, but noticeable #define PARAM_SLEW_DEFAULT 0x7ffecccc // enumerate parameters // the order defined here must be matched in the descriptor ! enum params { + + eParam0, + eParam1, + eParam2, + eParam3, + // cv slew eParam_cvSlew0, eParam_cvSlew1, From fb4915072035af4377b25b23c4b82dfcb61c8fa3 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:29:46 +0100 Subject: [PATCH 28/37] Update params.c --- modules/mix/params.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/modules/mix/params.c b/modules/mix/params.c index 2d4192f48..88f39f9e5 100644 --- a/modules/mix/params.c +++ b/modules/mix/params.c @@ -16,6 +16,31 @@ // this function extern void fill_param_desc(ParamDesc* desc) { + strcpy(desc[eParam0].label, "level"); + desc[eParam0].type = eParamTypeAmp; + desc[eParam0].min = 0x00000000; + desc[eParam0].max = PARAM_AMP_MAX; + desc[eParam0].radix = 16; + + strcpy(desc[eParam1].label, "start"); + desc[eParam1].type = eParamTypeFix; + desc[eParam1].min = 0x00000000; + desc[eParam1].max = PARAM_SECONDS_MAX; + desc[eParam1].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam2].label, "loop"); + desc[eParam2].type = eParamTypeFix; + desc[eParam2].min = 0x00000000; + desc[eParam2].max = PARAM_SECONDS_MAX; + desc[eParam2].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam3].label, "speed"); + desc[eParam3].type = eParamTypeFix; + desc[eParam3].min = 0x00000000; + desc[eParam3].max = PARAM_SECONDS_MAX; + desc[eParam3].radix = PARAM_SECONDS_RADIX; + + // obviously, these could be done in other ways ( easier to read/edit maybe. ) // but neither code space nor speed is a big deal here. // this code can also be script-generated easily enough. From 39685c1e87ff38043e2fb2aac8dbc969e1ea2cea Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 10:33:23 +0100 Subject: [PATCH 29/37] Update mix.c --- modules/mix/mix.c | 51 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/modules/mix/mix.c b/modules/mix/mix.c index da7fb4955..de68f9cae 100644 --- a/modules/mix/mix.c +++ b/modules/mix/mix.c @@ -36,6 +36,7 @@ #include "params.h" #define BUFFERSIZE 0x100000 +#define BUFFERSIZE_1 (0x1000000 - 1) typedef struct _sampleBuffer { volatile fract32 *data; //pointer to data @@ -62,6 +63,10 @@ ModuleData *gModuleData; mixData *data; sampleBuffer onchipbuffer[4]; u32 offset = 0; +fract32 param0 = 0; //output gain +fract32 param1 = 0; //start +fract32 param2 = 48000; //end +fract32 param3 = 0; //speed bufferHead heads[4]; @@ -105,6 +110,11 @@ void module_init(void) { offset = 0; // init parameters + param_setup(eParam0, PARAM_AMP_MAX >> 2); + param_setup(eParam1, 0); + param_setup(eParam2, 48000); + param_setup(eParam3, 0); + // for(n=0; n 48000) + if (heads[0].idx > param2) { - heads[0].idx = 0; + heads[0].idx = param1; } out[0] = out[1] = buffer_head_play(&(heads[0])); - - /* - const fract32 c = 1664525 ; - const fract32 a = 1013904223 ; - static fract32 x = 666; - x = x * c + a; - */ } // sample offset @@ -190,6 +193,36 @@ void module_set_sample(ParamValue v) { void module_set_param(u32 idx, ParamValue v) { // switch on the param index switch(idx) { + + switch(idx) { + // level + case eParam0: + param0 = v; + break; + + // start + case eParam1: + tmp = v; + if (tmp < 0) tmp = 0; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + if (tmp > param2 - 48) tmp = param2 - 48; + param1 = tmp; + break; + + // loop + case eParam2: + tmp = v; + if (tmp < 48) tmp = 48; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + if (tmp < param1 + 48) tmp = param1 + 48; + param2 = tmp; + break; + + // speed + case eParam3: + param3 = v; + break; + // cv output values case eParam_cv0 : filter_1p_lo_in( &(cvSlew[0]), v ); From dfea2a4465b4eefe8ece53ba63097a3184cb1e79 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 11:46:38 +0100 Subject: [PATCH 30/37] Update files.c --- apps/bees/src/files.c | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bees/src/files.c b/apps/bees/src/files.c index 1a48f3568..fed987c16 100644 --- a/apps/bees/src/files.c +++ b/apps/bees/src/files.c @@ -163,6 +163,7 @@ void files_init(void) { list_fill(&dspList, DSP_PATH, ".ldr"); list_fill(&sceneList, SCENES_PATH, ".scn"); list_fill(&scalerList, SCALERS_PATH, ".dat"); + list_fill(&sampleList, SAMPLES_PATH, ".pcm_s32be"); } From c33da7a9674bd7ff53a0e606c997e034dbb08b12 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Sat, 24 Mar 2018 14:17:47 +0100 Subject: [PATCH 31/37] Update files.c --- apps/bees/src/files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bees/src/files.c b/apps/bees/src/files.c index fed987c16..810d23e52 100644 --- a/apps/bees/src/files.c +++ b/apps/bees/src/files.c @@ -754,7 +754,7 @@ static u32 load_sample_withPath(const char *path, u32 offset) { ssize = fsize / sizeof(s32); // verify available SDRAM - if (offset < BFIN_SDRAM_MAX_FRACT32) + if ((offset + ssize) < BFIN_SDRAM_MAX_FRACT32) { if (fp != NULL) { From d50cf3e54d18e5543db5b41abcb1a25a2886bb88 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Mon, 26 Mar 2018 22:48:10 +0200 Subject: [PATCH 32/37] Update mix.c --- modules/mix/mix.c | 375 +++++++++++++++++++++++----------------------- 1 file changed, 184 insertions(+), 191 deletions(-) diff --git a/modules/mix/mix.c b/modules/mix/mix.c index de68f9cae..fd244ab4d 100644 --- a/modules/mix/mix.c +++ b/modules/mix/mix.c @@ -1,15 +1,8 @@ /* mix.c aleph-bfin - - a very simple template module. - - applies attenuation with slew to each input signal, - - then mixes all attenuated signals to all outputs. - - also performs CV changes with slew. - + //#define FR32_MAX 0x7fffffff //2147483647 + //#define FR32_MIN 0x80000000 //-2147483648 */ //-- aleph/common headers @@ -28,15 +21,15 @@ //-- dsp class headers // simple 1-pole integrator #include "filter_1p.h" + // global declarations for module data #include "module.h" - -//--- custom headers -// parameter lists and constants #include "params.h" -#define BUFFERSIZE 0x100000 +#define BUFFERSIZE 0x1000000 #define BUFFERSIZE_1 (0x1000000 - 1) +#define FR32_MAX1_2 0x3fffffff + typedef struct _sampleBuffer { volatile fract32 *data; //pointer to data @@ -45,7 +38,7 @@ typedef struct _sampleBuffer { typedef struct _bufferHead { sampleBuffer *buf; //pointer to buffer - u32 idx; //current idx + s32 idx; //current idx } bufferHead; static void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples); @@ -63,21 +56,14 @@ ModuleData *gModuleData; mixData *data; sampleBuffer onchipbuffer[4]; u32 offset = 0; -fract32 param0 = 0; //output gain -fract32 param1 = 0; //start -fract32 param2 = 48000; //end -fract32 param3 = 0; //speed bufferHead heads[4]; +fract32 level[4] = { PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2 }; +fract32 start[4] = { 0xff, 0xff, 0xff, 0xff }; +fract32 loop[4] = { 48000, 48000, 48000, 48000 }; +fract32 direction[4] = { 1, 1, 1, 1 }; +fract32 trig[4] = { 0, 0, 0, 0 }; -fract32 adcVal[4] = { 0, 0, 0, 0 }; -filter_1p_lo adcSlew[4]; -fract32 cvVal[4] = { 0, 0, 0, 0 }; -filter_1p_lo cvSlew[4]; -u8 cvChan = 0; -fract32 outBus = 0; - -static void process_cv(void); static inline void param_setup(u32 id, ParamValue v) { gModuleData->paramData[id].value = v; module_set_param(id, v); @@ -113,69 +99,92 @@ void module_init(void) { param_setup(eParam0, PARAM_AMP_MAX >> 2); param_setup(eParam1, 0); param_setup(eParam2, 48000); - param_setup(eParam3, 0); - + param_setup(eParam3, 1); + param_setup(eParam4, 0); + + param_setup(eParam5, PARAM_AMP_MAX >> 2); + param_setup(eParam6, 0); + param_setup(eParam7, 48000); + param_setup(eParam8, 1); + param_setup(eParam9, 0); + + param_setup(eParam10, PARAM_AMP_MAX >> 2); + param_setup(eParam11, 0); + param_setup(eParam12, 48000); + param_setup(eParam13, 1); + param_setup(eParam14, 0); + + param_setup(eParam15, PARAM_AMP_MAX >> 2); + param_setup(eParam16, 0); + param_setup(eParam17, 48000); + param_setup(eParam18, 1); + param_setup(eParam19, 0); + // for(n=0; n> 2 ); - param_setup(eParam_adc1, PARAM_AMP_MAX >> 2 ); - param_setup(eParam_adc2, PARAM_AMP_MAX >> 2 ); - param_setup(eParam_adc3, PARAM_AMP_MAX >> 2 ); - - // set slew defaults. the value is pretty arbitrary - param_setup(eParam_adcSlew0, PARAM_SLEW_DEFAULT); - param_setup(eParam_adcSlew1, PARAM_SLEW_DEFAULT); - param_setup(eParam_adcSlew2, PARAM_SLEW_DEFAULT); - param_setup(eParam_adcSlew3, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew0, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew1, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew2, PARAM_SLEW_DEFAULT); - param_setup(eParam_cvSlew3, PARAM_SLEW_DEFAULT); } // de-init (never actually used on blackfin, but maybe by emulator) void module_deinit(void) { - ;; } // get number of parameters u32 module_get_num_params(void) { - return eParamNumParams; + return eParamNumParams; } - - -// frame process function! -// called each audio frame from codec interrupt handler -// ( bad, i know, see github issues list ) void module_process_frame(void) { - heads[0].idx += 1; - if (heads[0].idx > param2) + u8 c; + static s64 x[4] = { FR32_MAX1_2, FR32_MAX1_2, FR32_MAX1_2, FR32_MAX1_2 }; + + // linear idx + for (c=0; c<4; c++) { - heads[0].idx = param1; + fract32 y0 = heads[c].idx; + fract32 y1 = heads[c].idx + 2; + + if (direction[c] > 0) + { + x[c] += direction[c]; + + if (x[c] > FR32_MAX) + { + x[c] = FR32_MAX1_2; + } + + heads[c].idx = add_fr1x32(y0, mult_fr1x32x32(x[c], sub_fr1x32(y1, y0))); + if (heads[c].idx > loop[c]) + { + heads[c].idx = start[c]; + } + if (trig[c]) + { + heads[c].idx = start[c]; + trig[c] = 0; + } + } + else + { + x[c] += -direction[c]; + + if (x[c] > FR32_MAX) + { + x[c] = FR32_MAX1_2; + } + + heads[c].idx = sub_fr1x32(y0, mult_fr1x32x32(x[c], sub_fr1x32(y1, y0))); + if (heads[c].idx < start[c]) + { + heads[c].idx = loop[c]; + } + if (trig[c]) + { + heads[c].idx = loop[c]; + trig[c] = 0; + } + } + + out[c] = mult_fr1x32x32(level[c], buffer_head_play(&(heads[c]))); } - - out[0] = out[1] = buffer_head_play(&(heads[0])); } // sample offset @@ -191,136 +200,120 @@ void module_set_sample(ParamValue v) { // parameter set function void module_set_param(u32 idx, ParamValue v) { - // switch on the param index - switch(idx) { - - switch(idx) { - // level + fract32 tmp; + + switch(idx) { + // level 0 case eParam0: - param0 = v; + level[0] = v; break; - - // start + // start 0 case eParam1: tmp = v; - if (tmp < 0) tmp = 0; + if (tmp < 0xff) tmp = 0xff; if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - if (tmp > param2 - 48) tmp = param2 - 48; - param1 = tmp; + start[0] = tmp; break; - - // loop + // loop 0 case eParam2: tmp = v; - if (tmp < 48) tmp = 48; + if (tmp < 0xff + 2) tmp = 0xff + 2; if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - if (tmp < param1 + 48) tmp = param1 + 48; - param2 = tmp; + loop[0] = tmp; break; - - // speed + // direction 0 case eParam3: - param3 = v; + direction[0] = v; + break; + // trig 0 + case eParam4: + trig[0] = v; break; - // cv output values - case eParam_cv0 : - filter_1p_lo_in( &(cvSlew[0]), v ); - break; - case eParam_cv1 : - filter_1p_lo_in( &(cvSlew[1]), v ); - break; - case eParam_cv2 : - filter_1p_lo_in( &(cvSlew[2]), v ); - break; - case eParam_cv3 : - filter_1p_lo_in( &(cvSlew[3]), v ); - - // cv slew values - break; - case eParam_cvSlew0 : - filter_1p_lo_set_slew(&(cvSlew[0]), v); - break; - case eParam_cvSlew1 : - filter_1p_lo_set_slew(&(cvSlew[1]), v); - break; - case eParam_cvSlew2 : - filter_1p_lo_set_slew(&(cvSlew[2]), v); - break; - case eParam_cvSlew3 : - filter_1p_lo_set_slew(&(cvSlew[3]), v); - break; - - // input attenuation values - case eParam_adc0 : - filter_1p_lo_in( &(adcSlew[0]), v ); - break; - case eParam_adc1 : - filter_1p_lo_in( &(adcSlew[1]), v ); - break; - case eParam_adc2 : - filter_1p_lo_in( &(adcSlew[2]), v ); - break; - case eParam_adc3 : - filter_1p_lo_in( &(adcSlew[3]), v ); - - // input attenuation slew values - break; - case eParam_adcSlew0 : - filter_1p_lo_set_slew(&(adcSlew[0]), v); - break; - case eParam_adcSlew1 : - filter_1p_lo_set_slew(&(adcSlew[1]), v); - break; - case eParam_adcSlew2 : - filter_1p_lo_set_slew(&(adcSlew[2]), v); - break; - case eParam_adcSlew3 : - filter_1p_lo_set_slew(&(adcSlew[3]), v); - break; - - default: - break; - } -} + // level 1 + case eParam5: + level[1] = v; + break; + // start 1 + case eParam6: + tmp = v; + if (tmp < 0xff) tmp = 0xff; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + start[1] = tmp; + break; + // loop 1 + case eParam7: + tmp = v; + if (tmp < 0xff + 2) tmp = 0xff + 2; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + loop[1] = tmp; + break; + // direction 1 + case eParam8: + direction[1] = v; + break; + // trig 1 + case eParam9: + trig[1] = v; + break; -//----- static function definitions - -//// NOTE / FIXME: -/* CV updates are staggered, each channel on a separate audio frame. - - the reason for this is that each channel takes some time to update. - for now, we just wait a full frame between channels, - and effectively reduce CV output sampling rate by a factor of 4. - (as well as changing the effecticve slew time, which is not great.) - - the more proper way to do this would be: - - enable DMA tx interrupt - - each ISR calls the next channel to be loaded - - last thing audio ISR does is call the first DAC channel to be loaded - - cv_update writes to 4x16 volatile buffer - - this could give rise to its own problems: - audio frame processing is currently interrupt-driven per frame, - so CV tx interrupt could be masked by the next audio frame if the schedule is tight. -*/ -// update cv output -void process_cv(void) { - // process the current channel - // do nothing if the value is stable - if( filter_1p_sync( &(cvSlew[cvChan]) ) ) { - ;; - } else { - // update the slew filter and store the value - cvVal[cvChan] = filter_1p_lo_next(&(cvSlew[cvChan])); - // send the value to the cv driver - cv_update( cvChan, cvVal[cvChan] ); - } - - // update the channel to be processed - if(++cvChan == 4) { - cvChan = 0; - } + // level 2 + case eParam10: + level[2] = v; + break; + // start 2 + case eParam11: + tmp = v; + if (tmp < 0xff) tmp = 0xff; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + start[2] = tmp; + break; + // loop 2 + case eParam12: + tmp = v; + if (tmp < 0xff + 2) tmp = 0xff + 2; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + loop[2] = tmp; + break; + // direction 2 + case eParam13: + direction[2] = v; + break; + // trig 2 + case eParam14: + trig[2] = v; + break; + + // level 3 + case eParam15: + level[3] = v; + break; + // start 3 + case eParam16: + tmp = v; + if (tmp < 0xff) tmp = 0xff; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + start[3] = tmp; + break; + // loop 3 + case eParam17: + tmp = v; + if (tmp < 0xff + 2) tmp = 0xff + 2; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + loop[3] = tmp; + break; + // direction 3 + case eParam18: + direction[3] = v; + break; + // trig 3 + case eParam19: + trig[3] = v; + break; + + default: + break; + } } void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples) { From c306f560f9e68fc31ae0015fd444553a2ea52779 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Mon, 26 Mar 2018 22:49:04 +0200 Subject: [PATCH 33/37] Update mix.c --- modules/mix/mix.c | 537 ++++++++++++++++++++++------------------------ 1 file changed, 260 insertions(+), 277 deletions(-) diff --git a/modules/mix/mix.c b/modules/mix/mix.c index fd244ab4d..c97b3e754 100644 --- a/modules/mix/mix.c +++ b/modules/mix/mix.c @@ -1,13 +1,23 @@ /* mix.c aleph-bfin - //#define FR32_MAX 0x7fffffff //2147483647 - //#define FR32_MIN 0x80000000 //-2147483648 + + a very simple template module. + + applies attenuation with slew to each input signal, + + then mixes all attenuated signals to all outputs. + + also performs CV changes with slew. + */ +//-- blackfin toolchain headers +// 1.32 and 1.15 fixed-point arithmeti +#include "fract_math.h" + //-- aleph/common headers #include "types.h" -#include //-- aleph/bfin-lib headers // global variables @@ -16,316 +26,289 @@ #include "cv.h" // gpio pin numbers #include "gpio.h" -#include "fract_math.h" //-- dsp class headers // simple 1-pole integrator #include "filter_1p.h" - // global declarations for module data #include "module.h" + +//--- custom headers +// parameter lists and constants #include "params.h" -#define BUFFERSIZE 0x1000000 -#define BUFFERSIZE_1 (0x1000000 - 1) -#define FR32_MAX1_2 0x3fffffff +// customized module data structure +// this will be located at the top of SDRAM (64MB) +// all other variables (code, stack, heap) are located in SRAM (64K) +typedef struct _mixData { + //... here is where you would put other large data structures. + + // for example, a multichannel delay module would need an audio buffer: + // volatile fract32 audioBuffer[NUM_BUFS][FRAMES_PER_BUF]; + // bear in mind that access to SDRAM is significantly slower than SRAM (10-20 cycles!) + // so don't put anything here that doesn't need the extra space. +} mixData; -typedef struct _sampleBuffer { - volatile fract32 *data; //pointer to data - u32 samples; //count of samples -} sampleBuffer; +//------------------------- +//----- extern variables (initialized here) -typedef struct _bufferHead { - sampleBuffer *buf; //pointer to buffer - s32 idx; //current idx -} bufferHead; -static void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples); -static void buffer_head_init(bufferHead *head, sampleBuffer *buf); -static s32 buffer_head_play(bufferHead *head); +// global pointer to module descriptor. +// required by the aleph-bfin library! +ModuleData* gModuleData; -typedef struct _mixData { - ModuleData super; - ParamData mParamData[eParamNumParams]; - - volatile fract32 sampleBuffer[BUFFERSIZE]; -} mixData; +//-----------------------bfin_lib/src/ +//------ static variables + +/* + here's the actual memory for module descriptor and param data + global pointers are to point at these here during module init. + we do it in this indirect way, because + a) modules have variable param count + b) in an extreme case, might need to locate param data in SDRAM + ( until recently, SDRAM contained full param descriptors.) +*/ +static ModuleData super; +static ParamData mParamData[eParamNumParams]; + +// input values +static fract32 adcVal[4]; +static filter_1p_lo adcSlew[4]; + + +// cv values (16 bits, but use fract32 and audio integrators) +static fract32 cvVal[4]; +static filter_1p_lo cvSlew[4]; +// current channel to update - see below in process_cv() +static u8 cvChan = 0; + +// audio output bus +static fract32 outBus = 0; -ModuleData *gModuleData; -mixData *data; -sampleBuffer onchipbuffer[4]; -u32 offset = 0; +//----------------- +//--- static function declaration -bufferHead heads[4]; -fract32 level[4] = { PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2 }; -fract32 start[4] = { 0xff, 0xff, 0xff, 0xff }; -fract32 loop[4] = { 48000, 48000, 48000, 48000 }; -fract32 direction[4] = { 1, 1, 1, 1 }; -fract32 trig[4] = { 0, 0, 0, 0 }; +// update cv output +static void process_cv(void); +// small helper function to set parameter initial values static inline void param_setup(u32 id, ParamValue v) { - gModuleData->paramData[id].value = v; - module_set_param(id, v); + // set the input data so that bfin core will report it + // back to the controller via SPI, when requested. + // (bees will make such a request of each param at launch to sync with network.) + // this is also how a polled analysis parameter would work. + gModuleData->paramData[id].value = v; + module_set_param(id, v); } + +//---------------------- +//----- external functions + void module_init(void) { - data = (mixData*)SDRAM_ADDRESS; - gModuleData = &(data->super); - strcpy(gModuleData->name, "mix"); - gModuleData->paramData = data->mParamData; - gModuleData->numParams = eParamNumParams; - - u32 n, i; - - for(n=0; n<4; n++) - { - buffer_init(&(onchipbuffer[n]), data->sampleBuffer, BUFFERSIZE); - } - - for(n=0; n<4; n++) - { - buffer_head_init(&(heads[n]), &(onchipbuffer[n])); - } - - for(i=0; isampleBuffer[i] = 0x00000000; - } - - offset = 0; - - // init parameters - param_setup(eParam0, PARAM_AMP_MAX >> 2); - param_setup(eParam1, 0); - param_setup(eParam2, 48000); - param_setup(eParam3, 1); - param_setup(eParam4, 0); - - param_setup(eParam5, PARAM_AMP_MAX >> 2); - param_setup(eParam6, 0); - param_setup(eParam7, 48000); - param_setup(eParam8, 1); - param_setup(eParam9, 0); - - param_setup(eParam10, PARAM_AMP_MAX >> 2); - param_setup(eParam11, 0); - param_setup(eParam12, 48000); - param_setup(eParam13, 1); - param_setup(eParam14, 0); - - param_setup(eParam15, PARAM_AMP_MAX >> 2); - param_setup(eParam16, 0); - param_setup(eParam17, 48000); - param_setup(eParam18, 1); - param_setup(eParam19, 0); - -// for(n=0; nparamData = mParamData; + gModuleData->numParams = eParamNumParams; + + // initialize 1pole filters for input attenuation slew + filter_1p_lo_init( &(adcSlew[0]), 0 ); + filter_1p_lo_init( &(adcSlew[1]), 0 ); + filter_1p_lo_init( &(adcSlew[2]), 0 ); + filter_1p_lo_init( &(adcSlew[3]), 0 ); + + // initialize 1pole filters for cv output slew + filter_1p_lo_init( &(cvSlew[0]), 0 ); + filter_1p_lo_init( &(cvSlew[1]), 0 ); + filter_1p_lo_init( &(cvSlew[2]), 0 ); + filter_1p_lo_init( &(cvSlew[3]), 0 ); + + + // set initial param values + // constants are from params.h + param_setup(eParam_cv0, 0 ); + param_setup(eParam_cv1, 0 ); + param_setup(eParam_cv2, 0 ); + param_setup(eParam_cv3, 0 ); + + // set amp to 1/4 (-12db) with right-shift intrinsic + param_setup(eParam_adc0, PARAM_AMP_MAX >> 2 ); + param_setup(eParam_adc1, PARAM_AMP_MAX >> 2 ); + param_setup(eParam_adc2, PARAM_AMP_MAX >> 2 ); + param_setup(eParam_adc3, PARAM_AMP_MAX >> 2 ); + + // set slew defaults. the value is pretty arbitrary + param_setup(eParam_adcSlew0, PARAM_SLEW_DEFAULT); + param_setup(eParam_adcSlew1, PARAM_SLEW_DEFAULT); + param_setup(eParam_adcSlew2, PARAM_SLEW_DEFAULT); + param_setup(eParam_adcSlew3, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew0, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew1, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew2, PARAM_SLEW_DEFAULT); + param_setup(eParam_cvSlew3, PARAM_SLEW_DEFAULT); + + + } // de-init (never actually used on blackfin, but maybe by emulator) void module_deinit(void) { + ;; } // get number of parameters u32 module_get_num_params(void) { - return eParamNumParams; + return eParamNumParams; } -void module_process_frame(void) { - u8 c; - static s64 x[4] = { FR32_MAX1_2, FR32_MAX1_2, FR32_MAX1_2, FR32_MAX1_2 }; - - // linear idx - for (c=0; c<4; c++) - { - fract32 y0 = heads[c].idx; - fract32 y1 = heads[c].idx + 2; - - if (direction[c] > 0) - { - x[c] += direction[c]; - - if (x[c] > FR32_MAX) - { - x[c] = FR32_MAX1_2; - } - - heads[c].idx = add_fr1x32(y0, mult_fr1x32x32(x[c], sub_fr1x32(y1, y0))); - if (heads[c].idx > loop[c]) - { - heads[c].idx = start[c]; - } - if (trig[c]) - { - heads[c].idx = start[c]; - trig[c] = 0; - } - } - else - { - x[c] += -direction[c]; - - if (x[c] > FR32_MAX) - { - x[c] = FR32_MAX1_2; - } - - heads[c].idx = sub_fr1x32(y0, mult_fr1x32x32(x[c], sub_fr1x32(y1, y0))); - if (heads[c].idx < start[c]) - { - heads[c].idx = loop[c]; - } - if (trig[c]) - { - heads[c].idx = loop[c]; - trig[c] = 0; - } - } - - out[c] = mult_fr1x32x32(level[c], buffer_head_play(&(heads[c]))); - } -} -// sample offset -void module_set_offset(ParamValue v) { - offset = v; -} -// sample -void module_set_sample(ParamValue v) { - data->sampleBuffer[offset] = v; - offset++; -} +// frame process function! +// called each audio frame from codec interrupt handler +// ( bad, i know, see github issues list ) +void module_process_frame(void) { -// parameter set function -void module_set_param(u32 idx, ParamValue v) { - fract32 tmp; - - switch(idx) { - // level 0 - case eParam0: - level[0] = v; - break; - // start 0 - case eParam1: - tmp = v; - if (tmp < 0xff) tmp = 0xff; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - start[0] = tmp; - break; - // loop 0 - case eParam2: - tmp = v; - if (tmp < 0xff + 2) tmp = 0xff + 2; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - loop[0] = tmp; - break; - // direction 0 - case eParam3: - direction[0] = v; - break; - // trig 0 - case eParam4: - trig[0] = v; - break; - - // level 1 - case eParam5: - level[1] = v; - break; - // start 1 - case eParam6: - tmp = v; - if (tmp < 0xff) tmp = 0xff; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - start[1] = tmp; - break; - // loop 1 - case eParam7: - tmp = v; - if (tmp < 0xff + 2) tmp = 0xff + 2; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - loop[1] = tmp; - break; - // direction 1 - case eParam8: - direction[1] = v; - break; - // trig 1 - case eParam9: - trig[1] = v; - break; - - // level 2 - case eParam10: - level[2] = v; - break; - // start 2 - case eParam11: - tmp = v; - if (tmp < 0xff) tmp = 0xff; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - start[2] = tmp; - break; - // loop 2 - case eParam12: - tmp = v; - if (tmp < 0xff + 2) tmp = 0xff + 2; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - loop[2] = tmp; - break; - // direction 2 - case eParam13: - direction[2] = v; - break; - // trig 2 - case eParam14: - trig[2] = v; - break; - - // level 3 - case eParam15: - level[3] = v; - break; - // start 3 - case eParam16: - tmp = v; - if (tmp < 0xff) tmp = 0xff; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - start[3] = tmp; - break; - // loop 3 - case eParam17: - tmp = v; - if (tmp < 0xff + 2) tmp = 0xff + 2; - if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; - loop[3] = tmp; - break; - // direction 3 - case eParam18: - direction[3] = v; - break; - // trig 3 - case eParam19: - trig[3] = v; - break; - - default: - break; - } -} + //--- process slew -void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples) { - buf->data = data; - buf->samples = samples; + // + // update filters, calling "class method" on pointer to each + adcVal[0] = filter_1p_lo_next( &(adcSlew[0]) ); + adcVal[1] = filter_1p_lo_next( &(adcSlew[1]) ); + adcVal[2] = filter_1p_lo_next( &(adcSlew[2]) ); + adcVal[3] = filter_1p_lo_next( &(adcSlew[3]) ); + + //--- mix + + // zero the output bus + outBus = 0; + + /* + note the use of fract32 arithmetic intrinsics! + these are fast saturating multiplies/adds for 32bit signed fractions in [-1, 1) + there are also intrinsics for fr16, mixed modes, and conversions. + for details see: + http://blackfin.uclinux.org/doku.php?id=toolchain:built-in_functions + */ + // scale each input and add it to the bus + outBus = add_fr1x32( outBus, mult_fr1x32x32(in[0], adcVal[0]) ); + outBus = add_fr1x32( outBus, mult_fr1x32x32(in[1], adcVal[1]) ); + outBus = add_fr1x32( outBus, mult_fr1x32x32(in[2], adcVal[2]) ); + outBus = add_fr1x32( outBus, mult_fr1x32x32(in[3], adcVal[3]) ); + + // copy the bus to all the outputs + out[0] = outBus; + out[1] = outBus; + out[2] = outBus; + out[3] = outBus; + + + //--- cv + process_cv(); } -void buffer_head_init(bufferHead *head, sampleBuffer *buf) { - head->buf = buf; - head->idx = 0; + +// parameter set function +void module_set_param(u32 idx, ParamValue v) { + // switch on the param index + switch(idx) { + // cv output values + case eParam_cv0 : + filter_1p_lo_in( &(cvSlew[0]), v ); + break; + case eParam_cv1 : + filter_1p_lo_in( &(cvSlew[1]), v ); + break; + case eParam_cv2 : + filter_1p_lo_in( &(cvSlew[2]), v ); + break; + case eParam_cv3 : + filter_1p_lo_in( &(cvSlew[3]), v ); + + // cv slew values + break; + case eParam_cvSlew0 : + filter_1p_lo_set_slew(&(cvSlew[0]), v); + break; + case eParam_cvSlew1 : + filter_1p_lo_set_slew(&(cvSlew[1]), v); + break; + case eParam_cvSlew2 : + filter_1p_lo_set_slew(&(cvSlew[2]), v); + break; + case eParam_cvSlew3 : + filter_1p_lo_set_slew(&(cvSlew[3]), v); + break; + + // input attenuation values + case eParam_adc0 : + filter_1p_lo_in( &(adcSlew[0]), v ); + break; + case eParam_adc1 : + filter_1p_lo_in( &(adcSlew[1]), v ); + break; + case eParam_adc2 : + filter_1p_lo_in( &(adcSlew[2]), v ); + break; + case eParam_adc3 : + filter_1p_lo_in( &(adcSlew[3]), v ); + + // input attenuation slew values + break; + case eParam_adcSlew0 : + filter_1p_lo_set_slew(&(adcSlew[0]), v); + break; + case eParam_adcSlew1 : + filter_1p_lo_set_slew(&(adcSlew[1]), v); + break; + case eParam_adcSlew2 : + filter_1p_lo_set_slew(&(adcSlew[2]), v); + break; + case eParam_adcSlew3 : + filter_1p_lo_set_slew(&(adcSlew[3]), v); + break; + + default: + break; + } } -s32 buffer_head_play(bufferHead *head) { - return head->buf->data[head->idx]; +//----- static function definitions + +//// NOTE / FIXME: +/* CV updates are staggered, each channel on a separate audio frame. + + the reason for this is that each channel takes some time to update. + for now, we just wait a full frame between channels, + and effectively reduce CV output sampling rate by a factor of 4. + (as well as changing the effecticve slew time, which is not great.) + + the more proper way to do this would be: + - enable DMA tx interrupt + - each ISR calls the next channel to be loaded + - last thing audio ISR does is call the first DAC channel to be loaded + - cv_update writes to 4x16 volatile buffer + + this could give rise to its own problems: + audio frame processing is currently interrupt-driven per frame, + so CV tx interrupt could be masked by the next audio frame if the schedule is tight. +*/ +// update cv output +void process_cv(void) { + // process the current channel + // do nothing if the value is stable + if( filter_1p_sync( &(cvSlew[cvChan]) ) ) { + ;; + } else { + // update the slew filter and store the value + cvVal[cvChan] = filter_1p_lo_next(&(cvSlew[cvChan])); + // send the value to the cv driver + cv_update( cvChan, cvVal[cvChan] ); + } + + // update the channel to be processed + if(++cvChan == 4) { + cvChan = 0; + } } From 25f8a27ffb1ab63805f9e0b6ed0dfd91c955fda1 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Mon, 26 Mar 2018 22:49:44 +0200 Subject: [PATCH 34/37] Update params.c --- modules/mix/params.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/modules/mix/params.c b/modules/mix/params.c index 88f39f9e5..2d4192f48 100644 --- a/modules/mix/params.c +++ b/modules/mix/params.c @@ -16,31 +16,6 @@ // this function extern void fill_param_desc(ParamDesc* desc) { - strcpy(desc[eParam0].label, "level"); - desc[eParam0].type = eParamTypeAmp; - desc[eParam0].min = 0x00000000; - desc[eParam0].max = PARAM_AMP_MAX; - desc[eParam0].radix = 16; - - strcpy(desc[eParam1].label, "start"); - desc[eParam1].type = eParamTypeFix; - desc[eParam1].min = 0x00000000; - desc[eParam1].max = PARAM_SECONDS_MAX; - desc[eParam1].radix = PARAM_SECONDS_RADIX; - - strcpy(desc[eParam2].label, "loop"); - desc[eParam2].type = eParamTypeFix; - desc[eParam2].min = 0x00000000; - desc[eParam2].max = PARAM_SECONDS_MAX; - desc[eParam2].radix = PARAM_SECONDS_RADIX; - - strcpy(desc[eParam3].label, "speed"); - desc[eParam3].type = eParamTypeFix; - desc[eParam3].min = 0x00000000; - desc[eParam3].max = PARAM_SECONDS_MAX; - desc[eParam3].radix = PARAM_SECONDS_RADIX; - - // obviously, these could be done in other ways ( easier to read/edit maybe. ) // but neither code space nor speed is a big deal here. // this code can also be script-generated easily enough. From 7fc23662ed18e4292df8aea6565c85ea09711b48 Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Mon, 26 Mar 2018 22:50:09 +0200 Subject: [PATCH 35/37] Update params.h --- modules/mix/params.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/mix/params.h b/modules/mix/params.h index 1bc3469d6..9c572e185 100644 --- a/modules/mix/params.h +++ b/modules/mix/params.h @@ -9,21 +9,12 @@ #define PARAM_CV_MAX 0x7fffffff #define PARAM_SLEW_MAX 0x7fffffff -#define PARAM_SECONDS_MAX 0x003c0000 -#define PARAM_SECONDS_RADIX 7 - // something pretty fast, but noticeable #define PARAM_SLEW_DEFAULT 0x7ffecccc // enumerate parameters // the order defined here must be matched in the descriptor ! enum params { - - eParam0, - eParam1, - eParam2, - eParam3, - // cv slew eParam_cvSlew0, eParam_cvSlew1, From dc7f395677de3b3a1fba4a5a45d3c72c00fb7e8a Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Mon, 26 Mar 2018 22:52:42 +0200 Subject: [PATCH 36/37] Create sample.c --- modules/sample/sample.c | 329 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 modules/sample/sample.c diff --git a/modules/sample/sample.c b/modules/sample/sample.c new file mode 100644 index 000000000..af5b785c8 --- /dev/null +++ b/modules/sample/sample.c @@ -0,0 +1,329 @@ +/* + sample.c + aleph-bfin +*/ + +//-- aleph/common headers +#include "types.h" +#include + +//-- aleph/bfin-lib headers +// global variables +#include "bfin_core.h" +// cv output driver +#include "cv.h" +// gpio pin numbers +#include "gpio.h" +#include "fract_math.h" + +//-- dsp class headers +// simple 1-pole integrator +#include "filter_1p.h" + +// global declarations for module data +#include "module.h" +#include "params.h" + +#define BUFFERSIZE 0x1000000 +#define BUFFERSIZE_1 (0x1000000 - 1) +#define FR32_MAX1_2 0x3fffffff + + +typedef struct _sampleBuffer { + volatile fract32 *data; //pointer to data + u32 samples; //count of samples +} sampleBuffer; + +typedef struct _bufferHead { + sampleBuffer *buf; //pointer to buffer + s32 idx; //current idx +} bufferHead; + +static void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples); +static void buffer_head_init(bufferHead *head, sampleBuffer *buf); +static s32 buffer_head_play(bufferHead *head); + +typedef struct _mixData { + ModuleData super; + ParamData mParamData[eParamNumParams]; + + volatile fract32 sampleBuffer[BUFFERSIZE]; +} mixData; + +ModuleData *gModuleData; +mixData *data; +sampleBuffer onchipbuffer[4]; +u32 offset = 0; + +bufferHead heads[4]; +fract32 level[4] = { PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2, PARAM_AMP_MAX >> 2 }; +fract32 start[4] = { 0xff, 0xff, 0xff, 0xff }; +fract32 loop[4] = { 48000, 48000, 48000, 48000 }; +fract32 direction[4] = { 1, 1, 1, 1 }; +fract32 trig[4] = { 0, 0, 0, 0 }; + +static inline void param_setup(u32 id, ParamValue v) { + gModuleData->paramData[id].value = v; + module_set_param(id, v); +} + +void module_init(void) { + data = (mixData*)SDRAM_ADDRESS; + gModuleData = &(data->super); + strcpy(gModuleData->name, "mix"); + gModuleData->paramData = data->mParamData; + gModuleData->numParams = eParamNumParams; + + u32 n, i; + + for(n=0; n<4; n++) + { + buffer_init(&(onchipbuffer[n]), data->sampleBuffer, BUFFERSIZE); + } + + for(n=0; n<4; n++) + { + buffer_head_init(&(heads[n]), &(onchipbuffer[n])); + } + + for(i=0; isampleBuffer[i] = 0x00000000; + } + + offset = 0; + + // init parameters + param_setup(eParam0, PARAM_AMP_MAX >> 2); + param_setup(eParam1, 0); + param_setup(eParam2, 48000); + param_setup(eParam3, 1); + param_setup(eParam4, 0); + + param_setup(eParam5, PARAM_AMP_MAX >> 2); + param_setup(eParam6, 0); + param_setup(eParam7, 48000); + param_setup(eParam8, 1); + param_setup(eParam9, 0); + + param_setup(eParam10, PARAM_AMP_MAX >> 2); + param_setup(eParam11, 0); + param_setup(eParam12, 48000); + param_setup(eParam13, 1); + param_setup(eParam14, 0); + + param_setup(eParam15, PARAM_AMP_MAX >> 2); + param_setup(eParam16, 0); + param_setup(eParam17, 48000); + param_setup(eParam18, 1); + param_setup(eParam19, 0); + +// for(n=0; n 0) + { + x[c] += direction[c]; + + if (x[c] > FR32_MAX) + { + x[c] = FR32_MAX1_2; + } + + heads[c].idx = add_fr1x32(y0, mult_fr1x32x32(x[c], sub_fr1x32(y1, y0))); + if (heads[c].idx > loop[c]) + { + heads[c].idx = start[c]; + } + if (trig[c]) + { + heads[c].idx = start[c]; + trig[c] = 0; + } + } + else + { + x[c] += -direction[c]; + + if (x[c] > FR32_MAX) + { + x[c] = FR32_MAX1_2; + } + + heads[c].idx = sub_fr1x32(y0, mult_fr1x32x32(x[c], sub_fr1x32(y1, y0))); + if (heads[c].idx < start[c]) + { + heads[c].idx = loop[c]; + } + if (trig[c]) + { + heads[c].idx = loop[c]; + trig[c] = 0; + } + } + + out[c] = mult_fr1x32x32(level[c], buffer_head_play(&(heads[c]))); + } +} + +// sample offset +void module_set_offset(ParamValue v) { + offset = v; +} + +// sample +void module_set_sample(ParamValue v) { + data->sampleBuffer[offset] = v; + offset++; +} + +// parameter set function +void module_set_param(u32 idx, ParamValue v) { + fract32 tmp; + + switch(idx) { + // level 0 + case eParam0: + level[0] = v; + break; + // start 0 + case eParam1: + tmp = v; + if (tmp < 0xff) tmp = 0xff; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + start[0] = tmp; + break; + // loop 0 + case eParam2: + tmp = v; + if (tmp < 0xff + 2) tmp = 0xff + 2; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + loop[0] = tmp; + break; + // direction 0 + case eParam3: + direction[0] = v; + break; + // trig 0 + case eParam4: + trig[0] = v; + break; + + // level 1 + case eParam5: + level[1] = v; + break; + // start 1 + case eParam6: + tmp = v; + if (tmp < 0xff) tmp = 0xff; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + start[1] = tmp; + break; + // loop 1 + case eParam7: + tmp = v; + if (tmp < 0xff + 2) tmp = 0xff + 2; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + loop[1] = tmp; + break; + // direction 1 + case eParam8: + direction[1] = v; + break; + // trig 1 + case eParam9: + trig[1] = v; + break; + + // level 2 + case eParam10: + level[2] = v; + break; + // start 2 + case eParam11: + tmp = v; + if (tmp < 0xff) tmp = 0xff; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + start[2] = tmp; + break; + // loop 2 + case eParam12: + tmp = v; + if (tmp < 0xff + 2) tmp = 0xff + 2; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + loop[2] = tmp; + break; + // direction 2 + case eParam13: + direction[2] = v; + break; + // trig 2 + case eParam14: + trig[2] = v; + break; + + // level 3 + case eParam15: + level[3] = v; + break; + // start 3 + case eParam16: + tmp = v; + if (tmp < 0xff) tmp = 0xff; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + start[3] = tmp; + break; + // loop 3 + case eParam17: + tmp = v; + if (tmp < 0xff + 2) tmp = 0xff + 2; + if (tmp > BUFFERSIZE_1) tmp = BUFFERSIZE_1; + loop[3] = tmp; + break; + // direction 3 + case eParam18: + direction[3] = v; + break; + // trig 3 + case eParam19: + trig[3] = v; + break; + + default: + break; + } +} + +void buffer_init(sampleBuffer *buf, volatile fract32 *data, u32 samples) { + buf->data = data; + buf->samples = samples; +} + +void buffer_head_init(bufferHead *head, sampleBuffer *buf) { + head->buf = buf; + head->idx = 0; +} + +s32 buffer_head_play(bufferHead *head) { + return head->buf->data[head->idx]; +} From 3fc43320952d513354a40d2cc68f438ebad68f5e Mon Sep 17 00:00:00 2001 From: prgmsoftware <35396092+prgmsoftware@users.noreply.github.com> Date: Mon, 26 Mar 2018 22:54:26 +0200 Subject: [PATCH 37/37] Add files via upload --- modules/sample/Makefile | 92 ++++++++++++ modules/sample/module_custom.h | 20 +++ modules/sample/params.c | 133 +++++++++++++++++ modules/sample/params.h | 50 +++++++ modules/sample/sample.lds | 256 +++++++++++++++++++++++++++++++++ modules/sample/version.mk | 3 + 6 files changed, 554 insertions(+) create mode 100644 modules/sample/Makefile create mode 100644 modules/sample/module_custom.h create mode 100644 modules/sample/params.c create mode 100644 modules/sample/params.h create mode 100644 modules/sample/sample.lds create mode 100644 modules/sample/version.mk diff --git a/modules/sample/Makefile b/modules/sample/Makefile new file mode 100644 index 000000000..9ced6f521 --- /dev/null +++ b/modules/sample/Makefile @@ -0,0 +1,92 @@ + +# change this to your module name +module_name = sample + +# paths to aleph repository sources +audio = ../../dsp +bfin = ../../bfin_lib/src + +include version.mk +version = $(maj).$(min).$(rev) +ldr_name = $(module_name)-$(version).ldr + +# add sources from here/audio library. +module_obj = sample.o \ + $(audio)/filter_1p.o \ + + +# ----- below here, probably dont need to customize. + +all: $(module_name).ldr + +# this gets the core configuration and sources +include ../../bfin_lib/bfin_lib.mk + +CFLAGS += -D ARCH_BFIN=1 +# diagnose gcc errors +# CFLAGS += --verbose + +desc_src = \ + $(bfin_lib_srcdir)desc.c \ + $(bfin_lib_srcdir)pickle.c \ + params.c + +# this target generates the descriptor helper program +desc: + gcc $(desc_src) \ + $(INC) \ + -D NAME=\"$(module_name)\" \ + -o $(module_name)_desc_build + +$(module_obj): %.o : %.c + $(CC) $(CFLAGS) -c -o $@ $< $(LDFLAGS) + +$(module_name): bfin_lib_target $(module_obj) + $(CC) $(LDFLAGS) -T $(module_name).lds \ + $(patsubst %.o, $(bfin_lib_objdir)%.o, $(bfin_lib_obj)) \ + $(module_obj) \ + -o $(module_name) \ + -lm -lbfdsp -lbffastfp + +clean: bfin_lib_clean + rm $(module_obj) + rm $(module_name).ldr + rm $(module_name) + +# this generates the module and descriptor helper app, +# runs the descrptor app to generate .dsc, +# and makes copies with version number strings. +# best used after "make clean" +deploy: $(module_name).ldr + make desc + ./$(module_name)_desc_build + cp $(module_name).ldr $(module_name)-$(maj).$(min).$(rev).ldr + cp $(module_name).dsc $(module_name)-$(maj).$(min).$(rev).dsc + +.PHONY: clean + deploy + + +sim_sourcefiles = mix.c \ + $(audio)/filter_1p.c \ + params.c \ + ../../utils/bfin_sim/main.c \ + ../../utils/bfin_sim/src/cv.c \ + ../../utils/bfin_sim/fract2float_conv.c \ + ../../utils/bfin_sim/fract_math.c + +sim_inc = -I ../../dsp \ + -I ../../utils/bfin_sim/src \ + -I ../../utils/bfin_sim/ \ + -I ../../utils/bfin_sim/src/libfixmath \ + -I ./ \ + -I ../../common\ + +sim_outfile = mix_jack + +sim_flags = -ljack -llo -D ARCH_LINUX=1 + +sim: + touch $(sim_outfile) + rm ./$(sim_outfile) + gcc $(sim_sourcefiles) $(sim_flags) $(sim_inc) -o $(sim_outfile) -g diff --git a/modules/sample/module_custom.h b/modules/sample/module_custom.h new file mode 100644 index 000000000..827595f34 --- /dev/null +++ b/modules/sample/module_custom.h @@ -0,0 +1,20 @@ +/* module_custom.h + + some consants should be both customized for each module, + and preprocessed for efficiency. + here is where such things live. + + most likely, this is just a count of parameters. + + a copy of this header should exist in your custom modiule directory + (e.g. aleph/bfin/modules/mymodule/ + */ + +#ifndef _ALEPH_MODULE_CUSTOM_H_ +#define _ALEPH_MODULE_CUSTOM_H_ + +#include "params.h" + +#define NUM_PARAMS eParamNumParams + +#endif diff --git a/modules/sample/params.c b/modules/sample/params.c new file mode 100644 index 000000000..e03cb3560 --- /dev/null +++ b/modules/sample/params.c @@ -0,0 +1,133 @@ +/* + params.c + parameter descriptor fields. +*/ + +#include +#include "module.h" +#include "params.h" + +extern void fill_param_desc(ParamDesc* desc) { + + strcpy(desc[eParam0].label, "level 0"); + desc[eParam0].type = eParamTypeAmp; + desc[eParam0].min = 0x00000000; + desc[eParam0].max = PARAM_AMP_MAX; + desc[eParam0].radix = 16; + + strcpy(desc[eParam1].label, "start 0"); + desc[eParam1].type = eParamTypeFix; + desc[eParam1].min = 0x00000000; + desc[eParam1].max = PARAM_SECONDS_MAX; + desc[eParam1].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam2].label, "loop 0"); + desc[eParam2].type = eParamTypeFix; + desc[eParam2].min = 0x00000000; + desc[eParam2].max = PARAM_SECONDS_MAX; + desc[eParam2].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam3].label, "direction 0"); + desc[eParam3].type = eParamTypeBool; + desc[eParam3].min = 0; + desc[eParam3].max = 1; + desc[eParam3].radix = 1; + + strcpy(desc[eParam4].label, "trig 0"); + desc[eParam4].type = eParamTypeBool; + desc[eParam4].min = 0; + desc[eParam4].max = 1; + desc[eParam4].radix = 1; + + strcpy(desc[eParam5].label, "level 1"); + desc[eParam5].type = eParamTypeAmp; + desc[eParam5].min = 0x00000000; + desc[eParam5].max = PARAM_AMP_MAX; + desc[eParam5].radix = 16; + + strcpy(desc[eParam6].label, "start 1"); + desc[eParam6].type = eParamTypeFix; + desc[eParam6].min = 0x00000000; + desc[eParam6].max = PARAM_SECONDS_MAX; + desc[eParam6].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam7].label, "loop 1"); + desc[eParam7].type = eParamTypeFix; + desc[eParam7].min = 0x00000000; + desc[eParam7].max = PARAM_SECONDS_MAX; + desc[eParam7].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam8].label, "direction 1"); + desc[eParam8].type = eParamTypeBool; + desc[eParam8].min = 0; + desc[eParam8].max = 1; + desc[eParam8].radix = 1; + + strcpy(desc[eParam9].label, "trig 1"); + desc[eParam9].type = eParamTypeBool; + desc[eParam9].min = 0; + desc[eParam9].max = 1; + desc[eParam9].radix = 1; + + strcpy(desc[eParam10].label, "level 2"); + desc[eParam10].type = eParamTypeAmp; + desc[eParam10].min = 0x00000000; + desc[eParam10].max = PARAM_AMP_MAX; + desc[eParam10].radix = 16; + + strcpy(desc[eParam11].label, "start 2"); + desc[eParam11].type = eParamTypeFix; + desc[eParam11].min = 0x00000000; + desc[eParam11].max = PARAM_SECONDS_MAX; + desc[eParam11].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam12].label, "loop 2"); + desc[eParam12].type = eParamTypeFix; + desc[eParam12].min = 0x00000000; + desc[eParam12].max = PARAM_SECONDS_MAX; + desc[eParam12].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam13].label, "direction 2"); + desc[eParam13].type = eParamTypeBool; + desc[eParam13].min = 0; + desc[eParam13].max = 1; + desc[eParam13].radix = 1; + + strcpy(desc[eParam14].label, "trig 2"); + desc[eParam14].type = eParamTypeBool; + desc[eParam14].min = 0; + desc[eParam14].max = 1; + desc[eParam14].radix = 1; + + strcpy(desc[eParam15].label, "level 3"); + desc[eParam15].type = eParamTypeAmp; + desc[eParam15].min = 0x00000000; + desc[eParam15].max = PARAM_AMP_MAX; + desc[eParam15].radix = 16; + + strcpy(desc[eParam16].label, "start 3"); + desc[eParam16].type = eParamTypeFix; + desc[eParam16].min = 0x00000000; + desc[eParam16].max = PARAM_SECONDS_MAX; + desc[eParam16].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam17].label, "loop 3"); + desc[eParam17].type = eParamTypeFix; + desc[eParam17].min = 0x00000000; + desc[eParam17].max = PARAM_SECONDS_MAX; + desc[eParam17].radix = PARAM_SECONDS_RADIX; + + strcpy(desc[eParam18].label, "direction 3"); + desc[eParam18].type = eParamTypeBool; + desc[eParam18].min = 0; + desc[eParam18].max = 1; + desc[eParam18].radix = 1; + + strcpy(desc[eParam19].label, "trig 3"); + desc[eParam19].type = eParamTypeBool; + desc[eParam19].min = 0; + desc[eParam19].max = 1; + desc[eParam19].radix = 1; +} + +// EOF diff --git a/modules/sample/params.h b/modules/sample/params.h new file mode 100644 index 000000000..c716ba843 --- /dev/null +++ b/modules/sample/params.h @@ -0,0 +1,50 @@ +#ifndef _ALEPH_MIX_PARAMS_H_ +#define _ALEPH_MIX_PARAMS_H_ + +#include "param_common.h" + +// define some constants here for the param descriptor code +// here, all the parameter ranges are pretty simple. +#define PARAM_AMP_MAX 0x7fffffff +#define PARAM_CV_MAX 0x7fffffff +#define PARAM_SLEW_MAX 0x7fffffff + +#define PARAM_SECONDS_MAX 0x003c0000 +#define PARAM_SECONDS_RADIX 7 + +// something pretty fast, but noticeable +#define PARAM_SLEW_DEFAULT 0x7ffecccc + +// enumerate parameters +// the order defined here must be matched in the descriptor ! +enum params { + + eParam0, + eParam1, + eParam2, + eParam3, + eParam4, + eParam5, + eParam6, + eParam7, + eParam8, + eParam9, + eParam10, + eParam11, + eParam12, + eParam13, + eParam14, + eParam15, + eParam16, + eParam17, + eParam18, + eParam19, + + eParamNumParams +}; + +// this is only defined by the descriptor helper program. +extern void fill_param_desc(ParamDesc* desc); + +#endif // header guard +// EOF diff --git a/modules/sample/sample.lds b/modules/sample/sample.lds new file mode 100644 index 000000000..03da2913b --- /dev/null +++ b/modules/sample/sample.lds @@ -0,0 +1,256 @@ +/* +* Copyright (C) 2007, 2008 Analog Devices, Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice is included verbatim in any distributions. No written agreement, +* license, or royalty fee is required for any of the authorized uses. +* Modifications to this software may be copyrighted by their authors +* and need not follow the licensing terms described here, provided that +* the new terms are clearly indicated on the first page of each file where +* they apply. +*/ + +/* The default linker script, for single core blackfin standalone executables */ + +MEMORY +{ +MEM_L1_CODE : ORIGIN = 0xFFA00000, LENGTH = 0x10000 +MEM_L1_CODE_CACHE : ORIGIN = 0xFFA10000, LENGTH = 0x4000 +MEM_L1_SCRATCH : ORIGIN = 0xFFB00000, LENGTH = 0x1000 +MEM_L1_DATA_B : ORIGIN = 0xFF900000, LENGTH = 0x8000 +MEM_L1_DATA_A : ORIGIN = 0xFF800000, LENGTH = 0x8000 +MEM_L2 : ORIGIN = 0xFEB00000, LENGTH = 0x0 +} + +OUTPUT_FORMAT("elf32-bfin", "elf32-bfin", +"elf32-bfin") +OUTPUT_ARCH(bfin) +ENTRY(__start) + +SECTIONS +{ +/* Read-only sections, merged into text segment: */ +PROVIDE (__executable_start = 0x0); . = 0x0; +.interp : { *(.interp) } +.hash : { *(.hash) } +.dynsym : { *(.dynsym) } +.dynstr : { *(.dynstr) } +.gnu.version : { *(.gnu.version) } +.gnu.version_d : { *(.gnu.version_d) } +.gnu.version_r : { *(.gnu.version_r) } +.rel.init : { *(.rel.init) } +.rela.init : { *(.rela.init) } +.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } +.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } +.rel.fini : { *(.rel.fini) } +.rela.fini : { *(.rela.fini) } +.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } +.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } +.rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } +.rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } +.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } +.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } +.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } +.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } +.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } +.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } +.rel.ctors : { *(.rel.ctors) } +.rela.ctors : { *(.rela.ctors) } +.rel.dtors : { *(.rel.dtors) } +.rela.dtors : { *(.rela.dtors) } +.rel.got : { *(.rel.got) } +.rela.got : { *(.rela.got) } +.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } +.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } +.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } +.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } +.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } +.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } +.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } +.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } +.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } +.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } +.rel.plt : { *(.rel.plt) } +.rela.plt : { *(.rela.plt) } + +.l2 : +{ +*(.l2 .l2.*) +} >MEM_L2 =0 + +.text : +{ +*(.text .stub .text.* .gnu.linkonce.t.* .l1.text .l1.text.*) +KEEP (*(.text.*personality*)) +/* .gnu.warning sections are handled specially by elf32.em. */ +*(.gnu.warning) +} >MEM_L1_CODE =0 + +.init : +{ +KEEP (*(.init)) +} >MEM_L1_CODE =0 +.plt : { *(.plt) } >MEM_L1_CODE +.fini : + +{ +KEEP (*(.fini)) +} >MEM_L1_CODE =0 + +PROVIDE (__etext = .); +PROVIDE (_etext = .); +PROVIDE (etext = .); +.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } >MEM_L1_DATA_A +.rodata1 : { *(.rodata1) } >MEM_L1_DATA_A + +.sdata2 : +{ +*(.sdata2 .sdata2.* .gnu.linkonce.s2.*) +} >MEM_L1_DATA_A + +.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } >MEM_L1_DATA_A +.eh_frame_hdr : { *(.eh_frame_hdr) } >MEM_L1_DATA_A +.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } >MEM_L1_DATA_A +.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >MEM_L1_DATA_A +/* Adjust the address for the data segment. We want to adjust up to +the same address within the page on the next page up. */ +. = ALIGN(0x1000) + (. & (0x1000 - 1)); +/* Exception handling */ +.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } >MEM_L1_DATA_A +.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >MEM_L1_DATA_A +/* Thread Local Storage sections */ +.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } >MEM_L1_DATA_A +.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } >MEM_L1_DATA_A +.preinit_array : +{ +PROVIDE_HIDDEN (___preinit_array_start = .); +KEEP (*(.preinit_array)) +PROVIDE_HIDDEN (___preinit_array_end = .); +} >MEM_L1_DATA_A +.init_array : +{ +PROVIDE_HIDDEN (___init_array_start = .); +KEEP (*(SORT(.init_array.*))) +KEEP (*(.init_array)) +PROVIDE_HIDDEN (___init_array_end = .); +} >MEM_L1_DATA_A +.fini_array : +{ +PROVIDE_HIDDEN (___fini_array_start = .); +KEEP (*(.fini_array)) +KEEP (*(SORT(.fini_array.*))) +PROVIDE_HIDDEN (___fini_array_end = .); +} >MEM_L1_DATA_A + +.ctors : +{ +/* gcc uses crtbegin.o to find the start of +the constructors, so we make sure it is +first. Because this is a wildcard, it +doesn't matter if the user does not +actually link against crtbegin.o; the +linker won't look for a file to match a +wildcard. The wildcard also means that it +doesn't matter which directory crtbegin.o +is in. */ +KEEP (*crtbegin*.o(.ctors)) +/* We don't want to include the .ctor section from +the crtend.o file until after the sorted ctors. +The .ctor section from the crtend file contains the +end of ctors marker and it must be last */ +KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) +KEEP (*(SORT(.ctors.*))) +KEEP (*(.ctors)) +} >MEM_L1_DATA_A + +.dtors : +{ +KEEP (*crtbegin*.o(.dtors)) +KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) +KEEP (*(SORT(.dtors.*))) +KEEP (*(.dtors)) +} >MEM_L1_DATA_A + +.jcr : { KEEP (*(.jcr)) } >MEM_L1_DATA_A +.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } >MEM_L1_DATA_A +.dynamic : { *(.dynamic) } >MEM_L1_DATA_A +.data : +{ +*(.data .data.* .gnu.linkonce.d.* .l1.data .l1.data.*) +KEEP (*(.gnu.linkonce.d.*personality*)) +SORT(CONSTRUCTORS) +} >MEM_L1_DATA_A +.data1 : { *(.data1) } >MEM_L1_DATA_A +.got : { *(.got.plt) *(.got) } >MEM_L1_DATA_A +/* We want the small data sections together, so single-instruction offsets +can access them all, and initialized data all before uninitialized, so +we can shorten the on-disk segment size. */ +.sdata : +{ +*(.sdata .sdata.* .gnu.linkonce.s.*) +} >MEM_L1_DATA_A +__edata = .; PROVIDE (_edata = .); +.sbss : +{ +__bss_start = .; +*(.dynsbss) +*(.sbss .sbss.* .gnu.linkonce.sb.*) +*(.scommon) +} >MEM_L1_DATA_A +.bss : +{ +*(.dynbss) +*(.bss .bss.* .gnu.linkonce.b.*) +*(COMMON) +/* Align here to ensure that the .bss section occupies space up to +_end. Align after .bss to ensure correct alignment even if the +.bss section disappears because there are no input sections. +FIXME: Why do we need it? When there is no .bss section, we don't +pad the .data section. */ +. = ALIGN(. != 0 ? 32 / 8 : 1); +__bss_end = .; +} >MEM_L1_DATA_A +. = ALIGN(32 / 8); +. = ALIGN(32 / 8); +__end = .; PROVIDE (_end = .); +/* Stabs debugging sections. */ +.stab 0 : { *(.stab) } +.stabstr 0 : { *(.stabstr) } +.stab.excl 0 : { *(.stab.excl) } +.stab.exclstr 0 : { *(.stab.exclstr) } +.stab.index 0 : { *(.stab.index) } +.stab.indexstr 0 : { *(.stab.indexstr) } +.comment 0 : { *(.comment) } +/* DWARF debug sections. +Symbols in the DWARF debugging sections are relative to the beginning +of the section so we begin them at 0. */ +/* DWARF 1 */ +.debug 0 : { *(.debug) } +.line 0 : { *(.line) } +/* GNU DWARF 1 extensions */ +.debug_srcinfo 0 : { *(.debug_srcinfo) } +.debug_sfnames 0 : { *(.debug_sfnames) } +/* DWARF 1.1 and DWARF 2 */ +.debug_aranges 0 : { *(.debug_aranges) } +.debug_pubnames 0 : { *(.debug_pubnames) } +/* DWARF 2 */ +.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } +.debug_abbrev 0 : { *(.debug_abbrev) } +.debug_line 0 : { *(.debug_line) } +.debug_frame 0 : { *(.debug_frame) } +.debug_str 0 : { *(.debug_str) } +.debug_loc 0 : { *(.debug_loc) } +.debug_macinfo 0 : { *(.debug_macinfo) } +/* SGI/MIPS DWARF 2 extensions */ +.debug_weaknames 0 : { *(.debug_weaknames) } +.debug_funcnames 0 : { *(.debug_funcnames) } +.debug_typenames 0 : { *(.debug_typenames) } +.debug_varnames 0 : { *(.debug_varnames) } + +__stack_end = ORIGIN(MEM_L1_SCRATCH) + LENGTH(MEM_L1_SCRATCH); + +/DISCARD/ : { *(.note.GNU-stack) } +} + diff --git a/modules/sample/version.mk b/modules/sample/version.mk new file mode 100644 index 000000000..f9ea5a843 --- /dev/null +++ b/modules/sample/version.mk @@ -0,0 +1,3 @@ +maj = 0 +min = 0 +rev = 0