// Play a file from the SD card in looping mode, from the SD card. // Example program to demonstrate the use of the MIDFile library // // Hardware required: // SD card interface - change SD_SELECT for SPI comms #include #include "wiring_private.h" #include #include #include #include #define DEBUG_ON 0 // set to 1 for MIDI output, 0 for debug output #define GENERATE_TICKS 1 #define DEBUGS(s) SerialUSB.print(s) #define DEBUG(s, x) { SerialUSB.print(F(s)); SerialUSB.print(x); } #define DEBUGX(s, x) { SerialUSB.print(F(s)); SerialUSB.print(x, HEX); } #define SERIAL_RATE 115200 byte mac[] = { //0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 // FEATHER 1 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x02 // FEATHER 2 }; IPAddress ip(192, 168, 8, 10); // IP FEATHER2 //const char ip[] = "192.168.8.10"; unsigned int localPort = 8888; // local port to listen on unsigned int destPort[7] = { 2345, 2346, 2347, 2348, 2349, 2350, 2351 }; // TO SET SENDING PORT PLAYER EthernetUDP Udp; #define UDP_RX_PACKET_MAX_SIZE 8 // SD chip select pin for SPI comms. // Arduino Ethernet shield, pin 4. // Default SD chip select is the SPI SS pin (10). // Other hardware will be different as documented for that hardware. #define SD_SELECT 4 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) // The files in the tune list should be located on the SD card // or an error will occur opening the file and the next in the // list will be opened (skips errors). const char *loopfile = "final.mid"; // simple and short file #if GENERATE_TICKS uint32_t lclBPM = 105; //uint32_t lclBPM = 60; //uint32_t lclBPM = 30; #endif SdFat SD; MD_MIDIFile SMF; byte state_ = 0; byte channel_ = 0; byte intensity_ = 0; char* outIp[8] = {"192.168.8.116", "192.168.8.117", "192.168.8.118", "192.168.8.119", "192.168.8.120", "192.168.8.121", "192.168.8.122", "192.168.8.255"};; int pinOut[6] = {A0, A1, A2, A3, A4, A5}; void OSCSend(int out, char* val) { // Udp.beginPacket(outIp[7], destPort[out]); // Udp.printf(val); // Udp.endPacket(); // mark the end of the OSC Packet } void midiCallback(midi_event *pev) { #if DEBUG_ON DEBUG("M T", pev->track); DEBUG(": Ch ", pev->channel+1); DEBUGS(" Data"); #endif state_ = pev->data[0]; channel_ = pev->data[1]; intensity_ = pev->data[2]; #if DEBUG_ON DEBUGX(" ", state_); DEBUGX(" ", channel_); DEBUGX(" ", intensity_); SerialUSB.print(" "); SerialUSB.print((channel_-0x24), HEX); #endif if (intensity_>0) { OSCSend(channel_-0x24, "1"); digitalWrite(pinOut[channel_-0x24], HIGH); //digitalWrite(pin_out[channel_-0x24], HIGH); #if DEBUG_ON SerialUSB.println(" Solenoide ON"); #endif } else digitalWrite(pinOut[channel_-0x24], LOW); } #if GENERATE_TICKS uint16_t tickClock(void) // Check if enough time has passed for a MIDI tick and work out how many! { static uint32_t lastTickCheckTime, lastTickError; uint8_t ticks = 0; lclBPM= map(analogRead(A5), 0, 1023, 60, 300); SerialUSB.println(lclBPM); uint32_t elapsedTime = lastTickError + micros() - lastTickCheckTime; uint32_t tickTime = (60 * 1000000L) / (lclBPM * SMF.getTicksPerQuarterNote()); // microseconds per tick tickTime = (tickTime * 4) / (SMF.getTimeSignature() & 0xf); // Adjusted for time signature if (elapsedTime >= tickTime) { ticks = elapsedTime/tickTime; lastTickError = elapsedTime - (tickTime * ticks); lastTickCheckTime = micros(); // save for next round of checks } return(ticks); } #endif void setup(void) { int err; SerialUSB.begin(SERIAL_RATE); delay(4000); SerialUSB.println("Hola"); // start the Ethernet and UDP: Ethernet.begin(mac, ip); // Check for Ethernet hardware present if (Ethernet.hardwareStatus() == EthernetNoHardware) { SerialUSB.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); // while (true) { // delay(1); // do nothing, no point running without Ethernet hardware // } } if (Ethernet.linkStatus() == LinkOFF) { SerialUSB.println("Ethernet cable is not connected."); } Udp.begin(localPort); for (int i= 0; i<6; i++) { pinMode(pinOut[i], OUTPUT); digitalWrite(pinOut[i], LOW); } DEBUGS("\n[MidiFile Looper]"); // Initialize SD if (!SD.begin(SD_SELECT, SPI_FULL_SPEED)) { DEBUGS("\nSD init fail!"); while (true) ; } // Initialize MIDIFile SMF.begin(&SD); SMF.setMidiHandler(midiCallback); SMF.looping(true); // use the next file name and play it DEBUG("\nFile: ", loopfile); SMF.setFilename(loopfile); err = SMF.load(); if (err != -1) { DEBUG("\nSMF load Error ", err); while (true); } } void loop(void) { // OSCSend(0, "1"); // delay(500); #if GENERATE_TICKS static bool fBeat = false; static uint16_t sumTicks = 0; uint32_t ticks = tickClock(); if (ticks > 0) { //LCDBeat(fBeat); SMF.processEvents(ticks); SMF.isEOF(); // side effect to cause restart at EOF if looping //LCDbpm(); sumTicks += ticks; if (sumTicks >= SMF.getTicksPerQuarterNote()) { sumTicks = 0; fBeat = !fBeat; } } #else // play the file if (!SMF.isEOF()) { SMF.getNextEvent(); } #endif }