Jump to content

Anybody know anything about midi signal specifications?


SenPi
 Share

Recommended Posts

Ok, well I mentioned in another thread that I was essentially making a synth out of an FPGA board. Now, I have a midi controller im going to use for crontrolling this beast (Axiom-25). Now, Ive spliced a midi cord in to a serial cord to send data to the FPGA, and I am definitely getting the bits, but the timing is what is killing me.

From what I have read, midi will send 1 start bit, 8 data bits, and 1 stop bit, all within 320 micro seconds (1000 milli = 1 second, 1000 micro = 1 milli), and its kind of a bitch to time properly.

So far, I have been getting constant results, but the bytes im getting dont quite make sense with the midi signal data ive read (like It doesnt look like im getting the proper signals.. when I hit a note I seem to be getting the tune up signal or something).

So yeah, just wondering if anybody has any sort of info or knows where I can get infor on this stuff. I would really appreciate it. Thanks.

Link to comment
Share on other sites

Ok, well I mentioned in another thread that I was essentially making a synth out of an FPGA board.

i've actually done that for a class project. i found this MIDI spec:

http://www.ibiblio.org/emusic-l/info-docs-FAQs/MIDI-doc/

and of course an easy way to find out whats going on is to press a button on your controller and look at the signal coming out of it on the scope

Link to comment
Share on other sites

scope?

Also have found that site. The bit streams I was getting (assuming I was capturing them properly) didnt seem to properly match what I was pressing on the keyboard. I might have to work on the timings a bit more perhaps.

btw Im using a Cyclone II http://rocky.digikey.com/weblib/Altera/Web%20photos/mfgDK-CYCII-2C20Nboard.jpg, Also I am doing this for a class, so I am not allowed to use ANY libraries or anything at all. Im coding all the drivers and stuff from scratch.

EDIT: hmm after reading a bit more about my axiom, I found out that I was on a different preset. Preset 1 is General MIDI, and I was on a preset used for reason, so those bit streams probably mean different stuff in the context of reason :D. Im gonna try with preset 1 and see if I get proper things.

Edit2:... omg so it turns out the data the midi controller sends, is opposite. 1 = off, and 0 = on. I thought it was the other way (looks like I didnt read carefully enough).

This is awesome, Im finally getting the bytes im expecing. Thanks for that site also :D

Link to comment
Share on other sites

short answer... yes.

Different hardware requires a different way to code I think.

Anyways, I posted a pic of what hardware I was using. It is a Field Programmable Gate Array (FPGA). The way I am progeamming for it right now is with a language called Verilog.

I could show you what I have going so far. If you have any questions about the code just ask.

NOTE: This code is dirty as hell. Since im just messing around so far just trying to figure stuff out, I havent taken the time to clean the code or anything.


module Drivers(SW,KEY,LEDR,LEDG,UART_RXD,CLOCK_27,HEX0,HEX1,SRAM_ADDR,SRAM_DQ,SRAM_WE_N,SRAM_OE_N,SRAM_CE_N);
input [9:0] SW; //Switches
input [3:0] KEY; //Keys
input [1:0] CLOCK_27; //27 Mhz Clock
input UART_RXD; //Serial Input
output [9:0] LEDR; //Red LED's
output [7:0] LEDG; //Green LED's
output [6:0] HEX0; //Seven Segment Display 0
output [6:0] HEX1; //Seven Segment Display 1
output [17:0] SRAM_ADDR; //SRAM Address
inout [15:0] SRAM_DQ; //SRAM Data
output SRAM_WE_N; //SRAM Write Enable
output SRAM_OE_N; //SRAM Output Enable
output SRAM_CE_N; //SRAM Chip Enable

assign LEDG[7] = UART_RXD; //Every time UART_RXD (i.e. midi) sends a bit, light the 7th green LED

// sramStuff ss(SRAM_ADDR,SRAM_DQ,SRAM_WE_N,SRAM_OE_N,SRAM_CE_N,~KEY[1:0],LEDG[7:0]);


getMidi gM(UART_RXD,CLOCK_27[1],LEDR[9:0],HEX0, HEX1);

endmodule

