home *** CD-ROM | disk | FTP | other *** search
- { Copyright 1995 by Ethan Brodsky. All rights reserved. }
- program SBPlay; {$X+}
- uses
- CRT,
- DOS,
- SBIO,
- XMS;
- const
- BaseIO = $220;
- IRQ = 5;
- DMA16 = 5;
- LoadChunkSize = 8192;
- BlockLength = 256;
- type
- PBuffer = ^TBuffer;
- TBuffer = array[1..2] of array[1..BlockLength] of integer;
- var
- Rate: word;
- FileName: string;
-
- NumSamples: LongInt;
- Buffer: PBuffer;
-
- Handle: word;
- CurSample: LongInt;
- MoveParams: TMoveParams;
-
- function GetParameters(var Rate: word; var FName: string): boolean;
- var
- Code: integer;
- i: byte;
- begin
- GetParameters := false;
- if ParamCount <> 2
- then
- Exit
- else
- begin
- Val(ParamStr(1), Rate, Code);
- if Code <> 0 then Exit;
-
- FName := ParamStr(2);
- for i := 1 to Length(FName) do FName[i] := UpCase(FName[i]);
- GetParameters := true;
- end;
- end;
-
- procedure CopyBlock(Offset: LongInt; Block: byte);
- begin
- with MoveParams do
- begin
- if (CurSample + BlockLength) <= NumSamples
- then Length := BlockLength*2
- else
- begin
- Length := (NumSamples-CurSample) * 2;
- FillChar(Buffer^[Block][BlockLength - (Length div 2) + 1], (BlockLength-(Length div 2))*2, $00);
- end;
- SourceHandle := Handle;
- SourceOffset := Offset;
- DestHandle := 0;
- DestOffset := LongInt(@(Buffer^[Block]));
- end;
- XMSMove(@MoveParams);
- end;
-
- procedure PlayHandler; far;
- var
- Result: word;
- i: word;
- begin
- if CurSample < NumSamples
- then
- begin
- CopyBlock(CurSample*2, CurBlock);
- Inc(CurSample, BlockLength);
- end
- else
- begin
- FillChar(Buffer^[CurBlock], BlockLength*2, $00);
- end;
-
- end;
-
- procedure LoadData;
- var
- f: file;
- Chunk: array[1..LoadChunkSize] of byte;
- Size: LongInt;
- Result, i: word;
- begin
- Assign(f, FileName); Reset(f, 1);
- Size := FileSize(f); NumSamples := Size div 2;
-
- XMSInit;
- if not(XMSAllocate(Handle, (NumSamples*2 div 1024)+1))
- then
- begin
- writeln('ERROR: Not enough free XMS');
- writeln(' Bytes required: ', 2 * NumSamples);
- writeln(' Bytes free: ', XMSGetFreeMem * 1024);
- Halt(2);
- end;
-
- with MoveParams do
- begin
- SourceHandle := 0;
- SourceOffset := LongInt(@Chunk);
- DestHandle := Handle;
- DestOffset := 0;
- end;
- repeat
- if Size > LoadChunkSize
- then MoveParams.Length := LoadChunkSize
- else MoveParams.Length := Size;
- BlockRead(f, Chunk, MoveParams.Length, Result);
- if Result < LoadChunkSize
- then for i := Result+1 to LoadChunkSize do Chunk[i] := 0;
- XMSMove(@MoveParams);
- Inc(MoveParams.DestOffset, MoveParams.Length);
- Dec(Size, MoveParams.Length);
- until Size <= 0;
-
- Close(f)
- end;
-
- procedure Init;
- begin
- LoadData;
- GetBuffer(pointer(Buffer), BlockLength);
- CopyBlock(0, 1);
- CopyBlock(BlockLength, 2);
- CurSample := BlockLength*2;
-
- SetHandler(@PlayHandler);
- SBIO.Init(BaseIO, IRQ, DMA16, Output, Rate);
- StartIO(NumSamples);
- end;
-
- procedure Shutdown;
- begin
- SBIO.Shutdown;
- SetHandler(nil);
-
- XMSFree(Handle);
-
- FreeBuffer(pointer(Buffer));
- end;
-
- begin
- writeln('SBPLAY - Copyright 1995 by Ethan Brodsky. All rights reserved.');
- if GetParameters(Rate, FileName)
- then
- writeln('Playing ', FileName, ' at ', Rate, ' HZ')
- else
- begin
- writeln('Syntax: sbrecord <rate> <filename>');
- writeln('Example: sbrecord 22050 data.raw');
- Halt(1);
- end;
-
- Init;
-
- repeat
- { writeln(DMACount:5);}
- until Done or KeyPressed;
-
- if KeyPressed
- then
- begin
- writeln('Output terminated by key press');
- ReadKey;
- end;
-
- Shutdown;
-
- writeln;
- end.
-