Problems converting Aud.lib wavetable synth example from FLASh based samples to RAM

Status
Not open for further replies.

bmillier

Well-known member
Hi: I'm not having much luck converting the audio library wavetable synth example which stores the sample data entirely in FLASH (i.e. compiled with the program thru .cpp and .h include files for the sample data) into something that stores the sample data in SRAM (loaded in from an SD card). I have succeeded in partically converting it over so that the large waveform data files are now stored in SRAM, but am unable to convert the FLASH-based arrays that store the voice parameter data for each of the ranges on the keyboard.
In the example, these voice parameter arrays were stored in FLASH as follows:

Code:
static const AudioSynthWavetable::sample_data AcousticBass_samples[3] = {
	{
		(int16_t*)sample_0_Flute_100kbyte_FluteD4, // sample
		true, // LOOP
		14, // LENGTH_BITS
		(1 << (32 - 14)) * WAVETABLE_CENTS_SHIFT(0) * 37248.0 / WAVETABLE_NOTE_TO_FREQUENCY(63) / AUDIO_SAMPLE_RATE_EXACT + 0.5, // PER_HERTZ_PHASE_INCREMENT
		((uint32_t)15713 - 1) << (32 - 14), // MAX_PHASE
		((uint32_t)15712 - 1) << (32 - 14), // LOOP_PHASE_END
		(((uint32_t)15712 - 1) << (32 - 14)) - (((uint32_t)9379 - 1) << (32 - 14)), // LOOP_PHASE_LENGTH
		uint16_t(UINT16_MAX * WAVETABLE_DECIBEL_SHIFT(0)), // INI
   and so on for 3 complete tables of voice parameters , 1 per each keyboard range


I can load in the waveform arrays from an SD card and place them sequentially into a big RAM array uint32_t SAMPLE_BUFFER[50000]. Then I can change the above to
Code:
AudioSynthWavetable::sample_data AcousticBass_samples[3] = {
	{
		 (int16_t*)  &SAMPLE_BUFFER[0],
		 true, // LOOP
		14, // LENGTH_BITS
		(1 << (32 - 14)) * CENTS_SHIFT(-1) * 22050.0 / NOTE(64) / AUDIO_SAMPLE_RATE_EXACT + 0.5, // PER_HERTZ_PHASE_INCREMENT
		((uint32_t)10502 - 1) << (32 - 14), // MAX_PHASE
		((uint32_t)10446 - 1) << (32 - 14), // LOOP_PHASE_END
		(((uint32_t)10446 - 1) << (32 - 14)) - (((uint32_t)10179 - 1) << (32 - 14)), // LOOP_PHASE_LENGTH
		uint16_t(UINT16_MAX * DECIBEL_SHIFT(0)), // INITIAL_ATTENUATION_SCALAR
		uint32_t(0.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // DELAY_COUNT
		uint32_t(6.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // ATTACK_COUNT

This works fine- I'm still using the FLASH-based voice parameter files, but now pointing the 1st parameter, the waveform data pointer into my SAMPLE_BUFFER SRAM array.

Things fall apart when I try to move the FLASH-based voice parameters into SRAM. First I set up a structure for these parameters, matching what is defined in the synth_wavetable.h file:

AudioSynthWavetable::sample_data* sd0[3];

I then fill sd0[0] (and [1] etc) it up with exactly the same parameter values as were in the FLASH-based array (i.e from the #included AcousticBass.cpp file) as follows
sd0[0]->LOOP = true; ss0[0]-> LENGTH_BITS = 14; etc.
I load these from an SD card file, and I've checked that the values all match those in the FLASH array.
The example program informed the wavetable routine of the pointers to the various arrays as follows:

Code:
 AudioSynthWavetable::instrument_data AcousticBass = { 3, AcousticBass_ranges, AcousticBass_samples };

which I change to
Code:
 AudioSynthWavetable::instrument_data AcousticBass = { 2, AcousticBass_ranges, sd0[0]};

I reduce the keyboard ranges from the original 3 down to 2, as I am only loading 2 of the 3 ranges on the SD card (too much extra code needed until I figure out what actually works) While testing, I only play notes in the first 2 ranges to allow for this.

The program compiles OK this way. When I play notes on the keyboard, everything works fine with the FLASH-based version of the example, even after I modify the program to load the actual waveform data into SRAM, and change the pointers to that SAMPLE_BUFFER array.
However when I change the program to use the second of the two lines shown just above (voice parameter arrays now in SRAM at sd0[0], sd0[1], the program will run, the serial monitor will indicate which note I am playing ( + CPU utilization), but no sounds are produced. Also, the CPU utilization will show 0, whereas it will show 1 or 2% when everything is working properly, with the FLASH-Based voice parameter data.
I've tried everything I know- I'm not an expert in transferring variables in a structure, to a class. Most of the other code variations I've tried won't compile properly- complaining that I am not matching the parameter types needed for this line (although the following does compile properly- just doesn't produce sound)
Code:
AudioSynthWavetable::instrument_data AcousticBass = { 2, AcousticBass_ranges, sd0[0]};

The complete listing is as follows (rather messy as I've tried many things along the way).

Any ideas?? Thanks

Code:
/*   This works using the waveform sample data brought in by the SD card
but  still using the Flash based program parameter files
*/


#include <SPI.h>
#include <SD.h>
#include <Audio.h>
#include <MIDI.h>


// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

//#define DEBUG_ALLOC
const int TOTAL_VOICES = 48;
const int TOTAL_MIXERS = 17;
const int SECONDARY_MIXERS = 1;


AudioControlSGTL5000 sgtl5000_1;
AudioSynthWavetable wavetable[TOTAL_VOICES];
AudioMixer4 mixer[TOTAL_MIXERS];
AudioOutputI2S i2s1;
AudioConnection patchCord[] = {
	{ wavetable[0], 0, mixer[0], 0 },{ wavetable[1], 0, mixer[0], 1 },{ wavetable[2], 0, mixer[0],  2 },{ wavetable[3], 0, mixer[0],  3 },{ mixer[0], 0, mixer[TOTAL_MIXERS - 2], 0 },
	{ wavetable[4], 0, mixer[1], 0 },{ wavetable[5], 0, mixer[1], 1 },{ wavetable[6], 0, mixer[1],  2 },{ wavetable[7], 0, mixer[1],  3 },{ mixer[1], 0, mixer[TOTAL_MIXERS - 2], 1 },
	{ wavetable[8], 0, mixer[2], 0 },{ wavetable[9], 0, mixer[2], 1 },{ wavetable[10], 0, mixer[2],  2 },{ wavetable[11], 0, mixer[2],  3 },{ mixer[2], 0, mixer[TOTAL_MIXERS - 2], 2 },
	{ wavetable[12], 0, mixer[3], 0 },{ wavetable[13], 0, mixer[3], 1 },{ wavetable[14], 0, mixer[3],  2 },{ wavetable[15], 0, mixer[3],  3 },{ mixer[3], 0, mixer[TOTAL_MIXERS - 2], 3 },
	{ wavetable[16], 0, mixer[4], 0 },{ wavetable[17], 0, mixer[4], 1 },{ wavetable[18], 0, mixer[4],  2 },{ wavetable[19], 0, mixer[4],  3 },{ mixer[4], 0, mixer[TOTAL_MIXERS - 3], 0 },
	{ wavetable[20], 0, mixer[5], 0 },{ wavetable[21], 0, mixer[5], 1 },{ wavetable[22], 0, mixer[5],  2 },{ wavetable[23], 0, mixer[5],  3 },{ mixer[5], 0, mixer[TOTAL_MIXERS - 3], 1 },
	{ wavetable[24], 0, mixer[6], 0 },{ wavetable[25], 0, mixer[6], 1 },{ wavetable[26], 0, mixer[6],  2 },{ wavetable[27], 0, mixer[6],  3 },{ mixer[6], 0, mixer[TOTAL_MIXERS - 3], 2 },
	{ wavetable[28], 0, mixer[7], 0 },{ wavetable[29], 0, mixer[7], 1 },{ wavetable[30], 0, mixer[7],  2 },{ wavetable[31], 0, mixer[7],  3 },{ mixer[7], 0, mixer[TOTAL_MIXERS - 3], 3 },
	{ wavetable[32], 0, mixer[8], 0 },{ wavetable[33], 0, mixer[8], 1 },{ wavetable[34], 0, mixer[8],  2 },{ wavetable[35], 0, mixer[8],  3 },{ mixer[8], 0, mixer[TOTAL_MIXERS - 4], 0 },
	{ wavetable[36], 0, mixer[9], 0 },{ wavetable[37], 0, mixer[9], 1 },{ wavetable[38], 0, mixer[9],  2 },{ wavetable[39], 0, mixer[9],  3 },{ mixer[9], 0, mixer[TOTAL_MIXERS - 4], 1 },
	{ wavetable[40], 0, mixer[10], 0 },{ wavetable[41], 0, mixer[10], 1 },{ wavetable[42], 0, mixer[10], 2 },{ wavetable[43], 0, mixer[10], 3 },{ mixer[10], 0, mixer[TOTAL_MIXERS - 4], 2 },
	{ wavetable[44], 0, mixer[11], 0 },{ wavetable[45], 0, mixer[11], 1 },{ wavetable[46], 0, mixer[11], 2 },{ wavetable[47], 0, mixer[11], 3 },{ mixer[11], 0, mixer[TOTAL_MIXERS - 4], 3 },
	{ mixer[TOTAL_MIXERS - 2], 0, mixer[TOTAL_MIXERS - 1], 0 },
	{ mixer[TOTAL_MIXERS - 3], 0, mixer[TOTAL_MIXERS - 1], 1 },
	{ mixer[TOTAL_MIXERS - 4], 0, mixer[TOTAL_MIXERS - 1], 2 },
	{ mixer[TOTAL_MIXERS - 5], 0, mixer[TOTAL_MIXERS - 1], 3 },
	{ mixer[TOTAL_MIXERS - 1], 0, i2s1, 0 },
	{ mixer[TOTAL_MIXERS - 1], 0, i2s1, 1 },
};

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);

File myFile;

#define CENTS_SHIFT(C) (pow(2.0, (C)/1200.0))
#define NOTE_TO_FREQUENCY(N) (440.0 * pow(2.0, ((N) - 69) / 12.0))
#define NOTE(N) (440.0 * pow(2.0, ((N) - 69) / 12.0))
#define DECIBEL_SHIFT(dB) (pow(10.0, (dB)/20.0))

const int32_t UNITY_GAIN = INT32_MAX;
const int32_t LFO_SMOOTHNESS = 3;
const float LFO_PERIOD = (AUDIO_BLOCK_SAMPLES / (1 << (LFO_SMOOTHNESS - 1)));
static  float SAMPLES_PER_MSEC = (AUDIO_SAMPLE_RATE_EXACT / 1000.0);
static const int32_t ENVELOPE_PERIOD = 8;
int used_voices = 0;
int stopped_voices = 0;
int evict_voice = 0;
int notes_played = 0;


int noteAlloc[TOTAL_VOICES];


char buffer[100];
String tmpString;
String paramString;
int totalSampleLength = 0;
int numRanges;
uint8_t ranges[10];
int sIndex;
int fIndex;
int rangeIndex;
String paramString2;


AudioSynthWavetable::sample_data* sd0[3];

// The 3rd range is loaded into the following array- I have not yet converted that code to place it into the sd0[3] array, since its too much trouble until I get the first ranges working
uint32_t* pointer3;
bool LOOP3;
int INDEX_BITS3;
float PER_HERTZ_PHASE_INCREMENT3;
uint32_t MAX_PHASE3;
uint32_t LOOP_PHASE_END3;
uint32_t LOOP_PHASE_LENGTH3;
uint16_t INITIAL_ATTENUATION_SCALAR3;
// VOLUME ENVELOPE VALUES
uint32_t DELAY_COUNT3;
uint32_t ATTACK_COUNT3;
uint32_t HOLD_COUNT3;
uint32_t DECAY_COUNT3;
uint32_t RELEASE_COUNT3;
int32_t SUSTAIN_MULT3;
// VIBRATO VALUES
uint32_t VIBRATO_DELAY3;
uint32_t VIBRATO_INCREMENT3;
float VIBRATO_PITCH_COEFFICIENT_INITIAL3;
float VIBRATO_PITCH_COEFFICIENT_SECOND3;
// MODULATION VALUES
uint32_t MODULATION_DELAY3;
uint32_t MODULATION_INCREMENT3;
float MODULATION_PITCH_COEFFICIENT_INITIAL3;
float MODULATION_PITCH_COEFFICIENT_SECOND3;
int32_t MODULATION_AMPLITUDE_INITIAL_GAIN3;
int32_t MODULATION_AMPLITUDE_SECOND_GAIN3;



uint32_t SAMPLE_BUFFER[50000];

int cents_offset;
float sample_rate;
int sample_note;


AudioSynthWavetable::sample_data AcousticBass_samples[3] = {
	{
		 (int16_t*)  &SAMPLE_BUFFER[0],
		 true, // LOOP
		14, // LENGTH_BITS
		(1 << (32 - 14)) * CENTS_SHIFT(-1) * 22050.0 / NOTE(64) / AUDIO_SAMPLE_RATE_EXACT + 0.5, // PER_HERTZ_PHASE_INCREMENT
		((uint32_t)10502 - 1) << (32 - 14), // MAX_PHASE
		((uint32_t)10446 - 1) << (32 - 14), // LOOP_PHASE_END
		(((uint32_t)10446 - 1) << (32 - 14)) - (((uint32_t)10179 - 1) << (32 - 14)), // LOOP_PHASE_LENGTH
		uint16_t(UINT16_MAX * DECIBEL_SHIFT(0)), // INITIAL_ATTENUATION_SCALAR
		uint32_t(0.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // DELAY_COUNT
		uint32_t(6.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // ATTACK_COUNT
		uint32_t(350.10 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // HOLD_COUNT
		uint32_t(5136.67 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // DECAY_COUNT
		uint32_t(1100.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // RELEASE_COUNT
		int32_t((1.0 - DECIBEL_SHIFT(-96.0)) * UNITY_GAIN), // SUSTAIN_MULT
		uint32_t(0.00 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)), // VIBRATO_DELAY
		uint32_t(8.2 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT)), // VIBRATO_INCREMENT
		(CENTS_SHIFT(0) - 1.0) * 4, // VIBRATO_PITCH_COEFFICIENT_INITIAL
		(1.0 - CENTS_SHIFT(0)) * 4, // VIBRATO_COEFFICIENT_SECONDARY
		uint32_t(0.00 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)), // MODULATION_DELAY
		uint32_t(8.2 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT)), // MODULATION_INCREMENT
		(CENTS_SHIFT(0) - 1.0) * 4, // MODULATION_PITCH_COEFFICIENT_INITIAL
		(1.0 - CENTS_SHIFT(0)) * 4, // MODULATION_PITCH_COEFFICIENT_SECOND
		int32_t(UINT16_MAX * (DECIBEL_SHIFT(0) - 1.0)) * 4, // MODULATION_AMPLITUDE_INITIAL_GAIN
		int32_t(UINT16_MAX * (1.0 - DECIBEL_SHIFT(0))) * 4, // MODULATION_AMPLITUDE_FINAL_GAIN
	},
	{
		//SAMPLE_BUFFER[5282],
		(int16_t*)&SAMPLE_BUFFER[5282],
		true, // LOOP
		13, // LENGTH_BITS
		(1 << (32 - 13)) * CENTS_SHIFT(25) * 28000.0 / NOTE(76) / AUDIO_SAMPLE_RATE_EXACT + 0.5, // PER_HERTZ_PHASE_INCREMENT
		((uint32_t)5880 - 1) << (32 - 13), // MAX_PHASE
		((uint32_t)5837 - 1) << (32 - 13), // LOOP_PHASE_END
		(((uint32_t)5837 - 1) << (32 - 13)) - (((uint32_t)5751 - 1) << (32 - 13)), // LOOP_PHASE_LENGTH
		uint16_t(UINT16_MAX * DECIBEL_SHIFT(-3.0)), // INITIAL_ATTENUATION_SCALAR
		uint32_t(0.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // DELAY_COUNT
		uint32_t(1.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // ATTACK_COUNT
		uint32_t(300.06 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // HOLD_COUNT
		uint32_t(5136.67 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // DECAY_COUNT
		uint32_t(1100.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // RELEASE_COUNT
		int32_t((1.0 - DECIBEL_SHIFT(-96.0)) * UNITY_GAIN), // SUSTAIN_MULT
		uint32_t(0.00 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)), // VIBRATO_DELAY
		uint32_t(8.2 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT)), // VIBRATO_INCREMENT
		(CENTS_SHIFT(0) - 1.0) * 4, // VIBRATO_PITCH_COEFFICIENT_INITIAL
		(1.0 - CENTS_SHIFT(0)) * 4, // VIBRATO_COEFFICIENT_SECONDARY
		uint32_t(0.00 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)), // MODULATION_DELAY
		uint32_t(8.2 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT)), // MODULATION_INCREMENT
		(CENTS_SHIFT(0) - 1.0) * 4, // MODULATION_PITCH_COEFFICIENT_INITIAL
		(1.0 - CENTS_SHIFT(0)) * 4, // MODULATION_PITCH_COEFFICIENT_SECOND
		int32_t(UINT16_MAX * (DECIBEL_SHIFT(0) - 1.0)) * 4, // MODULATION_AMPLITUDE_INITIAL_GAIN
		int32_t(UINT16_MAX * (1.0 - DECIBEL_SHIFT(0))) * 4, // MODULATION_AMPLITUDE_FINAL_GAIN
	},
	{
		(int16_t*) &SAMPLE_BUFFER[8223], // sample
		true, // LOOP
		12, // LENGTH_BITS
		(1 << (32 - 12)) * CENTS_SHIFT(18) * 28000.0 / NOTE(92) / AUDIO_SAMPLE_RATE_EXACT + 0.5, // PER_HERTZ_PHASE_INCREMENT
		((uint32_t)2152 - 1) << (32 - 12), // MAX_PHASE
		((uint32_t)2142 - 1) << (32 - 12), // LOOP_PHASE_END
		(((uint32_t)2142 - 1) << (32 - 12)) - (((uint32_t)2108 - 1) << (32 - 12)), // LOOP_PHASE_LENGTH
		uint16_t(UINT16_MAX * DECIBEL_SHIFT(0)), // INITIAL_ATTENUATION_SCALAR
		uint32_t(0.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // DELAY_COUNT
		uint32_t(1.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // ATTACK_COUNT
		uint32_t(250.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // HOLD_COUNT
		uint32_t(5136.67 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // DECAY_COUNT
		uint32_t(1100.00 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5), // RELEASE_COUNT
		int32_t((1.0 - DECIBEL_SHIFT(-96.0)) * UNITY_GAIN), // SUSTAIN_MULT
		uint32_t(0.00 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)), // VIBRATO_DELAY
		uint32_t(8.2 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT)), // VIBRATO_INCREMENT
		(CENTS_SHIFT(0) - 1.0) * 4, // VIBRATO_PITCH_COEFFICIENT_INITIAL
		(1.0 - CENTS_SHIFT(0)) * 4, // VIBRATO_COEFFICIENT_SECONDARY
		uint32_t(0.00 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)), // MODULATION_DELAY
		uint32_t(8.2 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT)), // MODULATION_INCREMENT
		(CENTS_SHIFT(0) - 1.0) * 4, // MODULATION_PITCH_COEFFICIENT_INITIAL
		(1.0 - CENTS_SHIFT(0)) * 4, // MODULATION_PITCH_COEFFICIENT_SECOND
		int32_t(UINT16_MAX * (DECIBEL_SHIFT(0) - 1.0)) * 4, // MODULATION_AMPLITUDE_INITIAL_GAIN
		int32_t(UINT16_MAX * (1.0 - DECIBEL_SHIFT(0))) * 4, // MODULATION_AMPLITUDE_FINAL_GAIN
	},
};


//uint8_t AcousticBass_ranges[] = { 47, 60, 127, };
uint8_t AcousticBass_ranges[10];  // loaded constants at start of setup()

//The following line works
// AudioSynthWavetable::instrument_data AcousticBass = { 3, AcousticBass_ranges, AcousticBass_samples };

// This one doesn't produce any sound, but program doesn't crash
 AudioSynthWavetable::instrument_data AcousticBass = { 2, AcousticBass_ranges, sd0[0]};


void setup() {
	AcousticBass_ranges[0] = 70;
	AcousticBass_ranges[1] = 90;	
	AcousticBass_ranges[2] = 127;
	Serial.begin(115200);
	MIDI.begin(MIDI_CHANNEL_OMNI);
	MIDI.setHandleNoteOn(handleNoteOn);
	MIDI.setHandleNoteOff(handleNoteOff);
	AudioMemory(120);
	sgtl5000_1.enable();
	sgtl5000_1.volume(0.8);
	for (int i = 0; i < TOTAL_VOICES; i++) {
		noteAlloc[i] = 0;
	}
	for (int i = 0; i < TOTAL_MIXERS - 3; i++) {
		for (int j = 0; j < 4; j++) {
			mixer[i].gain(j, 0.50);
		}
	}
	for (int j = 0; j < 4; j++) {
		mixer[TOTAL_MIXERS - 4].gain(j, 0.5);
		mixer[TOTAL_MIXERS - 3].gain(j, 0.5);
		mixer[TOTAL_MIXERS - 2].gain(j, 0.5);
	}
	mixer[TOTAL_MIXERS - 1].gain(0, 1);
	mixer[TOTAL_MIXERS - 1].gain(1, 1);


	for (int i = 0; i < TOTAL_VOICES; i++) {
		wavetable[i].setInstrument(AcousticBass);  
		wavetable[i].amplitude(1);
	}
	bool playing = false;


	if (!(SD.begin(SDCARD_CS_PIN))) {
		// stop here, but print a message repetitively
		while (1) {
			Serial.println("Unable to access the card");
			delay(1000);
		}
	}

	myFile = SD.open("sample1.cpp");
	if (myFile) {
		Serial.println("cpp file opened");
		int i = 0;
		while (myFile.available()) {
			myFile.readBytesUntil(',', buffer, 50);
			uint32_t value = strtoul(buffer, 0, 16);
			SAMPLE_BUFFER[i] = value;
			i++;
			// Serial.print(SAMPLE_BUFFER[i-1]);
			// Serial.write(" ");
		}
		// close the file:
		myFile.close();
		totalSampleLength = i - 1;
		Serial.println();
		Serial.print("num samples");
		Serial.println(totalSampleLength);

	}

	myFile = SD.open("sample1.h");
	if (myFile) {
		rangeIndex = 0;
		Serial.println("h file opened");
		int i = 0;
		int l;
		l = myFile.readBytesUntil('\n', buffer, 50);
		buffer[l] = 0;
		String paramString1(buffer);
		//	   Serial.println(paramString1);
		int index = paramString1.indexOf("[", 0);
		index++;
		for (i = 0; i < 10; i++) {
			buffer[i] = 0;
		}
		for (i = 0; i < 3; i++) {
			char t = paramString1.charAt(index + i);
			if (t == ']') {
				buffer[i] = 0;
			}
			else {
				buffer[i] = t;
			}
		}
		String tmpString(buffer);
		numRanges = tmpString.toInt();
		Serial.println(numRanges);

		// get key values for each range from following line

		l = myFile.readBytesUntil('\n', buffer, 50);
		String paramString2(buffer);
		Serial.println(paramString2);
		sIndex = paramString2.indexOf("=", 0);
		sIndex++;
		fIndex = paramString2.indexOf(",", 0);
		String tmpString2 = paramString2.substring(sIndex, fIndex);
		ranges[0] = tmpString2.toInt();
		Serial.println(ranges[0]);

		for (int i = 1; i < numRanges; i++) {
			sIndex = fIndex + 1;
			fIndex = paramString2.indexOf(",", sIndex);
			String tmpString3 = paramString2.substring(sIndex, fIndex);
			ranges[i] = tmpString3.toInt();
			Serial.println(ranges[i]);
		}
		l = myFile.readBytesUntil('\n', buffer, 50);   // region name
		Serial.println(buffer);

		// for (rangeIndex = 0; rangeIndex < numRanges; rangeIndex++) {
		// ***************************************************************

		l = myFile.readBytesUntil('\n', buffer, 50);   // get loop true/false
		String paramString3(buffer);
		sIndex = paramString3.indexOf("true", 0);
		if (sIndex >=0) {
			sd0[0]->LOOP = true;
			Serial.println("true");
		}
		else {
			sd0[0]->LOOP = false;
			Serial.println("false");
		}
		l = myFile.readBytesUntil('\n', buffer, 50);   // get INDEX_BITS
		String paramString4(buffer);
		sd0[0]->INDEX_BITS = paramString4.toInt();
		Serial.println(sd0[0]->INDEX_BITS);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get cents_offset
		String paramString5(buffer);
		cents_offset = paramString5.toInt();
		Serial.println(cents_offset);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get sample_rate
		String paramString6(buffer);
		sample_rate = paramString6.toFloat();
		Serial.println(sample_rate);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get sample_note
		String paramString7(buffer);
		sample_note = paramString7.toFloat();
		Serial.println(sample_note);
		// calculate PER_HERTZ_PHASE_INCREMENT
		sd0[0]->PER_HERTZ_PHASE_INCREMENT = (1 << (32 - sd0[0]->INDEX_BITS)) * CENTS_SHIFT(cents_offset) * sample_rate / NOTE(sample_note) / AUDIO_SAMPLE_RATE_EXACT + 0.5;
		Serial.println(sd0[0]->PER_HERTZ_PHASE_INCREMENT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MAX_PHASE
		String paramString8(buffer);
		int temp1 = paramString8.toInt();
		Serial.println(temp1);
		sd0[0]->MAX_PHASE = ((uint32_t)temp1 - 1) << (32 - sd0[0]->INDEX_BITS);
		Serial.println(sd0[0]->MAX_PHASE);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get LOOP_PHASE_END
		String paramString9(buffer);
		temp1 = paramString9.toInt();
		Serial.println(temp1);
		sd0[0]->LOOP_PHASE_END = ((uint32_t)temp1 - 1) << (32 - sd0[0]->INDEX_BITS);
		Serial.println(sd0[0]->LOOP_PHASE_END);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get LOOP_PHASE_LENGTH
		String paramString10(buffer);
		temp1 = paramString10.toInt();
		Serial.println(temp1);
		sd0[0]->LOOP_PHASE_LENGTH = ((uint32_t)temp1 - 1) << (32 - sd0[0]->INDEX_BITS);
		Serial.println(sd0[0]->LOOP_PHASE_LENGTH);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get INITIAL_ATTENUATION_SCALAR
		String paramString11(buffer);
		temp1 = paramString11.toInt();
		sd0[0]->INITIAL_ATTENUATION_SCALAR = (uint16_t) UINT16_MAX * DECIBEL_SHIFT(temp1);
		Serial.println(sd0[0]->INITIAL_ATTENUATION_SCALAR);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get DELAY_COUNT
		String paramString12(buffer);
		temp1 = paramString12.toFloat();
		sd0[0]->DELAY_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[0]->DELAY_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get ATTACK_COUNT
		String paramString13(buffer);
		temp1 = paramString13.toFloat();
		sd0[0]->ATTACK_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[0]->ATTACK_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get HOLD_COUNT
		String paramString14(buffer);
		temp1 = paramString14.toFloat();
		sd0[0]->HOLD_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[0]->HOLD_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get DECAY_COUNT
		String paramString15(buffer);
		temp1 = paramString15.toFloat();
		sd0[0]->DECAY_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[0]->DECAY_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get RELEASE_COUNT
		String paramString16(buffer);
		temp1 = paramString16.toFloat();
		sd0[0]->RELEASE_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[0]->RELEASE_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get SUSTAIN_MULT
		String paramString17(buffer);
		temp1 = paramString17.toFloat();
		sd0[0]->SUSTAIN_MULT = int32_t((1.0 - DECIBEL_SHIFT(temp1)) * UNITY_GAIN);
		Serial.println(sd0[0]->SUSTAIN_MULT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_DELAY
		String paramString18(buffer);
		temp1 = paramString18.toFloat();
		sd0[0]->VIBRATO_DELAY = uint32_t(temp1 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD));
		Serial.println(sd0[0]->VIBRATO_DELAY);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_INCREMENT
		String paramString19(buffer);
		temp1 = paramString19.toFloat();
		sd0[0]->VIBRATO_INCREMENT = uint32_t(temp1 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT));
		Serial.println(sd0[0]->VIBRATO_INCREMENT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_PITCH_COEFICIENT_INITIAL
		String paramString20(buffer);
		temp1 = paramString20.toFloat();
		sd0[0]->VIBRATO_PITCH_COEFFICIENT_INITIAL = (CENTS_SHIFT(temp1) - 1.0) * 4;
		Serial.println(sd0[0]->VIBRATO_PITCH_COEFFICIENT_INITIAL);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_PITCH_COEFICIENT_SECOND
		String paramString21(buffer);
		temp1 = paramString21.toFloat();
		sd0[0]->VIBRATO_PITCH_COEFFICIENT_SECOND = (1.0 - CENTS_SHIFT(temp1)) * 4;
		Serial.println(sd0[0]->VIBRATO_PITCH_COEFFICIENT_SECOND);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_DELAY
		String paramString22(buffer);
		temp1 = paramString22.toFloat();
		sd0[0]->MODULATION_DELAY = uint32_t(temp1 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)),
		Serial.println(sd0[0]->MODULATION_DELAY);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_INCREMENT
		String paramString23(buffer);
		temp1 = paramString23.toFloat();
		sd0[0]->MODULATION_INCREMENT = uint32_t(temp1 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT));
		Serial.println(sd0[0]->MODULATION_INCREMENT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_PITCH_COEFFICIENT_INITIAL
		String paramString24(buffer);
		temp1 = paramString24.toInt();
		sd0[0]->MODULATION_PITCH_COEFFICIENT_INITIAL = (CENTS_SHIFT(temp1) - 1.0) * 4;
		Serial.println(sd0[0]->MODULATION_PITCH_COEFFICIENT_INITIAL);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_PITCH_COEFFICIENT_SECOND
		String paramString25(buffer);
		temp1 = paramString25.toInt();
		sd0[0]->MODULATION_PITCH_COEFFICIENT_SECOND = (1.0 - CENTS_SHIFT(temp1)) * 4;
		Serial.println(sd0[0]->MODULATION_PITCH_COEFFICIENT_SECOND);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_AMPLITUDE_INITIAL_GAIN
		String paramString26(buffer);
		temp1 = paramString26.toInt();
		sd0[0]->MODULATION_AMPLITUDE_INITIAL_GAIN = (int32_t) (UINT16_MAX * (DECIBEL_SHIFT(temp1) - 1.0)) * 4;
		Serial.println(sd0[0]->MODULATION_AMPLITUDE_INITIAL_GAIN);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_AMPLITUDE_SECOND_GAIN
		String paramString27(buffer);
		temp1 = paramString27.toInt();
		sd0[0]->MODULATION_AMPLITUDE_SECOND_GAIN = (int32_t) (UINT16_MAX * (1.0 - DECIBEL_SHIFT(temp1))) * 4;
		Serial.println(sd0[0]->MODULATION_AMPLITUDE_SECOND_GAIN);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get closing parenthesis
		Serial.println(buffer);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get opening parenthesis (except in last record
		Serial.println(buffer);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get region name (except in last record is sample size list
		Serial.println(buffer);

	
			// second range


		l = myFile.readBytesUntil('\n', buffer, 50);   // get loop true/false
		String paramString28(buffer);
		sIndex = paramString28.indexOf("true", 0);
		if (sIndex >= 0) {
			sd0[1]->LOOP = true;
			Serial.println("true");
		}
		else {
			sd0[1]->LOOP = false;
			Serial.println("false");
		}
		l = myFile.readBytesUntil('\n', buffer, 50);   // get INDEX_BITS
		String paramString29(buffer);
		sd0[1]->INDEX_BITS = paramString29.toInt();
		Serial.println(sd0[1]->INDEX_BITS);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get cents_offset
		String paramString30(buffer);
		cents_offset = paramString30.toInt();
		Serial.println(cents_offset);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get sample_rate
		String paramString31(buffer);
		sample_rate = paramString31.toFloat();
		Serial.println(sample_rate);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get sample_note
		String paramString32(buffer);
		sample_note = paramString32.toFloat();
		Serial.println(sample_note);
		// calculate PER_HERTZ_PHASE_INCREMENT
		sd0[1]->PER_HERTZ_PHASE_INCREMENT = (1 << (32 - sd0[1]->INDEX_BITS)) * CENTS_SHIFT(cents_offset) * sample_rate / NOTE(sample_note) / AUDIO_SAMPLE_RATE_EXACT + 0.5;
		Serial.println(sd0[1]->PER_HERTZ_PHASE_INCREMENT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MAX_PHASE
		String paramString33(buffer);
		temp1 = paramString33.toInt();
		Serial.println(temp1);
		sd0[1]->MAX_PHASE = ((uint32_t)temp1 - 1) << (32 - sd0[1]->INDEX_BITS);
		Serial.println(sd0[1]->MAX_PHASE);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get LOOP_PHASE_END
		String paramString34(buffer);
		temp1 = paramString34.toInt();
		Serial.println(temp1);
		sd0[1]->LOOP_PHASE_END = ((uint32_t)temp1 - 1) << (32 - sd0[1]->INDEX_BITS);
		Serial.println(sd0[1]->LOOP_PHASE_END);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get LOOP_PHASE_LENGTH
		String paramString35(buffer);
		temp1 = paramString35.toInt();
		Serial.println(temp1);
		sd0[1]->LOOP_PHASE_LENGTH = ((uint32_t)temp1 - 1) << (32 - sd0[1]->INDEX_BITS);
		Serial.println(sd0[1]->LOOP_PHASE_LENGTH);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get INITIAL_ATTENUATION_SCALAR
		String paramString36(buffer);
		temp1 = paramString36.toInt();
		sd0[1]->INITIAL_ATTENUATION_SCALAR = (uint16_t)UINT16_MAX * DECIBEL_SHIFT(temp1);
		Serial.println(sd0[1]->INITIAL_ATTENUATION_SCALAR);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get DELAY_COUNT
		String paramString37(buffer);
		temp1 = paramString37.toFloat();
		sd0[1]->DELAY_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[1]->DELAY_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get ATTACK_COUNT
		String paramString38(buffer);
		temp1 = paramString38.toFloat();
		sd0[1]->ATTACK_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[1]->ATTACK_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get HOLD_COUNT
		String paramString39(buffer);
		temp1 = paramString39.toFloat();
		sd0[1]->HOLD_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[1]->HOLD_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get DECAY_COUNT
		String paramString40(buffer);
		temp1 = paramString40.toFloat();
		sd0[1]->DECAY_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[1]->DECAY_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get RELEASE_COUNT
		String paramString41(buffer);
		temp1 = paramString41.toFloat();
		sd0[1]->RELEASE_COUNT = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(sd0[1]->RELEASE_COUNT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get SUSTAIN_MULT
		String paramString42(buffer);
		temp1 = paramString42.toFloat();
		sd0[1]->SUSTAIN_MULT = int32_t((1.0 - DECIBEL_SHIFT(temp1)) * UNITY_GAIN);
		Serial.println(sd0[1]->SUSTAIN_MULT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_DELAY
		String paramString43(buffer);
		temp1 = paramString43.toFloat();
		sd0[1]->VIBRATO_DELAY = uint32_t(temp1 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD));
		Serial.println(sd0[1]->VIBRATO_DELAY);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_INCREMENT
		String paramString44(buffer);
		temp1 = paramString44.toFloat();
		sd0[1]->VIBRATO_INCREMENT = uint32_t(temp1 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT));
		Serial.println(sd0[1]->VIBRATO_INCREMENT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_PITCH_COEFICIENT_INITIAL
		String paramString45(buffer);
		temp1 = paramString45.toFloat();
		sd0[1]->VIBRATO_PITCH_COEFFICIENT_INITIAL = (CENTS_SHIFT(temp1) - 1.0) * 4;
		Serial.println(sd0[1]->VIBRATO_PITCH_COEFFICIENT_INITIAL);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_PITCH_COEFICIENT_SECOND
		String paramString46(buffer);
		temp1 = paramString46.toFloat();
		sd0[1]->VIBRATO_PITCH_COEFFICIENT_SECOND = (1.0 - CENTS_SHIFT(temp1)) * 4;
		Serial.println(sd0[1]->VIBRATO_PITCH_COEFFICIENT_SECOND);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_DELAY
		String paramString47(buffer);
		temp1 = paramString47.toFloat();
		sd0[1]->MODULATION_DELAY = uint32_t(temp1 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)),
			Serial.println(sd0[1]->MODULATION_DELAY);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_INCREMENT
		String paramString48(buffer);
		temp1 = paramString48.toFloat();
		sd0[1]->MODULATION_INCREMENT = uint32_t(temp1 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT));
		Serial.println(sd0[1]->MODULATION_INCREMENT);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_PITCH_COEFFICIENT_INITIAL
		String paramString49(buffer);
		temp1 = paramString49.toInt();
		sd0[1]->MODULATION_PITCH_COEFFICIENT_INITIAL = (CENTS_SHIFT(temp1) - 1.0) * 4;
		Serial.println(sd0[1]->MODULATION_PITCH_COEFFICIENT_INITIAL);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_PITCH_COEFFICIENT_SECOND
		String paramString50(buffer);
		temp1 = paramString50.toInt();
		sd0[1]->MODULATION_PITCH_COEFFICIENT_SECOND = (1.0 - CENTS_SHIFT(temp1)) * 4;
		Serial.println(sd0[1]->MODULATION_PITCH_COEFFICIENT_SECOND);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_AMPLITUDE_INITIAL_GAIN
		String paramString51(buffer);
		temp1 = paramString51.toInt();
		sd0[1]->MODULATION_AMPLITUDE_INITIAL_GAIN = (int32_t)(UINT16_MAX * (DECIBEL_SHIFT(temp1) - 1.0)) * 4;
		Serial.println(sd0[1]->MODULATION_AMPLITUDE_INITIAL_GAIN);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_AMPLITUDE_SECOND_GAIN
		String paramString52(buffer);
		temp1 = paramString52.toInt();
		sd0[1]->MODULATION_AMPLITUDE_SECOND_GAIN = (int32_t)(UINT16_MAX * (1.0 - DECIBEL_SHIFT(temp1))) * 4;
		Serial.println(sd0[1]->MODULATION_AMPLITUDE_SECOND_GAIN);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get closing parenthesis
		Serial.println(buffer);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get opening parenthesis (except in last record
		Serial.println(buffer);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get region name (except in last record is sample size list
		Serial.println(buffer);
		
		// Third range

		l = myFile.readBytesUntil('\n', buffer, 50);   // get loop true/false
		String paramString53(buffer);
		sIndex = paramString53.indexOf("true", 0);
		if (sIndex >= 0) {
			LOOP3 = true;
			Serial.println("true");
		}
		else {
			LOOP3 = false;
			Serial.println("false");
		}
		l = myFile.readBytesUntil('\n', buffer, 50);   // get INDEX_BITS
		String paramString54(buffer);
		INDEX_BITS3 = paramString54.toInt();
		Serial.println(INDEX_BITS3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get cents_offset
		String paramString55(buffer);
		cents_offset = paramString55.toInt();
		Serial.println(cents_offset);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get sample_rate
		String paramString56(buffer);
		sample_rate = paramString56.toFloat();
		Serial.println(sample_rate);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get sample_note
		String paramString57(buffer);
		sample_note = paramString57.toFloat();
		Serial.println(sample_note);
		// calculate PER_HERTZ_PHASE_INCREMENT
		PER_HERTZ_PHASE_INCREMENT3 = (1 << (32 - INDEX_BITS3)) * (pow(2.0, (cents_offset) / 1200.0)) * sample_rate / (440.0 * pow(2.0, ((sample_note)-69) / 12.0)) / AUDIO_SAMPLE_RATE_EXACT + 0.5;
		Serial.println(PER_HERTZ_PHASE_INCREMENT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MAX_PHASE
		String paramString58(buffer);
		temp1 = paramString58.toInt();
		Serial.println(temp1);
		MAX_PHASE3 = ((uint32_t)temp1 - 1) << (32 - INDEX_BITS3);
		Serial.println(MAX_PHASE3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get LOOP_PHASE_END
		String paramString59(buffer);
		temp1 = paramString59.toInt();
		Serial.println(temp1);
		LOOP_PHASE_END3 = ((uint32_t)temp1 - 1) << (32 - INDEX_BITS3);
		Serial.println(LOOP_PHASE_END3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get LOOP_PHASE_LENGTH
		String paramString60(buffer);
		temp1 = paramString60.toInt();
		Serial.println(temp1);
		LOOP_PHASE_LENGTH3 = ((uint32_t)temp1 - 1) << (32 - INDEX_BITS3);
		Serial.println(LOOP_PHASE_LENGTH3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get INITIAL_ATTENUATION_SCALAR
		String paramString61(buffer);
		temp1 = paramString61.toInt();
		INITIAL_ATTENUATION_SCALAR3 = uint16_t(UINT16_MAX * pow(10.0, (temp1) / 20.0));
		Serial.println(INITIAL_ATTENUATION_SCALAR3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get DELAY_COUNT
		String paramString62(buffer);
		temp1 = paramString62.toFloat();
		DELAY_COUNT3 = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(DELAY_COUNT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get ATTACK_COUNT
		String paramString63(buffer);
		temp1 = paramString63.toFloat();
		ATTACK_COUNT3 = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(ATTACK_COUNT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get HOLD_COUNT
		String paramString64(buffer);
		temp1 = paramString64.toFloat();
		HOLD_COUNT3 = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(HOLD_COUNT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get DECAY_COUNT
		String paramString65(buffer);
		temp1 = paramString65.toFloat();
		DECAY_COUNT3 = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(DECAY_COUNT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get RELEASE_COUNT
		String paramString66(buffer);
		temp1 = paramString66.toFloat();
		RELEASE_COUNT3 = uint32_t(temp1 * SAMPLES_PER_MSEC / ENVELOPE_PERIOD + 0.5);
		Serial.println(RELEASE_COUNT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get SUSTAIN_MULT
		String paramString67(buffer);
		temp1 = paramString67.toFloat();
		SUSTAIN_MULT3 = int32_t((1.0 - (pow(10.0, (temp1) / 20.0))) * UNITY_GAIN);
		Serial.println(SUSTAIN_MULT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_DELAY
		String paramString68(buffer);
		temp1 = paramString68.toFloat();
		VIBRATO_DELAY3 = uint32_t(temp1 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD));
		Serial.println(VIBRATO_DELAY3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_INCREMENT
		String paramString69(buffer);
		temp1 = paramString69.toFloat();
		VIBRATO_INCREMENT3 = uint32_t(temp1 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT));
		Serial.println(VIBRATO_INCREMENT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_PITCH_COEFICIENT_INITIAL
		String paramString70(buffer);
		temp1 = paramString70.toFloat();
		VIBRATO_PITCH_COEFFICIENT_INITIAL3 = (CENTS_SHIFT(temp1) - 1.0) * 4;
		Serial.println(VIBRATO_PITCH_COEFFICIENT_INITIAL3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get VIBRATO_PITCH_COEFICIENT_SECOND
		String paramString71(buffer);
		temp1 = paramString71.toFloat();
		VIBRATO_PITCH_COEFFICIENT_SECOND3 = (1.0 - CENTS_SHIFT(temp1)) * 4;
		Serial.println(VIBRATO_PITCH_COEFFICIENT_SECOND3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_DELAY
		String paramString72(buffer);
		temp1 = paramString72.toFloat();
		MODULATION_DELAY3 = uint32_t(temp1 * SAMPLES_PER_MSEC / (2 * LFO_PERIOD)),
			Serial.println(MODULATION_DELAY3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_INCREMENT
		String paramString73(buffer);
		temp1 = paramString73.toFloat();
		MODULATION_INCREMENT3 = uint32_t(temp1 * LFO_PERIOD * (UINT32_MAX / AUDIO_SAMPLE_RATE_EXACT));
		Serial.println(MODULATION_INCREMENT3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_PITCH_COEFFICIENT_INITIAL
		String paramString74(buffer);
		temp1 = paramString74.toInt();
		MODULATION_PITCH_COEFFICIENT_INITIAL3 = ((pow(2.0, (temp1) / 1200.0)) - 1.0) * 4;
		Serial.println(MODULATION_PITCH_COEFFICIENT_INITIAL3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_PITCH_COEFFICIENT_SECOND
		String paramString75(buffer);
		temp1 = paramString75.toInt();
		MODULATION_PITCH_COEFFICIENT_SECOND3 = (1.0 - (pow(2.0, (temp1) / 1200.0))) * 4;
		Serial.println(MODULATION_PITCH_COEFFICIENT_SECOND3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_AMPLITUDE_INITIAL_GAIN
		String paramString76(buffer);
		temp1 = paramString76.toInt();
		MODULATION_AMPLITUDE_INITIAL_GAIN3 = int32_t(UINT16_MAX * ((pow(10.0, (temp1) / 20.0)) - 1.0)) * 4;
		Serial.println(MODULATION_AMPLITUDE_INITIAL_GAIN3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get MODULATION_AMPLITUDE_SECOND_GAIN
		String paramString77(buffer);
		temp1 = paramString77.toInt();
		MODULATION_AMPLITUDE_SECOND_GAIN3 = int32_t(UINT16_MAX * (1.0 - (pow(10.0, (temp1) / 20.0)))) * 4;
		Serial.println(MODULATION_AMPLITUDE_SECOND_GAIN3);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get closing parenthesis
		Serial.println(buffer);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get opening parenthesis (except in last record
		Serial.println(buffer);
		l = myFile.readBytesUntil('\n', buffer, 50);   // get region name (except in last record is sample size list
		Serial.println(buffer);


		String paramString78(buffer);    // get length of first region of waveform samples- used as pointer to next region
		sIndex = paramString78.indexOf("[", 0);
		sIndex++;
		fIndex = paramString78.indexOf("]", 0);
		String tmpString3 = paramString78.substring(sIndex, fIndex);
		uint16_t temp2 = tmpString3.toInt();

		l = myFile.readBytesUntil('\n', buffer, 50);  // ignore blank line
		l = myFile.readBytesUntil('\n', buffer, 50);   // get length of second region of waveform samples- used as pointer to next region
		String paramString79(buffer);
		sIndex = paramString79.indexOf("[", 0);
		sIndex++;
		fIndex = paramString79.indexOf("]", 0);
		String tmpString4 = paramString79.substring(sIndex, fIndex);
		uint16_t temp3 = tmpString4.toInt();
		Serial.print("pointer3=");
		sd0[0]->sample = (int16_t*) &SAMPLE_BUFFER[0]; // also tried without & 
		sd0[1]->sample = (int16_t*)&SAMPLE_BUFFER[5282];
		myFile.close();
	}
}
 

void loop() {
	MIDI.read();
	freeVoices();
// Serial.println("in loop");
 
}

int allocateVoice(byte channel, byte note) {
	for (int i = 1; i < TOTAL_VOICES; i++) {
		if (noteAlloc[i] == 0) {
			noteAlloc[i] = note;
			return i;
			break;
		}
	}
	return -1;
}
void freeVoices() {
	for (int i = 0; i < TOTAL_VOICES; i++)
		if (wavetable[i].isPlaying() == false && noteAlloc[i] == -1) {
			noteAlloc[i] = 0;
		}
}

int findVoice(byte channel, byte note) {
	for (int i = 1; i < TOTAL_VOICES; i++) {
		if (noteAlloc[i] == note) {
			noteAlloc[i] = -1;
			return i;
			break;
		}
		}
	return -1;
	}

void handleNoteOn(byte channel, byte note, byte velocity) {
	notes_played++;
#ifdef DEBUG_ALLOC
	Serial.printf("\n**** NoteOn: channel==%hhu,note==%hhu ****", channel, note);
	//printVoices();
#endif //DEBUG_ALLOC
	Serial.print("note= ");
	Serial.println(note);
	int wavetable_id = allocateVoice(channel, note);
	Serial.println(wavetable_id);
	wavetable[wavetable_id].playNote(note, velocity);
	int usage = AudioProcessorUsage();
	Serial.print("CPU= ");
	Serial.println(usage);
#ifdef DEBUG_ALLOC
	//printVoices();
#endif //DEBUG_ALLOC
}

void handleNoteOff(byte channel, byte note, byte velocity) {
#ifdef DEBUG_ALLOC
	Serial.printf("\n**** NoteOff: channel==%hhu,note==%hhu ****", channel, note);
	//printVoices();
#endif //DEBUG_ALLOC
	int wavetable_id = findVoice(channel, note);
	if (wavetable_id != -1)
		wavetable[wavetable_id].stop();
#ifdef DEBUG_ALLOC
	//printVoices();
#endif //DEBUG_ALLOC
}
 
Status
Not open for further replies.
Back
Top