⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alut.pas

📁 Newton Game Dynamic 1.52 Delphi下基于GLScene的OpenGL游戏开发控件。功能非常强大和易于使用。 Advanced physics engine for re
💻 PAS
字号:
{
  Aki Nieminen contribution:
     Added Bool2ALBool helper function
}

{********************************************************************}
{ OpenAL cross platform audio library                                }
{ Copyright (C) 1999-2000 by authors.                                }
{ This library is free software; you can redistribute it and/or      }
{  modify it under the terms of the GNU Library General Public       }
{  License as published by the Free Software Foundation; either      }
{  version 2 of the License, or (at your option) any later version.  }
{                                                                    }
{ This library is distributed in the hope that it will be useful,    }
{  but WITHOUT ANY WARRANTY; without even the implied warranty of    }
{  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU }
{  Library General Public License for more details.                  }
{                                                                    }
{ You should have received a copy of the GNU Library General Public  }
{  License along with this library; if not, write to the             }
{  Free Software Foundation, Inc., 59 Temple Place - Suite 330,      }
{  Boston, MA  02111-1307, USA.                                      }
{ Or go to http://www.gnu.org/copyleft/lgpl.html                     }
{                                                                    }
{********************************************************************}

{********************************************************************}
{                                                                    }
{       Borland Delphi Runtime Library                               }
{       Copyright (c) 1995,2001 Borland International                }
{       Created by Project JEDI                                      }
{                                                                    }
{ The original Pascal code is: ALut.pas 	                           }
{ The initial developer of the Pascal code is Dominique Louis        }
{                                                                    }
{                                                                    }
{ Portions created by Dominique Louis are    	  			               }
{ Copyright (C) 2001 Dominique Louis (Dominique@SavageSoftware.com.au}
{                                                                    }
{ Portions created by Amresh Ramachandran are    	  			           }
{ Copyright (C) 2001 Amresh Ramachandran (amreshr@hotmail.com)       }
{                                                                    }
{ Contributor(s): Dominique Louis                                    }
{                 Amresh Ramachandran                                }
{                                                                    }
{       Obtained through:                                            }
{                                                                    }
{       Joint Endeavour of Delphi Innovators (Project JEDI)          }
{                                                                    }
{ You may retrieve the latest version of this file at the Project    }
{ JEDI home page, located at http://delphi-jedi.org                  }
{                                                                    }
{ The contents of this file are used with permission, subject to     }
{ the Mozilla Public License Version 1.1 (the "License"); you may    }
{ not use this file except in compliance with the License. You may   }
{ obtain a copy of the License at                                    }
{ http://www.mozilla.org/MPL/MPL-1.1.html 	                         }
{                                                                    }
{ Software distributed under the License is distributed on an 	     }
{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or     }
{ implied. See the License for the specific language governing       }
{ rights and limitations under the License. 				                 }
{                                                                    }
{********************************************************************}

unit ALut;
{***************************************************************
 *
 * Unit Name         : ALut
 * Purpose           :
 *  This is an interface unit for the use of OpenAL from within Delphi and
 *  contains the translations of alut.h and alut.c.
 * Author            : Amresh Ramachandran amreshr@hotmail.com
 * Project name      : OpenAL Delphi Translation
 * Created           : 12-Oct-2001
 * History           :
 * - first translation from Dominique Louis.
 * - previous versions from Amresh Ramachandran
 * - Amresh Ramachandran
 * - Saturday, October 20, 2001 16:12
 * Made a change in the division coz I was not able to read the full data. It
 * is not correct but now the whole wave file is read instead of only a portion
 * :)
 * Friday, October 19, 2001 16:16
 * - Finally got alutLoadWAVFile to work! Yeah! baby let's rock!
 * but it loads only half the file.
 * Thursday, October 18, 2001 15:16
 * - Changed if (not CompareMem(...)) to if (CompareMem(...))
 *  This loads data, but I still am not able to hear anything
 *  The orginal version always returned a nil pointer in data
 * - FillChar fixed (I think)
 *
 ****************************************************************}

interface

uses
	ALtypes, Classes;

const
	AL32 = 'OpenAL32.dll';

type
	TWAVFileHdr_Struct = packed record // WAV File-header
		Id: array[0..3] of TALubyte;
		Size: TALsizei;
		type_: array[0..3] of TALubyte;
	end;

	TWAVFmtHdr_Struct = packed record // WAV Fmt-header
		Format: TALushort;
		Channels: TALushort;
		SamplesPerSec: TALuint;
		BytesPerSec: TALuint;
		BlockAlign: TALushort;
		BitsPerSample: TALushort;
	end;

	TWAVFmtExHdr_Struct = packed record // WAV FmtEx-header
		Size: TALushort;
		SamplesPerBlock: TALushort;
	end;

	TLoop = packed record
		Identifier: TALuint;
		Type_: TALuint;
		Start: TALuint;
		End_: TALuint;
		Fraction: TALuint;
		Count: TALuint;
	end;

	TWAVSmplHdr_Struct = packed record // WAV Smpl-header
		Manufacturer: TALuint;
		Product: TALuint;
		SamplePeriod: TALuint;
		Note: TALuint;
		FineTune: TALuint;
		SMPTEFormat: TALuint;
		SMPTEOffest: TALuint;
		Loops: TALuint;
		SamplerData: TALuint;
		Loop: TLoop;
	end;

	TWAVChunkHdr_Struct = packed record // WAV Chunk-header
		Id: array[0..3] of TALubyte;
		Size: TALuint;
	end;

	TALutMemoryStream = class(TMemoryStream);

procedure alutInit(argc: PALint; argv: array of PChar);
procedure alutExit;

procedure alutLoadWAVFile(fname: string; var format: TALenum; var data:
	TALvoid;
	var size: TALsizei; var freq: TALsizei; var loop: TALint);
procedure alutLoadWAVMemory(memory: PALbyte; var format: TALenum; var data:
	TALvoid; var size: TALsizei; var freq: TALsizei; var loop: TALint);
procedure alutUnloadWAV(format: TALenum; data: TALvoid; size: TALsizei; freq:
	TALsizei);

//*********************************
//*** Aki Nieminen contribution ***
//*********************************
function Bool2ALBool(b: boolean): TALInt;

//*********************************
//*********************************

implementation

uses SysUtils, Alc;

procedure alutInit(argc: PALint; argv: array of PChar);
var
  Context: PALCcontext;
  Device: PALCdevice;
begin
  //Open device: DirectSound3D, nil
  //  nil = supposed to select "preferred device"
  Device := alcOpenDevice('DirectSound3D');
  //Device := alcOpenDevice(nil);
  //Create context(s)
  Context := alcCreateContext(Device, nil);
  //Set active context
  alcMakeContextCurrent(Context);
  //Register extensions
  // <no extensions>
end;

procedure alutExit;
var
  Context: PALCcontext;
  Device: PALCdevice;
begin
  //Unregister extensions
  // <no extensions>
  //Get active context
  Context := alcGetCurrentContext;
  //Get device for active context
  Device := alcGetContextsDevice(Context);
  //Release context(s)
  alcDestroyContext(Context);
  //Close device
  alcCloseDevice(Device);
end;

procedure alutLoadWAVFile(fname: string; var format: TALenum; var data:
  TALvoid; var size: TALsizei; var freq: TALsizei; var loop: TALint);
var
   ChunkHdr: TWAVChunkHdr_Struct;
   FmtExHdr: TWAVFmtExHdr_Struct;
	FileHdr: TWAVFileHdr_Struct;
	SmplHdr: TWAVSmplHdr_Struct;
	FmtHdr: TWAVFmtHdr_Struct;
	Stream: TFileStream;
begin
	format := AL_FORMAT_MONO16;
	data := nil;
	size := 0;
	freq := 22050;
	loop := AL_FALSE;
	if (fname <> '') then begin
		Stream := TFileStream.Create(fname, fmOpenRead);
		try
			if (Stream <> nil) then begin
				Stream.Read(FileHdr, sizeof(TWAVFileHdr_Struct));
				FileHdr.Size := ((FileHdr.Size + 1) xor 1) - 4;
				while ((FileHdr.Size <> 0) and
					(Stream.Read(ChunkHdr, sizeof(TWAVChunkHdr_Struct)) <> 0)) do
				begin
					if (CompareMem(@ChunkHdr.Id, PChar('fmt '), 4)) then begin
						Stream.Read(FmtHdr, sizeof(TWAVFmtHdr_Struct));
						if (FmtHdr.Format = $0001) then begin
							if FmtHdr.Channels = 1 then begin
								if FmtHdr.BitsPerSample = 8 then
									format := AL_FORMAT_MONO8
								else
									format := AL_FORMAT_MONO16;
							end else if FmtHdr.BitsPerSample = 8 then
								format := AL_FORMAT_STEREO8
							else
								format := AL_FORMAT_STEREO16;
							freq := FmtHdr.SamplesPerSec;
							Stream.Seek(ChunkHdr.Size - sizeof(TWAVFmtHdr_Struct),
								soFromCurrent);
						end else begin
							Stream.Read(FmtExHdr, sizeof(TWAVFmtExHdr_Struct));
							Stream.Seek(ChunkHdr.Size - sizeof(TWAVFmtHdr_Struct) - sizeof(
								TWAVFmtExHdr_Struct), soFromCurrent);
						end;
					end else if (CompareMem(@ChunkHdr.Id, PChar('data'), 4)) then begin
						if (FmtHdr.Format = $0001) then begin
							size := ChunkHdr.Size;
							data := AllocMem(ChunkHdr.Size + 31);
							if (data <> nil) then
								Stream.Read(data^, Round(ChunkHdr.Size {/ FmtHdr.BlockAlign}));
							FillChar(PByteArray(data)[ChunkHdr.Size], 31, 0);
						end else if (FmtHdr.Format = $0011) then begin
         			   //IMA ADPCM
						end else if (FmtHdr.Format = $0055) then begin
                     //MP3 WAVE
						end;
					end
//					else if (not CompareMem(@ChunkHdr.Id, PChar('smpl'), 4)) then
					else if (CompareMem(@ChunkHdr.Id, PChar('smpl'), 4)) then begin
						Stream.Read(SmplHdr, sizeof(TWAVSmplHdr_Struct));
						if SmplHdr.Loops <> 0 then
							loop := AL_TRUE
						else
							loop := AL_FALSE;
						Stream.Seek(ChunkHdr.Size - sizeof(TWAVSmplHdr_Struct), soFromCurrent
							);
					end else
						Stream.Seek(ChunkHdr.Size, soFromCurrent);
					Stream.Seek(ChunkHdr.Size and 1, soFromCurrent);
					FileHdr.Size := FileHdr.Size - (((ChunkHdr.Size + 1) and not 1) + 8);
				end;
			end;
		finally
			Stream.Free;
		end;
	end;
end;

procedure alutLoadWAVMemory(memory: PALbyte; var format: TALenum; var data:
	TALvoid; var size: TALsizei; var freq: TALsizei; var loop: TALint);
var
	ChunkHdr: TWAVChunkHdr_Struct;
	FmtExHdr: TWAVFmtExHdr_Struct;
	FileHdr: TWAVFileHdr_Struct;
	SmplHdr: TWAVSmplHdr_Struct;
	FmtHdr: TWAVFmtHdr_Struct;
	Stream: TMemoryStream;
begin
	// Start : not yet tested
	format := AL_FORMAT_MONO16;
	data := nil;
	size := 0;
	freq := 22050;
	loop := AL_FALSE;

	if (memory <> nil) then begin
		Stream := TMemoryStream.Create;
		TALutMemoryStream(Stream).SetPointer(memory, sizeof(memory^)); //???
		try
			if (Stream <> nil) then begin
				Stream.Read(FileHdr, sizeof(TWAVFileHdr_Struct));
				Stream.Seek(sizeof(TWAVFileHdr_Struct), soFromCurrent);
				FileHdr.Size := ((FileHdr.Size + 1) xor 1) - 4;
				while ((FileHdr.Size <> 0) and
					(Stream.Read(ChunkHdr, sizeof(TWAVChunkHdr_Struct)) <> 0)) do
				begin
					Stream.Seek(sizeof(TWAVChunkHdr_Struct), soFromCurrent);
					if CompareMem(@ChunkHdr.Id, PChar('fmt '), 4) then begin
						Stream.Read(FmtHdr, sizeof(TWAVFmtHdr_Struct));
						if (FmtHdr.Format = $0001) then begin
							if FmtHdr.Channels = 1 then begin
								if FmtHdr.BitsPerSample = 8 then
									format := AL_FORMAT_MONO8
								else
									format := AL_FORMAT_MONO16;
							end else if FmtHdr.BitsPerSample = 8 then
								format := AL_FORMAT_STEREO8
							else
								format := AL_FORMAT_STEREO16;
							freq := FmtHdr.SamplesPerSec;
							Stream.Seek(ChunkHdr.Size, soFromCurrent);
						end else begin
							Stream.Read(FmtExHdr, sizeof(TWAVFmtExHdr_Struct));
							Stream.Seek(ChunkHdr.Size, soFromCurrent);
						end;
					end else if (CompareMem(@ChunkHdr.Id, PChar('data'), 4)) then begin
						if (FmtHdr.Format = $0001) then begin
							size := ChunkHdr.Size;
							data := AllocMem(ChunkHdr.Size + 31);
							if (data <> nil) then
								Stream.Read(data, ChunkHdr.Size);
							FillChar(PChar(data)[ChunkHdr.Size], 31, 0);
							Stream.Seek(ChunkHdr.Size, soFromCurrent);
						end else if (FmtHdr.Format = $0011) then begin
							//IMA ADPCM
						end else if (FmtHdr.Format = $0055) then begin
							//MP3 WAVE
						end
					end else if (CompareMem(@ChunkHdr.Id, PChar('smpl'), 4)) then begin
						Stream.Read(SmplHdr, sizeof(TWAVSmplHdr_Struct));
						if SmplHdr.Loops <> 0 then
							loop := AL_TRUE
						else
							loop := AL_FALSE;
						Stream.Seek(ChunkHdr.Size, soFromCurrent);
					end else
						Stream.Seek(ChunkHdr.Size, soFromCurrent);
					Stream.Seek(ChunkHdr.Size and 1, soFromCurrent);
					FileHdr.Size := FileHdr.Size - (((ChunkHdr.Size + 1) and not 1) + 8);
				end;
			end;
		finally
			Stream.Free;
		end;
	end;
end;

procedure alutUnloadWAV(format: TALenum; data: TALvoid; size: TALsizei; freq:
	TALsizei);
begin
	if assigned(data) then begin
		Dispose(data);
		//Data := nil;      
	end;
end;

//*********************************
//*** Aki Nieminen contribution ***
//*********************************

{ Helper function: convert boolean to AL_TRUE/AL_FALSE }
function Bool2ALBool(b: boolean): TALInt;
begin
   if (b) then Result := AL_TRUE
   else Result := AL_FALSE;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -