Midi player (not done) :3

2

Sylveon 2024-11-29 01:43 (Edited)

It’s not done :3
But it will help if you guys improve it :3


SP4CEBAR 2024-11-29 08:41 (Edited)

Since you asked for improvements, you may be interested in the midi API, here you can also scrape MIDI data into arrays. Also, the code has been refactored so it should be pretty readable by now.


SP4CEBAR 2024-11-29 08:50

I'm impressed that you managed to get recognizable audio with so few lines!


SP4CEBAR 2024-11-29 09:21 (Edited)

I noticed that your Midi header reading might not read correctly

FORMAT_TYPE=PEEK($A000+(4))+PEEK($A000+(5)) MOD 3

TRACK_NUM=PEEK($A000+(6))+PEEK($A000+(7)) MOD 3

TICK_SPEED=PEEK($A000+(8))+PEEK($A000+(9)) MOD 3

According to this source

It looks like all indices in your program need to have four added to them


I'm not sure what the "MOD 3" is meant to do. If you read two bytes in NX using two PEEK commands, you have to multiply one of them by 256, which is 2^8 (because a byte has 8 bits), which is $100. After this, you can add the two values together. Which of the two bytes should be multiplied by 256 is called endianness. According to this source MIDI files are big-endian, meaning that the PEEK with the higher index should be multiplied by 256.

So reading two MIDI bytes should look something like this:

SUB PEEK_2_BIG_ENDIAN( RETURNS, ADDRESS )
  RETURNS = PEEK( ADDRESS ) + PEEK( ADDRESS +1 ) *$100
END SUB

the float variables NX uses cannot contain the full information of four bytes (without mad tricks). However, the 4-byte chunk-size parameters in MIDI files should not be that big, so we could write

SUB PEEK_4_BIG_ENDIAN( RETURNS, ADDRESS )
  'WARNING LOSES PRECISION ON BIG NUMBERS
  RETURNS = 0
  EXPONENT = 1
  FOR I=0 TO 3
    ADD RETURNS, PEEK( ADDRESS +I ) *EXPONENT
    EXPONENT = EXPONENT *$100
  NEXT I
END SUB


SP4CEBAR 2024-11-29 09:28 (Edited)

You can use the subprogram above to improve your 4-byte reading (it lacks exponents)

LENGHS(TRK)=PEEK($A000+(10))+PEEK($A000+(11))+PEEK($A000+(12))+PEEK($A000+(13))

Also, each index needs to have four added to them


SP4CEBAR 2024-11-29 09:30

I assume the squaring of the "lengths" was done because its value was smaller than expected

FOR INDEX=0 TO LENGHS(TRK)*LENGHS(TRK)


SP4CEBAR 2024-11-29 09:45 (Edited)

Given the MIDI processing from your code I can spot a few issues

IF PEEK($A000+(3*INDEX+14))=144 THEN 
VOLUME 0,INT(PEEK($A000+(3*INDEX+16))) MOD 16,3
PLAY 0,INT(PEEK($A000+(3*INDEX+15))) MOD 97
END IF
'IF PEEK($A000+(3*INDEX+14))=128 THEN STOP 0

MIDI track events have a variable length, starting with a variable length quantity then a single byte status, and then several bytes depending on the status. And here too, the indexes need to have 4 added to them.

This is the source I used most for making MIDI tools.


SP4CEBAR 2024-11-29 09:53 (Edited)

Once your MIDI player works for this file, and you were to look for other files to test, you will run into running status, these lazy MIDI files require some additional code


Sylveon 2024-11-29 14:40

Thank you for helping SPACE4BAR :3

I try what you said :3


SP4CEBAR 2024-11-29 15:53

Good luck!


Sylveon 2024-11-29 16:45

:3


Log in to reply.