Commit b40338d

Nick Faro committed on
Handle continuous effects, duty sequences
commit b40338de4311408e52185af0fe989ae56fb0af6d parent 59fa72f
1 changed files +73−8
Modifiedtbmimport.pas +73−8
@@ -118,6 +118,15 @@ type
118 etSetGlobalVolume = 22 // `Jxy` set global volume scale 118 etSetGlobalVolume = 22 // `Jxy` set global volume scale
119 ); 119 );
120 120
121 const
122 ContinuousEffects = [
123 etArpeggio,
124 etPitchUp,
125 etPitchDown,
126 etAutoPortamento,
127 etVibrato
128 ];
129
121 function TStreamHelper.ReadLString: String; 130 function TStreamHelper.ReadLString: String;
122 var 131 var
123 Len: Word; 132 Len: Word;
@@ -169,13 +178,16 @@ begin
169 if Channel = itSquare then 178 if Channel = itSquare then
170 OutParams.Value := Params shl 6; 179 OutParams.Value := Params shl 6;
171 180
172 if Channel = itWave then 181 if Channel = itWave then begin
182 OutCode := $C;
183
173 case Params of 184 case Params of
174 0: OutParams.Value := $00; 185 0: OutParams.Value := $00;
175 1: OutParams.Value := $01; 186 1: OutParams.Value := $01;
176 2: OutParams.Value := $08; 187 2: OutParams.Value := $08;
177 3: OutParams.Value := $0F; 188 3: OutParams.Value := $0F;
178 end; 189 end;
190 end;
179 191
180 if Channel = itNoise then begin 192 if Channel = itNoise then begin
181 if Params > 0 then 193 if Params > 0 then
@@ -263,6 +275,10 @@ begin
263 Continue; 275 Continue;
264 276
265 ConvertEffect(Row.Effects[I].EffectType, Row.Effects[I].Param, RowType, Result.EffectCode, Result.EffectParams); 277 ConvertEffect(Row.Effects[I].EffectType, Row.Effects[I].Param, RowType, Result.EffectCode, Result.EffectParams);
278 if TTBMEffectType(Row.Effects[I].EffectType) in ContinuousEffects then
279 Result.Volume := 1 // Mark this effect as "continuous"
280 else
281 Result.Volume := 0;
266 end; 282 end;
267 283
268 if Row.Note = 0 then 284 if Row.Note = 0 then
@@ -280,6 +296,8 @@ procedure CleanupPattern(Pat: PPattern; InstMap: TTBMInstrumentMap);
280 var 296 var
281 I: Integer; 297 I: Integer;
282 CurNote: Integer = NO_NOTE; 298 CurNote: Integer = NO_NOTE;
299 ContinuousCode: Byte = 0;
300 ContinuousParam: Byte = 0;
283 begin 301 begin
284 for I := Low(TPattern) to High(TPattern) do begin 302 for I := Low(TPattern) to High(TPattern) do begin
285 if not InstMap.TryGetData(Pat^[I].Instrument-1, Pat^[I].Instrument) then 303 if not InstMap.TryGetData(Pat^[I].Instrument-1, Pat^[I].Instrument) then
@@ -290,6 +308,18 @@ begin
290 308
291 if (Pat^[I].Instrument <> 0) and (Pat^[I].Note = NO_NOTE) then 309 if (Pat^[I].Instrument <> 0) and (Pat^[I].Note = NO_NOTE) then
292 Pat^[I].Note := CurNote; 310 Pat^[I].Note := CurNote;
311
312 if Pat^[I].Volume = 1 then begin
313 ContinuousCode := Pat^[I].EffectCode;
314 ContinuousParam := Pat^[I].EffectParams.Value;
315 end;
316
317 if (ContinuousParam <> 0) and (Pat^[I].EffectCode = 0) and (Pat^[I].EffectParams.Value = 0) then begin
318 Pat^[I].EffectCode := ContinuousCode;
319 Pat^[I].EffectParams.Value := ContinuousParam;
320 end;
321
322 Pat^[I].Volume := 0;
293 end; 323 end;
294 end; 324 end;
295 325
@@ -341,7 +371,7 @@ begin
341 Stream.ReadBuffer(SongFormat, SizeOf(TTBMSongFormat)); 371 Stream.ReadBuffer(SongFormat, SizeOf(TTBMSongFormat));
342 Stream.ReadByte; // ????????????????? 372 Stream.ReadByte; // ?????????????????
343 373
344 Result.TicksPerRow := SongFormat.RowsPerBeat - 1; 374 Result.TicksPerRow := SongFormat.RowsPerBeat;
345 375
346 for I := Low(Result.OrderMatrix) to High(Result.OrderMatrix) do 376 for I := Low(Result.OrderMatrix) to High(Result.OrderMatrix) do
347 SetLength(Result.OrderMatrix[I], SongFormat.PatternCount+2); // off-by-one error on my part 377 SetLength(Result.OrderMatrix[I], SongFormat.PatternCount+2); // off-by-one error on my part
@@ -422,15 +452,20 @@ begin
422 452
423 Ins^.SubpatternEnabled := True; 453 Ins^.SubpatternEnabled := True;
424 454
455 // Arpeggio sequence
425 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat)); 456 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat));
426 for J := 0 to SeqFormat.Length-1 do begin 457 for J := 0 to SeqFormat.Length-1 do begin
427 Offs := ShortInt(Stream.ReadByte); 458 Offs := ShortInt(Stream.ReadByte);
428 Ins^.Subpattern[J].Note := MIDDLE_NOTE + Offs; 459 Ins^.Subpattern[J].Note := MIDDLE_NOTE + Offs;
429 end; 460 end;
430 461
462 Ins^.Subpattern[SeqFormat.Length].Volume := SeqFormat.LoopIndex;
463
464 // Panning sequence
431 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat)); 465 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat));
432 Stream.Seek(SeqFormat.Length, soCurrent); 466 Stream.Seek(SeqFormat.Length, soCurrent);
433 467
468 // Pitch sequence
434 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat)); 469 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat));
435 PitchOffset := 0; 470 PitchOffset := 0;
436 Offs := 0; 471 Offs := 0;
@@ -450,13 +485,43 @@ begin
450 485
451 Ins^.Subpattern[SeqFormat.Length].Volume := SeqFormat.LoopIndex; 486 Ins^.Subpattern[SeqFormat.Length].Volume := SeqFormat.LoopIndex;
452 487
488 // Duty/noise-type sequence
453 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat)); 489 Stream.ReadBuffer(SeqFormat, SizeOf(TTBMSequenceFormat));
454 if (InsType = itSquare) and (SeqFormat.Length > 0) then begin 490 case InsType of
455 Ins^.Duty := Stream.ReadByte; 491 itSquare: begin
456 Stream.Seek(SeqFormat.Length-1, soCurrent); 492 for J := 0 to SeqFormat.Length-1 do begin
457 end 493 Ins^.Subpattern[J].EffectCode := $9;
458 else 494 case Stream.ReadByte of
459 Stream.Seek(SeqFormat.Length, soCurrent); 495 0: Ins^.Subpattern[J].EffectParams.Value := $00;
496 1: Ins^.Subpattern[J].EffectParams.Value := $40;
497 2: Ins^.Subpattern[J].EffectParams.Value := $80;
498 3: Ins^.Subpattern[J].EffectParams.Value := $C0;
499 end;
500 end;
501 end;
502 itWave: begin
503 for J := 0 to SeqFormat.Length-1 do begin
504 Ins^.Subpattern[J].EffectCode := $C;
505 case Stream.ReadByte of
506 0: Ins^.Subpattern[J].EffectParams.Value := $00;
507 1: Ins^.Subpattern[J].EffectParams.Value := $01;
508 2: Ins^.Subpattern[J].EffectParams.Value := $08;
509 3: Ins^.Subpattern[J].EffectParams.Value := $0F;
510 end;
511 end;
512 end;
513 itNoise: begin
514 for J := 0 to SeqFormat.Length-1 do begin
515 Ins^.Subpattern[J].EffectCode := $9;
516 if Stream.ReadByte = 0 then
517 Ins^.Subpattern[J].EffectParams.Value := $00
518 else
519 Ins^.Subpattern[J].EffectParams.Value := $80;
520 end;
521 end
522 end;
523
524 Ins^.Subpattern[SeqFormat.Length].Volume := SeqFormat.LoopIndex;
460 end; 525 end;
461 526
462 // WAVE Block 527 // WAVE Block