I'm trying to store a char array of sound sample data, under 60Kb. I get "error, array size is too large. If I split it into two arrays I don't get the error. It has to be one array, I need to step through the array at different step sizes to generate different frequencies. This all works fine with an array of less than 32K.
I tried multidimensional, still got the error if the total memory size exceeded 32K. That would have been an easy solution for me. I'm not sure how to proceed from here if there is in fact a 32k limit to array size using PROGMEM. Perhaps I need an array of pointers? In that case I need to learn a lot more. I have to access the data fast enough to produce 6 different frequencies simultaneously inside an interupt service. Any solution has to be very brief, any guidance appreciated.
Wow, that sounds so simple, and logical. I've just downloaded "Flashlibrary" and that does not seem to mind arrays bigger than 32k. Just going to check if there is going to be a time overhead problem inside the ISR using "Flash library". I'll try your solution next.
Another failure A negative value for the array index did not work, just white noise from output (sound data is plucked guitar string) Then an inspiration, PROGMEM the data in two arrays, use the the first array as "base" and index through it and into the second array.
Failure The first 2 seconds sound fine then white noise for the second half. I need to see where the data is being put in memory, how do I do that? I'm using standard Arduino environment in Windows. Also Processing for helper data organising routines (write the data header file)
A negative index will always fail, irrespective of the ssize of the array UNLESS the array is accessed via a pointer offset from the zoreth index (handy for lookup tables involving negative numbers)
unsigned int lastsamp = 60000;
volatile unsigned long waveindex0;
volatile int inc0;
volatile unsigned int comb;
volatile unsigned int tempindex;
const unsigned char E00[] PROGMEM = {124, 127, 132, 127,...30k of samples
const unsigned char E0[] PROGMEM = {124, 127, 132, 127,...30k of samples
error if more than 32k in one array.
//Timer 4 on port H
TCCR4A = B10101010;//
TCCR4B = B00011001;//
TIMSK4 = B00100000;//flag mask, enable TOP int on top
ICR4 = 1000;//set top value, should be 1000 for 16KHz sample rate
ISR(TIMER4_CAPT_vect) {// ready for next sample
tempindex = waveindex0>>8;//lower 8 bits only used for fractional stepping through audio data
comb =(pgm_read_byte_far(&(E00[tempindex])));//tried with and without _far, gets lost at 32k(random noise)
if (tempindex < lastsamp){waveindex0+=inc0;}//inc waveindex and load next sample until it has reached the end of the second array
OCR4A=comb;//PWM
Thanks very much AWOL Some of the terms I'm unfamiliar with but I can just about get the gist of it. I'll look up prog_char and that memcpy stuff. The syntax is hard going for a non programmer.
My concern now is I need to use your code six times in the ISR, and all the time the clock is ticking! Well, I'd just about reconciled myself to being happy with max 2 second sample time so nothing to lose and everything (about 6 sec) to again.
OK, an Iliffe vector is simply a table of pointers to other arrays, typically vectors.
It is normally used if the shape of the intended array is not rectangular, say a triangle or a circle, where the Iliffe vector entries point to adjacent chords of the circle.
Here, however, the array is a simple vector, but not compilable.
So, we break it into a number of smaller vectors, each with their staring addresses held in the Iliffe vector.
Note that with an Iliffe vector, the arrays segments do not have to be consecutive in memory, and the segments do not have to be the same length, though if they are not, you are advised to have a second vector giving the segment lengths.
[edit] I forgot: I compiled my test on a processor that doesn't have "pgm_read_byte_far", so :
return pgm_read_byte_far(iliffe [iliffeIndex] + arrayIndex);
should do the trick on a Mega.[/edit]
AWOL, I have a working synthetic guitar that sounds very nice even before filtering!
I studied your code until fairly comfortable with it and started to implement. I looked up prog_char and realised I should have been using prog_uchar and not unsigned char for PROGMEM. On whim I changed this in my code and recompiled, immiediatly noticing for the first time the program size was now over 65k! I had been wondering why it never got beyond 35K...
I'm now wondering whether you can in fact have arrays bigger than 32K. Almost irrelevent now but I will try again with a single array.
Thanks again, I would not have found this without your code to look at and I'm sure the knowledge you've imparted will be very useful to me.
thanks for the edit, I tried with _far earlier, it got very flaky with the overhead. It's working fine now without the _far but I'm sure I'm very close to the limit, at least until there is a faster clock speed available.