// furby sound sampler MIDI test (for USB MIDI and wired) // playing a sample from memory. #include // arduino core / framework #include // library for the neopixel LED #include // cp process to play audio on PWM pin #include "furby.h" // converted furby sample data (using Wav2c) Adafruit_NeoPixel colorLED(1, 28, NEO_GRB + NEO_KHZ800); // The sample pointers const int16_t *start = (const int16_t *)out_raw; const int16_t *p = start; // the real sample value pointer // Create the PWM audio device on pin A3 (internal buzzer on Expansion board) PWMAudio pwm(18); unsigned int count = 0; // check where in the sample you are, human readable volatile int hue = 0; // to cycle through LED colours (and misused as frequency setting) bool playing = 0; #include #include // and attach usb_midi and wired MIDI Adafruit_USBD_MIDI usb_midi; MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, MIDI); MIDI_CREATE_INSTANCE(HardwareSerial, Serial2, wiredMIDI); // Serial MIDI const int midi_tx_pin = 4; const int midi_rx_pin = 5; // the sample playing interrupt routine void cb() { // thread process to do audio update regularly if (playing) { while (pwm.availableForWrite()) { pwm.write(*p++); count += 2; // was 2 if (count >= sizeof(out_raw)) { count = 0; p = start; playing = 0; } } } } // now for the code void setup() { Serial2.setRX(midi_rx_pin); Serial2.setTX(midi_tx_pin); pinMode(LED_BUILTIN,OUTPUT); TinyUSB_Device_Init(0); // RGB LED colorLED.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) colorLED.show(); // Turn OFF all pixels ASAP colorLED.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255) // audio PWM playback pwm.onTransmit(cb); // start the audio playback pwm.begin(22050); // set the playback frequency // MIDI settings MIDI.begin(MIDI_CHANNEL_OMNI); wiredMIDI.begin(MIDI_CHANNEL_OMNI); // Attach the handleNoteOn function to the MIDI Library. It will // be called whenever the Bluefruit receives MIDI Note On messages. MIDI.setHandleNoteOn(handleNoteOn); wiredMIDI.setHandleNoteOn(handleNoteOn); // Do the same for MIDI Note Off messages. MIDI.setHandleNoteOff(handleNoteOff); wiredMIDI.setHandleNoteOff(handleNoteOff); // three playback buttons pinMode(20, INPUT_PULLUP); pinMode(21, INPUT_PULLUP); pinMode(22, INPUT_PULLUP); } void loop() { static unsigned long looptime; if (millis() > looptime + 49) { // run this code at 50Hz looptime = millis(); colorLED.setPixelColor(0, colorLED.Color(hue, 255 - hue, 0)); // Set pixel 0 to a color between red and green colorLED.show(); if (!digitalRead(20)) { handleNoteOn(0, 1, 20); } else if (!digitalRead(21)) { handleNoteOn(0, 1, 80); } else if (!digitalRead(22)) { handleNoteOn(0, 1, 100); } digitalWrite(LED_BUILTIN,playing); } // read any new MIDI messages MIDI.read(); wiredMIDI.read(); } void playfurb(int note) { hue = max(note, 35) - 35; p = start; if (!playing) { p = start; pwm.setFrequency(22050 + hue * 300); } playing = 1; } void handleNoteOn(byte channel, byte pitch, byte velocity) { playfurb(velocity); } void handleNoteOff(byte channel, byte pitch, byte velocity) { }