/*
 *	mini sequenceur àlc
 */

#define  NOTEOFF		(0x80)
#define  NOTEON			(0x90)
#define	 AFTERTOUCH		(0xa0)
#define  CONTROLCHANGE		(0xb0)
#define  PROGRAMMCHANGE		(0xc0)
#define  CHANNELPRESSURE	(0xd0)
/*------------------------------------------------------*/


#define USE_POOL    1
#define DEBUG15     0

#define DELAY       100
#define CHANNEL     7
#define CONTROL     10         /* panoramic */
/*-------------------------------------------------------*/
/* */
void sendnote(short chan, short note, short velo)
{
unsigned char frame[3];

chan &= 0x0f;
if (velo) frame[0] = NOTEON | chan;
else      frame[0] = NOTEOFF | chan;
frame[1] = note & 0x7f;
frame[2] = velo & 0x7f;
Serial.write(frame, 3);
}
/*------------------------------------------------------*/
void controlchange(short chan, short ctrl, short value)
{
unsigned char frame[3];

frame[0] = CONTROLCHANGE | (chan & 0x0f);
frame[1] = ctrl & 0x7f;
frame[2] = value & 0x7f;
Serial.write(frame, 3);
}
/*------------------------------------------------------*/
/*------------------------------------------------------*/
void setup() {
  Serial.begin(31250);
  pinMode(LED_BUILTIN, OUTPUT);
}
/*------------------------------------------------------*/
#if USE_POOL
int poll_cc(int chan, int ctrl, long duration)
{
static unsigned long oldtime;
static short oldcc = -1;
short cc;

#if DEBUG15
sendnote(15, 42, 42);
#endif

oldtime = millis();
while ((millis()-oldtime) < duration) {
  cc = analogRead(A0) / 8;
  if (cc != oldcc) {
    controlchange(chan, ctrl, cc);
    oldcc = cc;
    }
  }
  
#if DEBUG15
sendnote(15, 42, 0);
#endif
return 0;
}
#endif
/*------------------------------------------------------*/

static char melodie[] =
  { 57, 57, 64, 64, 66, 66, 64, 62, 62, 61, 61, 59, 59, 57 };
  
/*------------------------------------------------------*/

void loop() {
int idx, note;

for (idx=0; idx<sizeof(melodie); idx++) {

  note = melodie[idx];
  
  sendnote(CHANNEL, note, 99);
  
#if USE_POOL
  poll_cc(CHANNEL, CONTROL, (long)DELAY);
#else 
  delay(DELAY);
#endif

  sendnote(CHANNEL, note, 0);
    
#if USE_POOL
  poll_cc(CHANNEL, CONTROL, ((long)DELAY)*4);
#else 
  delay(DELAY*4);
#endif
  }
delay(500);
}
/*------------------------------------------------------*/