//module sramStuff (Addr, Data, WriteEnable, OutputEnable, ChipEnable, Keys, LED);
//endmodule

module getMidi(MidiIn,Clock,RedLED,Hex0,Hex1);
input MidiIn;
input Clock;
output [9:0] RedLED;
output [6:0] Hex0; //Seven Segment Display 0
output [6:0] Hex1; //Seven Segment Display 1

wire newClock;

//Anything with reg means Register. Just think of it like an int or something.
reg cool;
initial cool = 0;
reg notCool;
initial notCool = 0;

reg [32:0] counter;
initial counter = 0;

reg [7:0] data;
initial data = 0;

clocker c(Clock,newClock); //Start the clock
changeSSD a(data[3:0],Hex0); //Set SSD 0 to the rightmost 4 bits of data
changeSSD b(data[7:4],Hex1); //Set SSD 1 to the leftmost 4 bits of data

assign RedLED = data; //Make the Red LED's the same as data (if data = 1, led0 is on, if data = 2, led 1 is on, if data = 4 led 2 is on, etc)

always @(posedge newClock) //Whenever newClock becomes positive, do this...
begin
if(cool == 1) //If we are reading in midi bits...
begin
data[counter] = ~MidiIn; //Set the proper bit in data to the NOT of the midi bit coming in.
counter = counter + 1; //Increment counter

if(counter == 9) //If we are at the 9th bit, just stop getting in bits
begin
notCool = notCool + 1;
cool = 0;
end
end
else //if we are not getting bits yet
begin
if(MidiIn == 1) //Check if the midi controller sent the Start Bit
begin
if(notCool == 0) //If we havent stopped, set cool to 1
begin
cool = 1; //This means we will start to grab the bits
end
end
end
end

endmodule

module clocker(inclock, outclock);
input inclock;
output outclock;

reg [32:0] counter;
reg tick;

initial counter = 160;
assign outclock = tick;

//Basically we want tick to = 1 every 32 micro seconds.

always @(posedge inclock) //Everytime the 27 MHz clock fires do this...
begin
counter = counter + 1;

//Just ignore this math stuff, Basically we are making tick = 1 every 32 micro seconds.
if(counter == 1024)
begin
tick = 1;
counter = 160;
end

if(counter == 592)
begin
tick = 0;
end
end
endmodule

//This method just takes in a 4 bit value and sets the proper bits for the seven segment displays
module changeSSD(value,SSD);
input [3:0] value;
output [6:0] SSD;
reg [6:0] SSD;

always @(value)
case(value)
0: SSD = 7'b1000000;
1: SSD = 7'b1111001;
2: SSD = 7'b0100100;
3: SSD = 7'b0110000;
4: SSD = 7'b0011001;
5: SSD = 7'b0010010;
6: SSD = 7'b0000010;
7: SSD = 7'b1111000;
8: SSD = 7'b0000000;
9: SSD = 7'b0010000;
10:SSD = 7'b0001000;
11:SSD = 7'b0000011;
12:SSD = 7'b1000110;
13:SSD = 7'b0100001;
14:SSD = 7'b0000110;
15:SSD = 7'b0001110;
endcase
endmodule

Ok so I'll kind of break this down for you.

Basically I have a 27 MHz clock running. Midi data sends 1 bit every 32 micro seconds. So when midi isnt sending anything its just zero.

So basically every 32 micro seconds I am checking to see if my midi controller has sent the midi start bit (basically it sends a 1 first to let you now that it will now start to send data.

So midi will send a status byte (telling you what to do, i.e. Note on, Note Off, etc), then depending on the status byte it will send one or two more bytes.

The code above is basically just reading in the first byte and storing it and displaying it on the LED's and as Hex on the Seven Segment Displays.

And thats really all this code is doing :P.. seems like alot of work for only this.. :P.

Note, it took me like 24 hours so far of working on this to figure what I know so far out. This is from knowing NOTHING about verilog or driver programming, or how midi sends stuff.

Link to comment
Share on other sites

Man that sounds freaking awesome. I can't wait until I'm in the part of my Real-Time class where we're doing that stuff (right now it's just modeling state transition diagrams (i.e. finite state automata), but eventually we'll be synthesizing sounds).

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...