Started SysEX reading from SD.

pull/4/head
Holger Wirtz 7 years ago
parent 01e701bd59
commit f5bae5286f
  1. 180
      MicroDexed.ino
  2. 40
      dexed.h

@ -12,18 +12,23 @@
#include <MIDI.h> #include <MIDI.h>
#include "dexed.h" #include "dexed.h"
#define AUDIO_MEM 2 #define VOLUME 0.5
#define SAMPLE_RATE 44100 #define SAMPLE_RATE 44100
#define INIT_AUDIO_QUEUE 1 //#define INIT_AUDIO_QUEUE 1
//#define SHOW_DEXED_TIMING 1 //#define SHOW_DEXED_TIMING 1
#define SHOW_XRUN 1 #define SHOW_XRUN 1
#define SHOW_CPU_LOAD_MSEC 5000 #define SHOW_CPU_LOAD_MSEC 5000
#define MAX_NOTES 10 #define MAX_NOTES 10
#define TEST_MIDI 1 //#define TEST_MIDI 1
#define TEST_NOTE 40 #define TEST_NOTE 40
#define TEST_VEL_MIN 60 #define TEST_VEL_MIN 60
#define TEST_VEL_MAX 110 #define TEST_VEL_MAX 110
//#define ADD_EFFECT_CHORUS 1 //#define ADD_EFFECT_CHORUS 1
#ifdef ADD_EFFECT_CHORUS
#define AUDIO_MEM 6
#else
#define AUDIO_MEM 2
#endif
// Use these with the Teensy Audio Shield // Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10 #define SDCARD_CS_PIN 10
@ -53,8 +58,7 @@ AudioControlSGTL5000 sgtl5000_1; //xy=507,403
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI); MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
Dexed* dexed = new Dexed(SAMPLE_RATE); Dexed* dexed = new Dexed(SAMPLE_RATE);
IntervalTimer sched; IntervalTimer sched;
Sd2Card card; bool sd_card_available = false;
SdVolume volume;
#ifdef ADD_EFFECT_CHORUS #ifdef ADD_EFFECT_CHORUS
// Number of samples in each delay line // Number of samples in each delay line
@ -65,38 +69,24 @@ short delayline[CHORUS_DELAY_LENGTH];
void setup() void setup()
{ {
//while (!Serial) ; // wait for Arduino Serial Monitor //while (!Serial) ; // wait for Arduino Serial Monitor
Serial.begin(115200); Serial.begin(115200);
delay(50);
Serial.println(F("MicroDexed based on https://github.com/asb2m10/dexed")); Serial.println(F("MicroDexed based on https://github.com/asb2m10/dexed"));
Serial.println(F("(c)2018 H. Wirtz")); Serial.println(F("(c)2018 H. Wirtz"));
Serial.println(F("setup start")); Serial.println(F("setup start"));
SPI.setMOSI(SDCARD_MOSI_PIN); SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN); SPI.setSCK(SDCARD_SCK_PIN);
if (card.init(SPI_FULL_SPEED, SDCARD_CS_PIN)) { if (!SD.begin(SDCARD_CS_PIN))
Serial.println(F("SD card found."));
}
else
{ {
Serial.println(F("No SD card found.")); Serial.println(F("SD card not accessable"));
} }
else
switch (card.type())
{ {
case SD_CARD_TYPE_SD1: sd_card_available = true;
case SD_CARD_TYPE_SD2:
Serial.println(F("Card type is SD"));
break;
case SD_CARD_TYPE_SDHC:
Serial.println(F("Card type is SDHC"));
break;
default:
Serial.println(F("Card is an unknown type (maybe SDXC?)"));
}
if (!volume.init(card)) {
Serial.println(F("Unable to access the filesystem"));
} }
//load_sysex_file("ROM1A.SYX");
MIDI.begin(MIDI_CHANNEL_OMNI); MIDI.begin(MIDI_CHANNEL_OMNI);
@ -105,7 +95,7 @@ void setup()
AudioMemory(AUDIO_MEM); AudioMemory(AUDIO_MEM);
sgtl5000_1.enable(); sgtl5000_1.enable();
sgtl5000_1.volume(0.2); sgtl5000_1.volume(VOLUME);
// Initialize processor and memory measurements // Initialize processor and memory measurements
#ifdef SHOW_CPU_LOAD_MSEC #ifdef SHOW_CPU_LOAD_MSEC
@ -225,8 +215,140 @@ void cpu_and_mem_usage(void)
} }
#endif #endif
void spaces(int num) { void load_sysex_file(char *name)
for (int i = 0; i < num; i++) { {
Serial.print(" "); File root;
if (sd_card_available)
{
root = SD.open("/");
while (42 == 42)
{
File entry = root.openNextFile();
if (!entry)
break;
else
{
if (!entry.isDirectory())
{
if (strcmp(name, entry.name()) == 0)
{
Serial.println(entry.name());
check_sysex(entry);
load_sysex(entry, 2);
entry.close();
break;
}
entry.close();
}
}
}
}
}
bool load_sysex(File sysex, uint8_t voice_number)
{
File file;
char voice_name[11];
if (file = SD.open(sysex.name()))
{
uint8_t* p_data = dexed->data;
uint8_t i;
uint8_t tmp;
file.seek(6 + (voice_number * 128));
for (i = 0; i < 6; i++)
{
file.read(p_data + (i * 17), 11); // R1, R2, R3, R4, L1, L2, L3, L4, LEV SCL BRK PT, SCL LEFT DEPTH, SCL RGHT DEPTH
tmp = file.read();
*(p_data + 11 + (i * 21)) = (tmp & 0x0c) >> 2;
*(p_data + 12 + (i * 21)) = (tmp & 0x3);
tmp = file.read();
*(p_data + 13 + (i * 21)) = (tmp & 0x78) >> 3;
*(p_data + 14 + (i * 21)) = (tmp & 0x07);
tmp = file.read();
*(p_data + 15 + (i * 21)) = (tmp & 0x1c) >> 2;
*(p_data + 16 + (i * 21)) = (tmp & 0x03);
*(p_data + 17 + (i * 21)) = file.read();
tmp = file.read();
*(p_data + 18 + (i * 21)) = (tmp & 0x3e) >> 1;
*(p_data + 19 + (i * 21)) = (tmp & 0x01);
file.read(p_data + (i * 21), 1); // FREQ FINE
}
file.read(p_data + 125, 8); // PR1, PR2, PR3, PR4, PL1, PL2, PL3, PL4
tmp = file.read();
*(p_data + 133) = (tmp & 0x1f);
tmp = file.read();
*(p_data + 134) = (tmp & 0x08) >> 3;
*(p_data + 135) = (tmp & 0x07);
file.read(p_data + 136, 4); // LFS, LFD, LPMD, LAMD
tmp = file.read();
*(p_data + 140) = (tmp & 0x60) >> 5;
*(p_data + 141) = (tmp & 0x1e) >> 1;
*(p_data + 142) = (tmp & 0x01);
file.read(p_data + 143, 1); // TRNSP
file.read(p_data + 144, 10);
strncpy(voice_name, (char*)(p_data + 144), 10);
voice_name[10] = '\0';
*(p_data + 166) = 1;
*(p_data + 167) = 1;
*(p_data + 168) = 1;
*(p_data + 169) = 1;
*(p_data + 170) = 1;
*(p_data + 171) = 1;
*(p_data + 172) = 16;
}
Serial.println(voice_name);
return (true);
}
bool check_sysex(File sysex)
{
File file;
uint16_t i;
uint32_t calc_checksum = 0;
if (sysex.size() != 4104) // check sysex size
return (false);
if (file = SD.open(sysex.name()))
{
if (file.read() != 0xf0) // check sysex start-byte
{
Serial.println(F("E: SysEx start byte not found."));
return (false);
}
if (file.read() != 0x43) // check sysex vendor is Yamaha
{
Serial.println(F("E: SysEx vendor not Yamaha."));
return (false);
}
file.seek(4103);
if (file.read() != 0xf7) // check sysex end-byte
{
Serial.println(F("E: SysEx end byte not found."));
return (false);
} }
file.seek(3);
if (file.read() != 0x09) // check for sysex type (0x09=32 voices)
{
Serial.println(F("E: SysEx type not 32 voices."));
return (false);
}
file.seek(6); // start of 32*128 (=4096) bytes data
for (i = 0; i < 4096; i++)
calc_checksum += (file.read() & 0x7F); // calculate checksum
calc_checksum = uint8_t(~calc_checksum + 1);
if (calc_checksum != uint8_t(file.read()))
{
Serial.println(F("E: checksum mismatch."));
return (false);
}
}
file.close();
return (true);
} }

