aboutsummaryrefslogblamecommitdiffstats
path: root/src/lib/midi/MidiScope.pas
blob: 3eb51054def2c5e552940b56ec5ded0c13264e6d (plain) (tree)





















                                                                            
                           


        







           






                                     


                                                
 
                             
 
                                                
 


                                                          



                                                     
                                                      




                              


                   

                                
                    
                               



                                    

           







                                                  
               


                                  
                                                              
                     




                           
                     

                            

    


                                                       




                                
                                                            

                                
                                                                                         


                           


                

                                
                                        
                              



                             

                               
                                                                                        
                              



                                             
    

                                                           

                               
                                                 
    

                                                             



                                    


                                                                 


                     

                                             




                               


                                  
                                  
          


      
                                                             
     






                                                                  

      
 
    
{
  Shows a large black area where midi note/controller events are shown
  just to monitor midi activity (for the MidiPlayer)

  version 1.0 first release

  for comments/bugs
  F.Bouwmans
  fbouwmans@spiditel.nl

  if you think this component is nice and you use it, sent me a short email.
  I've seen that other of my components have been downloaded a lot, but I've
  got no clue wether they are actually used.
  Don't worry because you are free to use these components
}

unit MidiScope;

interface

{$IFDEF FPC}
  {$MODE Delphi}
  {$H+} // use long strings
{$ENDIF}

uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs;

type
  TMidiScope = class(TGraphicControl)
  private
    { Private declarations }
  protected
    { Protected declarations }
    notes:       array[0..15,0..127] of integer;
    controllers: array[0..15,0..17]  of integer;
    aftertouch:  array[0..15,0..127] of integer;

    selectedChannel: integer;

    procedure PaintSlide(ch, pos, val: integer);

    procedure NoteOn(channel, note, speed: integer);
    procedure Controller(channel, number, value: integer);
    procedure AfterTch(channel, note, value: integer);

  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure MidiEvent(event, data1, data2: integer);
    procedure Paint; override;
  published
    { Published declarations }
  end;

procedure Register;

const
  BarHeight     = 16;
  BarHeightInc  = BarHeight + 2;
  BarWidth      = 3;
  BarWidthInc   = BarWidth + 1;
  HeightDiv     = 128 div BarHeight;

implementation

uses
  MidiCons;

procedure Register;
begin
  RegisterComponents('Synth', [TMidiScope]);
end;

constructor TMidiScope.Create(AOwner: TComponent);
var
 i, j: integer;
begin
  inherited Create(AOwner);
  Height := BarHeightinc * 16 + 4;
  Width :=  147 * BarWidthInc + 4 + 20;  // for channel number
  for i := 0 to 15 do
    for j := 0 to 127 do
    begin
      notes[i,j] := 0;
      aftertouch[i,j] := 0;
    end;
  for i := 0 to 17 do
    for j := 0 to 15 do
      controllers[i,j] := 0;
end;

procedure TMidiScope.PaintSlide(ch, pos, val: integer);
var
  x, y:integer;
begin
  Canvas.Brush.Color := clBlack;
  Canvas.Pen.color := clBlack;
  x := pos * BarWidthInc + 2;
  y := 2 + ch * BarHeightInc;
  Canvas.Rectangle(x, y, x + BarWidthInc, y + BarHeightInc);
  Canvas.Brush.Color := clGreen;
  Canvas.Pen.Color := clGreen;
  Canvas.Rectangle(x, y + (BarHeight - (val div HeightDiv)), x + BarWidth, y + BarHeight)
end;

procedure TMidiScope.Paint;
var
  i, j: integer;
  x: integer;
begin
  Canvas.Brush.color := clBlack;
  Canvas.Rectangle(0, 0, Width, Height);
  Canvas.Pen.Color := clGreen;
  x := 128 * BarWidthInc + 2;
  Canvas.MoveTo(x, 0);
  Canvas.LineTo(x, Height);
  x := 148 * BarWIdthInc + 2;
  canvas.Font.Color := clGreen;
  for i := 0 to 15 do
    Canvas.TextOut(x, ((i + 1) * BarHeightInc) - Canvas.font.size - 3, IntToStr(i + 1));
  canvas.Pen.color := clBlack;
  for j := 0 to 127 do
    PaintSlide(i, j, notes[i,j]);
  for j := 0 to 17 do
    PaintSlide(i, j + 129, controllers[i,j]);
end;

procedure TMidiScope.NoteOn(channel, note, speed: integer);
begin
  notes[channel,note] := speed;
  PaintSlide(channel, note, notes[channel,note]);
end;

procedure TMidiScope.AfterTch(channel, note, value: integer);
begin
  aftertouch[channel,note] := value;
end;

procedure TMidiScope.Controller(channel, number, value: integer);
var
  i: integer;
begin
  if number < 18 then
  begin
    controllers[channel,number] := value;
    PaintSlide(channel, number + 129, value);
  end
  else if number >= $7B then
  begin
    // all notes of for channel
    for i := 0 to 127 do
      if notes[channel,i] > 0 then
      begin
        notes[channel,i] := 0;
        PaintSlide(channel, i, 0);
      end;
  end;
end;

procedure TMidiScope.MidiEvent(event, data1, data2: integer);
begin
  case (event and $F0) of
    MIDI_NOTEON :        NoteOn    ((event and $F), data1, data2);
    MIDI_NOTEOFF:        NoteOn    ((event and $F), data1, 0    );
    MIDI_CONTROLCHANGE:  Controller((event and $F), data1, data2);
    MIDI_CHANAFTERTOUCH: Controller((Event and $F), 16,    data1);
    MIDI_PITCHBEND:      Controller((Event and $F), 17,    data2);
    MIDI_KEYAFTERTOUCH: ;
  end;
end;

end.