Finally decided to release it. I hope that someone will use it and make nice 1k demos with music!

Here are the source. Asm syntax is masm.
you will need this instrument list:
http://www.hd.chalmers.se/~Saida/titan/instruments.txtCompiled version of the source:
http://www.hd.chalmers.se/~Saida/titan/mss.exeyou should add code to kick this off as a seperate thread with high priority...the music varies a lot with cpu load.
;
; 1024b Midi Sound System (mss)
;==============================================================================
; @@ Programmed by: Martin Gustafsson - saida/titan^rebels
; @@ Filename: mss.asm
; @@ Version: 3.1
; @@ Date: 2006-09-14
; @@ Web: http://saida.lava.nu
; @@ Mail: saida at lava dot nu
;
; If you use any of this code, please give me proper credits.
;
; compile syntax:
; \masm32\bin\ml /c /coff /nologo "mss.asm"
; \masm32\bin\Link /SUBSYSTEM:WINDOWS /WS:AGGRESSIVE "mss.obj" /section:.text,RWE /MERGE:.rdata=.data /MERGE:.text=.data
;==============================================================================
; HISTORY
;==============================================================================
; Version 3.1 - Optimized code size. Fixed some bugs.
; - Decided to go public with the midiSystem.
;
; Version 3.0 - Big change! Now using 1 byte per tone only!
; bit 7 = instrument (1 or 0)
; bit 6-5 = length 0 1 2 3
; bit 4-0 = tone data.
;
; Version 2.0 - Some code cleanups.
; - Optimized code size again. Tunes is now stored in another way.
; Set bit7 of toneByte to 1/0
; - Removed the data section. Exe now compiles to 1024b! \
/
; - Rearanged code to compress better with com-packers.
; - Fixed sleep bug between loops.
; - Added support for 2 different instruments!
;
; Version 1.0 - First release.
; - One instrument support.
; - two bytes per note.
;
;==============================================================================
; The 1024b Midi Sound System was used in these 1k demos:
; got balls?
; http://www.pouet.net/prod.php?which=18733
;
; rotor
; http://www.pouet.net/prod.php?which=17342
; MISC INFO
;==============================================================================
; Some information and thoughts behind the Init system:
; -----------------------------------------------------------------------------
; - First of all, let edi point to our data area, so we can use
; edi instead of big memory adresses in the code.
; - Second, take usage of the fact, that eax is 0 when the program starts.
; ok, this saves us what - 2 bytes... if you really done care about 2 bytes:
; uncomment the "xor eax, eax" line at the start...
;
; Some information and thoughts behind the Player part:
; -----------------------------------------------------------------------------
; - Ok, edi is still used as the data pointer.
; - EDI and ESI does not change when calling the external dll functions, so
; that is why I choosed ESI as a counter instead of ecx.
; Now, i dont have to push and pop the counter register all the time! \
/
; - Another thing -> A byte is copied into AL from [EDI:ESI].
; Then is the Length information is handled by BL register
; The tone data in ah is then proccessed and pushed to the stack.
; Next step is to see if the bit7 of AH is 1 or 0.
; If bit7=0 then, instrument 0 is set. Else the instrument 1 is used.
; The insrtument data is pushed to stack, and since we allready pushed the
; tone data information to the stack, a double call to midi is done.
; If a note byte would be 0, the song pattern loops.
;
; Limits etc
; -----------------------------------------------------------------------------
; The player does not play well if you have a high cpu load. This could be
; fixed (ofcourse it will cost you a lot of bytes) - by using GetTickCount
; instead of Sleep.
;
; Dont forget!
; -----------------------------------------------------------------------------
; We are writing data to the code segment!
; If the code segment isnt set to be RWE - the program will not work!
; (RWE = Readable, Writable, Executable)
; If you use the compile lines at the top of this document, you should be fine.
;
; To get your final code smaller:
; -----------------------------------------------------------------------------
; rewrite the code so you set the instrument with the MOV instruction,
; rather than storing it in the fake-data-section, and then wasting bytes on
; getting that data.
; To do this: change the following lines.
; ORIGINAL LINE:
; mov bx, word ptr [edi-16+(2*ebx)]
; CHANGE TO:
; mov bx, word ptr [edi-8+(2*ebx)]
;
;
; ORIGINAL LINES:
; mov eax, [edi-8] ; use instrument 0
; js @@bss_INSTRUMENT_DONE ; Jump if bit7 is 1.
; mov eax, [edi-4] ; else, use instrument 1
; CHANGE TO:
; mov eax, #dd_instrument_0 ; use instrument 0
; js @@bss_INSTRUMENT_DONE ; Jump if bit7 is 1.
; mov eax, #dd_instrument_1 ; else, use instrument 1
;
; (and dont forget to remove the stuff in the fakedata section):
; @@bss_Instruments: REMOVE
; dd 12594625 ; instrument index 0 REMOVE
; dd 12594625 ; instrument index 1 REMOVE
;
;
; if you know you are only using instrument 0, you can remove this line to:
; and ebx, 00000011b
;==============================================================================
.486
.MODEL flat, stdcall
includelib \masm32\lib\kernel32.lib ; Sleep call
includelib \masm32\lib\winmm.lib ; midi calls
Sleep PROTO :DWORD
midiOutOpen PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
midiOutShortMsg PROTO :DWORD,:DWORD
option casemap:none
.code
ProgramEntryPoint:
;------------------------------------------------------------------------------
; Initiate sound system
;------------------------------------------------------------------------------
;xor eax, eax ; uncomment this to loose 2 bytes 
; eax should be zero at start.
; Setup esi/edi, so it points at data section
;==========================================================================
mov edi, offset bss_hMidi ; use mov instead of lea. (smaller)
; Open midi device
;==========================================================================
push eax ; PUSH 0
push eax ; PUSH 0
push eax ; PUSH 0
dec eax
push eax ; PUSH 0xFFFFFFFF (MIDI_MAPPER)
push edi ; ( EDI is offset to hMidi )
CALL midiOutOpen ; call midiOutOpen
;------------------------------------------------------------------------------
; Playing part of sound system
;------------------------------------------------------------------------------
; Reset counter ESI that helps EDI to point at the music data
;==========================================================================
; xor eax, eax ; REMOVED! -> EAX should be zero if midiOutOpen was ok!
; if you are conserned by compatible/non-crashing demos. uncomment the
; "xor eax, eax" above...
@@bss_RESET_SONG:
mov esi, edi ; set esi to point at fake data section
LODSD ; Same as "add esi,4". (destoys eax)
; esi is now = offset "tone data"
; Get new tone data from our array
;==========================================================================
@@bss_LOAD_NEXT:
LODSB ; get BYTE from ES:ESI (the array)
xchg ah, al
xor ebx,ebx ; set to zero before.
add bl, ah ; if ah is zero, that means that we
; want to loop the song.
jz @@bss_RESET_SONG ; are we done? -> loop and play again.
; <get tone length in ms into ebx.>
; the data is in bl: ?TTx xxxx. after shr, its xxxx x?TT
shr bl, 5
; remove additional ? data from byte (instrument could be 1)
and ebx, 00000011b
; extract millisecond sleep from length-array.
mov bx, word ptr [edi-16+(2*ebx)]
; Setup eax for a call to midiOutShortMsg (to play a tone)
;==========================================================================
; here is the place where you can offset the midiNotes!
; (you can only use 0-31 midi notes)
;-----------------------
; add eax, SomeOffset
;-- OR:
; sub eax, SomeOffset
;-----------------------
mov ecx, eax ; save toneData to ECX
; mask tone in eax with magic numbers..
and ax, 0001111100000000b
or eax, 00000000011111110010000010010001b
push eax ; push tone to play. ##1 >---|
push dword ptr [edi] ; push handle to hMidi ##1 >---|
; |
; Was instrument should we use? 1 or 0? |
;======================================================================== |
xchg eax, ecx ; Restore toneData to eax. |
sahf ; pushes AH to flags.(SF=Bit7 in ah) |
mov eax, [edi-8] ; use instrument 0 |
js @@bss_INSTRUMENT_DONE ; Jump if bit7 is 1. |
mov eax, [edi-4] ; else, use instrument 1 |
; |
; Tell MIDI to change instrument for us. |
;======================================================================== |
@@bss_INSTRUMENT_DONE: ; |
push eax ; push the instrument ##2 >--| |
push dword ptr [edi] ; push handle to hMidi ##2 >--| |
call midiOutShortMsg ; <-------------------------------/ |
call midiOutShortMsg ; <-----------------------------------/
; Wait for the tone to play. Tone length is stored in BL
;==========================================================================
push ebx ; ebx = sleep time
call Sleep ; wait for tone to finish
jmp @@bss_LOAD_NEXT ; Repeat the procedure
; END OF .CODE SECTION
;******************************************************************************
; size measure tool code (outputs size when compiling):
;------------------------------------------------------------------------------
codelen TEXTEQU %($-ProgramEntryPoint)
% echo <code_size> codelen bytes
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Faked .DATA section (makes exe smaller ...sometimes...)
; you can move this stuff to data section... but dont EVER move the data around
;------------------------------------------------------------------------------
; music is stored like this (one byte per note):
; ILLT TTTT
; bits 7654 3210
; where:
; I = Instrument index
; L = Length-of-note-index
; T = midi note
;
; SET THE BYTE TO -ZERO- TO LOOP FROM THE START OF THE SONG.
; lengths are in milliseconds.
@@bss_lengths:
dw 240 ; lengh index 0.
dw 1 ; lengh index 1
dw 0 ; lengh index 2
dw 0 ; lengh index 3
@@bss_Instruments:
dd 12594625 ; instrument index 0
dd 12594625 ; instrument index 1
@@bss_dataStart:
bss_hMidi dd ? ; handle to midi out.
; the song starts here (some test music i did):
;i
db 10000101b;
db 10101001b;play fast (use length index 1)
db 10001100b
;a
db 10000000b
db 10101001b;play fast
db 10001100b
;i
db 10000101b
db 10101001b;play fast
db 10001100b
;a
db 10000000b
db 10101001b;play fast
db 10001100b
;i
db 10000101b
db 10101001b;play fast
db 10001100b
;a
db 10000000b
db 10101001b;play fast
db 10001100b
db 10000101b
; bam bam bam
db 10000000b
db 10000010b
db 10000100b
db 00000000b ;loop from first note.
end ProgramEntryPoint