Traktor track name / time to LCD via MIDI! ...using Denon LCD support & Arduino - Page 3
Page 3 of 6 FirstFirst 123456 LastLast
Results 21 to 30 of 55
  1. #21
    Tech Wizard Siytek's Avatar
    Join Date
    Apr 2011
    Location
    UK
    Posts
    36

    Default

    Some great findings guys, Iv been smiling at the idea of a twin processor project all weekend!

    Just one thing to add further to DjNecro's findings with the MIDI OUT stuff...

    'MIDI OUT > Output > Track End Warning' outputs CC every time you load a new track in whether it be right click and load, or drag and drop, the only problem is it also outputs the same message when the play point crosses the '30 seconds left' boundary, if you skip the play point before and after the 30 second left point this message is outputted whether the track is playing or not. I was thinking the LCD MIDI could be checked for new data if this message was received and the track was not playing, however if someone was to skip before and after the 30 second point with the track paused it would probably screw up the reading. grrr!! With what DjNecro said and what I have found there are several options that come close, but with a single quirk making it a pain!!

    I personally don't think Arduino-based scrolling in a 12 segment window is much of a problem as the remaining 4 segments could be used for other things (like time or a deck indicator)
    I was thinking about having something like...

    A> TRACK NAME
    TRACK NAME <B

    ...so I agree the 12 seg thing wont be a prob


    All it would have taken would be to send one command to indicate the start of the string, then send each character in order one by one, and one more command to indicate the end of the string... SIMPLE!!!
    Agreed agreed agreed! Anoying isnt it!

    Im gonna have a think a bit more about the final spec of my board design, defo got me thinking what has been said on here which is great, and part the reason I got involved on here so thanks again guys for giving me inspiration!
    ...dreams in binary

  2. #22
    Tech Mentor
    Join Date
    Feb 2011
    Location
    Southern Ontario, Canada
    Posts
    244

    Default

    Here's what I came up with... It will decode the track title and artist name, as well as the minute, second, track position (in percent). It also calculates the total track length every 20 seconds. It's not 100% accurate, but it's the best we have

    The example video shows it rotating between the artist/track and a two line time display with simple bar graph. The delay between changes is currently 15 seconds.

    http://www.youtube.com/watch?v=6nkZ4E0p2Nk

    Note: Just want to draw attention to the fact that the decoding functions are completely independent of the MIDI code and the lcd code. While they are of course designed to decode MIDI, how you get the MIDI messages to the functions is up to you

    Code:
    #include <WProgram.h>
    #include <LiquidCrystal.h>
    #include <Midi.h>
    
    struct DENON_SEGMENT {
      boolean valid;
      byte seg;
      byte col;
      byte val;
    };
    
    struct DENON_TIME {
      boolean valid;
      byte minute;
      byte sec;
      byte pos;
      byte totMin;
      byte totSec;
      
    };
    
    LiquidCrystal lcd(8, 11, 9, 4, 5, 6, 7); // initialize the library with the numbers of the interface pins
    
    class MyMidi : public Midi {
      public:
    
      MyMidi(HardwareSerial &s) : Midi(s) {}
    
      void handleControlChange(unsigned int channel, unsigned int controller, unsigned int value) {
        if (channel == 1 || channel == 2) {
          DENON_SEGMENT segData = checkForSegmentData(controller, value);
          DENON_TIME timeData = checkForTimeData(controller, value);
          static unsigned long curTime, prevTime = 0;
          static boolean flip = false;
          
          curTime = millis();
          if (curTime - prevTime > 15000) {
            prevTime = curTime;
            flip = !flip;
            lcd.clear();
          }
    
          if (segData.valid == true && flip == false) track_name(segData.seg, segData.col+2, segData.val); // col+2 to center it on my 2x16 screen (the denon only has a 2x12)
          if (timeData.valid == true && flip == true) updateTime(timeData.minute, timeData.sec, timeData.pos, timeData.totMin, timeData.totSec);
        }
      }
    };
    
    MyMidi midi(Serial);
    
    void setup() {
      lcd.begin(2, 16);
      digitalWrite(14, HIGH);
      midi.begin(0);
    }
    
    void loop() {
      midi.poll();
    }
    
    struct DENON_TIME checkForTimeData(byte controller, byte value) {
      static byte minute, second, pos, totMin, totSec, lastSecond;
      static float tot = 0;
      
      if (controller >= 0x40 && controller <= 0x49) {
        if (controller == 0x42) {
          minute = value;
        } else if (controller == 0x43) {
          second = value;
        } else if (controller == 0x48) {
          pos = value;
          if (second != lastSecond) {
            if (second % 20 == 0) {
              tot = ((minute*60)+second) / ((float)pos / 100);
              totMin = tot/60;
              totSec = (int)tot%60;
            }
            lastSecond = second;
            return (DENON_TIME){true, minute, second, pos, totMin, totSec};
          }
        }
      }
      return (DENON_TIME){false,0,0,0};
    }
    
    struct DENON_SEGMENT checkForSegmentData(byte controller, byte value) {
      static byte seg1MSB, seg2MSB = 0;
      if ((controller >= 0x01 && controller <= 0x05) || (controller >= 0x07 && controller <= 0x0D)) { // segment 1 MSB
        seg1MSB = value;
      } else if (controller >= 0x0E && controller <= 0x19) { // segment 2 MSB
        seg2MSB = value;
      } else if ((controller >= 0x21 && controller <= 0x25) || (controller >= 0x27 && controller <= 0x2D)) { // segment 1 LSB
        return (DENON_SEGMENT){true, 0, getColumn(controller, 1), ((seg1MSB<<4) + value)}; // return completed packet
      } else if (controller >= 0x2E && controller <= 0x39) { // segment 2 LSB
        return (DENON_SEGMENT){true, 1, getColumn(controller, 2), ((seg2MSB<<4) + value)}; // return completed packet
      }
      return (DENON_SEGMENT){false,0,0,0}; // incomplete packet
    }
    
    // parameters: cc- controller number, seg- segment number
    // returns: column number (zero indexed) or 255 if invalid segment
    byte getColumn(byte cc, byte seg) {
      byte col=255;
      if (seg == 1) {
        col = cc - 33; // convert into segment number (column)
        if (col >= 6) col--; // work around the fact that Denon skipped 0x06 for segment 1-6 (they got segment 2 correct)
      } else if (seg == 2) {
        col = cc - 46; // convert into segment number (column)
      }
      return col;
    }
    
    void track_name(byte lcd_row, byte lcd_col, byte lcd_data){
      lcd.setCursor(lcd_col, lcd_row);
      lcd.print(lcd_data); 
    }
    
    void updateTime(byte minute, byte sec, byte pos, byte totMin, byte totSec) {
      char one[17], two[17] = {};
    
      strcat(two, "|");
      for (byte i=1;i<=14;i++) {
       if (i <= map(pos, 0, 100, 0, 14)) strcat(two,"#");
       else strcat(two, " ");
      }
      strcat(two, "|");
    
      sprintf(one, "R:%02i:%02i  T:%02i:%02i", minute, sec, totMin, totSec);
      lcd.setCursor(0, 0);
      lcd.print(one);
      lcd.setCursor(0, 1);
      lcd.print(two);
    }
    Last edited by DjNecro; 04-18-2011 at 02:14 AM.

  3. #23
    Tech Guru MiL0's Avatar
    Join Date
    May 2009
    Location
    Brighton / Bangkok
    Posts
    1,387

    Default

    Good work man

    The percentage track position gave me an idea actually... what about mounting a softpot potentiometer just above or below the LCD? Like this:

    http://www.sparkfun.com/products/8607

    If the softpot is the same length as the LCD display then it could be used to interact with the LCD in interesting ways. For example, as a touch pad to quickly scroll through the track. When the softpot is touched, the LCD changes mode, displaying the current track position (like this perhaps: [0--------||-----99]. It could also be used as a filter, eq or effects control parameter (all with visual queues from the LCD display).

    Only problem is that the softpots are a bit pricey

  4. #24
    Tech Wizard Siytek's Avatar
    Join Date
    Apr 2011
    Location
    UK
    Posts
    36

    Default

    Nice! I like the way you managed to calculate the remaining time!

    I have just been doing some reading about the MIDIStreaming subclass with intentions to hopefully develop my own USB connectivity in the future and have discovered some interesting stuff...

    It turns out that USB-MIDI never emulates the serial MIDI baud rate of 31250bps. The basic principal is something like this... the MIDI bytes are encapsulated with an additional USB header byte to make a 32-bit packet of data which is transferred over USB at the USB connection speed and passed to the USB input of the MCU on the other end (MCU with USB input necessary). The MIDI bytes can then be manipulated as you choose within the code.

    So even by the USB 1.1 standard at 12Mb, USB-MIDI information is being transmitted at just over 50 times the speed of standard serial MIDI!

    When Denon setup their hardware to accept MIDI to control the LCD, as we discussed before it seems a bit stupid to have to receive all that data constantly to display information on the screen. It would seem better to send the track name and artist over MIDI with a start and end marker, as DjNecro mentioned in an earlier post, which could then be loaded in to the Denon and the Denon could handle the display including the scrolling.

    When you think about it though, having the LCD set up in the way which they have done it has a plus side too, the host software can have complete control over what is displayed on the screen rather than be bounded by the Denon displaying info in a certain way. In terms of 31,250bps, it takes quite a lot of bandwidth to deliver this information but when we are talking USB speed its no prob at all!

    Im not sure if this poses a problem, DjNecro your screen seems to be running nice and smooth with a standard MIDI connector, but this thought on USB does kind of answer why the Denon LCD MIDI stuff works in the way they have set it up!

    ...dreams in binary

  5. #25
    Tech Guru MiL0's Avatar
    Join Date
    May 2009
    Location
    Brighton / Bangkok
    Posts
    1,387

    Default

    Siytek - this was the site I was talking about for low run PCB manufacturing:

    http://dorkbotpdx.org/wiki/pcb_order

    It costs $5 per square inch (2 layer, 3 pcbs per order included in price)

    You reckon you could get the Arduino(s) talking to Traktor via midi over usb? That would be some achievement because afaik, this is notoriously difficult (especially with the older 1280 atmel's). Good luck!

    Oh and I might hit you up on Skype this week to discuss an idea I had regarding all of this stuff

  6. #26
    Tech Wizard Siytek's Avatar
    Join Date
    Apr 2011
    Location
    UK
    Posts
    36

    Default

    The percentage track position gave me an idea actually... what about mounting a softpot potentiometer just above or below the LCD? Like this:
    Defo good idea MiL0 I was thinking about adding a little header to the board (next to the LCD header) which could accept some kind of menu key / pot inputs, the user could then choose their own pot / buttons for menu control
    ...dreams in binary

  7. #27
    DJTT Infectious Moderator photojojo's Avatar
    Join Date
    Apr 2010
    Location
    Sherman, TX
    Posts
    13,939

    Default

    Mind if I get OT for a minute? Can any of you smart people help me with this?

    http://djtechtools.com/forum/showthr...ktor+text+file
    Chris Jennings FHP

    Podcast - Soundcloud - Mixcloud - Beatport Charts - x

  8. #28
    Tech Guru MiL0's Avatar
    Join Date
    May 2009
    Location
    Brighton / Bangkok
    Posts
    1,387

    Default

    Quote Originally Posted by photojojo View Post
    Mind if I get OT for a minute? Can any of you smart people help me with this?

    http://djtechtools.com/forum/showthr...ktor+text+file
    That's possible using the Autohotkey script I'm writing (thanks to djnecro and siytek for working out all the tricky bits). So far, I've got a Windows exe that acts sits between Traktor and your controller and reads the artist/track name (endlessly! see the 'bugs' above). This information could easily be written to a text file. Can I ask what you intend to do with this text afterwards? It might help me to customise the script to better suit you.

    Two disadvantages:

    - It requires Windows (no AHK support on MacOSX)
    - It requires a virtual midi input, rather than being plug'n'play

  9. #29
    Tech Wizard Siytek's Avatar
    Join Date
    Apr 2011
    Location
    UK
    Posts
    36

    Default LCD MIDI + MIDI Serial baud rate info

    Just pondering a few numbers with regards to my last post about USB-MIDI and baud rates, I realise this may be basic stuff to some but thought I would post it here just incase it was beneficial to anyone. I have done a few calculations related to the amount of bandwidth the LCD MIDI setup might take from a serial MIDI data stream, here are my findings….

    1 MIDI CC message = x3 bytes (status, data, data) = 24 bits per message.

    The LCD characters need two MIDI CC messages so a total of 48 bits to be sent to display a character.

    There are 12 characters displayed by the HC4500 so 12 * 48 = 576 bits needed to display the whole line.

    Both track and artist are on a separate line so 576 * 2 = 1152 bits are needed to display two lines with track and artist.

    The update of minutes within the track time requires one message = 24 bits

    The update of seconds within the track time requires one message = 24 bits

    The update of frames within the track time requires one message = 24 bits

    so…. If during 1 second of time, everything on the display needs to be updated…

    (im not sure how many times track and artist scroll along the line in a second, lets say six times for an extreme example)

    1152 * 6 = 6912 bits to move track and artist within the given second
    24 bits to change minutes
    24 bits to change seconds
    100 * 24 bits to change frames (as 100 frames count over in 1 second)

    = 9360 bits are required maximum to update all information over the period of one second

    9360 x 2 = 18,720 bits for both decks

    18,720 / 31250 * 100 = 59.9% of the MIDI bandwidth taken up.

    So to conclude, even with the maximum amount of messages being transmitted at any given time for both decks transmitting data for the LCD MIDI display, there is still almost half of the MIDI in bandwidth remaining, meaning 31,250bps standard serial MIDI should have no problem coping with the amount of data. I don't think the display actually scrolls 6 times a second (if it scrolls twice in a second the bandwidth drops to 30%) and is Traktor really going to need 40% of the bandwidth to Transmit all other MIDI message which will probably consist of a few messages to switch a few LEDs on and off periodically!
    ...dreams in binary

  10. #30
    Tech Mentor steffanko's Avatar
    Join Date
    Sep 2010
    Location
    Nis, Serbia
    Posts
    191

    Default

    So, I have no idea what you guys are doing, cuz Im a noob to electronics, but I have seen something similar in this vid. Traktor is sending song names to dns1200 display. Don't know how...

    http://www.youtube.com/watch?v=vEP3GLTrlvU

Page 3 of 6 FirstFirst 123456 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •