realbasic-nug
[Top] [All Lists]

Re: Porting MIDI variable-length quantity C code to REALbasic

To: REALbasic NUG <realbasic-nug at lists dot realsoftware dot com>
Subject: Re: Porting MIDI variable-length quantity C code to REALbasic
From: Mark Nutter <manutter51 at yahoo dot com>
Date: Sun, 30 Jan 2005 11:36:22 -0800 (PST)
Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys
Delivered-to: realbasic-nug at lists dot realsoftware dot com
Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; b=2aEEVX4vLaY7xTboLny1z7d28OYFQ3QvPi4fPyrbYdExttzawljsCVNIN5QZ54/E9Sat2OgN2tnrjsnBdaMbNDPc8+w50EAlEM6/CXQnlfwUbi9rmDvsnRN5cTaEd43tE3MzNwHaLdLfILsWD756Q9jA9bV3XRofm+FKi3DRVGo= ;
--- Philip Regan <pregan at mac dot com> wrote:

> Howdy--
>  
>  
>  I'm writing an application that will write Standard
> MIDI files as part
>  of its feature set. While the MIDI spec overall is
> pretty
>  straightforward, I'm completely and totally stuck
> on one part of it,
>  and that is variable-length quantities.

Basically, what you are doing is mapping 8-bit data
into 7 bits plus a flag bit that tells whether or not
there's more of this number in the next byte.  Looks
like assembly language translated into C--ah, the good
old days :)

This should be a functional RB equivalent.  I don't
have a full-blown MIDI framework to test it out in,
but it *should* be reasonably bug free (if not quite
as robust as it should be, in terms of error
checking).  Hopefully this will prove a bit more
readable to you.  You just have to get your mind
wrapped around the idea of data as being a stream of
bits that can be chopped up into arbitrary sizes.

Sub WriteVarLen(inData As Integer, outStr As
BinaryStream)
  Dim mb As MemoryBlock
  ' four bytes plus one extra, just in case
  mb = new MemoryBlock(5) 
  Dim i As Integer
  i = 0
  ' Convert data from 8 bits to 7 bits plus flag bit
  while (inData > 0)
    ' Get lowest 7 bits of current data
    mb.Byte(i) = Bitwise.BitAnd(inData, &h7f)
    ' slide all the bits of inData 7 bits to the right
    inData = Bitwise.ShiftRight(inData, 7)
    if i > 0 then ' not least significant byte?
      ' set a flag on the byte
      mb.Byte(i) = Bitwise.BitOr(mb.Byte(i), &h80)
    end if
    i = i + 1 ' count up for next byte
  wend
  ' mapping done, now output converted data
  while i > 0 ' i is number-of-bytes plus 1
      ' output most significant bytes 
      ' downto least significant
    i = i - 1 
    outStr.WriteByte mb.Byte(i)
  wend
End Sub

Function ReadVarLen(inStream As BinaryStream) As
Integer
  Dim c As Integer
  Dim result As Integer
  result = 0 ' initialize result
  c = InStream.ReadByte
  ' while flag bit is set
  while Bitwise.BitAnd(c, &h80) > 0 
    ' make room for next 7 bits
    result = Bitwise.ShiftLeft(result, 7)
    ' "or" in the next 7 bits of data
    result = Bitwise.BitOr(result, Bitwise.BitAnd(c,
&h7f))
    ' get next byte of data
    c = InStream.ReadByte 
  wend
  ' get last byte (the one without the flag bit set)
  ' make room for next 7 bits
  result = Bitwise.ShiftLeft(result, 7) 
  ' "or" in the last 7 bits
  result = Bitwise.BitOr(result, Bitwise.BitAnd(c,
&h7f))
  return result
End Function



__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

<Prev in Thread] Current Thread [Next in Thread>