@ -72,12 +72,29 @@ class Dexed
Controllers controllers; Controllers controllers;
VoiceStatus voiceStatus; VoiceStatus voiceStatus;
uint8_t data[173] = {
95, 29, 20, 50, 99, 95, 00, 00, 41, 00, 19, 00, 00, 03, 00, 06, 79, 00, 01, 00, 14, // OP6 eg_rate_1-4, level_1-4, kbd_lev_scl_brk_pt, kbd_lev_scl_lft_depth, kbd_lev_scl_rht_depth, kbd_lev_scl_lft_curve, kbd_lev_scl_rht_curve, kbd_rate_scaling, amp_mod_sensitivity, key_vel_sensitivity, operator_output_level, osc_mode, osc_freq_coarse, osc_freq_fine, osc_detune
95, 20, 20, 50, 99, 95, 00, 00, 00, 00, 00, 00, 00, 03, 00, 00, 99, 00, 01, 00, 00, // OP5
95, 29, 20, 50, 99, 95, 00, 00, 00, 00, 00, 00, 00, 03, 00, 06, 89, 00, 01, 00, 07, // OP4
95, 20, 20, 50, 99, 95, 00, 00, 00, 00, 00, 00, 00, 03, 00, 02, 99, 00, 01, 00, 07, // OP3
95, 50, 35, 78, 99, 75, 00, 00, 00, 00, 00, 00, 00, 03, 00, 07, 58, 00, 14, 00, 07, // OP2
96, 25, 25, 67, 99, 75, 00, 00, 00, 00, 00, 00, 00, 03, 00, 02, 99, 00, 01, 00, 10, // OP1
94, 67, 95, 60, 50, 50, 50, 50, // 4 * pitch EG rates, 4 *pitch EG level
04, 06, 00, // algorithm, feedback, osc sync
34, 33, 00, 00, 00, 04, // lfo speed, lfo delay, lfo pitch_mod_depth, lfo_amp_mod_depth, lfo_sync, lfo_waveform
03, 24, // pitch_mod_sensitivity, transpose
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 10 * char for name
01, 00, 99, 00, 99, 00, 99, 00, 99, 00, // pitch_bend_range, pitch_bend_step, mod_wheel_range, mod_wheel_assign, foot_ctrl_range, foot_ctrl_assign, breath_ctrl_range, breath_ctrl_assign, aftertouch_range, aftertouch_assign
00, // master tune
01, 01, 01, 01, 01, 01, // OP1-6 enable
16 // number of voices
}; // FM-Piano
protected: protected:
//void onParam(uint8_t param_num,float param_val); //void onParam(uint8_t param_num,float param_val);
void keyup(uint8_t pitch); void keyup(uint8_t pitch);
void keydown(uint8_t pitch, uint8_t velo); void keydown(uint8_t pitch, uint8_t velo);
static const uint8_t MAX_ACTIVE_NOTES = 16; static const uint8_t MAX_ACTIVE_NOTES = 16;
uint8_t max_notes = MAX_ACTIVE_NOTES; uint8_t max_notes = MAX_ACTIVE_NOTES;
ProcessorVoice voices[MAX_ACTIVE_NOTES]; ProcessorVoice voices[MAX_ACTIVE_NOTES];
@ -91,28 +108,11 @@ class Dexed
EngineMkI* engineMkI; EngineMkI* engineMkI;
EngineOpl* engineOpl; EngineOpl* engineOpl;
private: private:
uint8_t _k_rate_counter; uint8_t _k_rate_counter;
uint8_t _param_change_counter; uint8_t _param_change_counter;
uint8_t data[173] = {
95, 29, 20, 50, 99, 95, 00, 00, 41, 00, 19, 00, 00, 03, 00, 06, 79, 00, 01, 00, 14, // OP6 eg_rate_1-4, level_1-4, kbd_lev_scl_brk_pt, kbd_lev_scl_lft_depth, kbd_lev_scl_rht_depth, kbd_lev_scl_lft_curve, kbd_lev_scl_rht_curve, kbd_rate_scaling, amp_mod_sensitivity, key_vel_sensitivity, operator_output_level, osc_mode, osc_freq_coarse, osc_freq_fine, osc_detune
95, 20, 20, 50, 99, 95, 00, 00, 00, 00, 00, 00, 00, 03, 00, 00, 99, 00, 01, 00, 00, // OP5
95, 29, 20, 50, 99, 95, 00, 00, 00, 00, 00, 00, 00, 03, 00, 06, 89, 00, 01, 00, 07, // OP4
95, 20, 20, 50, 99, 95, 00, 00, 00, 00, 00, 00, 00, 03, 00, 02, 99, 00, 01, 00, 07, // OP3
95, 50, 35, 78, 99, 75, 00, 00, 00, 00, 00, 00, 00, 03, 00, 07, 58, 00, 14, 00, 07, // OP2
96, 25, 25, 67, 99, 75, 00, 00, 00, 00, 00, 00, 00, 03, 00, 02, 99, 00, 01, 00, 10, // OP1
94, 67, 95, 60, 50, 50, 50, 50, // 4 * pitch EG rates, 4 *pitch EG level
04, 06, 00, // algorithm, feedback, osc sync
34, 33, 00, 00, 00, 04, // lfo speed, lfo delay, lfo pitch_mod_depth, lfo_amp_mod_depth, lfo_sync, lfo_waveform
03, 24, // pitch_mod_sensitivity, transpose
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 10 * char for name
01, 00, 99, 00, 99, 00, 99, 00, 99, 00, // pitch_bend_range, pitch_bend_step, mod_wheel_range, mod_wheel_assign, foot_ctrl_range, foot_ctrl_assign, breath_ctrl_range, breath_ctrl_assign, aftertouch_range, aftertouch_assign
00, // master tune
01, 01, 01, 01, 01, 01, // OP1-6 enable
16 // number of voices
}; // INIT
}; };
#endif // PLUGINPROCESSOR_H_INCLUDED #endif // PLUGINPROCESSOR_H_INCLUDED

Loading…
Cancel
Save