ÄÄÄÄÄ Velvet Studio. AMS Format v2.2 ÄÄÄÄÄÄ Advanced Module System Offs Byte(s).Desc [Header] 0 7 Header: "AMShdr",1ah 7 1 Length of ModName (max 30 bytes) 8 x ModName ? 2 Version of format (Hi = MainVer, Low = SubVer e.g. 0202 = 2.2) +2 1 Nr of Instruments (0-255) +3 2 Nr of Patterns (1-1024) +5 2 Nr of Positions (1-65535) +7 2 Initial BPM (High byte=Integer part, Low byte=Fraction) +9 1 Initial Speed +10.1.Default Channels (1-32) +11.1.Default Commands (1-7) +12.1.Default.Rows (0-255) +13 2 Flags:uuuuuuuumfsuuuuu ³³³³³³³³³³³ÀÁÁÁÁÄ Unused ³³³³³³³³³³ÀÄÄÄÄÄÄ.1=Stereo,0=Mono ³³³³³³³³³ÀÄÄÄÄÄÄÄ Use Linear freq table. ³³³³³³³³ÀÄÄÄÄÄÄÄÄ MIDI channels are used in tune. .. ÀÁÁÁÁÁÁÁÄÄÄÄÄÄÄÄÄ Unused [Instrument] 1 Length of InstrumentName (max 30 bytes) x Instrument name 1 Number of samples in instrument (0-16) (if 0, skip this inst.) 120 Inst number for all notes 1 Volume Env. Speed 1 Volume sustain point 1 Volume loop start point 1 Volume loop end point 1 Number of volume points (0-63) x*3 Volume envelope info. uuuuuttx xxxxxxxx yyyyyyyy ³³³³³³³³ ³³³³³³³³ ÀÁÁÁÁÁÁÁÄ Volume (0-7f) ³³³³³³³ÀÄÁÁÁÁÁÁÁÁÄÄÄÄÄÄÄÄÄÄ Delta X ³³³³³ÀÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Curve (0=Line,1=sine 1, 2=sine 2) ÀÁÁÁÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Reserved for future use. 1 Panning Env. Speed 1 Panning sustain point 1 Panning loop start point 1 Panning loop end point 1 Number of panning points (0-63) x*3 Points for panning envelope uuuuuttx xxxxxxxx yyyyyyyy ³³³³³³³³ ³³³³³³³³ ÀÁÁÁÁÁÁÁÄ Pan value (0-ff) ³³³³³³³ÀÄÁÁÁÁÁÁÁÁÄÄÄÄÄÄÄÄÄÄ Delta X ³³³³³ÀÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Curve (0=Line,1=sine 1, 2=sine 2) ÀÁÁÁÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Reserved for future use. 1 Vibrato Env. Speed 1 Vibrato sustain point 1 Vibrato loop start point 1 Vibrato loop end point 1 Number of vibrato points (0-63) x*3 Points for vibrato envelope uuuuuttx xxxxxxxx yyyyyyyy ³³³³³³³³ ³³³³³³³³ ÀÁÁÁÁÁÁÁÄ Vibrato depth (0-ff) ³³³³³³³ÀÄÁÁÁÁÁÁÁÁÄÄÄÄÄÄÄÄÄÄ Delta X ³³³³³ÀÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Curve (0=Line,1=sine 1, 2=sine 2) ÀÁÁÁÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Reserved for future use. 1 Shadow Instrument. If non-zero, the value=the shadowed inst. 2 Vib.Amplify+Volume fadeout fedcba9876543210 ³³³³ÀÁÁÁÁÁÁÁÁÁÁÁ Volume Fadeout. ³³ÀÁÄÄÄÄÄÄÄÄÄÄÄÄ Vibrato Amplify ÀÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Reserved 2 Envelope flags: fedcba9876543210 ³³³³³³³³³³³³³³³À Volume :Loop on ³³³³³³³³³³³³³³ÀÄ Volume :Sustain on ³³³³³³³³³³³³³ÀÄÄ Volume :Envelope on ³³³³³³³³³³³³ÀÄÄÄ Panning:Loop on ³³³³³³³³³³³ÀÄÄÄÄ Panning:Sustain on ³³³³³³³³³³ÀÄÄÄÄÄ Panning:Envelope on ³³³³³³³³³ÀÄÄÄÄÄÄ Vibrato:Loop on ³³³³³³³³ÀÄÄÄÄÄÄÄ Vibrato:Sustain on ³³³³³³³ÀÄÄÄÄÄÄÄÄ Vibrato:Envelope on ³³³³³³ÀÄÄÄÄÄÄÄÄÄ Volume :Break Loop ³³³³³ÀÄÄÄÄÄÄÄÄÄÄ Panning:Break Loop ³³³³ÀÄÄÄÄÄÄÄÄÄÄÄ Vibrato:Break Loop ÀÁÁÁÄÄÄÄÄÄÄÄÄÄÄÄ Reserved [Sample] (repeated for each sample in the Instrument) 1 Length of SampName (max 22 bytes) x SampName 4 Length Of Sample (if 0, skip this sample.) .4.Repeat Start for sample .4.Repeat End for sample 2 Sampled rate (the rate the sample is sampled in) .1.Hi Nibble=PanPosition, Lo Nibble=FineTuneValue 2 SampleRate for C-4 (normally 8363Hz) 1 Relative note (signed byte) 1 Volume (0-127) 1 Info Byte 76543210 ³³³³³³ÀÁÄ Reserved ³³³³³ÀÄÄÄ 16 bit sample ³³³³ÀÄÄÄÄ Looped sample ³³³ÀÄÄÄÄÄ PingPong loop ³³ÀÄÄÄÄÄÄ Reserved ³ÀÄÄÄÄÄÄÄ Direction (1=Reversed) ÀÄÄÄÄÄÄÄÄ Reserved Data for rest of Instruments are exactly the same! [Text] 1 Length of Composer name (max 30 bytes) x Composer Name Ú>1 Length of ChannelName (max 11 bytes) ÀÄx ChannelName 4 Length of Description (packed, inclusive header) 4 Length of Description (unpacked) 1 Version of packroutine (currently 01h) 1 PreProcessing type (currently none) 1 Packing method (Currently RLE with #255 as packbyte) x Description of Module The Number of ChannelNames are always 32. [PatternOrder] .x.PatternNr. Holds number (0-65535) to tell the tracker what pattern to play at that position (x=Nr of Positions) [PatternData] .4.PatternSize (packed) 1 PatternLength-1 (0-255) 1 cccsssss c = Nr of Commands used in pattern s = Nr of Channels-1 used in pattern (0-31) 1 Length of PatternName (max 10 bytes) x PatternName x PatternData fp0aaaaa ennnnnnn iiiiiiii [rgcccccc bbbbbbbb...] ..Legend: f 1=Last data chunk on the row. p 0=Read Note+InstNr 1=Don't Read Note+Instnr a Channel (0-31) e 1=Read one command n Note. 2-121 (C-0 to B-9), 1=Key off note. i InstrumentNr (0-255) r 1=Read one more command g 1=Low 6 bits are volume/2 c Command-nr b Command-byte If first byte = -1 then this row is empty ..If g is set, the command only consist of that byte and ..the low 6 bits are assumed to be a volume command. You ..have to multiply the volume by 2 to get the proper value (Volume will only be stored this way if it's even) [Samples] All samples stored after eachother, packed with a special packing method not described here since we're so lazy! You've got a routine that does the unpacking instead. (You can also save the samples unpacked, and it that case they are in twos complement form.) ** MIDI not yet supported. If MIDI Bit=0 then skip this section ** [MIDI Section] 4 MIDI Section Size ÄÄÄÄÄ Velvet Studio. AIS Format v1.0 ÄÄÄÄÄÄ Advanced Instrument System The only that differs the AIS format from the Instrument used in the AMS is the following header before the other info: Offset bytes Desc 0 7 Header: "AIShdr",1ah 7 1 Type: 0aah=new version, <1fh=old version (Only new versions should exist, so don't bother with this flag) 8 2 Version of format (Hi = MainVer, Low = SubVer e.g. 0100 = 1.0) The actual sampledata is stored right after the Instrument data. ÄÄÄÄÄ Velvet Studio ASE Format v1.0 ÄÄÄÄÄÄ Advanced Sample System Offset Bytes Desc 0.7 Header: "ASEhdr",1ah 7.2 Version of format (Hi = MainVer, Low = SubVer e.g. 0100 = 1.0) 9.1.Length of SampName (max 22 bytes) 10.x.SampName .4.Length Of Sample .4.Repeat Start for sample .4.Repeat End for sample .2.Sampled rate (the rate the sample is sampled in) .1.Hi Nibble=PanPosition, Lo Nibble=FineTuneValue .2.SampleRate for C-4 (normally 8363Hz) .1.Relative note (signed byte) .1.Volume (0-127) .1.Info Byte 76543210 ³³³³³³ÀÁÄ Reserved ³³³³³ÀÄÄÄ 16 bit sample ³³³³ÀÄÄÄÄ Looped sample ³³³ÀÄÄÄÄÄ PingPong loop ³³ÀÄÄÄÄÄÄ Reserved ³ÀÄÄÄÄÄÄÄ Direction (1=Reversed) ÀÄÄÄÄÄÄÄÄ Reserved .x.Sample data. Maybe packed. ÄÄÄÄ== Velvet Studio Misc Info ==ÄÄÄÄ * The BPM Fraction value is multiplied with 26 to be able to do some optimizations. (9*26÷255) Values can range from 0*26 to 9*26. * The Default Channels/Command/Rows can be ignored since they are only used internally in VS. * If a Shadow sample is encountered, DON'T read any sample data for that sample, instead use the same sample data as it's shadowed to. * Each pattern can have different number of commands/rows/channels therefore you must use a variable patternwidth and length. * Up to 7 commands/note is possible * When allocating the needed amount of channels, check through the song to see which pattern that uses most channels. ÄÄÄÄÄÄÄÄÄÄÄÄÄ Volume ÄÄÄÄÄÄÄÄÄÄÄÄÄ (SampleVol*MasterVol*GlobalVol*ChannelMasterVol*EnvelopeVol/127^4)*FadeOut/65536 ÄÄÄÄÄÄÄÄÄÄÄÄÄ PanPot ÄÄÄÄÄÄÄÄÄÄÄÄÄ Sample panposition ranges from 0 to 15, where 0 means CH(annel). If it is set to CH, then use the default channel panpot instead of the sample panpot. Sample Panposition 8 is middle, 7 is skipped since 7 and 8 is the same on a GUS, and with an even number of panpositions you won't get a symmetric pan. If ChannelPan<=7 Then ChannelPan=ChannelPan-1 Pan=EnvelopePan/16-8+ChannelPan If Pan<0 Then Pan=0 If Pan>15 Then Pan=15 An 8xx command sets the ChannelPanpot, and if Sample Panpot is set to CH(annel) the ChannelPanpot will be used on the channel. If SamplePanpot is set to some value, that value is used instead, unless a 8xx is inserted on the same row as the note... Confusing? well, read it again... ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Freq ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Notes ranges from 0 to 119 (C-0 - B-9) AmigaFreq: PeriodTable: 109568,103418,97614,92135,86964,82083,77476,73128,69024,65150,61493,58042 Period=((Note MOD 12 [PeriodTable])/2^Note DIV 12) Freq=(16*428*C2rate)/Period+PerAdd Linear Freq: Freq = C4Rate*2 ^ ((Note+FreqAdd) / 12 - 4) (Actually the same as FT2, but with some minor modifications) ÄÄÄÄÄÄÄÄÄÄÄÄ FineTune ÄÄÄÄÄÄÄÄÄÄÄÄ AmigaFreq: If FineTune>7 Then FineTune=ABS(FineTune-16) PerAdd=(Period-1)-(Period)*FineTune/8 If FineTune<=7 Then PerAdd=ABS((Period)-(Period+1)*FineTune/8) (Period +/- 1 here means the Period for the note being finetuned +/- one note) Linear Freq: If FineTune>7 Then FreqAdd=NEG((FineTune-16)/8) Else FreqAdd=NEG(FineTune/8) (one note equals to 1 FreqAdd) ÄÄÄÄÄÄÄÄÄÄÄÄ Envelopes ÄÄÄÄÄÄÄÄÄÄÄÄ The Sinecurve for the envelope. (The 4:th part of the Sinecurve only. I calculate the other parts using this curve.) It has got 512 values since the maximum distance between 2 poins can be 512. EnvSine db 0,1,2,2,3,4,5,5,6,7,8,8,9,10,11,12,12,13,14,15,16,16,17,18,19,19,20,21,22,22,23,24,25,26,26,27,28,29,30,30,31,32,33,33,34,35,36,36,37,38,39,39,40,41,42,43,43,44,45,46,46,47,48,49,49,50,51,52,52,53,54,55,55,56,57,58,58,59,60,61,61,62,63,64,64,65,66,67,67,68,69,70,70,71,72,73,74,74,75,76,76,77,78,79,79,80,81,82,82,83,84,84,85,86,87,87,88,89,90,90,91,92,93,93,94,95,96,96,97,98,98,99,100,100,101,102,103,103,104,105,106,106,107,108,108,109,110,110,111,112,113,113,114,115,115,116,117,117,118 db 119,119,120,121,121,122,123,123,124,125,126,126,127,127,128,129,130,130,131,132,132,133,134,134,135,136,136,137,138,138,139,139,140,141,141,142,143,143,144,145,145,146,146,147,148,148,149,150,150,151,152,152,153,153,154,155,155,156,156,157,158,158,159,160,160,161,161,162,163,163,164,164,165,166,166,167,167,168,168,169,170,170,171,171,172,173,173,174,174,175,175,176,177,177,178,178,179,179,180,180,181,181,182,182,183,184,184,185,185,186,186,187,187,188,188,189,190,190,191,191,192,192,193 db 193,194,194,195,195,196,196,197,197,198,198,199,199,200,200,201,201,201,202,202,203,203,204,204,205,205,206,206,207,207,207,208,208,209,209,210,210,211,211,211,212,212,213,213,214,214,214,215,215,216,216,216,217,217,218,218,219,219,219,220,220,221,221,221,222,222,223,223,223,224,224,224,225,225,225,226,226,227,227,227,228,228,228,229,229,229,230,230,230,231,231,231,232,232,232,233,233,233,234,234,234,234,235,235,235,236,236,236,237,237,237,237,238,238,238,239,239,239,239,240,240,240,240 db 241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244,244,245,245,245,245,246,246,246,246,246,247,247,247,247,247,248,248,248,248,248,248,249,249,249,249,249,249,250,250,250,250,250,250,250,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 Envelope Types: 0=Line. A straight line, as in FT2 1=Sine1. 3:d or 4:th Part of the sinecurve depending on the locations of the points between 2=Sine2. 1:d or 2:d Part of the sinecurve depending on the locations of the points between --- / | \ | 4|1 | |-----| | 3|2 | \ | / --- The Break flag in the Envelope is used to stop looping the envelope when a keyoff is detected. Calculating the Vibrato Envelope: Using a sinecurve with full amplitude (80h) and Vibrato Amplify set to 3 equals the command 4xf played on C-5 (or using Linear Freq) Changing the Vib Amplify is just a matter of doubling/halving the amplitude. 0=No amplify 1=2*Amplitude 2=4*Amplitude 3=8*Amplitude A simple but clear "formula": Amp 80h, Ampf 0 = Amp 40h, Ampf 1 = Amp 20h, Ampf 2 = Amp 10h, Ampf 3 The following routine is used to unpack samples. There are no difference between 8 and 16 bits packing yet, and therefore 16 bits samples aren't packed very well... ;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² ; UnPack sample method 1 ;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² ; Input: ; esi = input offset ; edi = dest offset ; ecx = input size ; Output: ; ecx = output size ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± UnPackMethod1 Proc Near pushad mov inputoffset,esi mov outputoffset,edi mov inputsize,ecx ;unpacking mov esi,inputoffset mov edi,outputoffset mov ecx,dword ptr [esi] mov inputsize,ecx mov ecx,dword ptr [esi+4] mov al,byte ptr [esi+8] mov packcharacter,al add esi,9 unpackloop: lodsb cmp al,packcharacter jz unpacka stosb loop unpackloop jmp endofunpack unpacka: lodsb dec ecx cmp al,0 jz putpackcharacter push ecx movzx ecx,al lodsb rep stosb pop ecx dec ecx loop unpackloop jmp endofunpack putpackcharacter: mov al,packcharacter stosb loop unpackloop endofunpack: mov edi,inputoffset ;clear mov ecx,inputsize xor eax,eax mov edx,ecx shr ecx,2 rep stosd mov ecx,edx and ecx,3 rep stosb mov edi,inputoffset ;unpack bit split mov esi,outputoffset mov ebp,edi mov ecx,inputsize add ebp,ecx mov dl,10000000b bitunpackloop: push ecx xor dh,dh lodsb mov ecx,8 bitunpack2: mov bl,al and bl,dl add cl,dh ror bl,cl sub cl,dh ror dl,1 or byte ptr [edi],bl inc edi cmp edi,ebp jnz notsettaback mov edi,inputoffset inc dh notsettaback: loop bitunpack2 mov cl,dh ror dl,cl pop ecx loop bitunpackloop ;delta unpack mov esi,inputoffset mov edi,outputoffset mov ecx,inputsize xor bl,bl deltaunpack: lodsb cmp al,128 jz notnegative test al,10000000b jz notnegative and al,01111111b neg al notnegative: sub bl,al mov byte ptr [edi],bl inc edi loop deltaunpack sub edi,outputoffset mov inputoffset,edi popad mov ecx,inputoffset ret UnPackMethod1 Endp New commands ------------ 8 0x PanPosition (0-f) E 80 Break SampleLoop 10 00 Play Sample Forwards 10 01 Play Sample BackWards 10 02 Enable Bidirectional Loop (only on looped samples) 11 xx Extra Fine Slide Up (4 times finer than normal) 12 xx Extra Fine Slide Down (4times finer than normal) 13 xy Retrig with volslide (compare with E9) The x value tells if there should be a volumeslide between the retrigs. 0: 0 (No volslide) 8: 0 (No volslide) 1: -1 9: +1 2: -2 A: +2 3: -4 B: +4 4: -8 C: +8 5: -16 D: +16 6: 2/3 * the orig. vol. E: 3/2 * the orig vol 7: 1/2 * the orig. vol. F: 2 * the orig.vol. 15 xx Just Like 5, but with 2 times finer volslide. 16 xx Just Like 6, but with 2 times finer volslide. 1A xx 2 times finer volslide than A. 1C xx Channel MasterVolume (0-7fh) 1D xx Long PatternBreak (use instead of 0D when using long patterns). xx is in Hex 1E 1x Just like E1, but this uses all octaves. 1E 2x Just like E2, but this uses all octaves. 1E Ax 2 times Finer volslide than EA. 1E Bx 2 times Finer volslide than EB. 1F 0x Set BPM Decimal value. (0-9) 18 xy PanSlide x=left speed, y=right speed. 20 xx Key Off at tic xx 21 xx Just like 1, but this uses all octaves. 22 xx Just like 2, but this uses all octaves. 2A xx Global VolumeSlide 2C xx Global Volume (0-7fh) Well, that's about it. I guess there are alot of questions left so go ahead and ask me if there's something you wanna know. BTW, I don't take any responsibilities for faulty info in this doc :) (especially the formulas) Mail: ------ Patrik Oscarsson Hermansvagen 44 S-554 53 Jonkoping Sweden E-Mail. (Valid till Autumn '96) ------------------------------- da94ospa@hj.se Telephone --------- +46(0)36-711593