Monthly Archives: August 2018

Lazarus / FreePascal problem on 64 bit machines.

I ported some open source MIDI handler code from Delphi to Lazarus. This was originally working on a 32 bit Windows machine but when I compiled and ran it on my Windows 64 bit machine I got a Segment Violation error when opening the input MIDI port.

I tracked the error down to the system unit called “mmSystem”. This defines interfaces to the windows multimedia DLL –  “winmm.dll”. The offending interface was a function called “midiInOpen”.

The function has a parameter for the address of a callback function. The current “mmSystem” unit defines this as 32 bit and not 64 bit as it should be if the code is compiled for a 64 bit machine. The unit needs to be upgraded to handle both cases.

In the mean time, I hacked my (open source) MIDI driver code to handle both cases:

I used the compiler conditional expressions to determine when I am compiling a 32bit or 64 bit system.

I have defined an alternative interface for midiInOpen call midiInOpenX which has a 64bit parameter (int64) for the callback address.

Seems to do the trick…

 

// X64 hack
{$IFDEF WIN64}
Function midiInOpenX(x1: LPHMIDIIN; x2: UINT; x3: int64; x4: DWORD; x5: DWORD): MMRESULT;stdcall; external 'winmm.dll' name 'midiInOpen';
{$ENDIF}

procedure TMidiInput.Open(const aDeviceIndex: integer);
var
lHandle: THandle;
lResult: MMResult;

begin
inherited;
if assigned( fDevices.Objects[ aDeviceIndex ] ) then Exit;

{$IFDEF WIN64}
lResult := midiInOpenX( @lHandle, aDeviceIndex, int64(@midiCallback), aDeviceIndex, CALLBACK_FUNCTION );
{$ENDIF}

{$IFDEF WIN32}
lResult := midiInOpen( @lHandle, aDeviceIndex, longword(@midiCallback), aDeviceIndex, CALLBACK_FUNCTION );
{$ENDIF}

if lResult <> MMSYSERR_NOERROR then
raise exception.Create( GetLastErrorText );
midiInStart(lHandle);

fDevices.Objects[ aDeviceIndex ] := TObject( lHandle );
end;

MIDI gotchas !!

When I was writing code to handle the MIDI port it behaved well with my Yamaha P120 electronic Piano but behaved badly with my Yamaha PSR 6000. When I played keys on the PSR 6000, some notes would not play and others would not end correctly and kept sustaining.

I was baffled by this and saw that bytes seemed to be dropping out when viewing a raw dump of the port on the Raspberry PI. I was convinced there was a hardware problem, or a bug in the PI operating system.

I could play single notes and they would work but if I played a chord or two notes together I would get a problem. I then analysed the dump again and it struck me that there was a pattern. When a key is pressed, you normally get three bytes, the control byte $90, the pitch byte and the velocity byte. When two notes are pressed on the PSR 6000, I expected to get six bytes, two groups of three, but I got the control byte $90 for key down, the pitch byte for the first note, the velocity byte for the first note, the pitch byte for the second note and the velocity byte for the second note. I got 5 bytes instead of 6.

Its simple, multiple key presses are grouped together using a single MIDI control byte ! I altered the receiver code to keep accepting two byte segments until a new control byte is received. This solved the problem and the code works with both keyboards.

There is a subtle difference between theYamaha P120 midi firmware and the PSR 6000 firmware in this respect.

Gotcha #2 was that Yamaha do not use the MIDI spec for note off. (i.e. a control byte of $80). They use an alternative by using a key on but with a zero velocity. Presumably this helps when grouping mutiple key on/off events together.

Anyhow my code can handle both situations and always outputs 3 byte midi commands irrespective of what is received to keep things simple.

Gotcha #3 was that was a continuous flow of MIDI sense bytes of $F8 and $FE from both keyboards. These are simply filtered out.

 

 

AK47M project part 9 (PCB completed & updates)

I have received a set of PCBs and have built the first AK47M prototype. Everything seems to be working and I am currently working on an enclosure for it.

This shows the PCB populated with components:-

 

The next photo shows the addition of the two synthesizer modules:-

 

The final photo shows the addition of the PICs, the Raspberry PI Zero W and the wiring to additional components. It is ready to be put in the enclosure:-

 

There are a few tweaks required for the PIC firmware. I have done a lot more changes to the LIVE software running on the PI.

The “Band in the Bag ™” first cut of software is ready. I can create a chord sheet using an interactive editor using either the QWERTY keyboard or the MIDI keyboard. It handles repeats and variation selections. When a BIAB score is created and attached to a performance, it will play when the zero key is pressed. There is a tap intro for one bar before the sequence is played. The sequence can play to completion or repeat multiple number of times. This will be great to busk along with my Sax.

The LIVE software is now packaged as two versions, one for the Windows PC that interfaces to any attached MIDI device and one for the Raspberry PI that interfaces to the AK47M.

The hardware is modular so that certain functions can be added or dropped depending on requirement.

i.e.

  1. Either one or both Synth modules can be dropped and an external MIDI device used instead.
  2. The LCD display can be dropped and a HDMI device or Android tablet can be used instead.
  3. The Solo Parts keyboard function can be dropped.
  4. The Fluid softsynth can be installed on the PI to do drums / bass arrangements only.
  5. The PCB can be connected to a keypad with a single PIC and used as the self-powered MIDI-Mate for connecting to a BK7M.

I am now using PIC 16F628A chips that are cheaper and have a more accurate internal oscillator. So I can also drop the resonators.

I am now working on the display of sheet music and lyric sheets. The intention is to synchronise the selection of a music/lyric sheet with the performance selection. I am on the look out for a portable HDMI monitor that I can hook up to the PI.