Advertisement
Guest User

Untitled

a guest
Jul 15th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.05 KB | None | 0 0
  1. #include <Arduino.h>
  2. #include "MCP23008.h" //from http://gtbtech.com/?p=875
  3. #include "Wire.h"
  4. #include "SDU.h"
  5. #include "SSD1306Ascii.h"
  6. #include "SSD1306AsciiWire.h"
  7.  
  8. #include <MIDIUSB.h>
  9.  
  10. #define MCP23008_ADDR 0x20
  11.  
  12. /*
  13.  
  14. ██ ██ █████ ██████ ██████ ██ ██ █████ ██████ ███████
  15. ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  16. ███████ ███████ ██████ ██ ██ ██ █ ██ ███████ ██████ █████
  17. ██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██
  18. ██ ██ ██ ██ ██ ██ ██████ ███ ███ ██ ██ ██ ██ ███████
  19.  
  20. */
  21.  
  22. // +-----------------+
  23. // 9 |[ ]A/R OUT[ ]| Audio
  24. // 4 |[ ]R/W RS0[ ]| 11
  25. // 5 |[ ]SEN RS1[ ]| 31
  26. // |[ ]SCK RS2[ ]| 30
  27. // |[ ]NC SCL[ ]|
  28. // |[ ]SDI SDA[ ]|
  29. // 3V3 |[ ]3V3 5V[ ]| 5V
  30. // |[ ]GND GND[ ]| GND
  31. // +________________/
  32.  
  33. // Emy
  34. #define BUSY 38
  35. #define SW0 0
  36. #define SW1 1
  37. #define GATE 2
  38. #define PUSH 3
  39. #define ROTA 6
  40. #define ROTB 7
  41. #define GREEN_LED 12
  42. #define RED_LED 13
  43.  
  44. // SC0-02
  45. #define RS2 30
  46. #define RS1 31
  47. #define RS0 11
  48.  
  49. #define AR 9
  50. #define RW 4
  51.  
  52. // LTC6903
  53. #define SEN 5 //Serial Enable for LTC6903
  54. #define SCLK PIN_SPI_SCK //Serial Clock for clocking in data
  55. #define SDI PIN_SPI_MOSI //Serial Data Input, D15 first
  56.  
  57. int Word = 0; //shifting word sent to ltc6903
  58.  
  59. /*
  60. ██████ ██████ ██ ███████ ██████ ████████ ███████
  61. ██ ██ ██ ██ ██ ██ ██ ██ ██
  62. ██ ██ ██████ ██ █████ ██ ██ ███████
  63. ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  64. ██████ ██████ █████ ███████ ██████ ██ ███████
  65. */
  66.  
  67. MCP23008 SC02(MCP23008_ADDR);
  68. SSD1306AsciiWire display;
  69.  
  70. /*
  71.  
  72. ██ ██ █████ ██████ ██ █████ ██████ ██ ███████ ███████
  73. ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  74. ██ ██ ███████ ██████ ██ ███████ ██████ ██ █████ ███████
  75. ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  76. ████ ██ ██ ██ ██ ██ ██ ██ ██████ ███████ ███████ ███████
  77.  
  78. */
  79.  
  80. #define ON 0
  81. #define OFF 1
  82.  
  83. const char *Phoneme_label[] = {"U", ":UH", "IU", ":U", "O", "00", ":OH", "AW", ":OH", "AH", ":A", "ER", "E2", "EH", "I", "E", "IE", "YI", "NG", "M", "L1", "N", "R2", "HF", "SH", "J", "SH", "Z", "Ss", "F", "V", "HF", "B", "P", "D", "T", "K", "KV", "PA0", "O2", "UH", "AE", "A", "AY", "Y", "HV", "HVC", "HN", "LF", "L", "LB", "TH", "THV", "R", "R1", "W2", "KV", "HFC"};
  84. uint8_t Phoneme_map[58] = {0x3C, 0x3D, 0x14, 0x16, 0x11, 0x13, 0x3B, 0x10, 0, 0x0E, 0x08, 0x1C, 0x3E, 0x0A, 0x07, 0x01, 0x06, 0x04, 0x39, 0x37, 0x21, 0x38, 0x1F, 0x2C, 0, 0x31, 0x32, 0x2F, 0, 0x34, 0x33, 0x2C, 0x24, 0x27, 0x25, 0x28, 0x29, 0x26, 0, 0, 0x18, 0x0C, 0x08, 0x05, 0x03, 0x2A, 0x2B, 0x2E, 0x22, 0x20, 0x3F, 0x36, 0x35, 0x1D, 0x1E, 0, 0x26, 0x2D};
  85. int i;
  86. byte hello[] = {44, 10, 32, 17, 35, 0, 0x23, 0x1C, 0x20, 0x25};
  87.  
  88. void StatusLED()
  89. {
  90. digitalWrite(LED_BUILTIN, !digitalRead(AR));
  91. }
  92.  
  93. void Transfer(word sdi)
  94. {
  95. int value = 0; //set D15 test value to zero;
  96.  
  97. digitalWrite(SEN, LOW); //set Serial Enable True at ltc6903
  98. for (int i = 0; i != 16; i++) //Got 16 bits to clock in
  99. {
  100. value = sdi & 32768; //Strip for testing if D15
  101. if (value != 0) // 1?
  102. {
  103. digitalWrite(SDI, HIGH); //Set SDI to TRUE
  104. }
  105. else
  106. {
  107. digitalWrite(SDI, LOW); //Else set to LOW
  108. }
  109. digitalWrite(SCLK, LOW); //Drop the clock line
  110. digitalWrite(SCLK, HIGH); //Trigger in the SDI low
  111. sdi <<= 1; //Shift next bit into D15 position
  112. }
  113. digitalWrite(SEN, HIGH); //deselect serial transfer
  114. digitalWrite(SDI, HIGH); //put data high as initial state
  115. }
  116.  
  117. void ltc6903(int oct, unsigned int dac)
  118. {
  119. Word = oct; // do OCT first
  120. Word <<= 12; // move it to D15
  121. dac <<= 2; //align the DAC value
  122. Word |= dac; //OR it in, leave CN1 and CN0 at zero
  123. Transfer(Word); //Send word as sdi to ltc6903
  124. }
  125. void Strobe()
  126. {
  127. digitalWrite(RW, LOW);
  128. delayMicroseconds(1);
  129. digitalWrite(RW, HIGH);
  130. }
  131.  
  132. void Phoneme(byte value)
  133. {
  134. digitalWrite(RS0, 0);
  135. digitalWrite(RS1, 0);
  136. digitalWrite(RS2, 0);
  137.  
  138. SC02.writeGPIO(value + B11000000); // B11000000 smallest duration : it minimize the latency !
  139. //while (digitalRead(AR))
  140. // ;
  141. Strobe();
  142. }
  143.  
  144. void Command(byte registre, byte value)
  145. {
  146.  
  147. digitalWrite(RS0, registre & B00000001);
  148. digitalWrite(RS1, registre & B00000010);
  149. digitalWrite(RS2, registre & B00000100);
  150.  
  151. SC02.writeGPIO(value);
  152. delayMicroseconds(1);
  153.  
  154. Strobe();
  155. }
  156.  
  157. void pitchBend(byte channel, byte octet1, byte octet2)
  158. {
  159. int pitch = (( octet2 << 7 ) | octet1) - 8192;
  160. //display.clear();
  161. //display.print("pitch ");
  162. //display.println(map(pitch,8096,-8092,1023,8));
  163.  
  164. // display.print("channel=");
  165. // display.println(channel);
  166.  
  167. ltc6903(10, map(pitch,8096,-8092,1023,8));
  168. }
  169.  
  170. void noteOn(byte channel, byte pitch, byte velocity)
  171. {
  172. switch (channel)
  173. {
  174. case 0: // MIDI channel 1 for the Phonemes
  175. {
  176. pitch = constrain(pitch, 36, 93);
  177.  
  178. digitalWrite(LED_BUILTIN, ON);
  179. digitalWrite(BUSY, ON); // to measure latency from MIDI Note On to speech
  180. // Apply Velocity but keep articulation to 5
  181. Command(3,map(velocity,0,127,0,15)+B00110000);
  182. Phoneme(Phoneme_map[pitch - 36]); // let's start speech first to avoid delays from Oled
  183.  
  184. // Command(1, map(analogRead(A1), 0, 255, 0, 255));
  185. Wire.setClock(1500000L); // speed the display to the max
  186. display.setCursor(0, 2);
  187. display.clearToEOL();
  188. display.print(pitch);
  189.  
  190. pitch = pitch - 36;
  191.  
  192. display.setCursor(30, 2);
  193. display.clearToEOL();
  194. display.print(Phoneme_map[pitch], HEX);
  195. display.setCursor(60, 2);
  196. display.clearToEOL();
  197. display.print(Phoneme_label[pitch]);
  198. Wire.setClock(500000L); // Restore I2C speed to allow speech
  199. //Phoneme(Phoneme_map[pitch]);
  200. //digitalWrite(LED_BUILTIN, HIGH);
  201. }
  202. break;
  203. case 1: // MIDI channel 2 for the pitch
  204. {
  205. ltc6903(10, pitch*8);
  206. }
  207. break;
  208. }
  209. }
  210.  
  211. void noteOff(byte channel, byte pitch, byte velocity)
  212. {
  213. switch (channel)
  214. {
  215. case 0: // MIDI channel 1 for the Phonemes
  216. {
  217. digitalWrite(LED_BUILTIN, OFF);
  218. digitalWrite(BUSY, OFF);
  219. Phoneme(0); // Stop the sound
  220. }
  221. break;
  222. }
  223. }
  224.  
  225. void controlChange(byte channel, byte control, byte value)
  226. {
  227. if (control==1)
  228. {
  229. Command(4, map(value, 0, 127, 200, 251));
  230. }
  231. }
  232.  
  233. // the setup function runs once when you press reset or power the board
  234. void setup()
  235. {
  236. Wire.begin();
  237.  
  238. // Set LTC6903
  239. pinMode(SEN, OUTPUT); //define SEN enable
  240. pinMode(SCLK, OUTPUT); //define SCLK clock
  241. pinMode(SDI, OUTPUT); //define SDI data
  242. digitalWrite(SEN, HIGH); //set safely high
  243. digitalWrite(SCLK, HIGH); //set safely high
  244. digitalWrite(SDI, HIGH); //set safely high
  245.  
  246. display.begin(&Adafruit128x64, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
  247. display.clear();
  248. display.set1X();
  249. display.setFont(fixed_bold10x15);
  250. display.print("Robovox MIDI");
  251.  
  252. ltc6903(10, 516); //Set pitch to middle of pitch wheel
  253.  
  254. pinMode(RED_LED, OUTPUT);
  255. pinMode(GREEN_LED, OUTPUT);
  256.  
  257. digitalWrite(GREEN_LED, OFF);
  258. digitalWrite(RED_LED, OFF);
  259.  
  260. pinMode(RS0, OUTPUT);
  261. pinMode(RS1, OUTPUT);
  262. pinMode(RS2, OUTPUT);
  263.  
  264. pinMode(RW, OUTPUT);
  265. pinMode(AR, INPUT);
  266. digitalWrite(RW, HIGH);
  267.  
  268. pinMode(BUSY, OUTPUT);
  269. digitalWrite(BUSY, OFF);
  270.  
  271. delay(1000);
  272. //attachInterrupt(AR, StatusLED,CHANGE);
  273. //Reset();
  274. SC02.writeIODIR(0x0);
  275.  
  276. Command(3, 128); //Control bit to 1 (128)
  277. Command(0,192); // load DR1 DR2 bit to 1 (to activate A/R request mode) (192)
  278. Command(3, 0); // //Control bit to 0
  279.  
  280. Command(3, B01111111); // Set articulation to normal and amplitude to maximum & CTL to 0
  281. Command(4, 240); // Set Filter frequency to normal (231)
  282. Command(2, 200); // Set Speech rate to normal (168)
  283. Command(1, 127); // inflection
  284.  
  285. for (int y = 0; y < 11; y++)
  286. {
  287. Phoneme(hello[y]);
  288. delay(100);
  289. }
  290. }
  291.  
  292. // the loop function runs over and over again forever
  293. void loop()
  294. {
  295. midiEventPacket_t rx = MidiUSB.read();
  296.  
  297. switch (rx.header)
  298. {
  299. case 0:
  300. break; //No pending events
  301.  
  302. case 0x9:
  303. noteOn(
  304. rx.byte1 & 0xF, //channel
  305. rx.byte2, //pitch
  306. rx.byte3 //velocity
  307. );
  308. break;
  309.  
  310. case 0x8:
  311. noteOff(
  312. rx.byte1 & 0xF, //channel
  313. rx.byte2, //pitch
  314. rx.byte3 //velocity
  315. );
  316. break;
  317.  
  318. case 0xB:
  319. controlChange(
  320. rx.byte1 & 0xF, //channel
  321. rx.byte2, //control
  322. rx.byte3 //value
  323. );
  324. break;
  325.  
  326. case 0xE:
  327. pitchBend(
  328. rx.byte1 & 0xF, //channel
  329. rx.byte2, //value
  330. rx.byte3 //value
  331.  
  332. );
  333. break;
  334.  
  335. default:
  336. break;
  337. }
  338. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement