Advertisement
edwar64896

Untitled

Sep 5th, 2017
375
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.44 KB | None | 0 0
  1. #include <Wire.h>
  2. #include <LiquidCrystal.h>
  3. #include <MIDI.h>
  4.  
  5. LiquidCrystal lcd (8, 9, 4, 5, 6, 7);
  6.  
  7.  
  8. #define icpPin 49        // ICP input pin on arduino // not 8
  9.  
  10. unsigned int zero_time_max = 1000;
  11. unsigned int one_time_max = zero_time_max / 2;
  12. unsigned int zero_time_min = zero_time_max * 0.75;
  13. unsigned int one_time_min = one_time_max * 0.75;
  14.  
  15. #define end_data_position      63
  16. #define end_sync_position      77
  17. #define end_smpte_position     80
  18.  
  19. volatile unsigned int bit_time;
  20. volatile boolean valid_tc_word;
  21. volatile boolean ones_bit_count;
  22. volatile boolean tc_sync;
  23. volatile boolean write_tc_out;
  24. volatile boolean drop_frame_flag;
  25.  
  26. volatile byte total_bits;
  27. volatile byte current_bit;
  28. volatile byte sync_count;
  29.  
  30. volatile byte tc[8];
  31. char timeCode[12];
  32. char userBit[11];
  33. static byte toSend;
  34.  
  35. byte h, m, s, f;
  36.  
  37. byte MTCIndex = 0;
  38.  
  39.  
  40. MIDI_CREATE_DEFAULT_INSTANCE();
  41.  
  42. long runningAverage(int M) {
  43. #define LM_SIZE 64
  44.   static int LM[LM_SIZE];      // LastMeasurements
  45.   static byte index = 0;
  46.   static long sum = 0;
  47.   static byte count = 0;
  48.  
  49.   // keep sum updated to improve speed.
  50.   sum -= LM[index];
  51.   LM[index] = M;
  52.   sum += LM[index];
  53.   index++;
  54.   index = index % LM_SIZE;
  55.   if (count < LM_SIZE) count++;
  56.  
  57.   return sum / count;
  58. }
  59.  
  60.  
  61. int i = 0;
  62. volatile byte j = 0;
  63. volatile byte k = 0;
  64. volatile byte oldF;
  65.  
  66. ISR(TIMER5_COMPA_vect) {
  67.  
  68.   /*
  69.  
  70.     if (j++ > 24) {
  71.     j = 0;
  72.     k = 1 - k;
  73.     if (k)
  74.       digitalWrite(13, HIGH);
  75.     else
  76.       digitalWrite(13, LOW);
  77.     }
  78.   */
  79.  
  80.   if (f == 0) {
  81.     k = 1 - k;
  82.     if (k)
  83.       digitalWrite(13, HIGH);
  84.     else
  85.       digitalWrite(13, LOW);
  86.  
  87.   }
  88.  
  89.   if (f==0 && f != oldF) {
  90.     MTCIndex=0;
  91.   }
  92.  
  93.  
  94.   sendMTC();
  95.   /*
  96.     MIDI.sendNoteOn(i, i * 2, 1);
  97.  
  98.     if (i++ > 24)
  99.       i = 0;
  100.   */
  101.   oldF=f;
  102. }
  103.  
  104. /* ICR interrupt vector */
  105. ISR(TIMER4_CAPT_vect)
  106. {
  107.  
  108.   //toggleCaptureEdge
  109.   TCCR4B ^= _BV(ICES4);
  110.  
  111.   bit_time = ICR4;
  112.  
  113.   //resetTimer1
  114.   TCNT4 = 0;
  115.  
  116.   if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
  117.   {
  118.     total_bits = 0;
  119.   }
  120.   else
  121.   {
  122.     if (ones_bit_count == true) // only count the second ones pluse
  123.       ones_bit_count = false;
  124.     else
  125.     {
  126.       if (bit_time > zero_time_min)
  127.       {
  128.         current_bit = 0;
  129.         sync_count = 0;
  130.       }
  131.       else //if (bit_time < one_time_max)
  132.       {
  133.         ones_bit_count = true;
  134.         current_bit = 1;
  135.         sync_count++;
  136.         if (sync_count == 12) // part of the last two bytes of a timecode word
  137.         {
  138.           sync_count = 0;
  139.           tc_sync = true;
  140.           total_bits = end_sync_position;
  141.         }
  142.       }
  143.  
  144.       if (total_bits <= end_data_position) // timecode runs least to most so we need
  145.       { // to shift things around
  146.         tc[0] = tc[0] >> 1;
  147.  
  148.         for (int n = 1; n < 8; n++)
  149.         {
  150.           if (tc[n] & 1)
  151.             tc[n - 1] |= 0x80;
  152.  
  153.           tc[n] = tc[n] >> 1;
  154.         }
  155.  
  156.         if (current_bit == 1)
  157.           tc[7] |= 0x80;
  158.       }
  159.       total_bits++;
  160.     }
  161.  
  162.     if (total_bits == end_smpte_position) // we have the 80th bit
  163.     {
  164.       total_bits = 0;
  165.       if (tc_sync)
  166.       {
  167.         tc_sync = false;
  168.         valid_tc_word = true;
  169.       }
  170.     }
  171.  
  172.     if (valid_tc_word)
  173.     {
  174.       valid_tc_word = false;
  175.  
  176.       drop_frame_flag = bit_is_set(tc[1], 2);
  177.  
  178.       timeCode[11] = 0;
  179.       timeCode[10] = (tc[0] & 0x0F) + 0x30;  // frames
  180.       timeCode[9] = (tc[1] & 0x03) + 0x30;  // 10's of frames
  181.  
  182.       if (drop_frame_flag) {
  183.         timeCode[8] =  ';';
  184.       } else {
  185.         timeCode[8] =  ':';
  186.       }
  187.  
  188.       timeCode[7] = (tc[2] & 0x0F) + 0x30;  // seconds
  189.       timeCode[6] = (tc[3] & 0x07) + 0x30;  // 10's of seconds
  190.       timeCode[5] =  ':';
  191.       timeCode[4] = (tc[4] & 0x0F) + 0x30;  // minutes
  192.       timeCode[3] = (tc[5] & 0x07) + 0x30;  // 10's of minutes
  193.       timeCode[2] = ':';
  194.       timeCode[1] = (tc[6] & 0x0F) + 0x30;  // hours
  195.       timeCode[0] = (tc[7] & 0x03) + 0x30;  // 10's of hours
  196.  
  197.       h = (tc[6] & 0x0F) + (tc[7] & 0x03) * 10;
  198.       m = (tc[4] & 0x0F) + (tc[5] & 0x07) * 10;
  199.       s = (tc[2] & 0x0F) + (tc[3] & 0x07) * 10;
  200.       f = (tc[0] & 0x0F) + (tc[1] & 0x03) * 10;
  201.  
  202.       userBit[10] = 0;
  203.       userBit[9] = ((tc[0] & 0xF0) >> 4) + 0x30; // user bits 8
  204.       userBit[8] = ((tc[1] & 0xF0) >> 4) + 0x30; // user bits 7
  205.       userBit[7] = ((tc[2] & 0xF0) >> 4) + 0x30; // user bits 6
  206.       userBit[6] = ((tc[3] & 0xF0) >> 4) + 0x30; // user bits 5
  207.       userBit[5] = '-';
  208.       userBit[4] = ((tc[4] & 0xF0) >> 4) + 0x30; // user bits 4
  209.       userBit[3] = ((tc[5] & 0xF0) >> 4) + 0x30; // user bits 3
  210.       userBit[2] = '-';
  211.       userBit[1] = ((tc[6] & 0xF0) >> 4) + 0x30; // user bits 2
  212.       userBit[0] = ((tc[7] & 0xF0) >> 4) + 0x30; // user bits 1
  213.  
  214.       write_tc_out = true;
  215.     }
  216.   }
  217. }
  218.  
  219.  
  220. void setup()
  221. {
  222.  
  223.   noInterrupts();
  224.  
  225.   pinMode(13, OUTPUT);
  226.  
  227.   lcd.begin(16, 2);
  228.   //lcd.setCursor(0, 1);
  229.   //lcd.print("hello timecody");
  230.   //  beginSerial (115200);
  231.   //pinMode(icpPin, INPUT);                  // ICP pin (digital pin 8 on arduino) as input
  232.  
  233.   bit_time = 0;
  234.   valid_tc_word = false;
  235.   ones_bit_count = false;
  236.   tc_sync = false;
  237.   write_tc_out = false;
  238.   drop_frame_flag = false;
  239.   total_bits =  0;
  240.   current_bit =  0;
  241.   sync_count =  0;
  242.  
  243.   //Serial.println("Finished setup ");
  244.   delay (1000);
  245.  
  246.   // TIMER 4 - DECODE SMPTE LTC
  247.   TCCR4A = B00000000; // clear all
  248.   TCCR4B = B11000010; // ICNC4 noise reduction + ICES4 start on rising edge + CS11 divide by 8
  249.   TCCR4C = B00000000; // clear all
  250.   TIMSK4 = B00100000; // ICIE4 enable the icp
  251.  
  252.   TCNT4 = 0; // clear timer4
  253.  
  254.   // TIMER 5 - SYNCHRONIZE ON QUARTER FRAMES
  255.   TCCR5A = B00000000; // clear all
  256.   TCCR5B = B00000101; // CS11 divide by 64
  257.   TCCR5C = B00000000; // clear all
  258.   TIMSK5 = B00000010; // OCIE5A ENABLE.
  259.  
  260.   TCNT5 = 0;
  261.   OCR5A = 65535; // clear timer5
  262.  
  263.   interrupts();
  264.  
  265.   MIDI.begin(MIDI_CHANNEL_OMNI);
  266. }
  267.  
  268. /* send MIDI Timecode Quarter Frame*/
  269. void sendMTC() {
  270.  
  271.   switch (MTCIndex)
  272.   {
  273.     case 0:
  274.       toSend = ((f & 0xF));
  275.       break;
  276.  
  277.     case 1:
  278.       toSend = (((f & 0xF0) >> 4));
  279.       break;
  280.  
  281.     case 2:
  282.       toSend = ((s & 0xF));
  283.       break;
  284.  
  285.     case 3:
  286.       toSend = (((s & 0xF0) >> 4));
  287.       break;
  288.  
  289.     case 4:
  290.       toSend = ((m & 0xF));
  291.       break;
  292.  
  293.     case 5:
  294.       toSend = (((m & 0xF0) >> 4));
  295.       break;
  296.  
  297.     case 6:
  298.       toSend = ((h & 0xF));
  299.       break;
  300.  
  301.     case 7:
  302.       toSend = (((h & 0xF0) >> 4 )); // 0x70 = 24 fps // 0x72 = 25 fps // 0x74 = 30df fps // 0x76 = 30 fps
  303.       break;
  304.   }
  305.  
  306.   MIDI.sendTimeCodeQuarterFrame(MTCIndex++, toSend);
  307.  
  308.   if (MTCIndex > 7)
  309.     MTCIndex = 0;
  310. }
  311.  
  312. int kk = 1;
  313.  
  314. void loop()
  315. {
  316.   if (write_tc_out)
  317.   {
  318.     write_tc_out = false;
  319.  
  320.  
  321.     /*
  322.        We are polling TCNT5 (Timer 5 Counter) every time a frame comes past.
  323.        Each time we see a value, we are going to grab a running average and then
  324.        divide the value by 4. This is the timing interval we will use for
  325.        delivery of MTC Quarter Frames.
  326.     */
  327.  
  328.     OCR5A = runningAverage(TCNT5) / 4; //
  329.     TCNT5 = 0;
  330.  
  331.     lcd.setCursor(11, 1);
  332.     lcd.print("     ");
  333.     lcd.setCursor(11, 1);
  334.     lcd.print(OCR5A);
  335.  
  336.  
  337.     lcd.setCursor(0, 0);
  338.     lcd.print(timeCode);
  339.     lcd.setCursor(0, 1);
  340.     lcd.print(userBit);
  341.  
  342.     if (f == 0) {
  343.       MTCIndex = 0;
  344.       if (kk) {
  345.         j = 0;
  346.         kk = 0;
  347.       }
  348.     }
  349.   }
  350.  
  351. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement