BM* format. I wrote this for myself so it may be a bit hard to understand. :) BMW is just like BMX except it doesn't include the 'WAVE' section. (HtK: With annotations from HotKey aka. Bernhard Slawik (BUZZle.de), October 2005 Some quick infos: * "asciiz" means "zero-terminated string", e.g. "Buzz" = [B][U][Z][Z][00] * And for the byte-order: getWord() = getByte() + getByte() shl 8 getDWord() = getWord() + getWord() shl 16 * Global Parameters and Track Parameters?! The difference is: Almost none :) But track parameters may be used MULTIPLE times. e.g. Jeskola Tracker keeps ONE global Parameter for "subdivision" and "Note, Wave, Volume, EffectCommand, effectParam" for EACH TRACK - you can use multiple tracks, so track-parameters must be handles separately. In addition to that: the parameter info (min, max, def, no) must only be done once for the track parameters, but the parameter STATES must be stored for each track individually. Got it? No? Then everything is fine. * Hint: Keep a Hex-Editor at your side (e.g. hhdsoft.com) ) Header: Type/Size Description ------------------------------------------------------------------------- 4 "Buzz" dword number of sections 12*31 up to 31 section dir entries (HtK: There are always 31 entries - unused entries are padded with zeros) ========================================================================= Section dir entry: Type/Size Description ------------------------------------------------------------------------- 4 four-char name of section dword offset from begin of file dword size in bytes (HtK: It is recommended to load the MACH section at first - so that you have a rough overview of the machines used in the song. You may then load the machines and compare them to the PARAM section, but you can also skip the PARAM section completely, if you're lazy ass) ========================================================================= Section 'MACH' - machines v1.2 note: machines with MIF_CONTROL_MACHINE flag should be the last machines in this section Type/Size Description ------------------------------------------------------------------------- word number of machines (first machine - always master) asciiz name byte type (0 = master, 1 = generator, 2 = effect) asciiz name of DLL if type is 1 or 2 float X coordinate in machines view [-1..1] float Y coordinate in machines view [-1..1] dword size of machine specific data (HtK: e.g. Polac's VSTi stores the DLL name of the loaded VST) x data word number of attributes (HtK: CAUTION! May turn to "-1" (integer) for "no attributes". Be aware of this - "Elendiges Sauglump...!" Greetz to tOm level :-) ) (first attribute) (HtK: Attributes suck.) asciiz key dword value (second attribute) ... (HtK: Now you may do an IF/THEN) IF Master --------------------------> word Negative volume, 0000 = full amplification word Beats per Minute byte Ticks per Beat ELSE (Generators and Effects) ------> x state of global parameters (HtK: The size can not be told exactly here: since paramTypes 0,1,2 use BYTE, paramType 3 uses WORD) <--------------------------- word number of tracks x state of track parameters for each track (HtK: The size can not be told exactly here: since paramTypes 0,1,2 use BYTE, paramType 3 uses WORD) (x state of track parameters for 2nd track - if existing) (x state of track parameters for 3rd track - if existing) ... ... (second machine) ... ========================================================================= Section 'CONN' - machine connections Type/Size Description ------------------------------------------------------------------------- word number of connections (first connection) word index of source machine word index of destination machine word amp word pan (second connection) ... ========================================================================= Section 'PATT' - patterns for each machine Type/Size Description ------------------------------------------------------------------------- (first machine) word number of patterns word number of tracks (first pattern) asciiz name word length of pattern in number of ticks (rows) x pattern data (HtK: direction of reading foreach pattern do foreach connection foreach row read connection-in data (amp and pan of connected machines - word values) foreach row read global parameter row (dynamic size - according to the parameter type used) foreach track foreach row read track row ) (HtK: look at my annotation at MACH-section for Master's parameters (word neg.VOL, word BPM, byte TPB)) (second pattern) ... (second machine) ... ========================================================================= Section 'SEQU' - pattern sequences Type/Size Description ------------------------------------------------------------------------- dword end of song dword begin of loop dword end of loop word number of sequences (first sequence) word index of machine dword number of events byte bytes used per event pos (HtK: The idea: if a song gets longer than 64k rows, 4 bytes could be used for each POS instead of 2) byte bytes used per event (2 if there are more than 112 patterns) x event list (pos, event, pos, event, pos, event...). (x = according to previus info: [bytesPerPos] [bytesPerEvent] [bytesPerPos], ....) possible events: 00 = mute, 01 = break, 02 = thru > 0x0F = Pattern: 0x10 = first pattern, 0x11 = second pattern, etc. msb=1 indicates loop (HtK: ???) (second sequence) ... ========================================================================= Section 'WAVT' - wavetable (HtK: The wavetable is the information behind each sample. It contains index in table (0x00-0xC8), volume info, loop info, ... So: EVERYTHING BUT THE SAMPLE DATA (which comes in CWAV-section) ) Type/Size Description ------------------------------------------------------------------------- word number of waves (first wave) word index asciiz full file name of the sample originally loaded, e.g. "c:\waves\blah.wav" asciiz name in wavetable float volume byte flags: bit 0: loop bit 1: don't save bit 2: floating point memory format bit 3: stereo (since 1.2) bit 4: bidirectional loop (since 1.2) bit 7: envelopes follow (since alpha 14) if flag bit 7 ---------> word number of envelopes (first envelope) word Attack time word Decay time word Sustain level word Release time byte ADSR Subdivide byte ADSR Flags: 0-1 = attack mode, 2-3 = release mode, 4 = linear decay, 5 = sustain word number of points (can be zero) (bit 15 set = envelope disabled) (first point) word x word y byte flags: bit 0 = sustain (second point) ... (second envelope) ... <----------- end of if flag bit 7 byte number of levels (first level) dword number of samples dword loop begin dword loop end dword samples per second byte root note (second level) ... (second wave) ... ========================================================================= Section 'CWAV' or 'WAVE' - wave data, check for 'CWAV' first then for 'WAVE' Type/Size Description ------------------------------------------------------------------------- word number of waves (first wave) word index of wave byte format: 0 - raw 16bit, intel byteorder 1 - proprietary compressed format (v1.2 uses this one by default) (HtK: Mark Collier has reverse-engineered a working (de-)compressor!) (HtK: Delphi/Kylix/FPC-Version done by HotKey for www.BUZZle.de) format 0: dword number of bytes in all levels (data for first level) .. (data for second level) ... (second wave) ... format 1: (HtK: Based on "3rd degree polynomial predictors" - quite complex...) ========================================================================= Section 'BLAH' - song info Type/Size Description ------------------------------------------------------------------------- dword number of characters x raw ascii text (no zero at end) ========================================================================= Section 'PARA' - parameter information for machines - added in v1.2. This section is not required for loading the song if user has right versions of all machines installed. otherwise the information here can be used to convert pattern data to the new format. (HtK: Yeah right: you can simply skip this unless you're coding a BMX fixer) Type/Size Description ------------------------------------------------------------------------- dword number of machines (first machine) asciiz name asciiz type (for example "Jeskola Tracker") dword number of global parameters dword number of track parameters (first parameter - all global first followed track-parameters) see CMachineParameter in MachineInterface.h for more information all fields except "Description" are saved byte type asciiz name int minvalue int maxvalue int novalue int flags int defvalue (second parameter) ... (second machine) ... ========================================================================= Section 'PDLG' - parameter dialog placements on screen - added in v1.2 byte flags: bit 1: dialogs visible list of positions followed by terminating zero byte: asciiz name of machine WINDOWPLACEMENT win32 window placement structure (see win32 documentation) (HtK: That is: just a few bytes for left, top, width, height) ========================================================================= Section 'MIDI' - midi controller bindings - added in v1.2 list of bindings followed by terminating zero byte: asciiz name of machine byte parameter group byte parameter track byte parameter number byte midi channel byte midi controller number ========================================================================= Section 'BVER' - buzz version information - added in v1.2 asciiz buzz version, date and time of build =========================================================================